diff --git a/src/achown.h b/src/achown.h index eff3f7a32..0449c177f 100644 --- a/src/achown.h +++ b/src/achown.h @@ -18,4 +18,4 @@ void chown_advanced_cmd (void); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__ACHOWN_H */ diff --git a/src/background.h b/src/background.h index bbbcc109b..26de3ba02 100644 --- a/src/background.h +++ b/src/background.h @@ -52,4 +52,4 @@ void unregister_task_with_pid (pid_t pid); #endif /* !WITH_BACKGROUND */ -#endif /* MC_BACKGROUND_H */ +#endif /* MC__BACKGROUND_H */ diff --git a/src/boxes.h b/src/boxes.h index a04bde582..af1e48fc7 100644 --- a/src/boxes.h +++ b/src/boxes.h @@ -30,4 +30,4 @@ void symlink_dialog (const char *existing, const char *new, char **ret_existing, char *tree_box (const char *current_dir); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__BOXES_H */ diff --git a/src/charsets.h b/src/charsets.h index f2325b190..bb1a59271 100644 --- a/src/charsets.h +++ b/src/charsets.h @@ -106,4 +106,4 @@ convert_from_input_c (int c) #endif /* HAVE_CHARSET */ -#endif /* MC_CHARSETS_H */ +#endif /* MC__CHARSETS_H */ diff --git a/src/chmod.h b/src/chmod.h index 8c406a4d7..7b6d833d5 100644 --- a/src/chmod.h +++ b/src/chmod.h @@ -18,4 +18,4 @@ void chmod_cmd (void); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__CHMOD_H */ diff --git a/src/chown.h b/src/chown.h index e70303914..ba86ec4d6 100644 --- a/src/chown.h +++ b/src/chown.h @@ -18,4 +18,4 @@ void chown_cmd (void); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__CHOWN_H */ diff --git a/src/clipboard.h b/src/clipboard.h index 770b1dbd4..795f66f0b 100644 --- a/src/clipboard.h +++ b/src/clipboard.h @@ -19,4 +19,4 @@ gboolean copy_file_to_ext_clip (void); gboolean paste_to_file_from_ext_clip (void); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__CLIPBOARD_H */ diff --git a/src/cmd.h b/src/cmd.h index 8a6e00ecc..c397850c1 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -101,4 +101,4 @@ void toggle_listing_cmd (void); void encoding_cmd (void); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__CMD_H */ diff --git a/src/cmddef.h b/src/cmddef.h index ff9635736..c89b2aa7f 100644 --- a/src/cmddef.h +++ b/src/cmddef.h @@ -524,4 +524,4 @@ /*** declarations of public functions ************************************************************/ /*** inline functions ****************************************************************************/ -#endif /* MC_CMD_DEF_H */ +#endif /* MC__CMD_DEF_H */ diff --git a/src/command.h b/src/command.h index c5240ab61..795cabd29 100644 --- a/src/command.h +++ b/src/command.h @@ -24,4 +24,4 @@ void do_cd_command (char *cmd); void command_insert (WInput * in, const char *text, int insert_extra_space); /*** inline functions ****************************************************************************/ -#endif +#endif /* MC__COMMAND_H */ diff --git a/src/dialog-switch.c b/src/dialog-switch.c index 3db7de685..21e334710 100644 --- a/src/dialog-switch.c +++ b/src/dialog-switch.c @@ -37,13 +37,15 @@ #include "wtools.h" /* Listbox */ #include "dialog-switch.h" -/*** global variables **************************************************/ -/*** file scope macro definitions **************************************/ +/*** global variables ****************************************************************************/ -/*** file scope type declarations **************************************/ +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ -/*** file scope variables **********************************************/ /* List of dialogs: filemanagers, editors, viewers */ static GList *mc_dialogs = NULL; @@ -52,7 +54,8 @@ static GList *mc_current = NULL; /* Is there any dialogs that we have to run after returning to the manager from another dialog */ static gboolean dialog_switch_pending = FALSE; -/*** file scope functions **********************************************/ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static unsigned char get_hotkey (int n) @@ -60,8 +63,10 @@ get_hotkey (int n) return (n <= 9) ? '0' + n : 'a' + n - 10; } +/* --------------------------------------------------------------------------------------------- */ + static void -dialog_switch_goto (GList *dlg) +dialog_switch_goto (GList * dlg) { if (mc_current != dlg) { @@ -91,10 +96,12 @@ dialog_switch_goto (GList *dlg) } } -/*** public functions **************************************************/ +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ void -dialog_switch_add (Dlg_head *h) +dialog_switch_add (Dlg_head * h) { GList *dlg; @@ -109,8 +116,10 @@ dialog_switch_add (Dlg_head *h) } } +/* --------------------------------------------------------------------------------------------- */ + void -dialog_switch_remove (Dlg_head *h) +dialog_switch_remove (Dlg_head * h) { GList *this; @@ -128,12 +137,16 @@ dialog_switch_remove (Dlg_head *h) mc_current = mc_dialogs; } +/* --------------------------------------------------------------------------------------------- */ + size_t dialog_switch_num (void) { return g_list_length (mc_dialogs); } +/* --------------------------------------------------------------------------------------------- */ + void dialog_switch_next (void) { @@ -149,6 +162,8 @@ dialog_switch_next (void) dialog_switch_goto (next); } +/* --------------------------------------------------------------------------------------------- */ + void dialog_switch_prev (void) { @@ -164,6 +179,8 @@ dialog_switch_prev (void) dialog_switch_goto (prev); } +/* --------------------------------------------------------------------------------------------- */ + void dialog_switch_list (void) { @@ -177,8 +194,8 @@ dialog_switch_list (void) if (midnight_shutdown || mc_current == NULL) return; - lines = min ((size_t) (LINES * 2/3), dlg_num); - cols = COLS * 2/3; + lines = min ((size_t) (LINES * 2 / 3), dlg_num); + cols = COLS * 2 / 3; listbox = create_listbox_window (lines, cols, _("Screens"), "[Screen selector]"); @@ -190,7 +207,7 @@ dialog_switch_list (void) dlg = (Dlg_head *) h->data; if ((dlg != NULL) && (dlg->get_title != NULL)) - title = dlg->get_title (dlg, listbox->list->widget.cols - 2); /* FIXME! */ + title = dlg->get_title (dlg, listbox->list->widget.cols - 2); /* FIXME! */ else title = g_strdup (""); @@ -209,6 +226,8 @@ dialog_switch_list (void) } } +/* --------------------------------------------------------------------------------------------- */ + int dialog_switch_process_pending (void) { @@ -238,6 +257,8 @@ dialog_switch_process_pending (void) return ret; } +/* --------------------------------------------------------------------------------------------- */ + void dialog_switch_got_winch (void) { @@ -248,6 +269,8 @@ dialog_switch_got_winch (void) ((Dlg_head *) dlg->data)->winch_pending = TRUE; } +/* --------------------------------------------------------------------------------------------- */ + void dialog_switch_shutdown (void) { @@ -259,3 +282,5 @@ dialog_switch_shutdown (void) destroy_dlg (dlg); } } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/dialog-switch.h b/src/dialog-switch.h index adfdfb68c..6fc81c746 100644 --- a/src/dialog-switch.h +++ b/src/dialog-switch.h @@ -1,11 +1,22 @@ -#ifndef MC_DIALOG_SWITCH_H -#define MC_DIALOG_SWITCH_H +#ifndef MC__DIALOG_SWITCH_H +#define MC__DIALOG_SWITCH_H #include + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + struct Dlg_head; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + void dialog_switch_add (struct Dlg_head *h); void dialog_switch_remove (struct Dlg_head *h); size_t dialog_switch_num (void); @@ -18,4 +29,5 @@ int dialog_switch_process_pending (void); void dialog_switch_got_winch (void); void dialog_switch_shutdown (void); -#endif /* MC_DIALOG_SWITCH_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__DIALOG_SWITCH_H */ diff --git a/src/dialog.c b/src/dialog.c index 83946e632..0cdf1bd09 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -48,6 +48,8 @@ #include "dialog-switch.h" +/*** global variables ****************************************************************************/ + /* Color styles for normal and error dialogs */ dlg_colors_t dialog_colors; dlg_colors_t alarm_colors; @@ -62,15 +64,488 @@ hook_t *idle_hook = NULL; /* left click outside of dialog closes it */ int mouse_close_dialog = 0; +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/** What to do if the requested widget doesn't take focus */ +typedef enum +{ + SELECT_NEXT, /* go the the next widget */ + SELECT_PREV, /* go the the previous widget */ + SELECT_EXACT /* use current widget */ +} select_dir_t; + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, gboolean reverse, int flags); -/* draw box in window */ +/* --------------------------------------------------------------------------------------------- */ +/** + * broadcast a message to all the widgets in a dialog that have + * the options set to flags. If flags is zero, the message is sent + * to all widgets. + */ + +static void +dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, gboolean reverse, int flags) +{ + GList *p, *first; + + if (h->widgets == NULL) + return; + + if (h->current == NULL) + h->current = h->widgets; + + if (reverse) + { + p = g_list_previous (h->current); + + if (p == NULL) + p = g_list_last (h->widgets); + } + else + { + p = g_list_next (h->current); + + if (p == NULL) + p = h->widgets; + } + + first = p; + + do + { + Widget *w = (Widget *) p->data; + + if (reverse) + { + p = g_list_previous (p); + + if (p == NULL) + p = g_list_last (h->widgets); + } + else + { + p = g_list_next (p); + + if (p == NULL) + p = h->widgets; + } + + if ((flags == 0) || ((flags & w->options) != 0)) + send_message (w, message, 0); + } + while (first != p); +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +dlg_unfocus (Dlg_head * h) +{ + /* ... but can unfocus disabled widget */ + + if ((h->current != NULL) && (h->state == DLG_ACTIVE)) + { + Widget *current = (Widget *) h->current->data; + + if (send_message (current, WIDGET_UNFOCUS, 0) == MSG_HANDLED) + { + h->callback (h, current, DLG_UNFOCUS, 0, NULL); + return 1; + } + } + + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +dlg_find_widget_callback (const void *a, const void *b) +{ + const Widget *w = (const Widget *) a; + callback_fn f = (callback_fn) b; + + return (w->callback == f) ? 0 : 1; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Try to select another widget. If forward is set, follow tab order. + * Otherwise go to the previous widget. + */ + +static void +do_select_widget (Dlg_head * h, GList * w, select_dir_t dir) +{ + Widget *w0 = (Widget *) h->current->data; + + if (!dlg_unfocus (h)) + return; + + h->current = w; + + do + { + if (dlg_focus (h)) + break; + + switch (dir) + { + case SELECT_NEXT: + h->current = g_list_next (h->current); + if (h->current == NULL) + h->current = h->widgets; + break; + case SELECT_PREV: + h->current = g_list_previous (h->current); + if (h->current == NULL) + h->current = g_list_last (h->widgets); + break; + case SELECT_EXACT: + h->current = g_list_find (h->widgets, w0); + dlg_focus (h); + return; + } + } + while (h->current != w /* && (((Widget *) h->current->data)->options & W_DISABLED) == 0 */ ); + + if (dlg_overlap (w0, (Widget *) h->current->data)) + { + send_message ((Widget *) h->current->data, WIDGET_DRAW, 0); + send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +refresh_cmd (void) +{ +#ifdef HAVE_SLANG + tty_touch_screen (); + mc_refresh (); +#else + /* Use this if the refreshes fail */ + clr_scr (); + repaint_screen (); +#endif /* HAVE_SLANG */ +} + +/* --------------------------------------------------------------------------------------------- */ + +static cb_ret_t +dlg_execute_cmd (Dlg_head * h, unsigned long command) +{ + cb_ret_t ret = MSG_HANDLED; + switch (command) + { + case CK_DialogOK: + h->ret_value = B_ENTER; + dlg_stop (h); + break; + case CK_DialogCancel: + h->ret_value = B_CANCEL; + dlg_stop (h); + break; + + case CK_DialogPrevItem: + dlg_one_up (h); + break; + case CK_DialogNextItem: + dlg_one_down (h); + break; + + case CK_DialogHelp: + interactive_display (NULL, h->help_ctx); + do_refresh (); + break; + + case CK_DialogSuspend: + suspend_cmd (); + refresh_cmd (); + break; + case CK_DialogRefresh: + refresh_cmd (); + break; + + case CK_DialogListCmd: + if (!h->modal) + dialog_switch_list (); + else + ret = MSG_NOT_HANDLED; + break; + case CK_DialogNextCmd: + if (!h->modal) + dialog_switch_next (); + else + ret = MSG_NOT_HANDLED; + break; + case CK_DialogPrevCmd: + if (!h->modal) + dialog_switch_prev (); + else + ret = MSG_NOT_HANDLED; + break; + + default: + ret = MSG_NOT_HANDLED; + } + + return ret; +} + +/* --------------------------------------------------------------------------------------------- */ + +static cb_ret_t +dlg_handle_key (Dlg_head * h, int d_key) +{ + unsigned long command; + command = lookup_keymap_command (dialog_map, d_key); + if ((command == CK_Ignore_Key) || (dlg_execute_cmd (h, command) == MSG_NOT_HANDLED)) + return MSG_NOT_HANDLED; + else + return MSG_HANDLED; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +dlg_mouse_event (Dlg_head * h, Gpm_Event * event) +{ + GList *item; + GList *starting_widget = h->current; + Gpm_Event new_event; + int x = event->x; + int y = event->y; + + /* close the dialog by mouse click out of dialog area */ + if (mouse_close_dialog && !h->fullscreen && ((event->buttons & GPM_B_LEFT) != 0) && ((event->type & GPM_DOWN) != 0) /* left click */ + && !((x > h->x) && (x <= h->x + h->cols) && (y > h->y) && (y <= h->y + h->lines))) + { + h->ret_value = B_CANCEL; + dlg_stop (h); + return MOU_NORMAL; + } + + item = starting_widget; + do + { + Widget *widget; + + widget = (Widget *) item->data; + item = g_list_next (item); + if (item == NULL) + item = h->widgets; + + if (((widget->options & W_DISABLED) == 0) + && (x > widget->x) && (x <= widget->x + widget->cols) + && (y > widget->y) && (y <= widget->y + widget->lines)) + { + new_event = *event; + new_event.x -= widget->x; + new_event.y -= widget->y; + + if (widget->mouse != NULL) + return widget->mouse (&new_event, widget); + } + } + while (item != starting_widget); + + return MOU_NORMAL; +} + +/* --------------------------------------------------------------------------------------------- */ + +static cb_ret_t +dlg_try_hotkey (Dlg_head * h, int d_key) +{ + GList *hot_cur; + Widget *current; + cb_ret_t handled; + int c; + + if (h->widgets == NULL) + return MSG_NOT_HANDLED; + + if (h->current == NULL) + h->current = h->widgets; + + /* + * Explanation: we don't send letter hotkeys to other widgets if + * the currently selected widget is an input line + */ + + current = (Widget *) h->current->data; + + if ((current->options & W_DISABLED) != 0) + return MSG_NOT_HANDLED; + + if (current->options & W_IS_INPUT) + { + /* skip ascii control characters, anything else can valid character in + * some encoding */ + if (d_key >= 32 && d_key < 256) + return MSG_NOT_HANDLED; + } + + /* If it's an alt key, send the message */ + c = d_key & ~ALT (0); + if (d_key & ALT (0) && g_ascii_isalpha (c)) + d_key = g_ascii_tolower (c); + + handled = MSG_NOT_HANDLED; + if ((current->options & W_WANT_HOTKEY) != 0) + handled = send_message (current, WIDGET_HOTKEY, d_key); + + /* If not used, send hotkey to other widgets */ + if (handled == MSG_HANDLED) + return MSG_HANDLED; + + hot_cur = g_list_next (h->current); + if (hot_cur == NULL) + hot_cur = h->widgets; + + /* send it to all widgets */ + while (h->current != hot_cur && handled == MSG_NOT_HANDLED) + { + current = (Widget *) hot_cur->data; + + if ((current->options & W_WANT_HOTKEY) != 0) + handled = send_message (current, WIDGET_HOTKEY, d_key); + + if (handled == MSG_NOT_HANDLED) + { + hot_cur = g_list_next (hot_cur); + if (hot_cur == NULL) + hot_cur = h->widgets; + } + } + + if (handled == MSG_HANDLED) + do_select_widget (h, hot_cur, SELECT_EXACT); + + return handled; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +dlg_key_event (Dlg_head * h, int d_key) +{ + cb_ret_t handled; + + if (h->widgets == NULL) + return; + + if (h->current == NULL) + h->current = h->widgets; + + /* TAB used to cycle */ + if ((h->flags & DLG_WANT_TAB) == 0) + { + if (d_key == '\t') + { + dlg_one_down (h); + return; + } + else if (d_key == KEY_BTAB) + { + dlg_one_up (h); + return; + } + } + + /* first can dlg_callback handle the key */ + handled = h->callback (h, NULL, DLG_KEY, d_key, NULL); + + /* next try the hotkey */ + if (handled == MSG_NOT_HANDLED) + handled = dlg_try_hotkey (h, d_key); + + if (handled == MSG_HANDLED) + h->callback (h, NULL, DLG_HOTKEY_HANDLED, 0, NULL); + else + /* not used - then try widget_callback */ + handled = send_message ((Widget *) h->current->data, WIDGET_KEY, d_key); + + /* not used- try to use the unhandled case */ + if (handled == MSG_NOT_HANDLED) + handled = h->callback (h, NULL, DLG_UNHANDLED_KEY, d_key, NULL); + + if (handled == MSG_NOT_HANDLED) + handled = dlg_handle_key (h, d_key); + + h->callback (h, NULL, DLG_POST_KEY, d_key, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +frontend_run_dlg (Dlg_head * h) +{ + int d_key; + Gpm_Event event; + + event.x = -1; + + /* close opened editors, viewers, etc */ + if (!h->modal && midnight_shutdown) + { + h->callback (h, NULL, DLG_VALIDATE, 0, NULL); + return; + } + + while (h->state == DLG_ACTIVE) + { + if (winch_flag) + change_screen_size (); + + if (is_idle ()) + { + if (idle_hook) + execute_hooks (idle_hook); + + while ((h->flags & DLG_WANT_IDLE) && is_idle ()) + h->callback (h, NULL, DLG_IDLE, 0, NULL); + + /* Allow terminating the dialog from the idle handler */ + if (h->state != DLG_ACTIVE) + break; + } + + update_cursor (h); + + /* Clear interrupt flag */ + tty_got_interrupt (); + d_key = tty_get_event (&event, h->mouse_status == MOU_REPEAT, TRUE); + + dlg_process_event (h, d_key, &event); + + if (h->state == DLG_CLOSED) + h->callback (h, NULL, DLG_VALIDATE, 0, NULL); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** draw box in window */ void draw_box (Dlg_head * h, int y, int x, int ys, int xs, gboolean single) { tty_draw_box (h->y + y, h->x + x, ys, xs, single); } +/* --------------------------------------------------------------------------------------------- */ + void init_widget (Widget * w, int y, int x, int lines, int cols, callback_fn callback, mouse_h mouse_handler) @@ -87,6 +562,8 @@ init_widget (Widget * w, int y, int x, int lines, int cols, w->options = W_WANT_CURSOR; } +/* --------------------------------------------------------------------------------------------- */ + void widget_set_size (Widget * widget, int y, int x, int lines, int cols) { @@ -97,6 +574,8 @@ widget_set_size (Widget * widget, int y, int x, int lines, int cols) send_message (widget, WIDGET_RESIZED, 0 /* unused */ ); } +/* --------------------------------------------------------------------------------------------- */ + void widget_erase (Widget * w) { @@ -104,9 +583,11 @@ widget_erase (Widget * w) tty_fill_region (w->y, w->x, w->lines, w->cols, ' '); } -/* Clean the dialog area, draw the frame and the title */ +/* --------------------------------------------------------------------------------------------- */ +/** Clean the dialog area, draw the frame and the title */ + void -common_dialog_repaint (Dlg_head *h) +common_dialog_repaint (Dlg_head * h) { int space; @@ -127,7 +608,9 @@ common_dialog_repaint (Dlg_head *h) } } -/* this function allows to set dialog position */ +/* --------------------------------------------------------------------------------------------- */ +/** this function allows to set dialog position */ + void dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2) { @@ -205,7 +688,9 @@ dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2) } } -/* this function sets only size, leaving positioning to automatic methods */ +/* --------------------------------------------------------------------------------------------- */ +/** this function sets only size, leaving positioning to automatic methods */ + void dlg_set_size (Dlg_head * h, int lines, int cols) { @@ -224,7 +709,9 @@ dlg_set_size (Dlg_head * h, int lines, int cols) dlg_set_position (h, y, x, y + lines, x + cols); } -/* Default dialog callback */ +/* --------------------------------------------------------------------------------------------- */ +/** Default dialog callback */ + cb_ret_t default_dlg_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -262,6 +749,8 @@ default_dlg_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, vo return MSG_NOT_HANDLED; } +/* --------------------------------------------------------------------------------------------- */ + Dlg_head * create_dlg (gboolean modal, int y1, int x1, int lines, int cols, const int *colors, dlg_cb_fn callback, const char *help_ctx, @@ -302,6 +791,8 @@ create_dlg (gboolean modal, int y1, int x1, int lines, int cols, return new_d; } +/* --------------------------------------------------------------------------------------------- */ + void dlg_set_default_colors (void) { @@ -318,6 +809,8 @@ dlg_set_default_colors (void) alarm_colors[DLG_COLOR_TITLE] = ERROR_TITLE; } +/* --------------------------------------------------------------------------------------------- */ + void dlg_erase (Dlg_head * h) { @@ -325,6 +818,8 @@ dlg_erase (Dlg_head * h) tty_fill_region (h->y, h->x, h->lines, h->cols, ' '); } +/* --------------------------------------------------------------------------------------------- */ + void set_idle_proc (Dlg_head * d, int enable) { @@ -334,10 +829,12 @@ set_idle_proc (Dlg_head * d, int enable) d->flags &= ~DLG_WANT_IDLE; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Insert widget to dialog before current widget. For dialogs populated * from the bottom, make the widget current. Return widget number. */ + int add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags) { @@ -363,13 +860,17 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags) return widget->id; } -/* wrapper to simply add lefttop positioned controls */ +/* --------------------------------------------------------------------------------------------- */ +/** wrapper to simply add lefttop positioned controls */ + int add_widget (Dlg_head * h, void *w) { return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP); } +/* --------------------------------------------------------------------------------------------- */ + void do_refresh (void) { @@ -393,70 +894,17 @@ do_refresh (void) } } -/* broadcast a message to all the widgets in a dialog that have - * the options set to flags. If flags is zero, the message is sent - * to all widgets. - */ -static void -dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, gboolean reverse, int flags) -{ - GList *p, *first; +/* --------------------------------------------------------------------------------------------- */ +/** broadcast a message to all the widgets in a dialog */ - if (h->widgets == NULL) - return; - - if (h->current == NULL) - h->current = h->widgets; - - if (reverse) - { - p = g_list_previous (h->current); - - if (p == NULL) - p = g_list_last (h->widgets); - } - else - { - p = g_list_next (h->current); - - if (p == NULL) - p = h->widgets; - } - - first = p; - - do - { - Widget *w = (Widget *) p->data; - - if (reverse) - { - p = g_list_previous (p); - - if (p == NULL) - p = g_list_last (h->widgets); - } - else - { - p = g_list_next (p); - - if (p == NULL) - p = h->widgets; - } - - if ((flags == 0) || ((flags & w->options) != 0)) - send_message (w, message, 0); - } - while (first != p); -} - -/* broadcast a message to all the widgets in a dialog */ void dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, gboolean reverse) { dlg_broadcast_msg_to (h, message, reverse, 0); } +/* --------------------------------------------------------------------------------------------- */ + int dlg_focus (Dlg_head * h) { @@ -477,26 +925,9 @@ dlg_focus (Dlg_head * h) return 0; } -static int -dlg_unfocus (Dlg_head * h) -{ - /* ... but can unfocus disabled widget */ +/* --------------------------------------------------------------------------------------------- */ +/** Return true if the windows overlap */ - if ((h->current != NULL) && (h->state == DLG_ACTIVE)) - { - Widget *current = (Widget *) h->current->data; - - if (send_message (current, WIDGET_UNFOCUS, 0) == MSG_HANDLED) - { - h->callback (h, current, DLG_UNFOCUS, 0, NULL); - return 1; - } - } - - return 0; -} - -/* Return true if the windows overlap */ int dlg_overlap (Widget * a, Widget * b) { @@ -504,16 +935,10 @@ dlg_overlap (Widget * a, Widget * b) || (a->x >= b->x + b->cols) || (b->y >= a->y + a->lines) || (a->y >= b->y + b->lines)); } -static int -dlg_find_widget_callback (const void *a, const void *b) -{ - const Widget *w = (const Widget *) a; - callback_fn f = (callback_fn) b; - return (w->callback == f) ? 0 : 1; -} +/* --------------------------------------------------------------------------------------------- */ +/** Find the widget with the given callback in the dialog h */ -/* Find the widget with the given callback in the dialog h */ Widget * find_widget_type (const Dlg_head * h, callback_fn callback) { @@ -524,7 +949,9 @@ find_widget_type (const Dlg_head * h, callback_fn callback) return (w == NULL) ? NULL : (Widget *) w->data; } -/* Find the widget with the given id */ +/* --------------------------------------------------------------------------------------------- */ +/** Find the widget with the given id */ + Widget * dlg_find_by_id (const Dlg_head * h, unsigned int id) { @@ -540,7 +967,9 @@ dlg_find_by_id (const Dlg_head * h, unsigned int id) return NULL; } -/* Find the widget with the given id in the dialog h and select it */ +/* --------------------------------------------------------------------------------------------- */ +/** Find the widget with the given id in the dialog h and select it */ + void dlg_select_by_id (const Dlg_head * h, unsigned int id) { @@ -551,63 +980,11 @@ dlg_select_by_id (const Dlg_head * h, unsigned int id) dlg_select_widget (w); } -/* What to do if the requested widget doesn't take focus */ -typedef enum -{ - SELECT_NEXT, /* go the the next widget */ - SELECT_PREV, /* go the the previous widget */ - SELECT_EXACT /* use current widget */ -} select_dir_t; - -/* - * Try to select another widget. If forward is set, follow tab order. - * Otherwise go to the previous widget. - */ -static void -do_select_widget (Dlg_head * h, GList * w, select_dir_t dir) -{ - Widget *w0 = (Widget *) h->current->data; - - if (!dlg_unfocus (h)) - return; - - h->current = w; - - do - { - if (dlg_focus (h)) - break; - - switch (dir) - { - case SELECT_NEXT: - h->current = g_list_next (h->current); - if (h->current == NULL) - h->current = h->widgets; - break; - case SELECT_PREV: - h->current = g_list_previous (h->current); - if (h->current == NULL) - h->current = g_list_last (h->widgets); - break; - case SELECT_EXACT: - h->current = g_list_find (h->widgets, w0); - dlg_focus (h); - return; - } - } - while (h->current != w /* && (((Widget *) h->current->data)->options & W_DISABLED) == 0 */); - - if (dlg_overlap (w0, (Widget *) h->current->data)) - { - send_message ((Widget *) h->current->data, WIDGET_DRAW, 0); - send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0); - } -} - +/* --------------------------------------------------------------------------------------------- */ /* * Try to select widget in the dialog. */ + void dlg_select_widget (void *w) { @@ -617,7 +994,9 @@ dlg_select_widget (void *w) do_select_widget (h, g_list_find (h->widgets, widget), SELECT_NEXT); } -/* Try to select previous widget in the tab order */ +/* --------------------------------------------------------------------------------------------- */ +/** Try to select previous widget in the tab order */ + void dlg_one_up (Dlg_head * h) { @@ -633,7 +1012,9 @@ dlg_one_up (Dlg_head * h) } } -/* Try to select next widget in the tab order */ +/* --------------------------------------------------------------------------------------------- */ +/** Try to select next widget in the tab order */ + void dlg_one_down (Dlg_head * h) { @@ -648,6 +1029,8 @@ dlg_one_down (Dlg_head * h) } } +/* --------------------------------------------------------------------------------------------- */ + void update_cursor (Dlg_head * h) { @@ -681,9 +1064,12 @@ update_cursor (Dlg_head * h) } } -/* Redraw the widgets in reverse order, leaving the current widget +/* --------------------------------------------------------------------------------------------- */ +/** + * Redraw the widgets in reverse order, leaving the current widget * as the last one */ + void dlg_redraw (Dlg_head * h) { @@ -701,263 +1087,17 @@ dlg_redraw (Dlg_head * h) update_cursor (h); } +/* --------------------------------------------------------------------------------------------- */ + void dlg_stop (Dlg_head * h) { h->state = DLG_CLOSED; } -static void -refresh_cmd (void) -{ -#ifdef HAVE_SLANG - tty_touch_screen (); - mc_refresh (); -#else - /* Use this if the refreshes fail */ - clr_scr (); - repaint_screen (); -#endif /* HAVE_SLANG */ -} +/* --------------------------------------------------------------------------------------------- */ +/** Init the process */ -static cb_ret_t -dlg_execute_cmd (Dlg_head * h, unsigned long command) -{ - cb_ret_t ret = MSG_HANDLED; - switch (command) - { - case CK_DialogOK: - h->ret_value = B_ENTER; - dlg_stop (h); - break; - case CK_DialogCancel: - h->ret_value = B_CANCEL; - dlg_stop (h); - break; - - case CK_DialogPrevItem: - dlg_one_up (h); - break; - case CK_DialogNextItem: - dlg_one_down (h); - break; - - case CK_DialogHelp: - interactive_display (NULL, h->help_ctx); - do_refresh (); - break; - - case CK_DialogSuspend: - suspend_cmd (); - refresh_cmd (); - break; - case CK_DialogRefresh: - refresh_cmd (); - break; - - case CK_DialogListCmd: - if (!h->modal) - dialog_switch_list (); - else - ret = MSG_NOT_HANDLED; - break; - case CK_DialogNextCmd: - if (!h->modal) - dialog_switch_next (); - else - ret = MSG_NOT_HANDLED; - break; - case CK_DialogPrevCmd: - if (!h->modal) - dialog_switch_prev (); - else - ret = MSG_NOT_HANDLED; - break; - - default: - ret = MSG_NOT_HANDLED; - } - - return ret; -} - -static cb_ret_t -dlg_handle_key (Dlg_head * h, int d_key) -{ - unsigned long command; - command = lookup_keymap_command (dialog_map, d_key); - if ((command == CK_Ignore_Key) || (dlg_execute_cmd (h, command) == MSG_NOT_HANDLED)) - return MSG_NOT_HANDLED; - else - return MSG_HANDLED; -} - -static int -dlg_mouse_event (Dlg_head * h, Gpm_Event * event) -{ - GList *item; - GList *starting_widget = h->current; - Gpm_Event new_event; - int x = event->x; - int y = event->y; - - /* close the dialog by mouse click out of dialog area */ - if (mouse_close_dialog && !h->fullscreen && ((event->buttons & GPM_B_LEFT) != 0) && ((event->type & GPM_DOWN) != 0) /* left click */ - && !((x > h->x) && (x <= h->x + h->cols) && (y > h->y) && (y <= h->y + h->lines))) - { - h->ret_value = B_CANCEL; - dlg_stop (h); - return MOU_NORMAL; - } - - item = starting_widget; - do - { - Widget *widget; - - widget = (Widget *) item->data; - item = g_list_next (item); - if (item == NULL) - item = h->widgets; - - if (((widget->options & W_DISABLED) == 0) - && (x > widget->x) && (x <= widget->x + widget->cols) - && (y > widget->y) && (y <= widget->y + widget->lines)) - { - new_event = *event; - new_event.x -= widget->x; - new_event.y -= widget->y; - - if (widget->mouse != NULL) - return widget->mouse (&new_event, widget); - } - } - while (item != starting_widget); - - return MOU_NORMAL; -} - -static cb_ret_t -dlg_try_hotkey (Dlg_head * h, int d_key) -{ - GList *hot_cur; - Widget *current; - cb_ret_t handled; - int c; - - if (h->widgets == NULL) - return MSG_NOT_HANDLED; - - if (h->current == NULL) - h->current = h->widgets; - - /* - * Explanation: we don't send letter hotkeys to other widgets if - * the currently selected widget is an input line - */ - - current = (Widget *) h->current->data; - - if ((current->options & W_DISABLED) != 0) - return MSG_NOT_HANDLED; - - if (current->options & W_IS_INPUT) - { - /* skip ascii control characters, anything else can valid character in - * some encoding */ - if (d_key >= 32 && d_key < 256) - return MSG_NOT_HANDLED; - } - - /* If it's an alt key, send the message */ - c = d_key & ~ALT (0); - if (d_key & ALT (0) && g_ascii_isalpha (c)) - d_key = g_ascii_tolower (c); - - handled = MSG_NOT_HANDLED; - if ((current->options & W_WANT_HOTKEY) != 0) - handled = send_message (current, WIDGET_HOTKEY, d_key); - - /* If not used, send hotkey to other widgets */ - if (handled == MSG_HANDLED) - return MSG_HANDLED; - - hot_cur = g_list_next (h->current); - if (hot_cur == NULL) - hot_cur = h->widgets; - - /* send it to all widgets */ - while (h->current != hot_cur && handled == MSG_NOT_HANDLED) - { - current = (Widget *) hot_cur->data; - - if ((current->options & W_WANT_HOTKEY) != 0) - handled = send_message (current, WIDGET_HOTKEY, d_key); - - if (handled == MSG_NOT_HANDLED) - { - hot_cur = g_list_next (hot_cur); - if (hot_cur == NULL) - hot_cur = h->widgets; - } - } - - if (handled == MSG_HANDLED) - do_select_widget (h, hot_cur, SELECT_EXACT); - - return handled; -} - -static void -dlg_key_event (Dlg_head * h, int d_key) -{ - cb_ret_t handled; - - if (h->widgets == NULL) - return; - - if (h->current == NULL) - h->current = h->widgets; - - /* TAB used to cycle */ - if ((h->flags & DLG_WANT_TAB) == 0) - { - if (d_key == '\t') - { - dlg_one_down (h); - return; - } - else if (d_key == KEY_BTAB) - { - dlg_one_up (h); - return; - } - } - - /* first can dlg_callback handle the key */ - handled = h->callback (h, NULL, DLG_KEY, d_key, NULL); - - /* next try the hotkey */ - if (handled == MSG_NOT_HANDLED) - handled = dlg_try_hotkey (h, d_key); - - if (handled == MSG_HANDLED) - h->callback (h, NULL, DLG_HOTKEY_HANDLED, 0, NULL); - else - /* not used - then try widget_callback */ - handled = send_message ((Widget *) h->current->data, WIDGET_KEY, d_key); - - /* not used- try to use the unhandled case */ - if (handled == MSG_NOT_HANDLED) - handled = h->callback (h, NULL, DLG_UNHANDLED_KEY, d_key, NULL); - - if (handled == MSG_NOT_HANDLED) - handled = dlg_handle_key (h, d_key); - - h->callback (h, NULL, DLG_POST_KEY, d_key, NULL); -} - -/* Init the process */ void init_dlg (Dlg_head * h) { @@ -993,6 +1133,8 @@ init_dlg (Dlg_head * h) h->ret_value = 0; } +/* --------------------------------------------------------------------------------------------- */ + void dlg_process_event (Dlg_head * h, int key, Gpm_Event * event) { @@ -1010,53 +1152,9 @@ dlg_process_event (Dlg_head * h, int key, Gpm_Event * event) dlg_key_event (h, key); } -static void -frontend_run_dlg (Dlg_head * h) -{ - int d_key; - Gpm_Event event; +/* --------------------------------------------------------------------------------------------- */ +/** Shutdown the run_dlg */ - event.x = -1; - - /* close opened editors, viewers, etc */ - if (!h->modal && midnight_shutdown) - { - h->callback (h, NULL, DLG_VALIDATE, 0, NULL); - return; - } - - while (h->state == DLG_ACTIVE) - { - if (winch_flag) - change_screen_size (); - - if (is_idle ()) - { - if (idle_hook) - execute_hooks (idle_hook); - - while ((h->flags & DLG_WANT_IDLE) && is_idle ()) - h->callback (h, NULL, DLG_IDLE, 0, NULL); - - /* Allow terminating the dialog from the idle handler */ - if (h->state != DLG_ACTIVE) - break; - } - - update_cursor (h); - - /* Clear interrupt flag */ - tty_got_interrupt (); - d_key = tty_get_event (&event, h->mouse_status == MOU_REPEAT, TRUE); - - dlg_process_event (h, d_key, &event); - - if (h->state == DLG_CLOSED) - h->callback (h, NULL, DLG_VALIDATE, 0, NULL); - } -} - -/* Shutdown the run_dlg */ void dlg_run_done (Dlg_head * h) { @@ -1071,11 +1169,14 @@ dlg_run_done (Dlg_head * h) } -/* Standard run dialog routine +/* --------------------------------------------------------------------------------------------- */ +/** + * Standard run dialog routine * We have to keep this routine small so that we can duplicate it's * behavior on complex routines like the file routines, this way, * they can call the dlg_process_event without rewriting all the code */ + int run_dlg (Dlg_head * h) { @@ -1085,6 +1186,8 @@ run_dlg (Dlg_head * h) return h->ret_value; } +/* --------------------------------------------------------------------------------------------- */ + void destroy_dlg (Dlg_head * h) { @@ -1097,8 +1200,10 @@ destroy_dlg (Dlg_head * h) do_refresh (); } +/* --------------------------------------------------------------------------------------------- */ + char * -dlg_get_title (const Dlg_head *h, size_t len) +dlg_get_title (const Dlg_head * h, size_t len) { char *t; @@ -1113,7 +1218,9 @@ dlg_get_title (const Dlg_head *h, size_t len) return t; } -/* Replace widget old_w for widget new_w in the dialog */ +/* --------------------------------------------------------------------------------------------- */ +/** Replace widget old_w for widget new_w in the dialog */ + void dlg_replace_widget (Widget * old_w, Widget * new_w) { @@ -1145,3 +1252,5 @@ dlg_replace_widget (Widget * old_w, Widget * new_w) send_message (new_w, WIDGET_DRAW, 0); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/dialog.h b/src/dialog.h index 0db0946d8..633e1a5e0 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -3,7 +3,7 @@ 2005, 2007, 2009, 2010 Free Software Foundation Authors: 1994, 1995 Radek Doulik, Miguel de Icaza - 2009, 2010 Andrew Borodin + 2009, 2010 Andrew Borodin 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 @@ -24,8 +24,8 @@ * \brief Header: dialog box features module */ -#ifndef MC_DIALOG_H -#define MC_DIALOG_H +#ifndef MC__DIALOG_H +#define MC__DIALOG_H #include /* size_t */ @@ -33,6 +33,8 @@ #include "lib/tty/mouse.h" #include "lib/hook.h" /* hook_t */ +/*** defined constants ***************************************************************************/ + /* Common return values */ #define B_EXIT 0 #define B_CANCEL 1 @@ -40,7 +42,19 @@ #define B_HELP 3 #define B_USER 100 -typedef struct Widget Widget; +#define widget_move(w, _y, _x) tty_gotoyx (((Widget *)(w))->y + _y, ((Widget *)(w))->x + _x) +#define dlg_move(h, _y, _x) tty_gotoyx (((Dlg_head *)(h))->y + _y, ((Dlg_head *)(h))->x + _x) + +/* Sets/clear the specified flag in the options field */ +#define widget_option(w,f,i) \ + w.options = ((i) ? ((w).options | (f)) : ((w).options & (~(f)))) + +#define widget_want_cursor(w,i) widget_option((w), W_WANT_CURSOR, (i)) +#define widget_want_hotkey(w,i) widget_option((w), W_WANT_HOTKEY, (i)) +#define widget_disable(w,i) widget_option((w), W_DISABLED, (i)) + + +/*** enums ***************************************************************************************/ /* Widget messages */ typedef enum @@ -111,23 +125,9 @@ typedef enum DLG_CLOSED = 2 /* Dialog is closed */ } dlg_state_t; -/* Dialog callback */ -typedef struct Dlg_head Dlg_head; -typedef cb_ret_t (*dlg_cb_fn) (Dlg_head * h, Widget * sender, - dlg_msg_t msg, int parm, void *data); - -/* menu command execution */ -typedef cb_ret_t (*menu_exec_fn) (int command); - -/* get string representation of shortcut assigned with command */ -/* as menu is a widget of dialog, ask dialog about shortcut string */ -typedef char *(*dlg_shortcut_str) (unsigned long command); - -/* get dialog name to show in dialog list */ -typedef char *(*dlg_title_str) (const Dlg_head * h, size_t len); - /* Dialog color constants */ -typedef enum { +typedef enum +{ DLG_COLOR_NORMAL, DLG_COLOR_FOCUS, DLG_COLOR_HOT_NORMAL, @@ -136,15 +136,61 @@ typedef enum { DLG_COLOR_COUNT } dlg_colors_enum_t; +/* widget options */ +typedef enum +{ + W_WANT_HOTKEY = (1 << 1), + W_WANT_CURSOR = (1 << 2), + W_WANT_IDLE = (1 << 3), + W_IS_INPUT = (1 << 4), + W_DISABLED = (1 << 5) /* Widget cannot be selected */ +} widget_options_t; + +/* Flags for widget repositioning on dialog resize */ +typedef enum +{ + WPOS_KEEP_LEFT = (1 << 0), /* keep widget distance to left border of dialog */ + WPOS_KEEP_RIGHT = (1 << 1), /* keep widget distance to right border of dialog */ + WPOS_KEEP_TOP = (1 << 2), /* keep widget distance to top border of dialog */ + WPOS_KEEP_BOTTOM = (1 << 3), /* keep widget distance to bottom border of dialog */ + WPOS_KEEP_HORZ = WPOS_KEEP_LEFT | WPOS_KEEP_RIGHT, + WPOS_KEEP_VERT = WPOS_KEEP_TOP | WPOS_KEEP_BOTTOM, + WPOS_KEEP_ALL = WPOS_KEEP_HORZ | WPOS_KEEP_VERT +} widget_pos_flags_t; + +/*** typedefs(not structures) ********************************************************************/ + +typedef struct Widget Widget; + +/* Dialog callback */ +typedef struct Dlg_head Dlg_head; + +/* get string representation of shortcut assigned with command */ +/* as menu is a widget of dialog, ask dialog about shortcut string */ +typedef char *(*dlg_shortcut_str) (unsigned long command); + +/* get dialog name to show in dialog list */ +typedef char *(*dlg_title_str) (const Dlg_head * h, size_t len); + typedef int dlg_colors_t[DLG_COLOR_COUNT]; +/* Widget callback */ +typedef cb_ret_t (*callback_fn) (Widget * widget, widget_msg_t msg, int parm); + +typedef cb_ret_t (*dlg_cb_fn) (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data); + +/* menu command execution */ +typedef cb_ret_t (*menu_exec_fn) (int command); + +/*** structures declarations (and typedefs of structures)*****************************************/ + struct Dlg_head { /* Set by the user */ gboolean modal; /* type of dialog: modal or not */ dlg_flags_t flags; /* User flags */ const char *help_ctx; /* Name of the help entry */ - dlg_colors_t color; /* Color set. Unused in viewer and editor */ + dlg_colors_t color; /* Color set. Unused in viewer and editor */ char *title; /* Title of the dialog */ /* Set and received by the user */ @@ -172,35 +218,6 @@ struct Dlg_head struct Dlg_head *parent; /* Parent dialog */ }; -/* Color styles for normal and error dialogs */ -extern dlg_colors_t dialog_colors; -extern dlg_colors_t alarm_colors; - -/* Widget callback */ -typedef cb_ret_t (*callback_fn) (Widget * widget, widget_msg_t msg, int parm); - -/* widget options */ -typedef enum -{ - W_WANT_HOTKEY = (1 << 1), - W_WANT_CURSOR = (1 << 2), - W_WANT_IDLE = (1 << 3), - W_IS_INPUT = (1 << 4), - W_DISABLED = (1 << 5) /* Widget cannot be selected */ -} widget_options_t; - -/* Flags for widget repositioning on dialog resize */ -typedef enum -{ - WPOS_KEEP_LEFT = (1 << 0), /* keep widget distance to left border of dialog */ - WPOS_KEEP_RIGHT = (1 << 1), /* keep widget distance to right border of dialog */ - WPOS_KEEP_TOP = (1 << 2), /* keep widget distance to top border of dialog */ - WPOS_KEEP_BOTTOM = (1 << 3), /* keep widget distance to bottom border of dialog */ - WPOS_KEEP_HORZ = WPOS_KEEP_LEFT | WPOS_KEEP_RIGHT, - WPOS_KEEP_VERT = WPOS_KEEP_TOP | WPOS_KEEP_BOTTOM, - WPOS_KEEP_ALL = WPOS_KEEP_HORZ | WPOS_KEEP_VERT -} widget_pos_flags_t; - /* Every Widget must have this as its first element */ struct Widget { @@ -208,12 +225,25 @@ struct Widget int cols, lines; widget_options_t options; widget_pos_flags_t pos_flags; /* repositioning flags */ - unsigned int id; /* Number of the widget, starting with 0 */ + unsigned int id; /* Number of the widget, starting with 0 */ callback_fn callback; mouse_h mouse; struct Dlg_head *owner; }; +/*** global variables defined in .c file *********************************************************/ + +/* Color styles for normal and error dialogs */ +extern dlg_colors_t dialog_colors; +extern dlg_colors_t alarm_colors; + +extern GList *top_dlg; + +/* A hook list for idle events */ +extern hook_t *idle_hook; + +/*** declarations of public functions ************************************************************/ + /* draw box in window */ void draw_box (Dlg_head * h, int y, int x, int ys, int xs, gboolean single); @@ -240,7 +270,7 @@ void destroy_dlg (Dlg_head * h); void dlg_run_done (Dlg_head * h); void dlg_process_event (Dlg_head * h, int key, Gpm_Event * event); -char *dlg_get_title (const Dlg_head *h, size_t len); +char *dlg_get_title (const Dlg_head * h, size_t len); /* To activate/deactivate the idle message generation */ void set_idle_proc (Dlg_head * d, int enable); @@ -258,15 +288,30 @@ void init_widget (Widget * w, int y, int x, int lines, int cols, cb_ret_t default_dlg_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data); /* Default paint routine for dialogs */ -void common_dialog_repaint (Dlg_head *h); +void common_dialog_repaint (Dlg_head * h); -#define widget_move(w, _y, _x) tty_gotoyx (((Widget *)(w))->y + _y, ((Widget *)(w))->x + _x) -#define dlg_move(h, _y, _x) tty_gotoyx (((Dlg_head *)(h))->y + _y, ((Dlg_head *)(h))->x + _x) +void dlg_replace_widget (Widget * old, Widget * new); +int dlg_overlap (Widget * a, Widget * b); +void widget_erase (Widget *); +void dlg_erase (Dlg_head * h); +void dlg_stop (Dlg_head * h); -extern GList *top_dlg; +/* Widget selection */ +void dlg_select_widget (void *widget); +void dlg_one_up (Dlg_head * h); +void dlg_one_down (Dlg_head * h); +int dlg_focus (Dlg_head * h); +Widget *find_widget_type (const Dlg_head * h, callback_fn callback); +Widget *dlg_find_by_id (const Dlg_head * h, unsigned int id); +void dlg_select_by_id (const Dlg_head * h, unsigned int id); -/* A hook list for idle events */ -extern hook_t *idle_hook; +/* Redraw all dialogs */ +void do_refresh (void); + +/* Used in load_prompt() */ +void update_cursor (Dlg_head * h); + +/*** inline functions ****************************************************************************/ static inline cb_ret_t send_message (Widget * w, widget_msg_t msg, int parm) @@ -288,33 +333,4 @@ dlg_get_current_widget_id (const Dlg_head * h) return ((Widget *) h->current->data)->id; } -void dlg_replace_widget (Widget * old, Widget * new); -int dlg_overlap (Widget * a, Widget * b); -void widget_erase (Widget *); -void dlg_erase (Dlg_head * h); -void dlg_stop (Dlg_head * h); - -/* Widget selection */ -void dlg_select_widget (void *widget); -void dlg_one_up (Dlg_head * h); -void dlg_one_down (Dlg_head * h); -int dlg_focus (Dlg_head * h); -Widget *find_widget_type (const Dlg_head * h, callback_fn callback); -Widget *dlg_find_by_id (const Dlg_head * h, unsigned int id); -void dlg_select_by_id (const Dlg_head * h, unsigned int id); - -/* Redraw all dialogs */ -void do_refresh (void); - -/* Sets/clear the specified flag in the options field */ -#define widget_option(w,f,i) \ - w.options = ((i) ? ((w).options | (f)) : ((w).options & (~(f)))) - -#define widget_want_cursor(w,i) widget_option((w), W_WANT_CURSOR, (i)) -#define widget_want_hotkey(w,i) widget_option((w), W_WANT_HOTKEY, (i)) -#define widget_disable(w,i) widget_option((w), W_DISABLED, (i)) - -/* Used in load_prompt() */ -void update_cursor (Dlg_head * h); - -#endif /* MC_DIALOG_H */ +#endif /* MC__DIALOG_H */ diff --git a/src/dir.c b/src/dir.c index a55ed5706..75dcd1f82 100644 --- a/src/dir.c +++ b/src/dir.c @@ -40,28 +40,45 @@ #include "setup.h" /* panels_options */ #include "layout.h" /* rotate_dash() */ +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +#define MY_ISDIR(x) (\ + (is_exe (x->st.st_mode) && !(S_ISDIR (x->st.st_mode) || x->f.link_to_dir) && (exec_first == 1)) \ + ? 1 \ + : ( (S_ISDIR (x->st.st_mode) || x->f.link_to_dir) ? 2 : 0) ) + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + /* Reverse flag */ static int reverse = 1; /* Are the files sorted case sensitively? */ static int case_sensitive = OS_SORT_CASE_SENSITIVE_DEFAULT; -/* Are the exec_bit files top in list*/ +/* Are the exec_bit files top in list */ static int exec_first = 1; -#define MY_ISDIR(x) ( (is_exe (x->st.st_mode) && !(S_ISDIR (x->st.st_mode) || x->f.link_to_dir) && (exec_first == 1)) ? 1 : ( (S_ISDIR (x->st.st_mode) || x->f.link_to_dir) ? 2 : 0) ) +static dir_list dir_copy = { 0, 0 }; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /* -sort_orders_t sort_orders [SORT_TYPES_TOTAL] = { - { N_("&Unsorted"), unsorted }, - { N_("&Name"), sort_name }, - { N_("&Extension"), sort_ext }, - { N_("&Modify time"), sort_time }, - { N_("&Access time"), sort_atime }, - { N_("C&Hange time"), sort_ctime }, - { N_("&Size"), sort_size }, - { N_("&Inode"), sort_inode }, -}; -*/ + sort_orders_t sort_orders [SORT_TYPES_TOTAL] = { + { N_("&Unsorted"), unsorted }, + { N_("&Name"), sort_name }, + { N_("&Extension"), sort_ext }, + { N_("&Modify time"), sort_time }, + { N_("&Access time"), sort_atime }, + { N_("C&Hange time"), sort_ctime }, + { N_("&Size"), sort_size }, + { N_("&Inode"), sort_inode }, + }; + */ static inline int key_collate (const char *t1, const char *t2) @@ -73,231 +90,366 @@ key_collate (const char *t1, const char *t2) switch (dotdot) { - case 0: - case 3: - ret = str_key_collate (t1, t2, case_sensitive) * reverse; - break; - case 1: - ret = -1; /* t1 < t2 */ - break; - case 2: - ret = 1; /* t1 > t2 */ - break; - default: - ret = 0; /* it must not happen */ + case 0: + case 3: + ret = str_key_collate (t1, t2, case_sensitive) * reverse; + break; + case 1: + ret = -1; /* t1 < t2 */ + break; + case 2: + ret = 1; /* t1 > t2 */ + break; + default: + ret = 0; /* it must not happen */ } return ret; } +/* --------------------------------------------------------------------------------------------- */ +/** clear keys, should be call after sorting is finished */ + +static void +clean_sort_keys (dir_list * list, int start, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + str_release_key (list->list[i + start].sort_key, case_sensitive); + list->list[i + start].sort_key = NULL; + str_release_key (list->list[i + start].second_sort_key, case_sensitive); + list->list[i + start].second_sort_key = NULL; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * If you change handle_dirent then check also handle_path. + * @returns -1 = failure, 0 = don't add, 1 = add to the list + */ + +static int +handle_dirent (dir_list * list, const char *fltr, struct dirent *dp, + struct stat *buf1, int next_free, int *link_to_dir, int *stale_link) +{ + if (dp->d_name[0] == '.' && dp->d_name[1] == 0) + return 0; + if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0) + return 0; + if (!panels_options.show_dot_files && (dp->d_name[0] == '.')) + return 0; + if (!panels_options.show_backups && dp->d_name[NLENGTH (dp) - 1] == '~') + return 0; + + if (mc_lstat (dp->d_name, buf1) == -1) + { + /* + * lstat() fails - such entries should be identified by + * buf1->st_mode being 0. + * It happens on QNX Neutrino for /fs/cd0 if no CD is inserted. + */ + memset (buf1, 0, sizeof (*buf1)); + } + + if (S_ISDIR (buf1->st_mode)) + tree_store_mark_checked (dp->d_name); + + /* A link to a file or a directory? */ + *link_to_dir = 0; + *stale_link = 0; + if (S_ISLNK (buf1->st_mode)) + { + struct stat buf2; + if (!mc_stat (dp->d_name, &buf2)) + *link_to_dir = S_ISDIR (buf2.st_mode) != 0; + else + *stale_link = 1; + } + if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && (fltr != NULL) + && !mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB)) + return 0; + + /* Need to grow the *list? */ + if (next_free == list->size) + { + list->list = g_try_realloc (list->list, sizeof (file_entry) * (list->size + RESIZE_STEPS)); + if (list->list == NULL) + return -1; + list->size += RESIZE_STEPS; + } + return 1; +} + +/* --------------------------------------------------------------------------------------------- */ +/** get info about ".." */ + +static gboolean +get_dotdot_dir_stat (const char *path, struct stat *st) +{ + gboolean ret = FALSE; + + if ((path != NULL) && (path[0] != '\0') && (st != NULL)) + { + char *dotdot_dir; + struct stat s; + + dotdot_dir = g_strdup_printf ("%s/../", path); + canonicalize_pathname (dotdot_dir); + ret = mc_stat (dotdot_dir, &s) == 0; + g_free (dotdot_dir); + *st = s; + } + + return ret; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +alloc_dir_copy (int size) +{ + if (dir_copy.size < size) + { + if (dir_copy.list) + { + int i; + for (i = 0; i < dir_copy.size; i++) + g_free (dir_copy.list[i].fname); + g_free (dir_copy.list); + } + + dir_copy.list = g_new0 (file_entry, size); + dir_copy.size = size; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + int -unsorted (file_entry *a, file_entry *b) +unsorted (file_entry * a, file_entry * b) { (void) a; (void) b; return 0; } +/* --------------------------------------------------------------------------------------------- */ + int -sort_name (file_entry *a, file_entry *b) +sort_name (file_entry * a, file_entry * b) { int ad = MY_ISDIR (a); int bd = MY_ISDIR (b); - if (ad == bd || panels_options.mix_all_files) { + if (ad == bd || panels_options.mix_all_files) + { /* create key if does not exist, key will be freed after sorting */ if (a->sort_key == NULL) a->sort_key = str_create_key_for_filename (a->fname, case_sensitive); if (b->sort_key == NULL) b->sort_key = str_create_key_for_filename (b->fname, case_sensitive); - return key_collate (a->sort_key, b->sort_key); + return key_collate (a->sort_key, b->sort_key); } return bd - ad; } -int -sort_vers (file_entry *a, file_entry *b) -{ - int ad = MY_ISDIR (a); - int bd = MY_ISDIR (b); - - if (ad == bd || panels_options.mix_all_files) { - return str_verscmp(a->fname, b->fname) * reverse; - } else { - return bd - ad; - } -} +/* --------------------------------------------------------------------------------------------- */ int -sort_ext (file_entry *a, file_entry *b) -{ - int r; - int ad = MY_ISDIR (a); - int bd = MY_ISDIR (b); - - if (ad == bd || panels_options.mix_all_files) { - if (a->second_sort_key == NULL) - a->second_sort_key = str_create_key (extension (a->fname), case_sensitive); - if (b->second_sort_key == NULL) - b->second_sort_key = str_create_key (extension (b->fname), case_sensitive); - - r = str_key_collate (a->second_sort_key, b->second_sort_key, case_sensitive); - if (r) - return r * reverse; - else - return sort_name (a, b); - } else - return bd-ad; -} - -int -sort_time (file_entry *a, file_entry *b) -{ - int ad = MY_ISDIR (a); - int bd = MY_ISDIR (b); - - if (ad == bd || panels_options.mix_all_files) { - int result = a->st.st_mtime < b->st.st_mtime ? -1 : - a->st.st_mtime > b->st.st_mtime; - if (result != 0) - return result * reverse; - else - return sort_name (a, b); - } - else - return bd-ad; -} - -int -sort_ctime (file_entry *a, file_entry *b) -{ - int ad = MY_ISDIR (a); - int bd = MY_ISDIR (b); - - if (ad == bd || panels_options.mix_all_files) { - int result = a->st.st_ctime < b->st.st_ctime ? -1 : - a->st.st_ctime > b->st.st_ctime; - if (result != 0) - return result * reverse; - else - return sort_name (a, b); - } - else - return bd-ad; -} - -int -sort_atime (file_entry *a, file_entry *b) -{ - int ad = MY_ISDIR (a); - int bd = MY_ISDIR (b); - - if (ad == bd || panels_options.mix_all_files) { - int result = a->st.st_atime < b->st.st_atime ? -1 : - a->st.st_atime > b->st.st_atime; - if (result != 0) - return result * reverse; - else - return sort_name (a, b); - } - else - return bd-ad; -} - -int -sort_inode (file_entry *a, file_entry *b) +sort_vers (file_entry * a, file_entry * b) { int ad = MY_ISDIR (a); int bd = MY_ISDIR (b); if (ad == bd || panels_options.mix_all_files) - return (a->st.st_ino - b->st.st_ino) * reverse; + { + return str_verscmp (a->fname, b->fname) * reverse; + } else - return bd-ad; + { + return bd - ad; + } } +/* --------------------------------------------------------------------------------------------- */ + int -sort_size (file_entry *a, file_entry *b) +sort_ext (file_entry * a, file_entry * b) +{ + int r; + int ad = MY_ISDIR (a); + int bd = MY_ISDIR (b); + + if (ad == bd || panels_options.mix_all_files) + { + if (a->second_sort_key == NULL) + a->second_sort_key = str_create_key (extension (a->fname), case_sensitive); + if (b->second_sort_key == NULL) + b->second_sort_key = str_create_key (extension (b->fname), case_sensitive); + + r = str_key_collate (a->second_sort_key, b->second_sort_key, case_sensitive); + if (r) + return r * reverse; + else + return sort_name (a, b); + } + else + return bd - ad; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +sort_time (file_entry * a, file_entry * b) +{ + int ad = MY_ISDIR (a); + int bd = MY_ISDIR (b); + + if (ad == bd || panels_options.mix_all_files) + { + int result = a->st.st_mtime < b->st.st_mtime ? -1 : a->st.st_mtime > b->st.st_mtime; + if (result != 0) + return result * reverse; + else + return sort_name (a, b); + } + else + return bd - ad; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +sort_ctime (file_entry * a, file_entry * b) +{ + int ad = MY_ISDIR (a); + int bd = MY_ISDIR (b); + + if (ad == bd || panels_options.mix_all_files) + { + int result = a->st.st_ctime < b->st.st_ctime ? -1 : a->st.st_ctime > b->st.st_ctime; + if (result != 0) + return result * reverse; + else + return sort_name (a, b); + } + else + return bd - ad; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +sort_atime (file_entry * a, file_entry * b) +{ + int ad = MY_ISDIR (a); + int bd = MY_ISDIR (b); + + if (ad == bd || panels_options.mix_all_files) + { + int result = a->st.st_atime < b->st.st_atime ? -1 : a->st.st_atime > b->st.st_atime; + if (result != 0) + return result * reverse; + else + return sort_name (a, b); + } + else + return bd - ad; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +sort_inode (file_entry * a, file_entry * b) +{ + int ad = MY_ISDIR (a); + int bd = MY_ISDIR (b); + + if (ad == bd || panels_options.mix_all_files) + return (a->st.st_ino - b->st.st_ino) * reverse; + else + return bd - ad; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +sort_size (file_entry * a, file_entry * b) { int ad = MY_ISDIR (a); int bd = MY_ISDIR (b); int result = 0; if (ad != bd && !panels_options.mix_all_files) - return bd - ad; + return bd - ad; - result = a->st.st_size < b->st.st_size ? -1 : - a->st.st_size > b->st.st_size; + result = a->st.st_size < b->st.st_size ? -1 : a->st.st_size > b->st.st_size; if (result != 0) - return result * reverse; + return result * reverse; else - return sort_name (a, b); -} - -/* clear keys, should be call after sorting is finished */ -static void -clean_sort_keys (dir_list *list, int start, int count) -{ - int i; - - for (i = 0; i < count; i++){ - str_release_key (list->list [i + start].sort_key, case_sensitive); - list->list [i + start].sort_key = NULL; - str_release_key (list->list [i + start].second_sort_key, case_sensitive); - list->list [i + start].second_sort_key = NULL; - } + return sort_name (a, b); } +/* --------------------------------------------------------------------------------------------- */ void -do_sort (dir_list *list, sortfn *sort, int top, int reverse_f, int case_sensitive_f, int exec_first_f) +do_sort (dir_list * list, sortfn * sort, int top, int reverse_f, int case_sensitive_f, + int exec_first_f) { int dot_dot_found = 0; if (top == 0) - return; + return; /* If there is an ".." entry the caller must take care to ensure that it occupies the first list element. */ - if (!strcmp (list->list [0].fname, "..")) - dot_dot_found = 1; + if (!strcmp (list->list[0].fname, "..")) + dot_dot_found = 1; reverse = reverse_f ? -1 : 1; case_sensitive = case_sensitive_f; exec_first = exec_first_f; - qsort (&(list->list) [dot_dot_found], - top + 1 - dot_dot_found, sizeof (file_entry), sort); - + qsort (&(list->list)[dot_dot_found], top + 1 - dot_dot_found, sizeof (file_entry), sort); + clean_sort_keys (list, dot_dot_found, top + 1 - dot_dot_found); } +/* --------------------------------------------------------------------------------------------- */ + void -clean_dir (dir_list *list, int count) +clean_dir (dir_list * list, int count) { int i; - for (i = 0; i < count; i++){ - g_free (list->list [i].fname); - list->list [i].fname = NULL; + for (i = 0; i < count; i++) + { + g_free (list->list[i].fname); + list->list[i].fname = NULL; } } -/* Used to set up a directory list when there is no access to a directory */ +/* --------------------------------------------------------------------------------------------- */ +/** Used to set up a directory list when there is no access to a directory */ + gboolean -set_zero_dir (dir_list *list) +set_zero_dir (dir_list * list) { /* Need to grow the *list? */ - if (list->size == 0) { - list->list = g_try_realloc (list->list, sizeof (file_entry) * - (list->size + RESIZE_STEPS)); - if (list->list == NULL) - return FALSE; + if (list->size == 0) + { + list->list = g_try_realloc (list->list, sizeof (file_entry) * (list->size + RESIZE_STEPS)); + if (list->list == NULL) + return FALSE; - list->size += RESIZE_STEPS; + list->size += RESIZE_STEPS; } - memset (&(list->list) [0], 0, sizeof(file_entry)); + memset (&(list->list)[0], 0, sizeof (file_entry)); list->list[0].fnamelen = 2; list->list[0].fname = g_strdup (".."); list->list[0].f.link_to_dir = 0; @@ -308,125 +460,57 @@ set_zero_dir (dir_list *list) return TRUE; } -/* If you change handle_dirent then check also handle_path. */ -/* Return values: -1 = failure, 0 = don't add, 1 = add to the list */ -static int -handle_dirent (dir_list *list, const char *fltr, struct dirent *dp, - struct stat *buf1, int next_free, int *link_to_dir, - int *stale_link) -{ - if (dp->d_name[0] == '.' && dp->d_name[1] == 0) - return 0; - if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0) - return 0; - if (!panels_options.show_dot_files && (dp->d_name[0] == '.')) - return 0; - if (!panels_options.show_backups && dp->d_name[NLENGTH (dp) - 1] == '~') - return 0; - - if (mc_lstat (dp->d_name, buf1) == -1) { - /* - * lstat() fails - such entries should be identified by - * buf1->st_mode being 0. - * It happens on QNX Neutrino for /fs/cd0 if no CD is inserted. - */ - memset (buf1, 0, sizeof (*buf1)); - } - - if (S_ISDIR (buf1->st_mode)) - tree_store_mark_checked (dp->d_name); - - /* A link to a file or a directory? */ - *link_to_dir = 0; - *stale_link = 0; - if (S_ISLNK (buf1->st_mode)) { - struct stat buf2; - if (!mc_stat (dp->d_name, &buf2)) - *link_to_dir = S_ISDIR (buf2.st_mode) != 0; - else - *stale_link = 1; - } - if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && (fltr != NULL) - && !mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB)) - return 0; - - /* Need to grow the *list? */ - if (next_free == list->size) { - list->list = g_try_realloc (list->list, sizeof (file_entry) * - (list->size + RESIZE_STEPS)); - if (list->list == NULL) - return -1; - list->size += RESIZE_STEPS; - } - return 1; -} - -/* get info about ".." */ -static gboolean -get_dotdot_dir_stat (const char *path, struct stat *st) -{ - gboolean ret = FALSE; - - if ((path != NULL) && (path[0] != '\0') && (st != NULL)) { - char *dotdot_dir; - struct stat s; - - dotdot_dir = g_strdup_printf ("%s/../", path); - canonicalize_pathname (dotdot_dir); - ret = mc_stat (dotdot_dir, &s) == 0; - g_free (dotdot_dir); - *st = s; - } - - return ret; -} - -/* handle_path is a simplified handle_dirent. The difference is that +/* --------------------------------------------------------------------------------------------- */ +/** + handle_path is a simplified handle_dirent. The difference is that handle_path doesn't pay attention to panels_options.show_dot_files and panels_options.show_backups. Moreover handle_path can't be used with a filemask. If you change handle_path then check also handle_dirent. */ /* Return values: -1 = failure, 0 = don't add, 1 = add to the list */ + int -handle_path (dir_list *list, const char *path, - struct stat *buf1, int next_free, int *link_to_dir, - int *stale_link) +handle_path (dir_list * list, const char *path, + struct stat *buf1, int next_free, int *link_to_dir, int *stale_link) { - if (path [0] == '.' && path [1] == 0) - return 0; - if (path [0] == '.' && path [1] == '.' && path [2] == 0) - return 0; + if (path[0] == '.' && path[1] == 0) + return 0; + if (path[0] == '.' && path[1] == '.' && path[2] == 0) + return 0; if (mc_lstat (path, buf1) == -1) return 0; if (S_ISDIR (buf1->st_mode)) - tree_store_mark_checked (path); + tree_store_mark_checked (path); /* A link to a file or a directory? */ *link_to_dir = 0; *stale_link = 0; - if (S_ISLNK(buf1->st_mode)){ - struct stat buf2; - if (!mc_stat (path, &buf2)) - *link_to_dir = S_ISDIR(buf2.st_mode) != 0; - else - *stale_link = 1; + if (S_ISLNK (buf1->st_mode)) + { + struct stat buf2; + if (!mc_stat (path, &buf2)) + *link_to_dir = S_ISDIR (buf2.st_mode) != 0; + else + *stale_link = 1; } /* Need to grow the *list? */ - if (next_free == list->size){ - list->list = g_try_realloc (list->list, sizeof (file_entry) * - (list->size + RESIZE_STEPS)); - if (list->list == NULL) - return -1; - list->size += RESIZE_STEPS; + if (next_free == list->size) + { + list->list = g_try_realloc (list->list, sizeof (file_entry) * (list->size + RESIZE_STEPS)); + if (list->list == NULL) + return -1; + list->size += RESIZE_STEPS; } return 1; } +/* --------------------------------------------------------------------------------------------- */ + int -do_load_dir (const char *path, dir_list *list, sortfn *sort, int lc_reverse, - int lc_case_sensitive, int exec_ff, const char *fltr) +do_load_dir (const char *path, dir_list * list, sortfn * sort, int lc_reverse, + int lc_case_sensitive, int exec_ff, const char *fltr) { DIR *dirp; struct dirent *dp; @@ -436,100 +520,91 @@ do_load_dir (const char *path, dir_list *list, sortfn *sort, int lc_reverse, /* ".." (if any) must be the first entry in the list */ if (!set_zero_dir (list)) - return next_free; + return next_free; if (get_dotdot_dir_stat (path, &st)) - list->list[next_free].st = st; + list->list[next_free].st = st; next_free++; dirp = mc_opendir (path); - if (!dirp) { - message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); - return next_free; + if (!dirp) + { + message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); + return next_free; } tree_store_start_check (path); /* Do not add a ".." entry to the root directory */ if ((path[0] == PATH_SEP) && (path[1] == '\0')) - next_free--; + next_free--; - while ((dp = mc_readdir (dirp))) { - status = - handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, - &stale_link); - if (status == 0) - continue; - if (status == -1) { - tree_store_end_check (); - mc_closedir (dirp); - return next_free; - } - list->list[next_free].fnamelen = NLENGTH (dp); - list->list[next_free].fname = g_strdup (dp->d_name); - list->list[next_free].f.marked = 0; - list->list[next_free].f.link_to_dir = link_to_dir; - list->list[next_free].f.stale_link = stale_link; - list->list[next_free].f.dir_size_computed = 0; - list->list[next_free].st = st; + while ((dp = mc_readdir (dirp))) + { + status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link); + if (status == 0) + continue; + if (status == -1) + { + tree_store_end_check (); + mc_closedir (dirp); + return next_free; + } + list->list[next_free].fnamelen = NLENGTH (dp); + list->list[next_free].fname = g_strdup (dp->d_name); + list->list[next_free].f.marked = 0; + list->list[next_free].f.link_to_dir = link_to_dir; + list->list[next_free].f.stale_link = stale_link; + list->list[next_free].f.dir_size_computed = 0; + list->list[next_free].st = st; list->list[next_free].sort_key = NULL; list->list[next_free].second_sort_key = NULL; - next_free++; + next_free++; - if ((next_free & 31) == 0) - rotate_dash (); + if ((next_free & 31) == 0) + rotate_dash (); } if (next_free != 0) - do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff); + do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff); mc_closedir (dirp); tree_store_end_check (); return next_free; } -int -link_isdir (const file_entry *file) -{ - if (file->f.link_to_dir) - return 1; - else - return 0; -} +/* --------------------------------------------------------------------------------------------- */ int -if_link_is_exe (const char *full_name, const file_entry *file) +link_isdir (const file_entry * file) +{ + if (file->f.link_to_dir) + return 1; + else + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +if_link_is_exe (const char *full_name, const file_entry * file) { struct stat b; - if (S_ISLNK (file->st.st_mode) && !mc_stat (full_name, &b)) { - return is_exe (b.st_mode); - } else - return 1; -} - -static dir_list dir_copy = { 0, 0 }; - -static void -alloc_dir_copy (int size) -{ - if (dir_copy.size < size) { - if (dir_copy.list) { - int i; - for (i = 0; i < dir_copy.size; i++) - g_free (dir_copy.list [i].fname); - g_free (dir_copy.list); - } - - dir_copy.list = g_new0 (file_entry, size); - dir_copy.size = size; + if (S_ISLNK (file->st.st_mode) && !mc_stat (full_name, &b)) + { + return is_exe (b.st_mode); } + else + return 1; } -/* If fltr is null, then it is a match */ +/* --------------------------------------------------------------------------------------------- */ +/** If fltr is null, then it is a match */ + int -do_reload_dir (const char *path, dir_list *list, sortfn *sort, int count, - int rev, int lc_case_sensitive, int exec_ff, const char *fltr) +do_reload_dir (const char *path, dir_list * list, sortfn * sort, int count, + int rev, int lc_case_sensitive, int exec_ff, const char *fltr) { DIR *dirp; struct dirent *dp; @@ -540,103 +615,110 @@ do_reload_dir (const char *path, dir_list *list, sortfn *sort, int count, GHashTable *marked_files; dirp = mc_opendir (path); - if (!dirp) { - message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); - clean_dir (list, count); - return set_zero_dir (list) ? 1 : 0; + if (!dirp) + { + message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); + clean_dir (list, count); + return set_zero_dir (list) ? 1 : 0; } tree_store_start_check (path); marked_files = g_hash_table_new (g_str_hash, g_str_equal); alloc_dir_copy (list->size); - for (marked_cnt = i = 0; i < count; i++) { - dir_copy.list[i].fnamelen = list->list[i].fnamelen; - dir_copy.list[i].fname = list->list[i].fname; - dir_copy.list[i].f.marked = list->list[i].f.marked; - dir_copy.list[i].f.dir_size_computed = - list->list[i].f.dir_size_computed; - dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir; - dir_copy.list[i].f.stale_link = list->list[i].f.stale_link; + for (marked_cnt = i = 0; i < count; i++) + { + dir_copy.list[i].fnamelen = list->list[i].fnamelen; + dir_copy.list[i].fname = list->list[i].fname; + dir_copy.list[i].f.marked = list->list[i].f.marked; + dir_copy.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed; + dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir; + dir_copy.list[i].f.stale_link = list->list[i].f.stale_link; dir_copy.list[i].sort_key = NULL; dir_copy.list[i].second_sort_key = NULL; - if (list->list[i].f.marked) { - g_hash_table_insert (marked_files, dir_copy.list[i].fname, - &dir_copy.list[i]); - marked_cnt++; - } + if (list->list[i].f.marked) + { + g_hash_table_insert (marked_files, dir_copy.list[i].fname, &dir_copy.list[i]); + marked_cnt++; + } } /* Add ".." except to the root directory. The ".." entry (if any) must be the first in the list. */ - if (!((path[0] == PATH_SEP) && (path[1] == '\0'))) { - if (!set_zero_dir (list)) { - clean_dir (list, count); - clean_dir (&dir_copy, count); - return next_free; - } + if (!((path[0] == PATH_SEP) && (path[1] == '\0'))) + { + if (!set_zero_dir (list)) + { + clean_dir (list, count); + clean_dir (&dir_copy, count); + return next_free; + } - if (get_dotdot_dir_stat (path, &st)) - list->list[next_free].st = st; + if (get_dotdot_dir_stat (path, &st)) + list->list[next_free].st = st; - next_free++; + next_free++; } - while ((dp = mc_readdir (dirp))) { - status = - handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, - &stale_link); - if (status == 0) - continue; - if (status == -1) { - mc_closedir (dirp); - /* Norbert (Feb 12, 1997): - Just in case someone finds this memory leak: - -1 means big trouble (at the moment no memory left), - I don't bother with further cleanup because if one gets to - this point he will have more problems than a few memory - leaks and because one 'clean_dir' would not be enough (and - because I don't want to spent the time to make it working, - IMHO it's not worthwhile). - clean_dir (&dir_copy, count); - */ - tree_store_end_check (); - g_hash_table_destroy (marked_files); - return next_free; - } + while ((dp = mc_readdir (dirp))) + { + status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link); + if (status == 0) + continue; + if (status == -1) + { + mc_closedir (dirp); + /* Norbert (Feb 12, 1997): + Just in case someone finds this memory leak: + -1 means big trouble (at the moment no memory left), + I don't bother with further cleanup because if one gets to + this point he will have more problems than a few memory + leaks and because one 'clean_dir' would not be enough (and + because I don't want to spent the time to make it working, + IMHO it's not worthwhile). + clean_dir (&dir_copy, count); + */ + tree_store_end_check (); + g_hash_table_destroy (marked_files); + return next_free; + } - list->list[next_free].f.marked = 0; + list->list[next_free].f.marked = 0; - /* - * If we have marked files in the copy, scan through the copy - * to find matching file. Decrease number of remaining marks if - * we copied one. - */ - if (marked_cnt > 0) { - if ((g_hash_table_lookup (marked_files, dp->d_name))) { - list->list[next_free].f.marked = 1; - marked_cnt--; - } - } + /* + * If we have marked files in the copy, scan through the copy + * to find matching file. Decrease number of remaining marks if + * we copied one. + */ + if (marked_cnt > 0) + { + if ((g_hash_table_lookup (marked_files, dp->d_name))) + { + list->list[next_free].f.marked = 1; + marked_cnt--; + } + } - list->list[next_free].fnamelen = NLENGTH (dp); - list->list[next_free].fname = g_strdup (dp->d_name); - list->list[next_free].f.link_to_dir = link_to_dir; - list->list[next_free].f.stale_link = stale_link; - list->list[next_free].f.dir_size_computed = 0; - list->list[next_free].st = st; - list->list[next_free].sort_key = NULL; - list->list[next_free].second_sort_key = NULL; - next_free++; - if (!(next_free % 16)) - rotate_dash (); + list->list[next_free].fnamelen = NLENGTH (dp); + list->list[next_free].fname = g_strdup (dp->d_name); + list->list[next_free].f.link_to_dir = link_to_dir; + list->list[next_free].f.stale_link = stale_link; + list->list[next_free].f.dir_size_computed = 0; + list->list[next_free].st = st; + list->list[next_free].sort_key = NULL; + list->list[next_free].second_sort_key = NULL; + next_free++; + if (!(next_free % 16)) + rotate_dash (); } mc_closedir (dirp); tree_store_end_check (); g_hash_table_destroy (marked_files); - if (next_free) { - do_sort (list, sort, next_free - 1, rev, lc_case_sensitive, exec_ff); + if (next_free) + { + do_sort (list, sort, next_free - 1, rev, lc_case_sensitive, exec_ff); } clean_dir (&dir_copy, count); return next_free; } +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/dir.h b/src/dir.h index 1a38aad5f..44631a735 100644 --- a/src/dir.h +++ b/src/dir.h @@ -1,20 +1,28 @@ - /** \file dir.h * \brief Header: directory routines */ -#ifndef MC_DIR_H -#define MC_DIR_H +#ifndef MC__DIR_H +#define MC__DIR_H #include #include "lib/global.h" +/*** typedefs(not structures) and defined constants **********************************************/ + #define MIN_FILES 128 #define RESIZE_STEPS 128 +typedef int sortfn (const void *, const void *); + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + /* keys are set only during sorting */ -typedef struct { +typedef struct +{ /* File attributes */ size_t fnamelen; char *fname; @@ -25,45 +33,49 @@ typedef struct { char *second_sort_key; /* Flags */ - struct { - unsigned int marked:1; /* File marked in pane window */ - unsigned int link_to_dir:1; /* If this is a link, does it point to directory? */ - unsigned int stale_link:1; /* If this is a symlink and points to Charon's land */ - unsigned int dir_size_computed:1; /* Size of directory was computed with dirsizes_cmd */ + struct + { + unsigned int marked:1; /* File marked in pane window */ + unsigned int link_to_dir:1; /* If this is a link, does it point to directory? */ + unsigned int stale_link:1; /* If this is a symlink and points to Charon's land */ + unsigned int dir_size_computed:1; /* Size of directory was computed with dirsizes_cmd */ } f; } file_entry; -typedef struct { +typedef struct +{ file_entry *list; - int size; + int size; } dir_list; -typedef int sortfn (const void *, const void *); +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ int do_load_dir (const char *path, dir_list * list, sortfn * sort, int reverse, - int case_sensitive, int exec_ff, const char *fltr); + int case_sensitive, int exec_ff, const char *fltr); void do_sort (dir_list * list, sortfn * sort, int top, int reverse, - int case_sensitive, int exec_ff); + int case_sensitive, int exec_ff); int do_reload_dir (const char *path, dir_list * list, sortfn * sort, int count, - int reverse, int case_sensitive, int exec_ff, const char *fltr); + int reverse, int case_sensitive, int exec_ff, const char *fltr); void clean_dir (dir_list * list, int count); -gboolean set_zero_dir (dir_list *list); -int handle_path (dir_list *list, const char *path, struct stat *buf1, - int next_free, int *link_to_dir, int *stale_link); +gboolean set_zero_dir (dir_list * list); +int handle_path (dir_list * list, const char *path, struct stat *buf1, + int next_free, int *link_to_dir, int *stale_link); /* Sorting functions */ -int unsorted (file_entry *a, file_entry *b); -int sort_name (file_entry *a, file_entry *b); -int sort_vers (file_entry *a, file_entry *b); -int sort_ext (file_entry *a, file_entry *b); -int sort_time (file_entry *a, file_entry *b); -int sort_atime (file_entry *a, file_entry *b); -int sort_ctime (file_entry *a, file_entry *b); -int sort_size (file_entry *a, file_entry *b); -int sort_inode (file_entry *a, file_entry *b); - +int unsorted (file_entry * a, file_entry * b); +int sort_name (file_entry * a, file_entry * b); +int sort_vers (file_entry * a, file_entry * b); +int sort_ext (file_entry * a, file_entry * b); +int sort_time (file_entry * a, file_entry * b); +int sort_atime (file_entry * a, file_entry * b); +int sort_ctime (file_entry * a, file_entry * b); +int sort_size (file_entry * a, file_entry * b); +int sort_inode (file_entry * a, file_entry * b); int link_isdir (const file_entry *); -int if_link_is_exe (const char *full_name, const file_entry *file); +int if_link_is_exe (const char *full_name, const file_entry * file); -#endif /* MC_DIR_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__DIR_H */ diff --git a/src/execute.c b/src/execute.c index d12fac2a3..8de31040e 100644 --- a/src/execute.c +++ b/src/execute.c @@ -41,6 +41,16 @@ #include "execute.h" #include "lib/vfs/mc-vfs/vfs.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static void edition_post_exec (void) @@ -59,6 +69,7 @@ edition_post_exec (void) application_keypad_mode (); } +/* --------------------------------------------------------------------------------------------- */ static void edition_pre_exec (void) @@ -89,23 +100,7 @@ edition_pre_exec (void) do_exit_ca_mode (); } - -/* Set up the terminal before executing a program */ -void -pre_exec (void) -{ - use_dash (FALSE); - edition_pre_exec (); -} - -/* Hide the terminal after executing a program */ -void -post_exec (void) -{ - edition_post_exec (); - use_dash (TRUE); -} - +/* --------------------------------------------------------------------------------------------- */ #ifdef HAVE_SUBSHELL_SUPPORT static void @@ -120,6 +115,8 @@ do_possible_cd (const char *new_dir) } #endif /* HAVE_SUBSHELL_SUPPORT */ +/* --------------------------------------------------------------------------------------------- */ + static void do_execute (const char *lc_shell, const char *command, int flags) { @@ -208,8 +205,63 @@ do_execute (const char *lc_shell, const char *command, int flags) use_dash (TRUE); } +/* --------------------------------------------------------------------------------------------- */ +static void +do_suspend_cmd (void) +{ + pre_exec (); + + if (console_flag && !use_subshell) + handle_console (CONSOLE_RESTORE); + +#ifdef SIGTSTP + { + struct sigaction sigtstp_action; + + /* Make sure that the SIGTSTP below will suspend us directly, + without calling ncurses' SIGTSTP handler; we *don't* want + ncurses to redraw the screen immediately after the SIGCONT */ + sigaction (SIGTSTP, &startup_handler, &sigtstp_action); + + kill (getpid (), SIGTSTP); + + /* Restore previous SIGTSTP action */ + sigaction (SIGTSTP, &sigtstp_action, NULL); + } +#endif /* SIGTSTP */ + + if (console_flag && !use_subshell) + handle_console (CONSOLE_SAVE); + + edition_post_exec (); +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** Set up the terminal before executing a program */ + +void +pre_exec (void) +{ + use_dash (FALSE); + edition_pre_exec (); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Hide the terminal after executing a program */ +void +post_exec (void) +{ + edition_post_exec (); + use_dash (TRUE); +} + +/* --------------------------------------------------------------------------------------------- */ /* Executes a command */ + void shell_execute (const char *command, int flags) { @@ -234,6 +286,7 @@ shell_execute (const char *command, int flags) g_free (cmd); } +/* --------------------------------------------------------------------------------------------- */ void exec_shell (void) @@ -241,6 +294,7 @@ exec_shell (void) do_execute (shell, 0, 0); } +/* --------------------------------------------------------------------------------------------- */ void toggle_panels (void) @@ -340,37 +394,7 @@ toggle_panels (void) repaint_screen (); } - -static void -do_suspend_cmd (void) -{ - pre_exec (); - - if (console_flag && !use_subshell) - handle_console (CONSOLE_RESTORE); - -#ifdef SIGTSTP - { - struct sigaction sigtstp_action; - - /* Make sure that the SIGTSTP below will suspend us directly, - without calling ncurses' SIGTSTP handler; we *don't* want - ncurses to redraw the screen immediately after the SIGCONT */ - sigaction (SIGTSTP, &startup_handler, &sigtstp_action); - - kill (getpid (), SIGTSTP); - - /* Restore previous SIGTSTP action */ - sigaction (SIGTSTP, &sigtstp_action, NULL); - } -#endif /* SIGTSTP */ - - if (console_flag && !use_subshell) - handle_console (CONSOLE_SAVE); - - edition_post_exec (); -} - +/* --------------------------------------------------------------------------------------------- */ void suspend_cmd (void) @@ -383,11 +407,12 @@ suspend_cmd (void) do_refresh (); } - -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Execute command on a filename that can be on VFS. * Errors are reported to the user. */ + void execute_with_vfs_arg (const char *command, const char *filename) { @@ -430,3 +455,5 @@ execute_with_vfs_arg (const char *command, const char *filename) g_free (localcopy); g_free (fn); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/execute.h b/src/execute.h index 79e820d50..fcc6a8511 100644 --- a/src/execute.h +++ b/src/execute.h @@ -1,16 +1,25 @@ - /** \file execute.h * \brief Header: execution routines */ -#ifndef MC_EXECUTE_H -#define MC_EXECUTE_H +#ifndef MC__EXECUTE_H +#define MC__EXECUTE_H + +/*** typedefs(not structures) and defined constants **********************************************/ /* flags for shell_execute */ #define EXECUTE_INTERNAL (1 << 0) #define EXECUTE_AS_SHELL (1 << 2) #define EXECUTE_HIDE (1 << 3) +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + /* Execute functions that use the shell to execute */ void shell_execute (const char *command, int flags); @@ -29,4 +38,5 @@ void execute_with_vfs_arg (const char *command, const char *filename); void post_exec (void); void pre_exec (void); -#endif /* MC_EXECUTE_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__EXECUTE_H */ diff --git a/src/ext.c b/src/ext.c index f5795e278..6abdfc2fb 100644 --- a/src/ext.c +++ b/src/ext.c @@ -55,23 +55,33 @@ #include "dialog-switch.h" #include "ext.h" +/*** global variables ****************************************************************************/ + /* If set, we execute the file command to check the file type */ int use_file_to_check_type = 1; +/*** file scope macro definitions ****************************************************************/ + +#ifdef FILE_L +#define FILE_CMD "file -L " +#else +#define FILE_CMD "file " +#endif + +/*** file scope type declarations ****************************************************************/ + +typedef char *(*quote_func_t) (const char *name, int quote_percent); + +/*** file scope variables ************************************************************************/ + /* This variable points to a copy of the mc.ext file in memory * With this we avoid loading/parsing the file each time we * need it */ static char *data = NULL; -void -flush_extension_file (void) -{ - g_free (data); - data = NULL; -} - -typedef char *(*quote_func_t) (const char *name, int quote_percent); +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static void exec_extension (const char *filename, const char *lc_data, int *move_dir, int start_line) @@ -134,8 +144,7 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st char *parameter; parameter_found = 0; - parameter = - input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, ""); + parameter = input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, ""); if (parameter == NULL) { /* User canceled */ @@ -364,19 +373,15 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st } } -#ifdef FILE_L -# define FILE_CMD "file -L " -#else -# define FILE_CMD "file " -#endif - -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Run cmd_file with args, put result into buf. * If error, put '\0' into buf[0] * Return 1 if the data is valid, 0 otherwise, -1 for fatal errors. * * NOTES: buf is null-terminated string. */ + static int get_popen_information (const char *cmd_file, const char *args, char *buf, int buflen) { @@ -413,10 +418,12 @@ get_popen_information (const char *cmd_file, const char *args, char *buf, int bu return read_bytes ? 1 : 0; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Run the "file" command on the local file. * Return 1 if the data is valid, 0 otherwise, -1 for fatal errors. */ + static int get_file_type_local (const char *filename, char *buf, int buflen) { @@ -430,11 +437,13 @@ get_file_type_local (const char *filename, char *buf, int buflen) return ret; } -#ifdef HAVE_CHARSET -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Run the "enca" command on the local file. * Return 1 if the data is valid, 0 otherwise, -1 for fatal errors. */ + +#ifdef HAVE_CHARSET static int get_file_encoding_local (const char *filename, char *buf, int buflen) { @@ -455,12 +464,14 @@ get_file_encoding_local (const char *filename, char *buf, int buflen) } #endif /* HAVE_CHARSET */ -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Invoke the "file" command on the file and match its output against PTR. * have_type is a flag that is set if we already have tried to determine * the type of that file. * Return 1 for match, 0 for no match, -1 errors. */ + static int regex_check_type (const char *filename, const char *ptr, int *have_type) { @@ -563,8 +574,20 @@ regex_check_type (const char *filename, const char *ptr, int *have_type) return found; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ -/* The second argument is action, i.e. Open, View or Edit +void +flush_extension_file (void) +{ + g_free (data); + data = NULL; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * The second argument is action, i.e. Open, View or Edit * * This function returns: * @@ -575,6 +598,7 @@ regex_check_type (const char *filename, const char *ptr, int *have_type) * If action == "View" then a parameter is checked in the form of "View:%d", * if the value for %d exists, then the viewer is started up at that line number. */ + int regex_command (const char *filename, const char *action, int *move_dir) { @@ -651,9 +675,8 @@ regex_command (const char *filename, const char *action, int *move_dir) } if (home_error) { - char *title = - g_strdup_printf (_("~/%s file error"), - MC_USERCONF_DIR PATH_SEP_STR MC_FILEBIND_FILE); + char *title = g_strdup_printf (_("~/%s file error"), + MC_USERCONF_DIR PATH_SEP_STR MC_FILEBIND_FILE); message (D_ERROR, title, _("The format of the ~/%s file has " "changed with version 3.0. You may either want to copy " @@ -812,3 +835,4 @@ regex_command (const char *filename, const char *action, int *move_dir) return ret; } +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/ext.h b/src/ext.h index 70912c378..806e7fb8e 100644 --- a/src/ext.h +++ b/src/ext.h @@ -1,10 +1,18 @@ - /** \file ext.h * \brief Header: extension dependent execution */ -#ifndef MC_EXT_H -#define MC_EXT_H +#ifndef MC__EXT_H +#define MC__EXT_H +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ int regex_command (const char *filename, const char *action, int *move_dir); @@ -13,4 +21,5 @@ int regex_command (const char *filename, const char *action, int *move_dir); */ void flush_extension_file (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__EXT_H */ diff --git a/src/file.c b/src/file.c index afe74b28f..02a1d7e84 100644 --- a/src/file.c +++ b/src/file.c @@ -81,11 +81,7 @@ /* }}} */ -/* Hack: the vfs code should not rely on this */ -#define WITH_FULL_PATHS 1 - -#define FILEOP_UPDATE_INTERVAL 2 -#define FILEOP_STALLING_INTERVAL 4 +/*** global variables ****************************************************************************/ int verbose = 1; @@ -96,6 +92,23 @@ int verbose = 1; */ int file_op_compute_totals = 1; +/* TRANSLATORS: no need to translate 'DialogTitle', it's just a context prefix */ +const char *op_names[3] = { + N_("DialogTitle|Copy"), + N_("DialogTitle|Move"), + N_("DialogTitle|Delete") +}; + +/*** file scope macro definitions ****************************************************************/ + +/* Hack: the vfs code should not rely on this */ +#define WITH_FULL_PATHS 1 + +#define FILEOP_UPDATE_INTERVAL 2 +#define FILEOP_STALLING_INTERVAL 4 + +/*** file scope type declarations ****************************************************************/ + /* This is a hard link cache */ struct link { @@ -108,6 +121,58 @@ struct link char name[1]; }; +/* Status of the destination file */ +typedef enum +{ + DEST_NONE = 0, /* Not created */ + DEST_SHORT = 1, /* Created, not fully copied */ + DEST_FULL = 2 /* Created, fully copied */ +} dest_status_t; + +/* + * This array introduced to avoid translation problems. The former (op_names) + * is assumed to be nouns, suitable in dialog box titles; this one should + * contain whatever is used in prompt itself (i.e. in russian, it's verb). + * (I don't use spaces around the words, because someday they could be + * dropped, when widgets get smarter) + */ + +/* TRANSLATORS: no need to translate 'FileOperation', it's just a context prefix */ +static const char *op_names1[] = { + N_("FileOperation|Copy"), + N_("FileOperation|Move"), + N_("FileOperation|Delete") +}; + +/* + * These are formats for building a prompt. Parts encoded as follows: + * %o - operation from op_names1 + * %f - file/files or files/directories, as appropriate + * %m - "with source mask" or question mark for delete + * %s - source name (truncated) + * %d - number of marked files + * %e - "to:" or question mark for delete + * + * xgettext:no-c-format */ +static const char *one_format = N_("%o %f \"%s\"%m"); +/* xgettext:no-c-format */ +static const char *many_format = N_("%o %d %f%m"); + +static const char *prompt_parts[] = { + N_("file"), + N_("files"), + N_("directory"), + N_("directories"), + N_("files/directories"), + /* TRANSLATORS: keep leading space here to split words in Copy/Move dialog */ + N_(" with source mask:"), + N_("to:") +}; + +static const char *question_format = N_("%s?"); + +/*** file scope variables ************************************************************************/ + /* the hard link cache */ static struct link *linklist = NULL; @@ -126,14 +191,10 @@ static struct link *erase_list; */ static struct link *dest_dirs = NULL; -/* TRANSLATORS: no need to translate 'DialogTitle', it's just a context prefix */ -const char *op_names[3] = { - N_("DialogTitle|Copy"), - N_("DialogTitle|Move"), - N_("DialogTitle|Delete") -}; +static FileProgressStatus transform_error = FILE_CONT; -/* }}} */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static FileProgressStatus query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, struct stat *_d_stat); @@ -144,7 +205,7 @@ static FileProgressStatus erase_file (FileOpTotalContext * tctx, FileOpContext * const char *s, gboolean is_toplevel_file); static FileProgressStatus files_error (const char *format, const char *file1, const char *file2); -static FileProgressStatus transform_error = FILE_CONT; +/* --------------------------------------------------------------------------------------------- */ static char * transform_source (FileOpContext * ctx, const char *source) @@ -174,6 +235,8 @@ transform_source (FileOpContext * ctx, const char *source) return q; } +/* --------------------------------------------------------------------------------------------- */ + static void free_linklist (struct link **lc_linklist) { @@ -187,6 +250,8 @@ free_linklist (struct link **lc_linklist) *lc_linklist = NULL; } +/* --------------------------------------------------------------------------------------------- */ + static int is_in_linklist (struct link *lp, const char *path, struct stat *sb) { @@ -204,10 +269,12 @@ is_in_linklist (struct link *lp, const char *path, struct stat *sb) return 0; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Returns 0 if the inode wasn't found in the cache and 1 if it was found * and a hardlink was succesfully made */ + static int check_hardlinks (const char *src_name, const char *dst_name, struct stat *pstat) { @@ -258,13 +325,15 @@ check_hardlinks (const char *src_name, const char *dst_name, struct stat *pstat) return 0; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Duplicate the contents of the symbolic link src_path in dst_path. * Try to make a stable symlink if the option "stable symlink" was * set in the file mask dialog. * If dst_path is an existing symlink it will be deleted silently * (upper levels take already care of existing files at dst_path). */ + static FileProgressStatus make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) { @@ -350,6 +419,8 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) return return_status; } +/* --------------------------------------------------------------------------------------------- */ + static FileProgressStatus progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add, gboolean is_toplevel_file) @@ -377,13 +448,7 @@ progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add, return check_progress_buttons (ctx); } -/* Status of the destination file */ -typedef enum -{ - DEST_NONE = 0, /* Not created */ - DEST_SHORT = 1, /* Created, not fully copied */ - DEST_FULL = 2 /* Created, fully copied */ -} dest_status_t; +/* --------------------------------------------------------------------------------------------- */ static FileProgressStatus real_warn_same_file (enum OperationMode mode, const char *fmt, const char *a, const char *b) @@ -402,6 +467,8 @@ real_warn_same_file (enum OperationMode mode, const char *fmt, const char *a, co return (result == 1) ? FILE_ABORT : FILE_SKIP; } +/* --------------------------------------------------------------------------------------------- */ + #ifdef WITH_BACKGROUND static FileProgressStatus warn_same_file (const char *fmt, const char *a, const char *b) @@ -427,6 +494,8 @@ warn_same_file (const char *fmt, const char *a, const char *b) } #endif +/* --------------------------------------------------------------------------------------------- */ + static void copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx, struct timeval tv_current, struct timeval tv_transfer_start, @@ -478,6 +547,710 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx, } } +/* --------------------------------------------------------------------------------------------- */ + + +/* {{{ Move routines */ +static FileProgressStatus +move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *d) +{ + struct stat src_stats, dst_stats; + FileProgressStatus return_status = FILE_CONT; + gboolean copy_done = FALSE; + gboolean old_ask_overwrite; + + file_progress_show_source (ctx, s); + file_progress_show_target (ctx, d); + if (check_progress_buttons (ctx) == FILE_ABORT) + return FILE_ABORT; + + mc_refresh (); + + while (mc_lstat (s, &src_stats) != 0) + { + /* Source doesn't exist */ + return_status = file_error (_("Cannot stat file \"%s\"\n%s"), s); + if (return_status != FILE_RETRY) + return return_status; + } + + if (mc_lstat (d, &dst_stats) == 0) + { + if (src_stats.st_dev == dst_stats.st_dev && src_stats.st_ino == dst_stats.st_ino) + return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), s, d); + + if (S_ISDIR (dst_stats.st_mode)) + { + message (D_ERROR, MSG_ERROR, _("Cannot overwrite directory \"%s\""), d); + do_refresh (); + return FILE_SKIP; + } + + if (confirm_overwrite) + { + return_status = query_replace (ctx, d, &src_stats, &dst_stats); + if (return_status != FILE_CONT) + return return_status; + } + /* Ok to overwrite */ + } + + if (!ctx->do_append) + { + if (S_ISLNK (src_stats.st_mode) && ctx->stable_symlinks) + { + return_status = make_symlink (ctx, s, d); + if (return_status == FILE_CONT) + goto retry_src_remove; + else + return return_status; + } + + if (mc_rename (s, d) == 0) + return progress_update_one (tctx, ctx, src_stats.st_size, TRUE); + } +#if 0 + /* Comparison to EXDEV seems not to work in nfs if you're moving from + one nfs to the same, but on the server it is on two different + filesystems. Then nfs returns EIO instead of EXDEV. + Hope it will not hurt if we always in case of error try to copy/delete. */ + else + errno = EXDEV; /* Hack to copy (append) the file and then delete it */ + + if (errno != EXDEV) + { + return_status = files_error (_("Cannot move file \"%s\" to \"%s\"\n%s"), s, d); + if (return_status == FILE_RETRY) + goto retry_rename; + return return_status; + } +#endif + + /* Failed because filesystem boundary -> copy the file instead */ + old_ask_overwrite = tctx->ask_overwrite; + tctx->ask_overwrite = FALSE; + return_status = copy_file_file (tctx, ctx, s, d); + tctx->ask_overwrite = old_ask_overwrite; + if (return_status != FILE_CONT) + return return_status; + + copy_done = TRUE; + + file_progress_show_source (ctx, NULL); + file_progress_show (ctx, 0, 0, "", FALSE); + + return_status = check_progress_buttons (ctx); + if (return_status != FILE_CONT) + return return_status; + + mc_refresh (); + + retry_src_remove: + if (mc_unlink (s)) + { + return_status = file_error (_("Cannot remove file \"%s\"\n%s"), s); + if (return_status == FILE_RETRY) + goto retry_src_remove; + return return_status; + } + + if (!copy_done) + return_status = progress_update_one (tctx, ctx, src_stats.st_size, TRUE); + + return return_status; +} + +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ +/* {{{ Erase routines */ +/** Don't update progress status if progress_count==NULL */ + +static FileProgressStatus +erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, + gboolean is_toplevel_file) +{ + int return_status; + struct stat buf; + + file_progress_show_deleting (ctx, s); + if (check_progress_buttons (ctx) == FILE_ABORT) + return FILE_ABORT; + mc_refresh (); + + if (tctx->progress_count && mc_lstat (s, &buf)) + { + /* ignore, most likely the mc_unlink fails, too */ + buf.st_size = 0; + } + + while (mc_unlink (s)) + { + return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s); + if (return_status != FILE_RETRY) + return return_status; + } + + if (tctx->progress_count) + return progress_update_one (tctx, ctx, buf.st_size, is_toplevel_file); + else + return FILE_CONT; +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +recursive_erase (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) +{ + struct dirent *next; + struct stat buf; + DIR *reading; + char *path; + FileProgressStatus return_status = FILE_CONT; + + if (!strcmp (s, "..")) + return FILE_RETRY; + + reading = mc_opendir (s); + + if (!reading) + return FILE_RETRY; + + while ((next = mc_readdir (reading)) && return_status == FILE_CONT) + { + if (!strcmp (next->d_name, ".")) + continue; + if (!strcmp (next->d_name, "..")) + continue; + path = concat_dir_and_file (s, next->d_name); + if (mc_lstat (path, &buf)) + { + g_free (path); + mc_closedir (reading); + return FILE_RETRY; + } + if (S_ISDIR (buf.st_mode)) + return_status = + (recursive_erase (tctx, ctx, path) != FILE_CONT) ? FILE_RETRY : FILE_CONT; + else + return_status = erase_file (tctx, ctx, path, 0); + g_free (path); + } + mc_closedir (reading); + if (return_status != FILE_CONT) + return return_status; + file_progress_show_deleting (ctx, s); + if (check_progress_buttons (ctx) == FILE_ABORT) + return FILE_ABORT; + mc_refresh (); + + while (my_rmdir (s)) + { + return_status = file_error (_("Cannot remove directory \"%s\"\n%s"), s); + if (return_status != FILE_RETRY) + return return_status; + } + + return FILE_CONT; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Return -1 on error, 1 if there are no entries besides "." and ".." + in the directory path points to, 0 else. */ + +static int +check_dir_is_empty (const char *path) +{ + DIR *dir; + struct dirent *d; + int i; + + dir = mc_opendir (path); + if (!dir) + return -1; + + for (i = 1, d = mc_readdir (dir); d; d = mc_readdir (dir)) + { + if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; /* "." or ".." */ + i = 0; + break; + } + + mc_closedir (dir); + return i; +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +erase_dir_iff_empty (FileOpContext * ctx, const char *s) +{ + FileProgressStatus error; + + if (strcmp (s, "..") == 0) + return FILE_SKIP; + + if (strcmp (s, ".") == 0) + return FILE_SKIP; + + file_progress_show_deleting (ctx, s); + if (check_progress_buttons (ctx) == FILE_ABORT) + return FILE_ABORT; + mc_refresh (); + + if (1 != check_dir_is_empty (s)) /* not empty or error */ + return FILE_CONT; + + while (my_rmdir (s)) + { + error = file_error (_("Cannot remove directory \"%s\"\n%s"), s); + if (error != FILE_RETRY) + return error; + } + + return FILE_CONT; +} + +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ +/* {{{ Panel operate routines */ + +/** + * Return currently selected entry name or the name of the first marked + * entry if there is one. + */ + +static char * +panel_get_file (WPanel * panel, struct stat *stat_buf) +{ + int i; + + if (get_current_type () == view_tree) + { + WTree *tree = (WTree *) get_panel_widget (get_current_index ()); + char *tree_name = tree_selected_name (tree); + + mc_stat (tree_name, stat_buf); + return tree_name; + } + + if (panel->marked) + { + for (i = 0; i < panel->count; i++) + if (panel->dir.list[i].f.marked) + { + *stat_buf = panel->dir.list[i].st; + return panel->dir.list[i].fname; + } + } + else + { + *stat_buf = panel->dir.list[panel->selected].st; + return panel->dir.list[panel->selected].fname; + } + g_assert_not_reached (); + return NULL; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * panel_compute_totals: + * + * compute the number of files and the number of bytes + * used up by the whole selection, recursing directories + * as required. In addition, it checks to see if it will + * overwrite any files by doing the copy. + */ + +static FileProgressStatus +panel_compute_totals (const WPanel * panel, const void *ui, + compute_dir_size_callback cback, + off_t * ret_marked, double *ret_total, gboolean compute_symlinks) +{ + int i; + + *ret_marked = 0; + *ret_total = 0.0; + + for (i = 0; i < panel->count; i++) + { + struct stat *s; + + if (!panel->dir.list[i].f.marked) + continue; + + s = &panel->dir.list[i].st; + + if (S_ISDIR (s->st_mode)) + { + char *dir_name; + off_t subdir_count = 0; + double subdir_bytes = 0; + FileProgressStatus status; + + dir_name = concat_dir_and_file (panel->cwd, panel->dir.list[i].fname); + + status = compute_dir_size (dir_name, ui, cback, + &subdir_count, &subdir_bytes, compute_symlinks); + g_free (dir_name); + + if (status != FILE_CONT) + return FILE_ABORT; + + *ret_marked += subdir_count; + *ret_total += subdir_bytes; + } + else + { + (*ret_marked)++; + *ret_total += s->st_size; + } + } + + return FILE_CONT; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Initialize variables for progress bars */ +static FileProgressStatus +panel_operate_init_totals (FileOperation operation, + const WPanel * panel, const char *source, FileOpContext * ctx) +{ + FileProgressStatus status; + + if (operation != OP_MOVE && verbose && file_op_compute_totals) + { + ComputeDirSizeUI *ui; + + ui = compute_dir_size_create_ui (); + + if (source != NULL) + status = compute_dir_size (source, ui, compute_dir_size_update_ui, + &ctx->progress_count, &ctx->progress_bytes, + ctx->follow_links); + else + status = panel_compute_totals (panel, ui, compute_dir_size_update_ui, + &ctx->progress_count, &ctx->progress_bytes, + ctx->follow_links); + + compute_dir_size_destroy_ui (ui); + + ctx->progress_totals_computed = (status == FILE_CONT); + } + else + { + status = FILE_CONT; + ctx->progress_count = panel->marked; + ctx->progress_bytes = panel->total; + ctx->progress_totals_computed = FALSE; + } + + return status; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Generate user prompt for panel operation. + * single_source is the name if the source entry or NULL for multiple + * entries. + * src_stat is only used when single_source is not NULL. + */ + +static char * +panel_operate_generate_prompt (const WPanel * panel, FileOperation operation, + gboolean single_source, const struct stat *src_stat) +{ + const char *sp, *cp; + char format_string[BUF_MEDIUM]; + char *dp = format_string; + gboolean build_question = FALSE; + + static gboolean i18n_flag = FALSE; + if (!i18n_flag) + { + size_t i; + + for (i = sizeof (op_names1) / sizeof (op_names1[0]); i--;) + op_names1[i] = Q_ (op_names1[i]); + +#ifdef ENABLE_NLS + for (i = sizeof (prompt_parts) / sizeof (prompt_parts[0]); i--;) + prompt_parts[i] = _(prompt_parts[i]); + + one_format = _(one_format); + many_format = _(many_format); + question_format = _(question_format); +#endif /* ENABLE_NLS */ + i18n_flag = TRUE; + } + + sp = single_source ? one_format : many_format; + + while (*sp != '\0') + { + switch (*sp) + { + case '%': + cp = NULL; + switch (sp[1]) + { + case 'o': + cp = op_names1[operation]; + break; + case 'm': + if (operation == OP_DELETE) + { + cp = ""; + build_question = TRUE; + } + else + cp = prompt_parts[5]; + break; + case 'e': + if (operation == OP_DELETE) + { + cp = ""; + build_question = TRUE; + } + else + cp = prompt_parts[6]; + break; + case 'f': + if (single_source) + cp = S_ISDIR (src_stat->st_mode) ? prompt_parts[2] : prompt_parts[0]; + else + cp = (panel->marked == panel->dirs_marked) + ? prompt_parts[3] + : (panel->dirs_marked ? prompt_parts[4] : prompt_parts[1]); + break; + default: + *dp++ = *sp++; + } + + if (cp != NULL) + { + sp += 2; + while (*cp != '\0') + *dp++ = *cp++; + } + break; + default: + *dp++ = *sp++; + } + } + *dp = '\0'; + + if (build_question) + { + char tmp[BUF_MEDIUM]; + + memmove (tmp, format_string, sizeof (tmp)); + g_snprintf (format_string, sizeof (format_string), question_format, tmp); + } + + return g_strdup (format_string); +} + +/* --------------------------------------------------------------------------------------------- */ + +#ifdef WITH_BACKGROUND +static int +end_bg_process (FileOpContext * ctx, enum OperationMode mode) +{ + int pid = ctx->pid; + + (void) mode; + ctx->pid = 0; + + unregister_task_with_pid (pid); + /* file_op_context_destroy(ctx); */ + return 1; +} +#endif +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ +/* {{{ Query/status report routines */ + +static FileProgressStatus +real_do_file_error (enum OperationMode mode, const char *error) +{ + int result; + const char *msg; + + msg = mode == Foreground ? MSG_ERROR : _("Background process error"); + result = query_dialog (msg, error, D_ERROR, 3, _("&Skip"), _("&Retry"), _("&Abort")); + + switch (result) + { + case 0: + do_refresh (); + return FILE_SKIP; + + case 1: + do_refresh (); + return FILE_RETRY; + + case 2: + default: + return FILE_ABORT; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** Report error with two files */ + +static FileProgressStatus +files_error (const char *format, const char *file1, const char *file2) +{ + char buf[BUF_MEDIUM]; + char *nfile1 = g_strdup (path_trunc (file1, 15)); + char *nfile2 = g_strdup (path_trunc (file2, 15)); + + g_snprintf (buf, sizeof (buf), format, nfile1, nfile2, unix_error_string (errno)); + + g_free (nfile1); + g_free (nfile2); + + return do_file_error (buf); +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +real_query_recursive (FileOpContext * ctx, enum OperationMode mode, const char *s) +{ + gchar *text; + + if (ctx->recursive_result < RECURSIVE_ALWAYS) + { + const char *msg = mode == Foreground + ? _("\nDirectory not empty.\nDelete it recursively?") + : _("\nBackground process: Directory not empty.\nDelete it recursively?"); + text = g_strconcat (_("Delete:"), " ", path_trunc (s, 30), (char *) NULL); + + if (safe_delete) + query_set_sel (1); + + ctx->recursive_result = + (FileCopyMode) query_dialog (text, msg, D_ERROR, 5, + _("&Yes"), _("&No"), _("A&ll"), _("Non&e"), _("&Abort")); + + if (ctx->recursive_result != RECURSIVE_ABORT) + do_refresh (); + g_free (text); + } + + switch (ctx->recursive_result) + { + case RECURSIVE_YES: + case RECURSIVE_ALWAYS: + return FILE_CONT; + + case RECURSIVE_NO: + case RECURSIVE_NEVER: + return FILE_SKIP; + + case RECURSIVE_ABORT: + default: + return FILE_ABORT; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +#ifdef WITH_BACKGROUND +static FileProgressStatus +do_file_error (const char *str) +{ + union + { + void *p; + FileProgressStatus (*f) (enum OperationMode, const char *); + } pntr; + pntr.f = real_do_file_error; + + if (we_are_background) + return parent_call (pntr.p, NULL, 1, strlen (str), str); + else + return real_do_file_error (Foreground, str); +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +query_recursive (FileOpContext * ctx, const char *s) +{ + union + { + void *p; + FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *); + } pntr; + pntr.f = real_query_recursive; + + if (we_are_background) + return parent_call (pntr.p, ctx, 1, strlen (s), s); + else + return real_query_recursive (ctx, Foreground, s); +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, + struct stat *_d_stat) +{ + union + { + void *p; + FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *, + struct stat *, struct stat *); + } pntr; + pntr.f = file_progress_real_query_replace; + + if (we_are_background) + return parent_call (pntr.p, ctx, 3, strlen (destname), destname, + sizeof (struct stat), _s_stat, sizeof (struct stat), _d_stat); + else + return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat); +} + +#else +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +do_file_error (const char *str) +{ + return real_do_file_error (Foreground, str); +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +query_recursive (FileOpContext * ctx, const char *s) +{ + return real_query_recursive (ctx, Foreground, s); +} + +/* --------------------------------------------------------------------------------------------- */ + +static FileProgressStatus +query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, + struct stat *_d_stat) +{ + return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat); +} + +#endif /* !WITH_BACKGROUND */ +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + FileProgressStatus copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *src_path, const char *dst_path) @@ -533,8 +1306,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, { /* Destination already exists */ if (sb.st_dev == sb2.st_dev && sb.st_ino == sb2.st_ino) - return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), - src_path, dst_path); + return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), src_path, dst_path); /* Should we replace destination? */ if (tctx->ask_overwrite) { @@ -562,8 +1334,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, { while (mc_mknod (dst_path, sb.st_mode & ctx->umask_kill, sb.st_rdev) < 0) { - return_status = - file_error (_("Cannot create special file \"%s\"\n%s"), dst_path); + return_status = file_error (_("Cannot create special file \"%s\"\n%s"), dst_path); if (return_status == FILE_RETRY) continue; return return_status; @@ -692,8 +1463,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, else while ((n_read = mc_read (src_desc, buf, sizeof (buf))) < 0) { - return_status = - file_error (_("Cannot read source file\"%s\"\n%s"), src_path); + return_status = file_error (_("Cannot read source file\"%s\"\n%s"), src_path); if (return_status == FILE_RETRY) continue; goto ret; @@ -725,8 +1495,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, t += n_written; continue; } - return_status = - file_error (_("Cannot write target file \"%s\"\n%s"), dst_path); + return_status = file_error (_("Cannot write target file \"%s\"\n%s"), dst_path); if (return_status != FILE_RETRY) goto ret; } @@ -825,8 +1594,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, { while (mc_chmod (dst_path, (src_mode & ctx->umask_kill))) { - temp_status = - file_error (_("Cannot chmod target file \"%s\"\n%s"), dst_path); + temp_status = file_error (_("Cannot chmod target file \"%s\"\n%s"), dst_path); if (temp_status != FILE_RETRY) { return_status = temp_status; @@ -851,12 +1619,14 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, return return_status; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * I think these copy_*_* functions should have a return type. * anyway, this function *must* have two directories as arguments. */ /* FIXME: This function needs to check the return values of the function calls */ + FileProgressStatus copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *_d, gboolean toplevel, gboolean move_over, gboolean do_delete, struct link * parent_dirs) @@ -988,8 +1758,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con { while (mc_chown (dest_dir, cbuf.st_uid, cbuf.st_gid)) { - return_status = - file_error (_("Cannot chown target directory \"%s\"\n%s"), dest_dir); + return_status = file_error (_("Cannot chown target directory \"%s\"\n%s"), dest_dir); if (return_status != FILE_RETRY) goto ret; } @@ -1096,117 +1865,9 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con /* }}} */ +/* --------------------------------------------------------------------------------------------- */ /* {{{ Move routines */ -static FileProgressStatus -move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *d) -{ - struct stat src_stats, dst_stats; - FileProgressStatus return_status = FILE_CONT; - gboolean copy_done = FALSE; - gboolean old_ask_overwrite; - - file_progress_show_source (ctx, s); - file_progress_show_target (ctx, d); - if (check_progress_buttons (ctx) == FILE_ABORT) - return FILE_ABORT; - - mc_refresh (); - - while (mc_lstat (s, &src_stats) != 0) - { - /* Source doesn't exist */ - return_status = file_error (_("Cannot stat file \"%s\"\n%s"), s); - if (return_status != FILE_RETRY) - return return_status; - } - - if (mc_lstat (d, &dst_stats) == 0) - { - if (src_stats.st_dev == dst_stats.st_dev && src_stats.st_ino == dst_stats.st_ino) - return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), s, d); - - if (S_ISDIR (dst_stats.st_mode)) - { - message (D_ERROR, MSG_ERROR, _("Cannot overwrite directory \"%s\""), d); - do_refresh (); - return FILE_SKIP; - } - - if (confirm_overwrite) - { - return_status = query_replace (ctx, d, &src_stats, &dst_stats); - if (return_status != FILE_CONT) - return return_status; - } - /* Ok to overwrite */ - } - - if (!ctx->do_append) - { - if (S_ISLNK (src_stats.st_mode) && ctx->stable_symlinks) - { - return_status = make_symlink (ctx, s, d); - if (return_status == FILE_CONT) - goto retry_src_remove; - else - return return_status; - } - - if (mc_rename (s, d) == 0) - return progress_update_one (tctx, ctx, src_stats.st_size, TRUE); - } -#if 0 - /* Comparison to EXDEV seems not to work in nfs if you're moving from - one nfs to the same, but on the server it is on two different - filesystems. Then nfs returns EIO instead of EXDEV. - Hope it will not hurt if we always in case of error try to copy/delete. */ - else - errno = EXDEV; /* Hack to copy (append) the file and then delete it */ - - if (errno != EXDEV) - { - return_status = files_error (_("Cannot move file \"%s\" to \"%s\"\n%s"), s, d); - if (return_status == FILE_RETRY) - goto retry_rename; - return return_status; - } -#endif - - /* Failed because filesystem boundary -> copy the file instead */ - old_ask_overwrite = tctx->ask_overwrite; - tctx->ask_overwrite = FALSE; - return_status = copy_file_file (tctx, ctx, s, d); - tctx->ask_overwrite = old_ask_overwrite; - if (return_status != FILE_CONT) - return return_status; - - copy_done = TRUE; - - file_progress_show_source (ctx, NULL); - file_progress_show (ctx, 0, 0, "", FALSE); - - return_status = check_progress_buttons (ctx); - if (return_status != FILE_CONT) - return return_status; - - mc_refresh (); - - retry_src_remove: - if (mc_unlink (s)) - { - return_status = file_error (_("Cannot remove file \"%s\"\n%s"), s); - if (return_status == FILE_RETRY) - goto retry_src_remove; - return return_status; - } - - if (!copy_done) - return_status = progress_update_one (tctx, ctx, src_stats.st_size, TRUE); - - return return_status; -} - FileProgressStatus move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *d) { @@ -1323,119 +1984,8 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con /* }}} */ +/* --------------------------------------------------------------------------------------------- */ /* {{{ Erase routines */ -/* Don't update progress status if progress_count==NULL */ -static FileProgressStatus -erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, - gboolean is_toplevel_file) -{ - int return_status; - struct stat buf; - - file_progress_show_deleting (ctx, s); - if (check_progress_buttons (ctx) == FILE_ABORT) - return FILE_ABORT; - mc_refresh (); - - if (tctx->progress_count && mc_lstat (s, &buf)) - { - /* ignore, most likely the mc_unlink fails, too */ - buf.st_size = 0; - } - - while (mc_unlink (s)) - { - return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s); - if (return_status != FILE_RETRY) - return return_status; - } - - if (tctx->progress_count) - return progress_update_one (tctx, ctx, buf.st_size, is_toplevel_file); - else - return FILE_CONT; -} - -static FileProgressStatus -recursive_erase (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) -{ - struct dirent *next; - struct stat buf; - DIR *reading; - char *path; - FileProgressStatus return_status = FILE_CONT; - - if (!strcmp (s, "..")) - return FILE_RETRY; - - reading = mc_opendir (s); - - if (!reading) - return FILE_RETRY; - - while ((next = mc_readdir (reading)) && return_status == FILE_CONT) - { - if (!strcmp (next->d_name, ".")) - continue; - if (!strcmp (next->d_name, "..")) - continue; - path = concat_dir_and_file (s, next->d_name); - if (mc_lstat (path, &buf)) - { - g_free (path); - mc_closedir (reading); - return FILE_RETRY; - } - if (S_ISDIR (buf.st_mode)) - return_status = - (recursive_erase (tctx, ctx, path) != FILE_CONT) ? FILE_RETRY : FILE_CONT; - else - return_status = erase_file (tctx, ctx, path, 0); - g_free (path); - } - mc_closedir (reading); - if (return_status != FILE_CONT) - return return_status; - file_progress_show_deleting (ctx, s); - if (check_progress_buttons (ctx) == FILE_ABORT) - return FILE_ABORT; - mc_refresh (); - - while (my_rmdir (s)) - { - return_status = file_error (_("Cannot remove directory \"%s\"\n%s"), s); - if (return_status != FILE_RETRY) - return return_status; - } - - return FILE_CONT; -} - -/* Return -1 on error, 1 if there are no entries besides "." and ".." - in the directory path points to, 0 else. */ -static int -check_dir_is_empty (const char *path) -{ - DIR *dir; - struct dirent *d; - int i; - - dir = mc_opendir (path); - if (!dir) - return -1; - - for (i = 1, d = mc_readdir (dir); d; d = mc_readdir (dir)) - { - if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; /* "." or ".." */ - i = 0; - break; - } - - mc_closedir (dir); - return i; -} FileProgressStatus erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) @@ -1480,76 +2030,11 @@ erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) return FILE_CONT; } -static FileProgressStatus -erase_dir_iff_empty (FileOpContext * ctx, const char *s) -{ - FileProgressStatus error; - - if (strcmp (s, "..") == 0) - return FILE_SKIP; - - if (strcmp (s, ".") == 0) - return FILE_SKIP; - - file_progress_show_deleting (ctx, s); - if (check_progress_buttons (ctx) == FILE_ABORT) - return FILE_ABORT; - mc_refresh (); - - if (1 != check_dir_is_empty (s)) /* not empty or error */ - return FILE_CONT; - - while (my_rmdir (s)) - { - error = file_error (_("Cannot remove directory \"%s\"\n%s"), s); - if (error != FILE_RETRY) - return error; - } - - return FILE_CONT; -} - /* }}} */ +/* --------------------------------------------------------------------------------------------- */ /* {{{ Panel operate routines */ -/* - * Return currently selected entry name or the name of the first marked - * entry if there is one. - */ -static char * -panel_get_file (WPanel * panel, struct stat *stat_buf) -{ - int i; - - if (get_current_type () == view_tree) - { - WTree *tree = (WTree *) get_panel_widget (get_current_index ()); - char *tree_name = tree_selected_name (tree); - - mc_stat (tree_name, stat_buf); - return tree_name; - } - - if (panel->marked) - { - for (i = 0; i < panel->count; i++) - if (panel->dir.list[i].f.marked) - { - *stat_buf = panel->dir.list[i].st; - return panel->dir.list[i].fname; - } - } - else - { - *stat_buf = panel->dir.list[panel->selected].st; - return panel->dir.list[panel->selected].fname; - } - g_assert_not_reached (); - return NULL; -} - - ComputeDirSizeUI * compute_dir_size_create_ui (void) { @@ -1579,6 +2064,8 @@ compute_dir_size_create_ui (void) return ui; } +/* --------------------------------------------------------------------------------------------- */ + void compute_dir_size_destroy_ui (ComputeDirSizeUI * ui) { @@ -1594,6 +2081,8 @@ compute_dir_size_destroy_ui (ComputeDirSizeUI * ui) } } +/* --------------------------------------------------------------------------------------------- */ + FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname) { @@ -1627,11 +2116,13 @@ compute_dir_size_update_ui (const void *ui, const char *dirname) } } +/* --------------------------------------------------------------------------------------------- */ /** * compute_dir_size: * * Computes the number of bytes used by the files in a directory */ + FileProgressStatus compute_dir_size (const char *dirname, const void *ui, compute_dir_size_callback cback, @@ -1718,257 +2209,7 @@ compute_dir_size (const char *dirname, const void *ui, return ret; } -/** - * panel_compute_totals: - * - * compute the number of files and the number of bytes - * used up by the whole selection, recursing directories - * as required. In addition, it checks to see if it will - * overwrite any files by doing the copy. - */ -static FileProgressStatus -panel_compute_totals (const WPanel * panel, const void *ui, - compute_dir_size_callback cback, - off_t * ret_marked, double *ret_total, gboolean compute_symlinks) -{ - int i; - - *ret_marked = 0; - *ret_total = 0.0; - - for (i = 0; i < panel->count; i++) - { - struct stat *s; - - if (!panel->dir.list[i].f.marked) - continue; - - s = &panel->dir.list[i].st; - - if (S_ISDIR (s->st_mode)) - { - char *dir_name; - off_t subdir_count = 0; - double subdir_bytes = 0; - FileProgressStatus status; - - dir_name = concat_dir_and_file (panel->cwd, panel->dir.list[i].fname); - - status = compute_dir_size (dir_name, ui, cback, - &subdir_count, &subdir_bytes, compute_symlinks); - g_free (dir_name); - - if (status != FILE_CONT) - return FILE_ABORT; - - *ret_marked += subdir_count; - *ret_total += subdir_bytes; - } - else - { - (*ret_marked)++; - *ret_total += s->st_size; - } - } - - return FILE_CONT; -} - -/* Initialize variables for progress bars */ -static FileProgressStatus -panel_operate_init_totals (FileOperation operation, - const WPanel * panel, const char *source, FileOpContext * ctx) -{ - FileProgressStatus status; - - if (operation != OP_MOVE && verbose && file_op_compute_totals) - { - ComputeDirSizeUI *ui; - - ui = compute_dir_size_create_ui (); - - if (source != NULL) - status = compute_dir_size (source, ui, compute_dir_size_update_ui, - &ctx->progress_count, &ctx->progress_bytes, - ctx->follow_links); - else - status = panel_compute_totals (panel, ui, compute_dir_size_update_ui, - &ctx->progress_count, &ctx->progress_bytes, - ctx->follow_links); - - compute_dir_size_destroy_ui (ui); - - ctx->progress_totals_computed = (status == FILE_CONT); - } - else - { - status = FILE_CONT; - ctx->progress_count = panel->marked; - ctx->progress_bytes = panel->total; - ctx->progress_totals_computed = FALSE; - } - - return status; -} - -/* - * This array introduced to avoid translation problems. The former (op_names) - * is assumed to be nouns, suitable in dialog box titles; this one should - * contain whatever is used in prompt itself (i.e. in russian, it's verb). - * (I don't use spaces around the words, because someday they could be - * dropped, when widgets get smarter) - */ - -/* TRANSLATORS: no need to translate 'FileOperation', it's just a context prefix */ -static const char *op_names1[] = { - N_("FileOperation|Copy"), - N_("FileOperation|Move"), - N_("FileOperation|Delete") -}; - -/* - * These are formats for building a prompt. Parts encoded as follows: - * %o - operation from op_names1 - * %f - file/files or files/directories, as appropriate - * %m - "with source mask" or question mark for delete - * %s - source name (truncated) - * %d - number of marked files - * %e - "to:" or question mark for delete - * - * xgettext:no-c-format */ -static const char *one_format = N_("%o %f \"%s\"%m"); -/* xgettext:no-c-format */ -static const char *many_format = N_("%o %d %f%m"); - -static const char *prompt_parts[] = { - N_("file"), - N_("files"), - N_("directory"), - N_("directories"), - N_("files/directories"), -/* TRANSLATORS: keep leading space here to split words in Copy/Move dialog */ - N_(" with source mask:"), - N_("to:") -}; - -static const char *question_format = N_("%s?"); - -/* - * Generate user prompt for panel operation. - * single_source is the name if the source entry or NULL for multiple - * entries. - * src_stat is only used when single_source is not NULL. - */ -static char * -panel_operate_generate_prompt (const WPanel * panel, FileOperation operation, - gboolean single_source, const struct stat *src_stat) -{ - const char *sp, *cp; - char format_string[BUF_MEDIUM]; - char *dp = format_string; - gboolean build_question = FALSE; - - static gboolean i18n_flag = FALSE; - if (!i18n_flag) - { - size_t i; - - for (i = sizeof (op_names1) / sizeof (op_names1[0]); i--;) - op_names1[i] = Q_ (op_names1[i]); - -#ifdef ENABLE_NLS - for (i = sizeof (prompt_parts) / sizeof (prompt_parts[0]); i--;) - prompt_parts[i] = _(prompt_parts[i]); - - one_format = _(one_format); - many_format = _(many_format); - question_format = _(question_format); -#endif /* ENABLE_NLS */ - i18n_flag = TRUE; - } - - sp = single_source ? one_format : many_format; - - while (*sp != '\0') - { - switch (*sp) - { - case '%': - cp = NULL; - switch (sp[1]) - { - case 'o': - cp = op_names1[operation]; - break; - case 'm': - if (operation == OP_DELETE) - { - cp = ""; - build_question = TRUE; - } - else - cp = prompt_parts[5]; - break; - case 'e': - if (operation == OP_DELETE) - { - cp = ""; - build_question = TRUE; - } - else - cp = prompt_parts[6]; - break; - case 'f': - if (single_source) - cp = S_ISDIR (src_stat->st_mode) ? prompt_parts[2] : prompt_parts[0]; - else - cp = (panel->marked == panel->dirs_marked) - ? prompt_parts[3] - : (panel->dirs_marked ? prompt_parts[4] : prompt_parts[1]); - break; - default: - *dp++ = *sp++; - } - - if (cp != NULL) - { - sp += 2; - while (*cp != '\0') - *dp++ = *cp++; - } - break; - default: - *dp++ = *sp++; - } - } - *dp = '\0'; - - if (build_question) - { - char tmp[BUF_MEDIUM]; - - memmove (tmp, format_string, sizeof (tmp)); - g_snprintf (format_string, sizeof (format_string), question_format, tmp); - } - - return g_strdup (format_string); -} - -#ifdef WITH_BACKGROUND -static int -end_bg_process (FileOpContext * ctx, enum OperationMode mode) -{ - int pid = ctx->pid; - - (void) mode; - ctx->pid = 0; - - unregister_task_with_pid (pid); - /* file_op_context_destroy(ctx); */ - return 1; -} -#endif - +/* --------------------------------------------------------------------------------------------- */ /** * panel_operate: * @@ -1981,6 +2222,7 @@ end_bg_process (FileOpContext * ctx, enum OperationMode mode) * force_single forces operation on the current entry and affects * default destination. Current filename is used as default. */ + gboolean panel_operate (void *source_panel, FileOperation operation, gboolean force_single) { @@ -1992,7 +2234,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl #ifdef WITH_FULL_PATHS char *source_with_path = NULL; #else -# define source_with_path source +#define source_with_path source #endif /* !WITH_FULL_PATHS */ char *dest = NULL; char *temp = NULL; @@ -2274,8 +2516,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl if ((dst_result != 0) || S_ISDIR (dst_stat.st_mode)) break; - if (file_error (_("Destination \"%s\" must be a directory\n%s"), - dest) != FILE_RETRY) + if (file_error (_("Destination \"%s\" must be a directory\n%s"), dest) != FILE_RETRY) goto clean_up; } @@ -2422,34 +2663,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl /* }}} */ +/* --------------------------------------------------------------------------------------------- */ /* {{{ Query/status report routines */ - -static FileProgressStatus -real_do_file_error (enum OperationMode mode, const char *error) -{ - int result; - const char *msg; - - msg = mode == Foreground ? MSG_ERROR : _("Background process error"); - result = query_dialog (msg, error, D_ERROR, 3, _("&Skip"), _("&Retry"), _("&Abort")); - - switch (result) - { - case 0: - do_refresh (); - return FILE_SKIP; - - case 1: - do_refresh (); - return FILE_RETRY; - - case 2: - default: - return FILE_ABORT; - } -} - -/* Report error with one file */ +/** Report error with one file */ FileProgressStatus file_error (const char *format, const char *file) { @@ -2460,135 +2676,7 @@ file_error (const char *format, const char *file) return do_file_error (buf); } -/* Report error with two files */ -static FileProgressStatus -files_error (const char *format, const char *file1, const char *file2) -{ - char buf[BUF_MEDIUM]; - char *nfile1 = g_strdup (path_trunc (file1, 15)); - char *nfile2 = g_strdup (path_trunc (file2, 15)); - - g_snprintf (buf, sizeof (buf), format, nfile1, nfile2, unix_error_string (errno)); - - g_free (nfile1); - g_free (nfile2); - - return do_file_error (buf); -} - -static FileProgressStatus -real_query_recursive (FileOpContext * ctx, enum OperationMode mode, const char *s) -{ - gchar *text; - - if (ctx->recursive_result < RECURSIVE_ALWAYS) - { - const char *msg = mode == Foreground - ? _("\nDirectory not empty.\nDelete it recursively?") - : _("\nBackground process: Directory not empty.\nDelete it recursively?"); - text = g_strconcat (_("Delete:"), " ", path_trunc (s, 30), (char *) NULL); - - if (safe_delete) - query_set_sel (1); - - ctx->recursive_result = - (FileCopyMode) query_dialog (text, msg, D_ERROR, 5, - _("&Yes"), _("&No"), _("A&ll"), _("Non&e"), _("&Abort")); - - if (ctx->recursive_result != RECURSIVE_ABORT) - do_refresh (); - g_free (text); - } - - switch (ctx->recursive_result) - { - case RECURSIVE_YES: - case RECURSIVE_ALWAYS: - return FILE_CONT; - - case RECURSIVE_NO: - case RECURSIVE_NEVER: - return FILE_SKIP; - - case RECURSIVE_ABORT: - default: - return FILE_ABORT; - } -} - -#ifdef WITH_BACKGROUND -static FileProgressStatus -do_file_error (const char *str) -{ - union - { - void *p; - FileProgressStatus (*f) (enum OperationMode, const char *); - } pntr; - pntr.f = real_do_file_error; - - if (we_are_background) - return parent_call (pntr.p, NULL, 1, strlen (str), str); - else - return real_do_file_error (Foreground, str); -} - -static FileProgressStatus -query_recursive (FileOpContext * ctx, const char *s) -{ - union - { - void *p; - FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *); - } pntr; - pntr.f = real_query_recursive; - - if (we_are_background) - return parent_call (pntr.p, ctx, 1, strlen (s), s); - else - return real_query_recursive (ctx, Foreground, s); -} - -static FileProgressStatus -query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, - struct stat *_d_stat) -{ - union - { - void *p; - FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *, - struct stat *, struct stat *); - } pntr; - pntr.f = file_progress_real_query_replace; - - if (we_are_background) - return parent_call (pntr.p, ctx, 3, strlen (destname), destname, - sizeof (struct stat), _s_stat, sizeof (struct stat), _d_stat); - else - return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat); -} - -#else -static FileProgressStatus -do_file_error (const char *str) -{ - return real_do_file_error (Foreground, str); -} - -static FileProgressStatus -query_recursive (FileOpContext * ctx, const char *s) -{ - return real_query_recursive (ctx, Foreground, s); -} - -static FileProgressStatus -query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, - struct stat *_d_stat) -{ - return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat); -} - -#endif /* !WITH_BACKGROUND */ +/* --------------------------------------------------------------------------------------------- */ /* Cause emacs to enter folding mode for this file: diff --git a/src/file.h b/src/file.h index f73ab5dbe..58ef71715 100644 --- a/src/file.h +++ b/src/file.h @@ -1,10 +1,9 @@ - /** \file file.h * \brief Header: File and directory operation routines */ -#ifndef MC_FILE_H -#define MC_FILE_H +#ifndef MC__FILE_H +#define MC__FILE_H #include /* off_t */ #include @@ -14,8 +13,31 @@ #include "widget.h" /* WLabel */ #include "fileopctx.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +/* Compute directory size */ +/* callback to update status dialog */ +typedef FileProgressStatus (*compute_dir_size_callback) (const void *ui, const char *dirname); + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + struct link; +/* status dialog of directory size computing */ +typedef struct +{ + Dlg_head *dlg; + WLabel *dirname; +} ComputeDirSizeUI; + +/*** global variables defined in .c file *********************************************************/ + +extern int file_op_compute_totals; + +/*** declarations of public functions ************************************************************/ + FileProgressStatus copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *src_path, const char *dst_path); FileProgressStatus move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, @@ -28,32 +50,21 @@ FileProgressStatus erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, co gboolean panel_operate (void *source_panel, FileOperation op, gboolean force_single); -extern int file_op_compute_totals; - /* Error reporting routines */ /* Report error with one file */ FileProgressStatus file_error (const char *format, const char *file); -/* Compute directory size */ -/* callback to update status dialog */ -typedef FileProgressStatus (*compute_dir_size_callback) (const void *ui, const char *dirname); - /* return value is FILE_CONT or FILE_ABORT */ FileProgressStatus compute_dir_size (const char *dirname, const void *ui, compute_dir_size_callback cback, off_t * ret_marked, double *ret_total, gboolean compute_symlinks); -/* status dialog of directory size computing */ -typedef struct -{ - Dlg_head *dlg; - WLabel *dirname; -} ComputeDirSizeUI; ComputeDirSizeUI *compute_dir_size_create_ui (void); void compute_dir_size_destroy_ui (ComputeDirSizeUI * ui); FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname); -#endif /* MC_FILE_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__FILE_H */ diff --git a/src/filegui.c b/src/filegui.c index fa93fafe1..443aecc91 100644 --- a/src/filegui.c +++ b/src/filegui.c @@ -58,20 +58,20 @@ #if defined(STAT_STATVFS) \ && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) \ || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)) -# include -# define STRUCT_STATFS struct statvfs -# define STATFS statvfs +#include +#define STRUCT_STATFS struct statvfs +#define STATFS statvfs #elif defined(HAVE_STATFS) && !defined(STAT_STATFS4) -# ifdef HAVE_SYS_VFS_H -# include -# elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_SYS_PARAM_H) -# include -# include -# elif defined(HAVE_SYS_STATFS_H) -# include -# endif -# define STRUCT_STATFS struct statfs -# define STATFS statfs +#ifdef HAVE_SYS_VFS_H +#include +#elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_SYS_PARAM_H) +#include +#include +#elif defined(HAVE_SYS_STATFS_H) +#include +#endif +#define STRUCT_STATFS struct statfs +#define STATFS statfs #endif #include @@ -97,6 +97,26 @@ #include "filegui.h" /* }}} */ + +/*** global variables ****************************************************************************/ + +int classic_progressbar = 1; + +/*** file scope macro definitions ****************************************************************/ + +/* Hack: the vfs code should not rely on this */ +#define WITH_FULL_PATHS 1 + +/* File operate window sizes */ +#define WX 58 +#define WY 11 +#define FCOPY_LABEL_X 3 + +#define truncFileString(ui, s) str_trunc (s, 52) +#define truncFileStringSecure(ui, s) path_trunc (s, 52) + +/*** file scope type declarations ****************************************************************/ + /* *INDENT-OFF* */ typedef enum { MSDOS_SUPER_MAGIC = 0x4d44, @@ -109,9 +129,6 @@ typedef enum { } filegui_nonattrs_fs_t; /* *INDENT-ON* */ -/* Hack: the vfs code should not rely on this */ -#define WITH_FULL_PATHS 1 - /* Used for button result values */ typedef enum { @@ -156,15 +173,13 @@ typedef struct struct stat *s_stat, *d_stat; } FileOpContextUI; -int classic_progressbar = 1; +/*** file scope variables ************************************************************************/ /* Used to save the hint line */ static int last_hint_line; -/* File operate window sizes */ -#define WX 58 -#define WY 11 -#define FCOPY_LABEL_X 3 +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static gboolean filegui__check_attrs_on_fs (const char *fs_path) @@ -178,7 +193,7 @@ filegui__check_attrs_on_fs (const char *fs_path) if (STATFS (fs_path, &stfs) != 0) return TRUE; -# ifdef __linux__ +#ifdef __linux__ switch ((filegui_nonattrs_fs_t) stfs.f_type) { case MSDOS_SUPER_MAGIC: @@ -190,7 +205,7 @@ filegui__check_attrs_on_fs (const char *fs_path) case USBDEVICE_SUPER_MAGIC: return FALSE; } -# elif defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) \ +#elif defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) \ || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) if (!strcmp (stfs.f_fstypename, "msdos") || !strcmp (stfs.f_fstypename, "msdosfs") @@ -198,194 +213,19 @@ filegui__check_attrs_on_fs (const char *fs_path) || !strcmp (stfs.f_fstypename, "procfs") || !strcmp (stfs.f_fstypename, "smbfs") || strstr (stfs.f_fstypename, "fusefs")) return FALSE; -# elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) +#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) if (!strcmp (stfs.f_basetype, "pcfs") || !strcmp (stfs.f_basetype, "ntfs") || !strcmp (stfs.f_basetype, "proc") || !strcmp (stfs.f_basetype, "smbfs") || !strcmp (stfs.f_basetype, "fuse")) return FALSE; -# endif +#endif #endif /* STATFS */ return TRUE; } -FileProgressStatus -check_progress_buttons (FileOpContext * ctx) -{ - int c; - Gpm_Event event; - FileOpContextUI *ui; - - if (ctx->ui == NULL) - return FILE_CONT; - - ui = ctx->ui; - - event.x = -1; /* Don't show the GPM cursor */ - c = tty_get_event (&event, FALSE, FALSE); - if (c == EV_NONE) - return FILE_CONT; - - /* Reinitialize to avoid old values after events other than - selecting a button */ - ui->op_dlg->ret_value = FILE_CONT; - - dlg_process_event (ui->op_dlg, c, &event); - switch (ui->op_dlg->ret_value) - { - case FILE_SKIP: - return FILE_SKIP; - case B_CANCEL: - case FILE_ABORT: - return FILE_ABORT; - default: - return FILE_CONT; - } -} - -/* {{{ File progress display routines */ - -void -file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta, - filegui_dialog_type_t dialog_type) -{ - FileOpContextUI *ui; - int minus = 0, total_reserve = 0; - const char *abort_button_label = N_("&Abort"); - const char *skip_button_label = N_("&Skip"); - int abort_button_width, skip_button_width, buttons_width; - int dlg_width; - - g_return_if_fail (ctx != NULL); - g_return_if_fail (ctx->ui == NULL); - -#ifdef ENABLE_NLS - abort_button_label = _(abort_button_label); - skip_button_label = _(skip_button_label); -#endif - - abort_button_width = str_term_width1 (abort_button_label) + 3; - skip_button_width = str_term_width1 (skip_button_label) + 3; - buttons_width = abort_button_width + skip_button_width + 2; - - dlg_width = max (WX, buttons_width + 6); - - ui = g_new0 (FileOpContextUI, 1); - ctx->ui = ui; - - ctx->dialog_type = dialog_type; - - switch (dialog_type) - { - case FILEGUI_DIALOG_ONE_ITEM: - total_reserve = 0; - minus = verbose ? 0 : 2; - break; - case FILEGUI_DIALOG_MULTI_ITEM: - total_reserve = 5; - minus = verbose ? 0 : 7; - break; - case FILEGUI_DIALOG_DELETE_ITEM: - total_reserve = -5; - minus = 0; - break; - } - - ctx->recursive_result = RECURSIVE_YES; - - ui->replace_result = REPLACE_YES; - ui->showing_eta = with_eta; - ui->showing_bps = with_eta; - - ui->op_dlg = - create_dlg (TRUE, 0, 0, WY - minus + 1 + total_reserve, dlg_width, - dialog_colors, NULL, NULL, op_names[ctx->operation], DLG_CENTER | DLG_REVERSE); - - last_hint_line = the_hint->widget.y; - if ((ui->op_dlg->y + ui->op_dlg->lines) > last_hint_line) - the_hint->widget.y = ui->op_dlg->y + ui->op_dlg->lines + 1; - - add_widget (ui->op_dlg, - button_new (WY - minus - 2 + total_reserve, - dlg_width / 2 + 1, FILE_ABORT, - NORMAL_BUTTON, abort_button_label, NULL)); - add_widget (ui->op_dlg, - button_new (WY - minus - 2 + total_reserve, - dlg_width / 2 - 1 - skip_button_width, FILE_SKIP, - NORMAL_BUTTON, skip_button_label, NULL)); - - - if (verbose && dialog_type == FILEGUI_DIALOG_MULTI_ITEM) - { - add_widget (ui->op_dlg, hline_new (8, 1, dlg_width - 2)); - - add_widget (ui->op_dlg, ui->total_bytes_label = label_new (8, FCOPY_LABEL_X + 15, "")); - - add_widget (ui->op_dlg, ui->progress_total_gauge = - gauge_new (9, FCOPY_LABEL_X + 3, 0, 100, 0)); - - add_widget (ui->op_dlg, ui->total_files_processed_label = - label_new (11, FCOPY_LABEL_X, "")); - - add_widget (ui->op_dlg, ui->time_label = label_new (12, FCOPY_LABEL_X, "")); - } - - add_widget (ui->op_dlg, ui->progress_file_label = label_new (7, FCOPY_LABEL_X, "")); - - add_widget (ui->op_dlg, ui->progress_file_gauge = gauge_new (6, FCOPY_LABEL_X + 3, 0, 100, 0)); - - add_widget (ui->op_dlg, ui->file_string[1] = label_new (5, FCOPY_LABEL_X, "")); - - add_widget (ui->op_dlg, ui->file_label[1] = label_new (4, FCOPY_LABEL_X, "")); - add_widget (ui->op_dlg, ui->file_string[0] = label_new (3, FCOPY_LABEL_X, "")); - add_widget (ui->op_dlg, ui->file_label[0] = label_new (2, FCOPY_LABEL_X, "")); - - if ((right_panel == current_panel) && !classic_progressbar) - { - ui->progress_file_gauge->from_left_to_right = FALSE; - if (dialog_type == FILEGUI_DIALOG_MULTI_ITEM) - ui->progress_total_gauge->from_left_to_right = FALSE; - } -} - -void -file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta, - filegui_dialog_type_t dialog_type) -{ - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - g_return_if_fail (ctx->ui == NULL); - - file_op_context_create_ui_without_init (ctx, with_eta, dialog_type); - ui = ctx->ui; - - /* We will manage the dialog without any help, that's why - we have to call init_dlg */ - init_dlg (ui->op_dlg); -} - -void -file_op_context_destroy_ui (FileOpContext * ctx) -{ - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - - if (ctx->ui) - { - ui = ctx->ui; - - dlg_run_done (ui->op_dlg); - destroy_dlg (ui->op_dlg); - g_free (ui); - } - - the_hint->widget.y = last_hint_line; - - ctx->ui = NULL; -} +/* --------------------------------------------------------------------------------------------- */ static void file_frmt_time (char *buffer, double eta_secs) @@ -397,6 +237,8 @@ file_frmt_time (char *buffer, double eta_secs) g_snprintf (buffer, BUF_TINY, _("%d:%02d.%02d"), eta_hours, eta_mins, eta_s); } +/* --------------------------------------------------------------------------------------------- */ + static void file_eta_prepare_for_show (char *buffer, double eta_secs, gboolean always_show) { @@ -412,6 +254,8 @@ file_eta_prepare_for_show (char *buffer, double eta_secs, gboolean always_show) g_snprintf (buffer, BUF_TINY, _("ETA %s"), _fmt_buff); } +/* --------------------------------------------------------------------------------------------- */ + static void file_bps_prepare_for_show (char *buffer, long bps) { @@ -431,204 +275,7 @@ file_bps_prepare_for_show (char *buffer, long bps) *buffer = 0; } -/* - show progressbar for file - */ -void -file_progress_show (FileOpContext * ctx, off_t done, off_t total, - const char *stalled_msg, gboolean force_update) -{ - FileOpContextUI *ui; - char buffer[BUF_TINY]; - char buffer2[BUF_TINY]; - char buffer3[BUF_TINY]; - - g_return_if_fail (ctx != NULL); - - if (ctx->ui == NULL) - return; - - ui = ctx->ui; - - if (!verbose) - return; - - if (total == 0) - { - gauge_show (ui->progress_file_gauge, 0); - return; - } - - gauge_set_value (ui->progress_file_gauge, 1024, (int) (1024 * done / total)); - gauge_show (ui->progress_file_gauge, 1); - - if (!force_update) - return; - - if (ui->showing_eta && ctx->eta_secs > 0.5) - { - file_eta_prepare_for_show (buffer2, ctx->eta_secs, FALSE); - file_bps_prepare_for_show (buffer3, ctx->bps); - g_snprintf (buffer, BUF_TINY, "%s (%s) %s", buffer2, buffer3, stalled_msg); - } - else - { - g_snprintf (buffer, BUF_TINY, "%s", stalled_msg); - } - - label_set_text (ui->progress_file_label, buffer); -} - -void -file_progress_show_count (FileOpContext * ctx, off_t done, off_t total) -{ - char buffer[BUF_TINY]; - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - - if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL) - return; - - ui = ctx->ui; - - if (!verbose) - return; - - g_snprintf (buffer, BUF_TINY, _("Files processed: %llu of %llu"), - (unsigned long long) done, (unsigned long long) total); - - label_set_text (ui->total_files_processed_label, buffer); -} - -void -file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double copyed_bytes, - gboolean need_show_total_summary) -{ - char buffer[BUF_TINY]; - char buffer2[BUF_TINY]; - char buffer3[BUF_TINY]; - char buffer4[BUF_TINY]; - struct timeval tv_current; - FileOpContextUI *ui; - - if (!verbose) - return; - - if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL) - return; - - ui = ctx->ui; - - if (ctx->progress_bytes > 0) - { - gauge_set_value (ui->progress_total_gauge, 1024, - (int) (1024 * copyed_bytes / ctx->progress_bytes)); - gauge_show (ui->progress_total_gauge, 1); - } - else - gauge_show (ui->progress_total_gauge, 0); - - - if (!need_show_total_summary && tctx->bps == 0) - return; - - gettimeofday (&tv_current, NULL); - file_frmt_time (buffer2, tv_current.tv_sec - tctx->transfer_start.tv_sec); - file_eta_prepare_for_show (buffer3, tctx->eta_secs, TRUE); - file_bps_prepare_for_show (buffer4, (long) tctx->bps); - - g_snprintf (buffer, BUF_TINY, _("Time: %s %s (%s)"), buffer2, buffer3, buffer4); - label_set_text (ui->time_label, buffer); - - size_trunc_len (buffer2, 5, tctx->copyed_bytes, 0, panels_options.kilobyte_si); - size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si); - - g_snprintf (buffer, BUF_TINY, _("Total: %s of %s"), buffer2, buffer3); - - label_set_text (ui->total_bytes_label, buffer); - -} - -/* }}} */ - -#define truncFileString(ui, s) str_trunc (s, 52) -#define truncFileStringSecure(ui, s) path_trunc (s, 52) - -void -file_progress_show_source (FileOpContext * ctx, const char *s) -{ - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - - if (ctx->ui == NULL) - return; - - ui = ctx->ui; - - if (s != NULL) - { -#ifdef WITH_FULL_PATHS - int i = strlen (current_panel->cwd); - - /* We remove the full path we have added before */ - if (!strncmp (s, current_panel->cwd, i)) - { - if (s[i] == PATH_SEP) - s += i + 1; - } -#endif /* WITH_FULL_PATHS */ - - label_set_text (ui->file_label[0], _("Source")); - label_set_text (ui->file_string[0], truncFileString (ui, s)); - } - else - { - label_set_text (ui->file_label[0], ""); - label_set_text (ui->file_string[0], ""); - } -} - -void -file_progress_show_target (FileOpContext * ctx, const char *s) -{ - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - - if (ctx->ui == NULL) - return; - - ui = ctx->ui; - - if (s != NULL) - { - label_set_text (ui->file_label[1], _("Target")); - label_set_text (ui->file_string[1], truncFileStringSecure (ui, s)); - } - else - { - label_set_text (ui->file_label[1], ""); - label_set_text (ui->file_string[1], ""); - } -} - -void -file_progress_show_deleting (FileOpContext * ctx, const char *s) -{ - FileOpContextUI *ui; - - g_return_if_fail (ctx != NULL); - - if (ctx->ui == NULL) - return; - - ui = ctx->ui; - label_set_text (ui->file_label[0], _("Deleting")); - label_set_text (ui->file_label[0], truncFileStringSecure (ui, s)); -} - +/* --------------------------------------------------------------------------------------------- */ /* * FIXME: probably it is better to replace this with quick dialog machinery, * but actually I'm not familiar with it and have not much time :( @@ -825,6 +472,417 @@ overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode) #undef ADD_RD_BUTTON } +/* --------------------------------------------------------------------------------------------- */ + +static gboolean +is_wildcarded (char *p) +{ + for (; *p; p++) + { + if (*p == '*') + return TRUE; + if (*p == '\\' && p[1] >= '1' && p[1] <= '9') + return TRUE; + } + return FALSE; +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +FileProgressStatus +check_progress_buttons (FileOpContext * ctx) +{ + int c; + Gpm_Event event; + FileOpContextUI *ui; + + if (ctx->ui == NULL) + return FILE_CONT; + + ui = ctx->ui; + + event.x = -1; /* Don't show the GPM cursor */ + c = tty_get_event (&event, FALSE, FALSE); + if (c == EV_NONE) + return FILE_CONT; + + /* Reinitialize to avoid old values after events other than + selecting a button */ + ui->op_dlg->ret_value = FILE_CONT; + + dlg_process_event (ui->op_dlg, c, &event); + switch (ui->op_dlg->ret_value) + { + case FILE_SKIP: + return FILE_SKIP; + case B_CANCEL: + case FILE_ABORT: + return FILE_ABORT; + default: + return FILE_CONT; + } +} + + +/* --------------------------------------------------------------------------------------------- */ +/* {{{ File progress display routines */ + +void +file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta, + filegui_dialog_type_t dialog_type) +{ + FileOpContextUI *ui; + int minus = 0, total_reserve = 0; + const char *abort_button_label = N_("&Abort"); + const char *skip_button_label = N_("&Skip"); + int abort_button_width, skip_button_width, buttons_width; + int dlg_width; + + g_return_if_fail (ctx != NULL); + g_return_if_fail (ctx->ui == NULL); + +#ifdef ENABLE_NLS + abort_button_label = _(abort_button_label); + skip_button_label = _(skip_button_label); +#endif + + abort_button_width = str_term_width1 (abort_button_label) + 3; + skip_button_width = str_term_width1 (skip_button_label) + 3; + buttons_width = abort_button_width + skip_button_width + 2; + + dlg_width = max (WX, buttons_width + 6); + + ui = g_new0 (FileOpContextUI, 1); + ctx->ui = ui; + + ctx->dialog_type = dialog_type; + + switch (dialog_type) + { + case FILEGUI_DIALOG_ONE_ITEM: + total_reserve = 0; + minus = verbose ? 0 : 2; + break; + case FILEGUI_DIALOG_MULTI_ITEM: + total_reserve = 5; + minus = verbose ? 0 : 7; + break; + case FILEGUI_DIALOG_DELETE_ITEM: + total_reserve = -5; + minus = 0; + break; + } + + ctx->recursive_result = RECURSIVE_YES; + + ui->replace_result = REPLACE_YES; + ui->showing_eta = with_eta; + ui->showing_bps = with_eta; + + ui->op_dlg = + create_dlg (TRUE, 0, 0, WY - minus + 1 + total_reserve, dlg_width, + dialog_colors, NULL, NULL, op_names[ctx->operation], DLG_CENTER | DLG_REVERSE); + + last_hint_line = the_hint->widget.y; + if ((ui->op_dlg->y + ui->op_dlg->lines) > last_hint_line) + the_hint->widget.y = ui->op_dlg->y + ui->op_dlg->lines + 1; + + add_widget (ui->op_dlg, + button_new (WY - minus - 2 + total_reserve, + dlg_width / 2 + 1, FILE_ABORT, + NORMAL_BUTTON, abort_button_label, NULL)); + add_widget (ui->op_dlg, + button_new (WY - minus - 2 + total_reserve, + dlg_width / 2 - 1 - skip_button_width, FILE_SKIP, + NORMAL_BUTTON, skip_button_label, NULL)); + + + if (verbose && dialog_type == FILEGUI_DIALOG_MULTI_ITEM) + { + add_widget (ui->op_dlg, hline_new (8, 1, dlg_width - 2)); + + add_widget (ui->op_dlg, ui->total_bytes_label = label_new (8, FCOPY_LABEL_X + 15, "")); + + add_widget (ui->op_dlg, ui->progress_total_gauge = + gauge_new (9, FCOPY_LABEL_X + 3, 0, 100, 0)); + + add_widget (ui->op_dlg, ui->total_files_processed_label = + label_new (11, FCOPY_LABEL_X, "")); + + add_widget (ui->op_dlg, ui->time_label = label_new (12, FCOPY_LABEL_X, "")); + } + + add_widget (ui->op_dlg, ui->progress_file_label = label_new (7, FCOPY_LABEL_X, "")); + + add_widget (ui->op_dlg, ui->progress_file_gauge = gauge_new (6, FCOPY_LABEL_X + 3, 0, 100, 0)); + + add_widget (ui->op_dlg, ui->file_string[1] = label_new (5, FCOPY_LABEL_X, "")); + + add_widget (ui->op_dlg, ui->file_label[1] = label_new (4, FCOPY_LABEL_X, "")); + add_widget (ui->op_dlg, ui->file_string[0] = label_new (3, FCOPY_LABEL_X, "")); + add_widget (ui->op_dlg, ui->file_label[0] = label_new (2, FCOPY_LABEL_X, "")); + + if ((right_panel == current_panel) && !classic_progressbar) + { + ui->progress_file_gauge->from_left_to_right = FALSE; + if (dialog_type == FILEGUI_DIALOG_MULTI_ITEM) + ui->progress_total_gauge->from_left_to_right = FALSE; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta, + filegui_dialog_type_t dialog_type) +{ + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + g_return_if_fail (ctx->ui == NULL); + + file_op_context_create_ui_without_init (ctx, with_eta, dialog_type); + ui = ctx->ui; + + /* We will manage the dialog without any help, that's why + we have to call init_dlg */ + init_dlg (ui->op_dlg); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_op_context_destroy_ui (FileOpContext * ctx) +{ + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + + if (ctx->ui) + { + ui = ctx->ui; + + dlg_run_done (ui->op_dlg); + destroy_dlg (ui->op_dlg); + g_free (ui); + } + + the_hint->widget.y = last_hint_line; + + ctx->ui = NULL; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + show progressbar for file + */ + +void +file_progress_show (FileOpContext * ctx, off_t done, off_t total, + const char *stalled_msg, gboolean force_update) +{ + FileOpContextUI *ui; + char buffer[BUF_TINY]; + char buffer2[BUF_TINY]; + char buffer3[BUF_TINY]; + + g_return_if_fail (ctx != NULL); + + if (ctx->ui == NULL) + return; + + ui = ctx->ui; + + if (!verbose) + return; + + if (total == 0) + { + gauge_show (ui->progress_file_gauge, 0); + return; + } + + gauge_set_value (ui->progress_file_gauge, 1024, (int) (1024 * done / total)); + gauge_show (ui->progress_file_gauge, 1); + + if (!force_update) + return; + + if (ui->showing_eta && ctx->eta_secs > 0.5) + { + file_eta_prepare_for_show (buffer2, ctx->eta_secs, FALSE); + file_bps_prepare_for_show (buffer3, ctx->bps); + g_snprintf (buffer, BUF_TINY, "%s (%s) %s", buffer2, buffer3, stalled_msg); + } + else + { + g_snprintf (buffer, BUF_TINY, "%s", stalled_msg); + } + + label_set_text (ui->progress_file_label, buffer); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_progress_show_count (FileOpContext * ctx, off_t done, off_t total) +{ + char buffer[BUF_TINY]; + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + + if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL) + return; + + ui = ctx->ui; + + if (!verbose) + return; + + g_snprintf (buffer, BUF_TINY, _("Files processed: %llu of %llu"), + (unsigned long long) done, (unsigned long long) total); + + label_set_text (ui->total_files_processed_label, buffer); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double copyed_bytes, + gboolean need_show_total_summary) +{ + char buffer[BUF_TINY]; + char buffer2[BUF_TINY]; + char buffer3[BUF_TINY]; + char buffer4[BUF_TINY]; + struct timeval tv_current; + FileOpContextUI *ui; + + if (!verbose) + return; + + if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL) + return; + + ui = ctx->ui; + + if (ctx->progress_bytes > 0) + { + gauge_set_value (ui->progress_total_gauge, 1024, + (int) (1024 * copyed_bytes / ctx->progress_bytes)); + gauge_show (ui->progress_total_gauge, 1); + } + else + gauge_show (ui->progress_total_gauge, 0); + + + if (!need_show_total_summary && tctx->bps == 0) + return; + + gettimeofday (&tv_current, NULL); + file_frmt_time (buffer2, tv_current.tv_sec - tctx->transfer_start.tv_sec); + file_eta_prepare_for_show (buffer3, tctx->eta_secs, TRUE); + file_bps_prepare_for_show (buffer4, (long) tctx->bps); + + g_snprintf (buffer, BUF_TINY, _("Time: %s %s (%s)"), buffer2, buffer3, buffer4); + label_set_text (ui->time_label, buffer); + + size_trunc_len (buffer2, 5, tctx->copyed_bytes, 0, panels_options.kilobyte_si); + size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si); + + g_snprintf (buffer, BUF_TINY, _("Total: %s of %s"), buffer2, buffer3); + + label_set_text (ui->total_bytes_label, buffer); + +} + +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ + +void +file_progress_show_source (FileOpContext * ctx, const char *s) +{ + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + + if (ctx->ui == NULL) + return; + + ui = ctx->ui; + + if (s != NULL) + { +#ifdef WITH_FULL_PATHS + int i = strlen (current_panel->cwd); + + /* We remove the full path we have added before */ + if (!strncmp (s, current_panel->cwd, i)) + { + if (s[i] == PATH_SEP) + s += i + 1; + } +#endif /* WITH_FULL_PATHS */ + + label_set_text (ui->file_label[0], _("Source")); + label_set_text (ui->file_string[0], truncFileString (ui, s)); + } + else + { + label_set_text (ui->file_label[0], ""); + label_set_text (ui->file_string[0], ""); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_progress_show_target (FileOpContext * ctx, const char *s) +{ + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + + if (ctx->ui == NULL) + return; + + ui = ctx->ui; + + if (s != NULL) + { + label_set_text (ui->file_label[1], _("Target")); + label_set_text (ui->file_string[1], truncFileStringSecure (ui, s)); + } + else + { + label_set_text (ui->file_label[1], ""); + label_set_text (ui->file_string[1], ""); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_progress_show_deleting (FileOpContext * ctx, const char *s) +{ + FileOpContextUI *ui; + + g_return_if_fail (ctx != NULL); + + if (ctx->ui == NULL) + return; + + ui = ctx->ui; + label_set_text (ui->file_label[0], _("Deleting")); + label_set_text (ui->file_label[0], truncFileStringSecure (ui, s)); +} + +/* --------------------------------------------------------------------------------------------- */ + FileProgressStatus file_progress_real_query_replace (FileOpContext * ctx, enum OperationMode mode, const char *destname, @@ -882,18 +940,7 @@ file_progress_real_query_replace (FileOpContext * ctx, } } -static gboolean -is_wildcarded (char *p) -{ - for (; *p; p++) - { - if (*p == '*') - return TRUE; - if (*p == '\\' && p[1] >= '1' && p[1] <= '9') - return TRUE; - } - return FALSE; -} +/* --------------------------------------------------------------------------------------------- */ char * file_mask_dialog (FileOpContext * ctx, FileOperation operation, @@ -1135,3 +1182,5 @@ file_mask_dialog (FileOpContext * ctx, FileOperation operation, return dest_dir; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/filegui.h b/src/filegui.h index 1cb372699..29cb12fa9 100644 --- a/src/filegui.h +++ b/src/filegui.h @@ -1,39 +1,52 @@ - /** \file filegui.h * \brief Header: file management GUI for the text mode edition */ -#ifndef MC_FILEGUI_H -#define MC_FILEGUI_H +#ifndef MC__FILEGUI_H +#define MC__FILEGUI_H #include "lib/global.h" #include "fileopctx.h" -typedef enum { +/*** typedefs(not structures) and defined constants **********************************************/ + +typedef enum +{ FILEGUI_DIALOG_ONE_ITEM, FILEGUI_DIALOG_MULTI_ITEM, FILEGUI_DIALOG_DELETE_ITEM } filegui_dialog_type_t; -void file_op_context_create_ui (FileOpContext *ctx, gboolean with_eta, filegui_dialog_type_t dialog_type); -void file_op_context_create_ui_without_init (FileOpContext *ctx, gboolean with_eta, filegui_dialog_type_t dialog_type); -void file_op_context_destroy_ui (FileOpContext *ctx); +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +void file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta, + filegui_dialog_type_t dialog_type); +void file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta, + filegui_dialog_type_t dialog_type); +void file_op_context_destroy_ui (FileOpContext * ctx); -char *file_mask_dialog (FileOpContext *ctx, FileOperation operation, - gboolean only_one, - const char *format, const void *text, - const char *def_text, gboolean *do_background); +char *file_mask_dialog (FileOpContext * ctx, FileOperation operation, + gboolean only_one, + const char *format, const void *text, + const char *def_text, gboolean * do_background); -FileProgressStatus check_progress_buttons (FileOpContext *ctx); +FileProgressStatus check_progress_buttons (FileOpContext * ctx); -void file_progress_show (FileOpContext *ctx, off_t done, off_t total, - const char *stalled_msg, gboolean force_update); -void file_progress_show_count (FileOpContext *ctx, off_t done, off_t total); -void file_progress_show_total (FileOpTotalContext *tctx, FileOpContext *ctx, - double copyed_bytes, gboolean need_show_total_summary); -void file_progress_show_source (FileOpContext *ctx, const char *path); -void file_progress_show_target (FileOpContext *ctx, const char *path); -void file_progress_show_deleting (FileOpContext *ctx, const char *path); +void file_progress_show (FileOpContext * ctx, off_t done, off_t total, + const char *stalled_msg, gboolean force_update); +void file_progress_show_count (FileOpContext * ctx, off_t done, off_t total); +void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, + double copyed_bytes, gboolean need_show_total_summary); +void file_progress_show_source (FileOpContext * ctx, const char *path); +void file_progress_show_target (FileOpContext * ctx, const char *path); +void file_progress_show_deleting (FileOpContext * ctx, const char *path); -#endif /* MC_FILEGUI_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__FILEGUI_H */ diff --git a/src/filenot.c b/src/filenot.c index 61831d1a2..ce7ecfcce 100644 --- a/src/filenot.c +++ b/src/filenot.c @@ -4,8 +4,8 @@ structure. Author: - Janne Kukonlehto - Miguel de Icaza + Janne Kukonlehto + 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 @@ -39,7 +39,16 @@ #include "lib/vfs/mc-vfs/vfs.h" +/*** global variables ****************************************************************************/ +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static char * get_absolute_name (const char *file) @@ -47,11 +56,13 @@ get_absolute_name (const char *file) char dir[MC_MAXPATHLEN]; if (file[0] == PATH_SEP) - return g_strdup (file); + return g_strdup (file); mc_get_current_wd (dir, MC_MAXPATHLEN); return concat_dir_and_file (dir, file); } +/* --------------------------------------------------------------------------------------------- */ + static int my_mkdir_rec (char *s, mode_t mode) { @@ -59,17 +70,18 @@ my_mkdir_rec (char *s, mode_t mode) int result; if (!mc_mkdir (s, mode)) - return 0; + return 0; else if (errno != ENOENT) - return -1; + return -1; /* FIXME: should check instead if s is at the root of that filesystem */ if (!vfs_file_is_local (s)) - return -1; + return -1; - if (!strcmp (s, PATH_SEP_STR)) { - errno = ENOTDIR; - return -1; + if (!strcmp (s, PATH_SEP_STR)) + { + errno = ENOTDIR; + return -1; } p = concat_dir_and_file (s, ".."); @@ -78,12 +90,16 @@ my_mkdir_rec (char *s, mode_t mode) result = my_mkdir_rec (q, mode); if (result == 0) - result = mc_mkdir (s, mode); + result = mc_mkdir (s, mode); g_free (q); return result; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + int my_mkdir (const char *s, mode_t mode) { @@ -91,24 +107,28 @@ my_mkdir (const char *s, mode_t mode) char *my_s; result = mc_mkdir (s, mode); - if (result) { - char *p = vfs_canon (s); + if (result) + { + char *p = vfs_canon (s); - result = my_mkdir_rec (p, mode); - g_free (p); + result = my_mkdir_rec (p, mode); + g_free (p); } - if (result == 0) { - my_s = get_absolute_name (s); + if (result == 0) + { + my_s = get_absolute_name (s); #ifdef FIXME - tree_add_entry (tree, my_s); + tree_add_entry (tree, my_s); #endif - g_free (my_s); + g_free (my_s); } return result; } +/* --------------------------------------------------------------------------------------------- */ + int my_rmdir (const char *s) { @@ -120,14 +140,17 @@ my_rmdir (const char *s) /* FIXME: Should receive a Wtree! */ result = mc_rmdir (s); - if (result == 0) { - my_s = get_absolute_name (s); + if (result == 0) + { + my_s = get_absolute_name (s); #ifdef FIXME - tree_remove_entry (tree, my_s); + tree_remove_entry (tree, my_s); #endif - g_free (my_s); + g_free (my_s); } return result; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/fileopctx.c b/src/fileopctx.c index 5356c77fe..87a2d2f11 100644 --- a/src/fileopctx.c +++ b/src/fileopctx.c @@ -38,6 +38,21 @@ #include "lib/search.h" #include "lib/vfs/mc-vfs/vfs.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /** * \fn FileOpContext * file_op_context_new (FileOperation op) * \param op file operation struct @@ -46,6 +61,7 @@ * Creates a new file operation context with the default values. If you later want * to have a user interface for this, call file_op_context_create_ui(). */ + FileOpContext * file_op_context_new (FileOperation op) { @@ -66,7 +82,7 @@ file_op_context_new (FileOperation op) return ctx; } - +/* --------------------------------------------------------------------------------------------- */ /** * \fn void file_op_context_destroy (FileOpContext *ctx) * \param ctx The file operation context to destroy. @@ -74,6 +90,7 @@ file_op_context_new (FileOperation op) * Destroys the specified file operation context and its associated UI data, if * it exists. */ + void file_op_context_destroy (FileOpContext * ctx) { @@ -89,6 +106,8 @@ file_op_context_destroy (FileOpContext * ctx) g_free (ctx); } +/* --------------------------------------------------------------------------------------------- */ + FileOpTotalContext * file_op_total_context_new (void) { @@ -99,9 +118,13 @@ file_op_total_context_new (void) return tctx; } +/* --------------------------------------------------------------------------------------------- */ + void file_op_total_context_destroy (FileOpTotalContext * tctx) { g_return_if_fail (tctx != NULL); g_free (tctx); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/fileopctx.h b/src/fileopctx.h index 30119c184..a2b7b24f1 100644 --- a/src/fileopctx.h +++ b/src/fileopctx.h @@ -1,4 +1,3 @@ - /** \file fileopctx.h * \brief Header: file operation contexts * \date 1998 @@ -12,8 +11,8 @@ * */ -#ifndef FILEOPCTX_H -#define FILEOPCTX_H +#ifndef MC__FILEOPCTX_H +#define MC__FILEOPCTX_H #include #include @@ -21,156 +20,169 @@ #include "lib/global.h" -struct mc_search_struct; -typedef enum { - OP_COPY = 0, - OP_MOVE = 1, - OP_DELETE = 2 +/*** typedefs(not structures) and defined constants **********************************************/ + +typedef int (*mc_stat_fn) (const char *filename, struct stat * buf); + +/*** enums ***************************************************************************************/ + +typedef enum +{ + OP_COPY = 0, + OP_MOVE = 1, + OP_DELETE = 2 } FileOperation; -typedef enum { - RECURSIVE_YES = 0, - RECURSIVE_NO = 1, +typedef enum +{ + RECURSIVE_YES = 0, + RECURSIVE_NO = 1, RECURSIVE_ALWAYS = 2, - RECURSIVE_NEVER = 3, - RECURSIVE_ABORT = 4 + RECURSIVE_NEVER = 3, + RECURSIVE_ABORT = 4 } FileCopyMode; -typedef int (*mc_stat_fn) (const char *filename, struct stat *buf); - -/* This structure describes a context for file operations. It is used to update - * the progress windows and pass around options. - */ -typedef struct FileOpContext { - /* Operation type (copy, move, delete) */ - FileOperation operation; - - /* The estimated time of arrival in seconds */ - double eta_secs; - - /* Transferred bytes per second */ - long bps; - - /* Transferred seconds */ - long bps_time; - - /* Whether the panel total has been computed */ - gboolean progress_totals_computed; - int dialog_type; - - /* Counters for progress indicators */ - off_t progress_count; - double progress_bytes; - - /* The value of the "preserve Attributes" checkbox in the copy file dialog. - * We can't use the value of "ctx->preserve" because it can change in order - * to preserve file attributs when moving files across filesystem boundaries - * (we want to keep the value of the checkbox between copy operations). - */ - gboolean op_preserve; - - /* Result from the recursive query */ - FileCopyMode recursive_result; - - /* Whether to do a reget */ - off_t do_reget; - - /* Controls appending to files */ - gboolean do_append; - - /* Whether to stat or lstat */ - gboolean follow_links; - - /* Pointer to the stat function we will use */ - mc_stat_fn stat_func; - - /* Whether to recompute symlinks */ - gboolean stable_symlinks; - - /* Preserve the original files' owner, group, permissions, and - * timestamps (owner, group only as root). - */ - int preserve; - - /* If running as root, preserve the original uid/gid (we don't want to - * try chown for non root) preserve_uidgid = preserve && uid == 0 - */ - gboolean preserve_uidgid; - - /* The bits to preserve in created files' modes on file copy */ - int umask_kill; - - /* The mask of files to actually operate on */ - char *dest_mask; - - /* search handler */ - struct mc_search_struct *search_handle; - - /* Whether to dive into subdirectories for recursive operations */ - int dive_into_subdirs; - - /* When moving directories cross filesystem boundaries delete the - * successfully copied files when all files below the directory and its - * subdirectories were processed. - * - * If erase_at_end is FALSE files will be deleted immediately after their - * successful copy (Note: this behavior is not tested and at the moment - * it can't be changed at runtime). - */ - gboolean erase_at_end; - - /* PID of the child for background operations */ - pid_t pid; - - /* User interface data goes here */ - void *ui; -} FileOpContext; - -typedef struct { - off_t progress_count; - double progress_bytes; - double copyed_bytes; - size_t bps; - size_t bps_count; - struct timeval transfer_start; - double eta_secs; - - gboolean ask_overwrite; - gboolean is_toplevel_file; - -} FileOpTotalContext; - - -FileOpContext *file_op_context_new (FileOperation op); -void file_op_context_destroy (FileOpContext *ctx); - -FileOpTotalContext *file_op_total_context_new (void); -void file_op_total_context_destroy (FileOpTotalContext *tctx); - - -extern const char *op_names [3]; - -typedef enum { - FILE_CONT = 0, - FILE_RETRY = 1, - FILE_SKIP = 2, - FILE_ABORT = 3 +typedef enum +{ + FILE_CONT = 0, + FILE_RETRY = 1, + FILE_SKIP = 2, + FILE_ABORT = 3 } FileProgressStatus; /* First argument passed to real functions */ -enum OperationMode { +enum OperationMode +{ Foreground, Background }; +/*** structures declarations (and typedefs of structures)*****************************************/ + +struct mc_search_struct; + +/* This structure describes a context for file operations. It is used to update + * the progress windows and pass around options. + */ +typedef struct FileOpContext +{ + /* Operation type (copy, move, delete) */ + FileOperation operation; + + /* The estimated time of arrival in seconds */ + double eta_secs; + + /* Transferred bytes per second */ + long bps; + + /* Transferred seconds */ + long bps_time; + + /* Whether the panel total has been computed */ + gboolean progress_totals_computed; + int dialog_type; + + /* Counters for progress indicators */ + off_t progress_count; + double progress_bytes; + + /* The value of the "preserve Attributes" checkbox in the copy file dialog. + * We can't use the value of "ctx->preserve" because it can change in order + * to preserve file attributs when moving files across filesystem boundaries + * (we want to keep the value of the checkbox between copy operations). + */ + gboolean op_preserve; + + /* Result from the recursive query */ + FileCopyMode recursive_result; + + /* Whether to do a reget */ + off_t do_reget; + + /* Controls appending to files */ + gboolean do_append; + + /* Whether to stat or lstat */ + gboolean follow_links; + + /* Pointer to the stat function we will use */ + mc_stat_fn stat_func; + + /* Whether to recompute symlinks */ + gboolean stable_symlinks; + + /* Preserve the original files' owner, group, permissions, and + * timestamps (owner, group only as root). + */ + int preserve; + + /* If running as root, preserve the original uid/gid (we don't want to + * try chown for non root) preserve_uidgid = preserve && uid == 0 + */ + gboolean preserve_uidgid; + + /* The bits to preserve in created files' modes on file copy */ + int umask_kill; + + /* The mask of files to actually operate on */ + char *dest_mask; + + /* search handler */ + struct mc_search_struct *search_handle; + + /* Whether to dive into subdirectories for recursive operations */ + int dive_into_subdirs; + + /* When moving directories cross filesystem boundaries delete the + * successfully copied files when all files below the directory and its + * subdirectories were processed. + * + * If erase_at_end is FALSE files will be deleted immediately after their + * successful copy (Note: this behavior is not tested and at the moment + * it can't be changed at runtime). + */ + gboolean erase_at_end; + + /* PID of the child for background operations */ + pid_t pid; + + /* User interface data goes here */ + void *ui; +} FileOpContext; + +typedef struct +{ + off_t progress_count; + double progress_bytes; + double copyed_bytes; + size_t bps; + size_t bps_count; + struct timeval transfer_start; + double eta_secs; + + gboolean ask_overwrite; + gboolean is_toplevel_file; + +} FileOpTotalContext; + +/*** global variables defined in .c file *********************************************************/ + +extern const char *op_names[3]; + +/*** declarations of public functions ************************************************************/ + +FileOpContext *file_op_context_new (FileOperation op); +void file_op_context_destroy (FileOpContext * ctx); + +FileOpTotalContext *file_op_total_context_new (void); +void file_op_total_context_destroy (FileOpTotalContext * tctx); + /* The following functions are implemented separately by each port */ +FileProgressStatus file_progress_real_query_replace (FileOpContext * ctx, + enum OperationMode mode, + const char *destname, + struct stat *_s_stat, struct stat *_d_stat); -FileProgressStatus file_progress_real_query_replace (FileOpContext *ctx, - enum OperationMode mode, - const char *destname, - struct stat *_s_stat, - struct stat *_d_stat); - - -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__FILEOPCTX_H */ diff --git a/src/find.c b/src/find.c index be307d3b4..0a415cc3f 100644 --- a/src/find.c +++ b/src/find.c @@ -57,20 +57,20 @@ #include "find.h" -/* Size of the find parameters window */ -#if HAVE_CHARSET -static int FIND_Y = 17; -#else -static int FIND_Y = 16; -#endif -static int FIND_X = 68; +/*** global variables ****************************************************************************/ + +/* List of directories to be ignored, separated by ':' */ +char **find_ignore_dirs = NULL; + +/*** file scope macro definitions ****************************************************************/ /* Size of the find window */ #define FIND2_Y (LINES - 4) -static int FIND2_X = 64; #define FIND2_X_USE (FIND2_X - 20) +/*** file scope type declarations ****************************************************************/ + /* A couple of extra messages we need */ enum { @@ -88,8 +88,36 @@ typedef enum FIND_ABORT } FindProgressStatus; -/* List of directories to be ignored, separated by ':' */ -char **find_ignore_dirs = NULL; +/* find file options */ +typedef struct +{ + /* file name options */ + gboolean file_case_sens; + gboolean file_pattern; + gboolean find_recurs; + gboolean skip_hidden; + gboolean file_all_charsets; + + /* file content options */ + gboolean content_use; + gboolean content_case_sens; + gboolean content_regexp; + gboolean content_first_hit; + gboolean content_whole_words; + gboolean content_all_charsets; +} find_file_options_t; + +/*** file scope variables ************************************************************************/ + +/* Size of the find parameters window */ +#if HAVE_CHARSET +static int FIND_Y = 17; +#else +static int FIND_Y = 16; +#endif +static int FIND_X = 68; + +static int FIND2_X = 64; /* static variables to remember find parameters */ static WInput *in_start; /* Start path */ @@ -162,25 +190,6 @@ static struct }; /* *INDENT-ON* */ -/* find file options */ -typedef struct -{ - /* file name options */ - gboolean file_case_sens; - gboolean file_pattern; - gboolean find_recurs; - gboolean skip_hidden; - gboolean file_all_charsets; - - /* file content options */ - gboolean content_use; - gboolean content_case_sens; - gboolean content_regexp; - gboolean content_first_hit; - gboolean content_whole_words; - gboolean content_all_charsets; -} find_file_options_t; - static find_file_options_t options = { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE @@ -191,12 +200,16 @@ static char *in_start_dir = INPUT_LAST_TEXT; static mc_search_t *search_file_handle = NULL; static mc_search_t *search_content_handle = NULL; +/*** file scope functions ************************************************************************/ + static int find_ignore_dirs_cmp (const void *d1, const void *d2) { return strcmp (*(const char **) d1, *(const char **) d2); } +/* --------------------------------------------------------------------------------------------- */ + static void find_load_options (void) { @@ -287,6 +300,8 @@ find_load_options (void) mc_config_get_bool (mc_main_config, "FindFile", "content_all_charsets", FALSE); } +/* --------------------------------------------------------------------------------------------- */ + static void find_save_options (void) { @@ -305,24 +320,32 @@ find_save_options (void) options.content_all_charsets); } +/* --------------------------------------------------------------------------------------------- */ + static inline char * add_to_list (const char *text, void *data) { return listbox_add_item (find_list, LISTBOX_APPEND_AT_END, 0, text, data); } +/* --------------------------------------------------------------------------------------------- */ + static inline void stop_idle (void *data) { set_idle_proc (data, 0); } +/* --------------------------------------------------------------------------------------------- */ + static inline void status_update (const char *text) { label_set_text (status_label, text); } +/* --------------------------------------------------------------------------------------------- */ + static void found_num_update (void) { @@ -331,13 +354,17 @@ found_num_update (void) label_set_text (found_num_label, buffer); } +/* --------------------------------------------------------------------------------------------- */ + static void get_list_info (char **file, char **dir) { listbox_get_current (find_list, file, (void **) dir); } -/* check regular expression */ +/* --------------------------------------------------------------------------------------------- */ +/** check regular expression */ + static gboolean find_check_regexp (const char *r) { @@ -356,10 +383,12 @@ find_check_regexp (const char *r) return regexp_ok; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Callback for the parameter dialog. * Validate regex, prevent closing the dialog if it's invalid. */ + static cb_ret_t find_parm_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -424,7 +453,8 @@ find_parm_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void } } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * find_parameters: gets information from the user * * If the return value is TRUE, then the following holds: @@ -437,6 +467,7 @@ find_parm_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void * behavior for the other two parameters. * */ + static gboolean find_parameters (char **start_dir, char **pattern, char **content) { @@ -659,21 +690,26 @@ find_parameters (char **start_dir, char **pattern, char **content) return return_value; } -#if GLIB_CHECK_VERSION (2, 14, 0) +/* --------------------------------------------------------------------------------------------- */ +#if GLIB_CHECK_VERSION (2, 14, 0) static inline void push_directory (const char *dir) { g_queue_push_head (&dir_queue, (void *) dir); } +/* --------------------------------------------------------------------------------------------- */ + static inline char * pop_directory (void) { return (char *) g_queue_pop_tail (&dir_queue); } -/* Remove all the items from the stack */ +/* --------------------------------------------------------------------------------------------- */ +/** Remove all the items from the stack */ + static void clear_stack (void) { @@ -681,8 +717,9 @@ clear_stack (void) g_queue_clear (&dir_queue); } -#else /* GLIB_CHECK_VERSION */ +/* --------------------------------------------------------------------------------------------- */ +#else /* GLIB_CHECK_VERSION */ static void push_directory (const char *dir) { @@ -694,6 +731,8 @@ push_directory (const char *dir) dir_stack_base = new; } +/* --------------------------------------------------------------------------------------------- */ + static char * pop_directory (void) { @@ -711,7 +750,9 @@ pop_directory (void) return name; } -/* Remove all the items from the stack */ +/* --------------------------------------------------------------------------------------------- */ +/** Remove all the items from the stack */ + static void clear_stack (void) { @@ -719,9 +760,10 @@ clear_stack (void) while ((dir = pop_directory ()) != NULL) g_free (dir); } - #endif /* GLIB_CHECK_VERSION */ +/* --------------------------------------------------------------------------------------------- */ + static void insert_file (const char *dir, const char *file) { @@ -751,6 +793,8 @@ insert_file (const char *dir, const char *file) g_free (tmp_name); } +/* --------------------------------------------------------------------------------------------- */ + static void find_add_match (const char *dir, const char *file) { @@ -765,7 +809,8 @@ find_add_match (const char *dir, const char *file) found_num_update (); } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * get_line_at: * * Returns malloced null-terminated line from file file_fd. @@ -774,6 +819,7 @@ find_add_match (const char *dir, const char *file) * n_read - number of read chars. * has_newline - is there newline ? */ + static char * get_line_at (int file_fd, char *buf, int buf_size, int *pos, int *n_read, gboolean * has_newline) { @@ -819,6 +865,8 @@ get_line_at (int file_fd, char *buf, int buf_size, int *pos, int *n_read, gboole return buffer; } +/* --------------------------------------------------------------------------------------------- */ + static FindProgressStatus check_find_events (Dlg_head * h) { @@ -846,7 +894,8 @@ check_find_events (Dlg_head * h) return FIND_CONT; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * search_content: * * Search the content_pattern string in the DIRECTORY/FILE. @@ -855,6 +904,7 @@ check_find_events (Dlg_head * h) * returns FALSE if do_search should look for another file * TRUE if do_search should exit and proceed to the event handler */ + static gboolean search_content (Dlg_head * h, const char *directory, const char *filename) { @@ -953,6 +1003,8 @@ search_content (Dlg_head * h, const char *directory, const char *filename) return ret_val; } +/* --------------------------------------------------------------------------------------------- */ + static inline gboolean find_ignore_dir_search (const char *dir) { @@ -981,6 +1033,8 @@ find_ignore_dir_search (const char *dir) return FALSE; } +/* --------------------------------------------------------------------------------------------- */ + static void find_rotate_dash (const Dlg_head *h, gboolean finish) { @@ -997,6 +1051,8 @@ find_rotate_dash (const Dlg_head *h, gboolean finish) } } +/* --------------------------------------------------------------------------------------------- */ + static int do_search (Dlg_head *h) { @@ -1129,6 +1185,8 @@ do_search (Dlg_head *h) return 1; } +/* --------------------------------------------------------------------------------------------- */ + static void init_find_vars (void) { @@ -1140,6 +1198,8 @@ init_find_vars (void) clear_stack (); } +/* --------------------------------------------------------------------------------------------- */ + static char * make_fullname (const char *dirname, const char *filename) { @@ -1151,6 +1211,8 @@ make_fullname (const char *dirname, const char *filename) return concat_dir_and_file (dirname, filename); } +/* --------------------------------------------------------------------------------------------- */ + static void find_do_view_edit (int unparsed_view, int edit, char *dir, char *file) { @@ -1177,6 +1239,8 @@ find_do_view_edit (int unparsed_view, int edit, char *dir, char *file) g_free (fullname); } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t view_edit_currently_selected_file (int unparsed_view, int edit) { @@ -1192,6 +1256,8 @@ view_edit_currently_selected_file (int unparsed_view, int edit) return MSG_HANDLED; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t find_callback (Dlg_head *h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -1218,7 +1284,9 @@ find_callback (Dlg_head *h, Widget * sender, dlg_msg_t msg, int parm, void *data } } -/* Handles the Stop/Start button in the find window */ +/* --------------------------------------------------------------------------------------------- */ +/** Handles the Stop/Start button in the find window */ + static int start_stop (WButton * button, int action) { @@ -1235,7 +1303,9 @@ start_stop (WButton * button, int action) return 0; } -/* Handle view command, when invoked as a button */ +/* --------------------------------------------------------------------------------------------- */ +/** Handle view command, when invoked as a button */ + static int find_do_view_file (WButton * button, int action) { @@ -1246,7 +1316,9 @@ find_do_view_file (WButton * button, int action) return 0; } -/* Handle edit command, when invoked as a button */ +/* --------------------------------------------------------------------------------------------- */ +/** Handle edit command, when invoked as a button */ + static int find_do_edit_file (WButton * button, int action) { @@ -1257,6 +1329,8 @@ find_do_edit_file (WButton * button, int action) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static void setup_gui (void) { @@ -1340,6 +1414,8 @@ setup_gui (void) add_widget (find_dlg, find_list); } +/* --------------------------------------------------------------------------------------------- */ + static int run_process (void) { @@ -1372,6 +1448,8 @@ run_process (void) return ret; } +/* --------------------------------------------------------------------------------------------- */ + static void kill_gui (void) { @@ -1379,6 +1457,8 @@ kill_gui (void) destroy_dlg (find_dlg); } +/* --------------------------------------------------------------------------------------------- */ + static int find_file (const char *start_dir, const char *pattern, const char *content, char **dirname, char **filename) @@ -1493,6 +1573,10 @@ find_file (const char *start_dir, const char *pattern, const char *content, return return_value; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void do_find (void) { @@ -1549,3 +1633,5 @@ do_find (void) } } } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/find.h b/src/find.h index 623086bdb..dac771752 100644 --- a/src/find.h +++ b/src/find.h @@ -1,11 +1,21 @@ - /** \file find.h * \brief Header: Find file command */ -#ifndef MC_FIND_H -#define MC_FIND_H +#ifndef MC__FIND_H +#define MC__FIND_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ void do_find (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__FIND_H */ diff --git a/src/help.c b/src/help.c index f7946b533..222d5712d 100644 --- a/src/help.c +++ b/src/help.c @@ -67,6 +67,10 @@ #include "help.h" #include "main.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define MAXLINKNAME 80 #define HISTORY_SIZE 20 #define HELP_WINDOW_WIDTH min(80, COLS - 16) @@ -76,6 +80,16 @@ #define STRING_LINK_END "\03" #define STRING_NODE_END "\04" +/*** file scope type declarations ****************************************************************/ + +/* Link areas for the mouse */ +typedef struct Link_Area +{ + int x1, y1, x2, y2; + const char *link_name; +} Link_Area; + +/*** file scope variables ************************************************************************/ static char *fdata = NULL; /* Pointer to the loaded data file */ static int help_lines; /* Lines in help viewer */ @@ -95,20 +109,17 @@ static struct const char *link; /* Pointer to the selected link */ } history[HISTORY_SIZE]; -/* Link areas for the mouse */ -typedef struct Link_Area -{ - int x1, y1, x2, y2; - const char *link_name; -} Link_Area; - static GSList *link_area = NULL; static gboolean inside_link_area = FALSE; static cb_ret_t help_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data); -/* returns the position where text was found in the start buffer */ -/* or 0 if not found */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** returns the position where text was found in the start buffer + * or 0 if not found + */ static const char * search_string (const char *start, const char *text) { @@ -144,8 +155,12 @@ search_string (const char *start, const char *text) return result; } -/* Searches text in the buffer pointed by start. Search ends */ -/* if the CHAR_NODE_END is found in the text. Returns 0 on failure */ +/* --------------------------------------------------------------------------------------------- */ +/** Searches text in the buffer pointed by start. Search ends + * if the CHAR_NODE_END is found in the text. + * @returns 0 on failure + */ + static const char * search_string_node (const char *start, const char *text) { @@ -166,8 +181,11 @@ search_string_node (const char *start, const char *text) return NULL; } -/* Searches the_char in the buffer pointer by start and searches */ -/* it can search forward (direction = 1) or backward (direction = -1) */ +/* --------------------------------------------------------------------------------------------- */ +/** Searches the_char in the buffer pointer by start and searches + * it can search forward (direction = 1) or backward (direction = -1) + */ + static const char * search_char_node (const char *start, char the_char, int direction) { @@ -180,7 +198,9 @@ search_char_node (const char *start, char the_char, int direction) return NULL; } -/* Returns the new current pointer when moved lines lines */ +/* --------------------------------------------------------------------------------------------- */ +/** Returns the new current pointer when moved lines lines */ + static const char * move_forward2 (const char *c, int lines) { @@ -199,6 +219,8 @@ move_forward2 (const char *c, int lines) return currentpoint = c; } +/* --------------------------------------------------------------------------------------------- */ + static const char * move_backward2 (const char *c, int lines) { @@ -225,6 +247,8 @@ move_backward2 (const char *c, int lines) return currentpoint = c; } +/* --------------------------------------------------------------------------------------------- */ + static void move_forward (int i) { @@ -232,12 +256,16 @@ move_forward (int i) currentpoint = move_forward2 (currentpoint, i); } +/* --------------------------------------------------------------------------------------------- */ + static void move_backward (int i) { currentpoint = move_backward2 (currentpoint, ++i); } +/* --------------------------------------------------------------------------------------------- */ + static void move_to_top (void) { @@ -250,6 +278,8 @@ move_to_top (void) selected_item = NULL; } +/* --------------------------------------------------------------------------------------------- */ + static void move_to_bottom (void) { @@ -259,6 +289,8 @@ move_to_bottom (void) move_backward (1); } +/* --------------------------------------------------------------------------------------------- */ + static const char * help_follow_link (const char *start, const char *lc_selected_item) { @@ -290,6 +322,8 @@ help_follow_link (const char *start, const char *lc_selected_item) return _("Help file format error\n"); } +/* --------------------------------------------------------------------------------------------- */ + static const char * select_next_link (const char *current_link) { @@ -307,12 +341,16 @@ select_next_link (const char *current_link) return p - 1; } +/* --------------------------------------------------------------------------------------------- */ + static const char * select_prev_link (const char *current_link) { return current_link == NULL ? NULL : search_char_node (current_link - 1, CHAR_LINK_START, -1); } +/* --------------------------------------------------------------------------------------------- */ + static void start_link_area (int x, int y, const char *link_name) { @@ -333,6 +371,8 @@ start_link_area (int x, int y, const char *link_name) inside_link_area = TRUE; } +/* --------------------------------------------------------------------------------------------- */ + static void end_link_area (int x, int y) { @@ -346,6 +386,8 @@ end_link_area (int x, int y) } } +/* --------------------------------------------------------------------------------------------- */ + static void clear_link_areas (void) { @@ -355,6 +397,8 @@ clear_link_areas (void) inside_link_area = FALSE; } +/* --------------------------------------------------------------------------------------------- */ + static void help_print_word (Dlg_head * h, GString * word, int *col, int *line, gboolean add_space) { @@ -397,6 +441,8 @@ help_print_word (Dlg_head * h, GString * word, int *col, int *line, gboolean add } } +/* --------------------------------------------------------------------------------------------- */ + static void help_show (Dlg_head * h, const char *paint_start) { @@ -549,6 +595,8 @@ help_show (Dlg_head * h, const char *paint_start) dlg_move (h, active_line, active_col); } +/* --------------------------------------------------------------------------------------------- */ + static int help_event (Gpm_Event * event, void *vp) { @@ -621,7 +669,9 @@ help_event (Gpm_Event * event, void *vp) return 0; } -/* show help */ +/* --------------------------------------------------------------------------------------------- */ +/** show help */ + static void help_help (Dlg_head * h) { @@ -640,6 +690,8 @@ help_help (Dlg_head * h) } } +/* --------------------------------------------------------------------------------------------- */ + static void help_index (Dlg_head * h) { @@ -661,6 +713,8 @@ help_index (Dlg_head * h) } } +/* --------------------------------------------------------------------------------------------- */ + static void help_back (Dlg_head * h) { @@ -673,6 +727,8 @@ help_back (Dlg_head * h) help_callback (h, NULL, DLG_DRAW, 0, NULL); /* FIXME: unneeded? */ } +/* --------------------------------------------------------------------------------------------- */ + static void help_next_link (gboolean move_down) { @@ -696,6 +752,8 @@ help_next_link (gboolean move_down) selected_item = NULL; } +/* --------------------------------------------------------------------------------------------- */ + static void help_prev_link (gboolean move_up) { @@ -714,6 +772,8 @@ help_prev_link (gboolean move_up) } } +/* --------------------------------------------------------------------------------------------- */ + static void help_next_node (void) { @@ -733,6 +793,8 @@ help_next_node (void) } } +/* --------------------------------------------------------------------------------------------- */ + static void help_prev_node (void) { @@ -750,6 +812,8 @@ help_prev_node (void) selected_item = NULL; } +/* --------------------------------------------------------------------------------------------- */ + static void help_select_link (void) { @@ -781,6 +845,8 @@ help_select_link (void) selected_item = NULL; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t help_execute_cmd (unsigned long command) { @@ -846,6 +912,8 @@ help_execute_cmd (unsigned long command) return ret; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t help_handle_key (Dlg_head * h, int c) { @@ -859,6 +927,8 @@ help_handle_key (Dlg_head * h, int c) return MSG_HANDLED; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t help_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -890,13 +960,17 @@ help_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *dat } } +/* --------------------------------------------------------------------------------------------- */ + static void interactive_display_finish (void) { clear_link_areas (); } -/* translate help file into terminal encoding */ +/* --------------------------------------------------------------------------------------------- */ +/** translate help file into terminal encoding */ + static void translate_file (char *filedata) { @@ -925,6 +999,8 @@ translate_file (char *filedata) } } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t md_callback (Widget * w, widget_msg_t msg, int parm) { @@ -939,6 +1015,8 @@ md_callback (Widget * w, widget_msg_t msg, int parm) } } +/* --------------------------------------------------------------------------------------------- */ + static Widget * mousedispatch_new (int y, int x, int yl, int xl) { @@ -947,6 +1025,10 @@ mousedispatch_new (int y, int x, int yl, int xl) return w; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void interactive_display (const char *filename, const char *node) { @@ -1043,3 +1125,5 @@ interactive_display (const char *filename, const char *node) interactive_display_finish (); destroy_dlg (whelp); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/help.h b/src/help.h index 73ebd29d1..8374442ba 100644 --- a/src/help.h +++ b/src/help.h @@ -1,4 +1,3 @@ - /** \file help.h * \brief Header: hypertext file browser * @@ -26,8 +25,10 @@ * This file is included by help.c and man2hlp.c */ -#ifndef MC_HELP_H -#define MC_HELP_H +#ifndef MC__HELP_H +#define MC__HELP_H + +/*** typedefs(not structures) and defined constants **********************************************/ /* Markers used in the help files */ #define CHAR_LINK_START '\01' /* Ctrl-A */ @@ -41,6 +42,15 @@ #define CHAR_FONT_NORMAL '\013' /* Ctrl-K */ #define CHAR_FONT_ITALIC '\024' /* Ctrl-T */ +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + void interactive_display (const char *filename, const char *node); -#endif /* MC_HELP_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__HELP_H */ diff --git a/src/history.h b/src/history.h index ebc91a128..370ce925e 100644 --- a/src/history.h +++ b/src/history.h @@ -1,10 +1,11 @@ - /** \file history.h * \brief Header: defines history section names */ -#ifndef MC_HISTORY_H -#define MC_HISTORY_H +#ifndef MC__HISTORY_H +#define MC__HISTORY_H + +/*** typedefs(not structures) and defined constants **********************************************/ /* history section names */ @@ -45,4 +46,14 @@ #define MC_HISTORY_YDIFF_GOTO_LINE "mc.ydiff.goto-line" -#endif /* MC_HISTORY_H */ +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +/*** inline functions ****************************************************************************/ + +#endif /* MC__HISTORY_H */ diff --git a/src/hotlist.c b/src/hotlist.c index 438c2cc2f..15da2c9b0 100644 --- a/src/hotlist.c +++ b/src/hotlist.c @@ -61,6 +61,12 @@ #include "command.h" /* cmdline */ #include "history.h" +/*** global variables ****************************************************************************/ + +int hotlist_has_dot_dot = 1; + +/*** file scope macro definitions ****************************************************************/ + #define UX 5 #define UY 2 @@ -83,15 +89,49 @@ #define B_REFRESH_VFS (B_USER + 9) #endif -int hotlist_has_dot_dot = 1; +#define new_hotlist() g_new0(struct hotlist, 1) -static WListbox *l_hotlist; -static WListbox *l_movelist; +#define CHECK_BUFFER \ +do \ +{ \ + size_t i; \ + i = strlen (current->label); \ + if (i + 3 > buflen) { \ + g_free (buf); \ + buflen = 1024 * (i/1024 + 1); \ + buf = g_malloc (buflen); \ + } \ + buf[0] = '\0'; \ +} while (0) -static Dlg_head *hotlist_dlg; -static Dlg_head *movelist_dlg; +#define TKN_GROUP 0 +#define TKN_ENTRY 1 +#define TKN_STRING 2 +#define TKN_URL 3 +#define TKN_ENDGROUP 4 +#define TKN_COMMENT 5 +#define TKN_EOL 125 +#define TKN_EOF 126 +#define TKN_UNKNOWN 127 -static WLabel *pname, *pname_group, *movelist_group; +#define SKIP_TO_EOL \ +{ \ + int _tkn; \ + while ((_tkn = hot_next_token ()) != TKN_EOF && _tkn != TKN_EOL) ; \ +} + +#define CHECK_TOKEN(_TKN_) \ +tkn = hot_next_token (); \ +if (tkn != _TKN_) \ +{ \ + hotlist_state.readonly = 1; \ + hotlist_state.file_error = 1; \ + while (tkn != TKN_EOL && tkn != TKN_EOF) \ + tkn = hot_next_token (); \ + break; \ +} + +/*** file scope type declarations ****************************************************************/ enum HotListType { @@ -122,6 +162,27 @@ static struct int type; /* LIST_HOTLIST || LIST_VFSLIST */ } hotlist_state; +/* Directory hotlist */ +struct hotlist +{ + enum HotListType type; + char *directory; + char *label; + struct hotlist *head; + struct hotlist *up; + struct hotlist *next; +}; + +/*** file scope variables ************************************************************************/ + +static WListbox *l_hotlist; +static WListbox *l_movelist; + +static Dlg_head *hotlist_dlg; +static Dlg_head *movelist_dlg; + +static WLabel *pname, *pname_group, *movelist_group; + static struct _hotlist_but { int ret_cmd, flags, y, x; @@ -159,19 +220,21 @@ static struct _hotlist_but /* *INDENT-ON* */ }; -/* Directory hotlist */ -static struct hotlist -{ - enum HotListType type; - char *directory; - char *label; - struct hotlist *head; - struct hotlist *up; - struct hotlist *next; -} *hotlist = NULL; +static struct hotlist *hotlist = NULL; static struct hotlist *current_group; +static GString *tkn_buf = NULL; + +static char *hotlist_file_name; +static FILE *hotlist_file; +static time_t hotlist_file_mtime; + +static int list_level = 0; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static void init_movelist (int, struct hotlist *); static void add_new_group_cmd (void); static void add_new_entry_cmd (void); @@ -179,7 +242,7 @@ static void remove_from_hotlist (struct hotlist *entry); static void load_hotlist (void); static void add_dotdot_to_list (void); -#define new_hotlist() g_new0(struct hotlist, 1) +/* --------------------------------------------------------------------------------------------- */ static void hotlist_refresh (Dlg_head * dlg) @@ -192,7 +255,9 @@ hotlist_refresh (Dlg_head * dlg) draw_box (dlg, dlg->lines - 8, 5, 3, dlg->cols - (UX * 2), TRUE); } -/* If current->data is 0, then we are dealing with a VFS pathname */ +/* --------------------------------------------------------------------------------------------- */ +/** If current->data is 0, then we are dealing with a VFS pathname */ + static void update_path_name (void) { @@ -232,18 +297,7 @@ update_path_name (void) dlg_redraw (dlg); } -#define CHECK_BUFFER \ -do \ -{ \ - size_t i; \ - i = strlen (current->label); \ - if (i + 3 > buflen) { \ - g_free (buf); \ - buflen = 1024 * (i/1024 + 1); \ - buf = g_malloc (buflen); \ - } \ - buf[0] = '\0'; \ -} while (0) +/* --------------------------------------------------------------------------------------------- */ static void fill_listbox (void) @@ -282,6 +336,8 @@ fill_listbox (void) g_string_free (buff, TRUE); } +/* --------------------------------------------------------------------------------------------- */ + static void unlink_entry (struct hotlist *entry) { @@ -299,6 +355,8 @@ unlink_entry (struct hotlist *entry) entry->next = entry->up = 0; } +/* --------------------------------------------------------------------------------------------- */ + #ifdef ENABLE_VFS static void add_name_to_list (const char *path) @@ -307,8 +365,10 @@ add_name_to_list (const char *path) } #endif /* !ENABLE_VFS */ +/* --------------------------------------------------------------------------------------------- */ + static int -hotlist_button_callback (WButton *button, int action) +hotlist_button_callback (WButton * button, int action) { (void) button; @@ -456,6 +516,8 @@ hotlist_button_callback (WButton *button, int action) } } +/* --------------------------------------------------------------------------------------------- */ + static inline cb_ret_t hotlist_handle_key (Dlg_head * h, int key) { @@ -521,6 +583,8 @@ hotlist_handle_key (Dlg_head * h, int key) } } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t hotlist_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -556,6 +620,8 @@ hotlist_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void * } } +/* --------------------------------------------------------------------------------------------- */ + static int l_call (WListbox * list) { @@ -596,7 +662,8 @@ l_call (WListbox * list) return LISTBOX_CONT; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Expands all button names (once) and recalculates button positions. * returns number of columns in the dialog box, which is 10 chars longer * then buttonbar. @@ -604,6 +671,7 @@ l_call (WListbox * list) * If common width of the window (i.e. in xterm) is less than returned * width - sorry :) (anyway this did not handled in previous version too) */ + static int init_i18n_stuff (int list_type, int cols) { @@ -677,6 +745,8 @@ init_i18n_stuff (int list_type, int cols) return cols; } +/* --------------------------------------------------------------------------------------------- */ + static void init_hotlist (int list_type) { @@ -755,6 +825,8 @@ init_hotlist (int list_type) /* add listbox to the dialogs */ } +/* --------------------------------------------------------------------------------------------- */ + static void init_movelist (int list_type, struct hotlist *item) { @@ -796,10 +868,12 @@ init_movelist (int list_type, struct hotlist *item) /* add listbox to the dialogs */ } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Destroy the list dialog. * Don't confuse with done_hotlist() for the list in memory. */ + static void hotlist_done (void) { @@ -810,12 +884,16 @@ hotlist_done (void) repaint_screen (); } +/* --------------------------------------------------------------------------------------------- */ + static inline char * find_group_section (struct hotlist *grp) { return g_strconcat (grp->directory, ".Group", (char *) NULL); } +/* --------------------------------------------------------------------------------------------- */ + static struct hotlist * add2hotlist (char *label, char *directory, enum HotListType type, listbox_append_t pos) { @@ -902,8 +980,8 @@ add2hotlist (char *label, char *directory, enum HotListType type, listbox_append } -#ifdef ENABLE_NLS -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Support routine for add_new_entry_input()/add_new_group_input() * Change positions of buttons (first three widgets). * @@ -911,6 +989,8 @@ add2hotlist (char *label, char *directory, enum HotListType type, listbox_append * internationalized label lengths and total buttonbar length...assume * 64 is longer anyway. */ + +#ifdef ENABLE_NLS static void add_widgets_i18n (QuickWidget * qw, int len) { @@ -931,6 +1011,8 @@ add_widgets_i18n (QuickWidget * qw, int len) } #endif /* ENABLE_NLS */ +/* --------------------------------------------------------------------------------------------- */ + static int add_new_entry_input (const char *header, const char *text1, const char *text2, const char *help, char **r1, char **r2) @@ -997,6 +1079,8 @@ add_new_entry_input (const char *header, const char *text1, const char *text2, #undef RELATIVE_Y_INPUT_PTH } +/* --------------------------------------------------------------------------------------------- */ + static void add_new_entry_cmd (void) { @@ -1027,6 +1111,8 @@ add_new_entry_cmd (void) hotlist_state.modified = 1; } +/* --------------------------------------------------------------------------------------------- */ + static int add_new_group_input (const char *header, const char *label, char **result) { @@ -1080,6 +1166,8 @@ add_new_group_input (const char *header, const char *label, char **result) return (ret != B_CANCEL) ? ret : 0; } +/* --------------------------------------------------------------------------------------------- */ + static void add_new_group_cmd (void) { @@ -1098,29 +1186,7 @@ add_new_group_cmd (void) hotlist_state.modified = 1; } -void -add2hotlist_cmd (void) -{ - char *lc_prompt, *label; - const char *cp = _("Label for \"%s\":"); - int l = str_term_width1 (cp); - char *label_string = g_strdup (current_panel->cwd); - - strip_password (label_string, 1); - - lc_prompt = g_strdup_printf (cp, path_trunc (current_panel->cwd, COLS - 2 * UX - (l + 8))); - label = input_dialog (_("Add to hotlist"), lc_prompt, MC_HISTORY_HOTLIST_ADD, label_string); - g_free (lc_prompt); - - if (!label || !*label) - { - g_free (label_string); - g_free (label); - return; - } - add2hotlist (label, label_string, HL_TYPE_ENTRY, LISTBOX_APPEND_AT_END); - hotlist_state.modified = 1; -} +/* --------------------------------------------------------------------------------------------- */ static void remove_group (struct hotlist *grp) @@ -1143,6 +1209,8 @@ remove_group (struct hotlist *grp) } +/* --------------------------------------------------------------------------------------------- */ + static void remove_from_hotlist (struct hotlist *entry) { @@ -1200,44 +1268,7 @@ remove_from_hotlist (struct hotlist *entry) hotlist_state.modified = 1; } -char * -hotlist_cmd (int vfs_or_hotlist) -{ - char *target = NULL; - - hotlist_state.type = vfs_or_hotlist; - load_hotlist (); - - init_hotlist (vfs_or_hotlist); - - /* display file info */ - tty_setcolor (SELECTED_COLOR); - - hotlist_state.running = 1; - run_dlg (hotlist_dlg); - hotlist_state.running = 0; - save_hotlist (); - - switch (hotlist_dlg->ret_value) - { - default: - case B_CANCEL: - break; - - case B_ENTER: - { - char *text = NULL; - struct hotlist *hlp = NULL; - - listbox_get_current (l_hotlist, &text, (void **) &hlp); - target = g_strdup (hlp != NULL ? hlp->directory : text); - break; - } - } /* switch */ - - hotlist_done (); - return target; -} +/* --------------------------------------------------------------------------------------------- */ static void load_group (struct hotlist *grp) @@ -1276,21 +1307,7 @@ load_group (struct hotlist *grp) load_group (current); } -#define TKN_GROUP 0 -#define TKN_ENTRY 1 -#define TKN_STRING 2 -#define TKN_URL 3 -#define TKN_ENDGROUP 4 -#define TKN_COMMENT 5 -#define TKN_EOL 125 -#define TKN_EOF 126 -#define TKN_UNKNOWN 127 - -static GString *tkn_buf = NULL; - -static char *hotlist_file_name; -static FILE *hotlist_file; -static time_t hotlist_file_mtime; +/* --------------------------------------------------------------------------------------------- */ static int hot_skip_blanks (void) @@ -1303,6 +1320,8 @@ hot_skip_blanks (void) } +/* --------------------------------------------------------------------------------------------- */ + static int hot_next_token (void) { @@ -1386,22 +1405,7 @@ hot_next_token (void) return ret; } -#define SKIP_TO_EOL \ -{ \ - int _tkn; \ - while ((_tkn = hot_next_token ()) != TKN_EOF && _tkn != TKN_EOL) ; \ -} - -#define CHECK_TOKEN(_TKN_) \ -tkn = hot_next_token (); \ -if (tkn != _TKN_) \ -{ \ - hotlist_state.readonly = 1; \ - hotlist_state.file_error = 1; \ - while (tkn != TKN_EOL && tkn != TKN_EOF) \ - tkn = hot_next_token (); \ - break; \ -} +/* --------------------------------------------------------------------------------------------- */ static void hot_load_group (struct hotlist *grp) @@ -1453,6 +1457,8 @@ hot_load_group (struct hotlist *grp) SKIP_TO_EOL; } +/* --------------------------------------------------------------------------------------------- */ + static void hot_load_file (struct hotlist *grp) { @@ -1497,6 +1503,8 @@ hot_load_file (struct hotlist *grp) } } +/* --------------------------------------------------------------------------------------------- */ + static void clean_up_hotlist_groups (const char *section) { @@ -1523,7 +1531,7 @@ clean_up_hotlist_groups (const char *section) g_free (grp_section); } - +/* --------------------------------------------------------------------------------------------- */ static void load_hotlist (void) @@ -1569,7 +1577,8 @@ load_hotlist (void) remove_old_list = 1; else message (D_ERROR, _("Hotlist Load"), - _("MC was unable to write ~/%s file,\nyour old hotlist entries were not deleted"), + _ + ("MC was unable to write ~/%s file,\nyour old hotlist entries were not deleted"), MC_USERCONF_DIR PATH_SEP_STR MC_HOTLIST_FILE); } else @@ -1592,8 +1601,7 @@ load_hotlist (void) current_group = hotlist; } - -static int list_level = 0; +/* --------------------------------------------------------------------------------------------- */ static void hot_save_group (struct hotlist *grp) @@ -1654,6 +1662,89 @@ do { \ } } +/* --------------------------------------------------------------------------------------------- */ + +static void +add_dotdot_to_list (void) +{ + if (current_group != hotlist) + { + if (hotlist_has_dot_dot != 0) + add2hotlist (g_strdup (".."), g_strdup (".."), HL_TYPE_DOTDOT, LISTBOX_APPEND_AT_END); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +add2hotlist_cmd (void) +{ + char *lc_prompt, *label; + const char *cp = _("Label for \"%s\":"); + int l = str_term_width1 (cp); + char *label_string = g_strdup (current_panel->cwd); + + strip_password (label_string, 1); + + lc_prompt = g_strdup_printf (cp, path_trunc (current_panel->cwd, COLS - 2 * UX - (l + 8))); + label = input_dialog (_("Add to hotlist"), lc_prompt, MC_HISTORY_HOTLIST_ADD, label_string); + g_free (lc_prompt); + + if (!label || !*label) + { + g_free (label_string); + g_free (label); + return; + } + add2hotlist (label, label_string, HL_TYPE_ENTRY, LISTBOX_APPEND_AT_END); + hotlist_state.modified = 1; +} + +/* --------------------------------------------------------------------------------------------- */ + +char * +hotlist_cmd (int vfs_or_hotlist) +{ + char *target = NULL; + + hotlist_state.type = vfs_or_hotlist; + load_hotlist (); + + init_hotlist (vfs_or_hotlist); + + /* display file info */ + tty_setcolor (SELECTED_COLOR); + + hotlist_state.running = 1; + run_dlg (hotlist_dlg); + hotlist_state.running = 0; + save_hotlist (); + + switch (hotlist_dlg->ret_value) + { + default: + case B_CANCEL: + break; + + case B_ENTER: + { + char *text = NULL; + struct hotlist *hlp = NULL; + + listbox_get_current (l_hotlist, &text, (void **) &hlp); + target = g_strdup (hlp != NULL ? hlp->directory : text); + break; + } + } /* switch */ + + hotlist_done (); + return target; +} + +/* --------------------------------------------------------------------------------------------- */ + int save_hotlist (void) { @@ -1681,10 +1772,12 @@ save_hotlist (void) return saved; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Unload list from memory. * Don't confuse with hotlist_done() for GUI. */ + void done_hotlist (void) { @@ -1711,12 +1804,4 @@ done_hotlist (void) } } -static void -add_dotdot_to_list (void) -{ - if (current_group != hotlist) - { - if (hotlist_has_dot_dot != 0) - add2hotlist (g_strdup (".."), g_strdup (".."), HL_TYPE_DOTDOT, LISTBOX_APPEND_AT_END); - } -} +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/hotlist.h b/src/hotlist.h index c4a1bb7aa..5c3cb0e2b 100644 --- a/src/hotlist.h +++ b/src/hotlist.h @@ -1,18 +1,28 @@ - /** \file hotlist.h * \brief Header: directory hotlist */ -#ifndef MC_HOTLIST_H -#define MC_HOTLIST_H +#ifndef MC__HOTLIST_H +#define MC__HOTLIST_H + +/*** typedefs(not structures) and defined constants **********************************************/ #define LIST_VFSLIST 0x01 #define LIST_HOTLIST 0x02 #define LIST_MOVELIST 0x04 +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + void add2hotlist_cmd (void); char *hotlist_cmd (int list_vfs); -int save_hotlist (void); +int save_hotlist (void); void done_hotlist (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__HOTLIST_H */ diff --git a/src/info.c b/src/info.c index 92f6b66fe..dbdd140f1 100644 --- a/src/info.c +++ b/src/info.c @@ -44,18 +44,29 @@ #include "setup.h" /* panels_options */ #include "info.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #ifndef VERSION -# define VERSION "undefined" +#define VERSION "undefined" #endif +/*** file scope type declarations ****************************************************************/ + struct WInfo { Widget widget; int ready; }; +/*** file scope variables ************************************************************************/ + static struct my_statfs myfs_stats; +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static void info_box (struct WInfo *info) { @@ -68,7 +79,7 @@ info_box (struct WInfo *info) draw_box (info->widget.owner, info->widget.y, info->widget.x, info->widget.lines, info->widget.cols, FALSE); - widget_move (&info->widget, 0, (info->widget.cols - len - 2)/2); + widget_move (&info->widget, 0, (info->widget.cols - len - 2) / 2); tty_printf (" %s ", title); widget_move (&info->widget, 2, 0); @@ -78,6 +89,8 @@ info_box (struct WInfo *info) tty_draw_hline (info->widget.y + 2, info->widget.x + 1, ACS_HLINE, info->widget.cols - 2); } +/* --------------------------------------------------------------------------------------------- */ + static void info_show_info (struct WInfo *info) { @@ -238,6 +251,8 @@ info_show_info (struct WInfo *info) g_string_free (buff, TRUE); } +/* --------------------------------------------------------------------------------------------- */ + static void info_hook (void *data) { @@ -254,6 +269,8 @@ info_hook (void *data) info_show_info (info); } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t info_callback (Widget * w, widget_msg_t msg, int parm) { @@ -285,6 +302,8 @@ info_callback (Widget * w, widget_msg_t msg, int parm) } } +/* --------------------------------------------------------------------------------------------- */ + static int info_event (Gpm_Event * event, void *data) { @@ -300,6 +319,10 @@ info_event (Gpm_Event * event, void *data) return MOU_NORMAL; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + WInfo * info_new (int y, int x, int lines, int cols) { @@ -312,3 +335,5 @@ info_new (int y, int x, int lines, int cols) return info; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/info.h b/src/info.h index e0bd9fdd2..cba2592e9 100644 --- a/src/info.h +++ b/src/info.h @@ -1,14 +1,24 @@ - /** \file info.h * \brief Header: panel managing */ -#ifndef MC_INFO_H -#define MC_INFO_H +#ifndef MC__INFO_H +#define MC__INFO_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ struct WInfo; typedef struct WInfo WInfo; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + WInfo *info_new (int y, int x, int lines, int cols); -#endif /* MC_INFO_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__INFO_H */ diff --git a/src/keybind.c b/src/keybind.c index cee45f30a..8624465fb 100644 --- a/src/keybind.c +++ b/src/keybind.c @@ -1,25 +1,25 @@ /* - Copyright (C) 2009 The Free Software Foundation, Inc. + Copyright (C) 2009 The Free Software Foundation, Inc. - Written by: 2005 Vitja Makarov - 2009 Ilia Maslakov + Written by: 2005 Vitja Makarov + 2009 Ilia Maslakov - This file is part of the Midnight Commander. + This file is part of the Midnight Commander. - 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 2 of the - License, or (at your option) any later version. + 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 2 of the + License, or (at your option) any later version. - The Midnight Commander 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. + The Midnight Commander 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. + 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., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ #include @@ -36,14 +36,17 @@ #include "lib/global.h" #include "lib/tty/win.h" -#include "lib/tty/key.h" /* KEY_M_ */ -#include "lib/tty/tty.h" /* keys */ +#include "lib/tty/key.h" /* KEY_M_ */ +#include "lib/tty/tty.h" /* keys */ #include "lib/strutil.h" -#include "cmddef.h" /* CK_ cmd name const */ +#include "cmddef.h" /* CK_ cmd name const */ #include "wtools.h" #include "keybind.h" +/*** global variables ****************************************************************************/ + + #ifdef USE_INTERNAL_EDIT GArray *editor_keymap = NULL; GArray *editor_x_keymap = NULL; @@ -78,1138 +81,1145 @@ const global_keymap_t *tree_map; const global_keymap_t *help_map; const global_keymap_t *dialog_map; -static name_keymap_t command_names[] = { -#ifdef USE_INTERNAL_EDIT - { "EditNoCommand", CK_Ignore_Key }, - { "EditIgnoreKey", CK_Ignore_Key }, - { "EditBackSpace", CK_BackSpace }, - { "EditDelete", CK_Delete }, - { "EditEnter", CK_Enter }, - { "EditPageUp", CK_Page_Up }, - { "EditPageDown", CK_Page_Down }, - { "EditLeft", CK_Left }, - { "EditRight", CK_Right }, - { "EditWordLeft", CK_Word_Left }, - { "EditWordRight", CK_Word_Right }, - { "EditUp", CK_Up }, - { "EditDown", CK_Down }, - { "EditHome", CK_Home }, - { "EditEnd", CK_End }, - { "EditTab", CK_Tab }, - { "EditUndo", CK_Undo }, - { "EditBeginningOfText", CK_Beginning_Of_Text }, - { "EditEndOfText", CK_End_Of_Text }, - { "EditScrollUp", CK_Scroll_Up }, - { "EditScrollDown", CK_Scroll_Down }, - { "EditReturn", CK_Return }, - { "EditBeginPage", CK_Begin_Page }, - { "EditEndPage", CK_End_Page }, - { "EditDeleteWordLeft", CK_Delete_Word_Left }, - { "EditDeleteWordRight", CK_Delete_Word_Right }, - { "EditParagraphUp", CK_Paragraph_Up }, - { "EditParagraphDown", CK_Paragraph_Down }, - { "EditMenu", CK_Menu }, - { "EditSave", CK_Save }, - { "EditLoad", CK_Load }, - { "EditNew", CK_New }, - { "EditSaveas", CK_Save_As }, - { "EditMark", CK_Mark }, - { "EditCopy", CK_Copy }, - { "EditMove", CK_Move }, - { "EditRemove", CK_Remove }, - { "EditMarkAll", CK_Mark_All }, - { "EditUnmark", CK_Unmark }, - { "EditSaveBlock", CK_Save_Block }, - { "EditColumnMark", CK_Column_Mark }, - { "EditFind", CK_Find }, - { "EditFindAgain", CK_Find_Again }, - { "EditReplace", CK_Replace }, - { "EditReplaceAgain", CK_Replace_Again }, - { "EditCompleteWord", CK_Complete_Word }, - -#if 0 - { "EditDebugStart", CK_Debug_Start }, - { "EditDebugStop", CK_Debug_Stop }, - { "EditDebugToggleBreak", CK_Debug_Toggle_Break }, - { "EditDebugClear", CK_Debug_Clear }, - { "EditDebugNext", CK_Debug_Next }, - { "EditDebugStep", CK_Debug_Step }, - { "EditDebugBackTrace", CK_Debug_Back_Trace }, - { "EditDebugContinue", CK_Debug_Continue }, - { "EditDebugEnterCommand", CK_Debug_Enter_Command }, - { "EditDebugUntilCurser", CK_Debug_Until_Curser }, -#endif - { "EditInsertFile", CK_Insert_File }, - { "EditQuit", CK_Quit }, - { "EditToggleInsert", CK_Toggle_Insert }, - { "EditHelp", CK_Help }, - { "EditDate", CK_Date }, - { "EditRefresh", CK_Refresh }, - { "EditGoto", CK_Goto }, - { "EditDeleteLine", CK_Delete_Line }, - { "EditDeleteToLineEnd", CK_Delete_To_Line_End }, - { "EditDeleteToLineBegin", CK_Delete_To_Line_Begin }, - { "EditManPage", CK_Man_Page }, - { "EditSort", CK_Sort }, - { "EditMail", CK_Mail }, - { "EditCancel", CK_Cancel }, - { "EditComplete", CK_Complete }, - { "EditParagraphFormat", CK_Paragraph_Format }, - { "EditUtil", CK_Util }, - { "EditTypeLoadPython", CK_Type_Load_Python }, - { "EditFindFile", CK_Find_File }, - { "EditCtags", CK_Ctags }, - { "EditMatchBracket", CK_Match_Bracket }, - { "EditTerminal", CK_Terminal }, - { "EditTerminalApp", CK_Terminal_App }, - { "EditExtCmd", CK_ExtCmd }, - { "EditUserMenu", CK_User_Menu }, - { "EditBeginRecordMacro", CK_Begin_Record_Macro }, - { "EditEndRecordMacro", CK_End_Record_Macro }, - { "EditDeleteMacro", CK_Delete_Macro }, - { "EditToggleBookmark", CK_Toggle_Bookmark }, - { "EditFlushBookmarks", CK_Flush_Bookmarks }, - { "EditNextBookmark", CK_Next_Bookmark }, - { "EditPrevBookmark", CK_Prev_Bookmark }, - { "EditPageUpHighlight", CK_Page_Up_Highlight }, - { "EditPageDownHighlight", CK_Page_Down_Highlight }, - { "EditLeftHighlight", CK_Left_Highlight }, - { "EditRightHighlight", CK_Right_Highlight }, - { "EditWordLeftHighlight", CK_Word_Left_Highlight }, - { "EditWordRightHighlight", CK_Word_Right_Highlight }, - { "EditUpHighlight", CK_Up_Highlight }, - { "EditDownHighlight", CK_Down_Highlight }, - { "EditHomeHighlight", CK_Home_Highlight }, - { "EditEndHighlight", CK_End_Highlight }, - { "EditBeginningOfTextHighlight", CK_Beginning_Of_Text_Highlight }, - { "EditEndOfTextHighlight", CK_End_Of_Text_Highlight }, - { "EditBeginPageHighlight", CK_Begin_Page_Highlight }, - { "EditEndPageHighlight", CK_End_Page_Highlight }, - { "EditScrollUpHighlight", CK_Scroll_Up_Highlight }, - { "EditScrollDownHighlight", CK_Scroll_Down_Highlight }, - { "EditParagraphUpHighlight", CK_Paragraph_Up_Highlight }, - { "EditParagraphDownHighlight", CK_Paragraph_Down_Highlight }, - - { "EditPageUpAltHighlight", CK_Page_Up_Alt_Highlight }, - { "EditPageDownAltHighlight", CK_Page_Down_Alt_Highlight }, - { "EditLeftAltHighlight", CK_Left_Alt_Highlight }, - { "EditRightAltHighlight", CK_Right_Alt_Highlight }, - { "EditWordLeftAltHighlight", CK_Word_Left_Alt_Highlight }, - { "EditWordRightAltHighlight", CK_Word_Right_Alt_Highlight }, - { "EditUpAltHighlight", CK_Up_Alt_Highlight }, - { "EditDownAltHighlight", CK_Down_Alt_Highlight }, - { "EditHomeAltHighlight", CK_Home_Alt_Highlight }, - { "EditEndAltHighlight", CK_End_Alt_Highlight }, - { "EditBeginningOfTextAltHighlight", CK_Beginning_Of_Text_Alt_Highlight }, - { "EditEndOfTextAltHighlight", CK_End_Of_Text_Alt_Highlight }, - { "EditBeginPageAltHighlight", CK_Begin_Page_Alt_Highlight }, - { "EditEndPageAltHighlight", CK_End_Page_Alt_Highlight }, - { "EditScrollUpAltHighlight", CK_Scroll_Up_Alt_Highlight }, - { "EditScrollDownAltHighlight", CK_Scroll_Down_Alt_Highlight }, - { "EditParagraphUpAltHighlight", CK_Paragraph_Up_Alt_Highlight }, - { "EditParagraphDownAltHighlight", CK_Paragraph_Down_Alt_Highlight }, - - { "EditShiftBlockLeft", CK_Shift_Block_Left }, - { "EditShiftBlockRight", CK_Shift_Block_Right }, - - { "EditXStore", CK_XStore }, - { "EditXCut", CK_XCut }, - { "EditXPaste", CK_XPaste }, - { "EditSelectionHistory", CK_Selection_History }, - { "EditShell", CK_Shell }, - { "EditInsertLiteral", CK_Insert_Literal }, - { "EditExecuteMacro", CK_Execute_Macro }, - { "EditBeginOrEndMacro", CK_Begin_End_Macro }, - { "EditExtMode", CK_Ext_Mode }, - { "EditToggleLineState", CK_Toggle_Line_State }, - { "EditToggleTabTWS", CK_Toggle_Tab_TWS }, - { "EditToggleSyntax", CK_Toggle_Syntax }, - { "EditToggleShowMargin", CK_Toggle_Show_Margin }, - { "EditFindDefinition", CK_Find_Definition }, - { "EditLoadPrevFile", CK_Load_Prev_File }, - { "EditLoadNextFile", CK_Load_Next_File }, - { "EditOptions", CK_Edit_Options }, - { "EditSaveMode", CK_Edit_Save_Mode }, - { "EditChooseSyntax", CK_Choose_Syntax }, - { "EditAbout", CK_About }, - -#if 0 - { "EditFocusNext", CK_Focus_Next }, - { "EditFocusPrev", CK_Focus_Prev }, - { "EditHeightInc", CK_Height_Inc }, - { "EditHeightDec", CK_Height_Dec }, - { "EditMake", CK_Make }, - { "EditErrorNext", CK_Error_Next }, - { "EditErrorPrev", CK_Error_Prev }, -#endif - -#if 0 - { "EditSaveDesktop", CK_Save_Desktop }, - { "EditNewWindow", CK_New_Window }, - { "EditCycle", CK_Cycle }, - { "EditSaveAndQuit", CK_Save_And_Quit }, - { "EditRunAnother", CK_Run_Another }, - { "EditCheckSaveAndQuit", CK_Check_Save_And_Quit }, - { "EditMaximize", CK_Maximize }, -#endif - -#endif /* USE_INTERNAL_EDIT */ - - /* viewer */ - { "ViewHelp", CK_ViewHelp }, - { "ViewToggleWrapMode", CK_ViewToggleWrapMode }, - { "ViewToggleHexEditMode", CK_ViewToggleHexEditMode }, - { "ViewQuit", CK_ViewQuit }, - { "ViewToggleHexMode", CK_ViewToggleHexMode }, - { "ViewGoto", CK_ViewGoto }, - { "ViewHexEditSave", CK_ViewHexEditSave }, - { "ViewSearch", CK_ViewSearch }, - { "ViewToggleMagicMode", CK_ViewToggleMagicMode }, - { "ViewToggleNroffMode", CK_ViewToggleNroffMode }, - { "ViewContinueSearch", CK_ViewContinueSearch }, - { "ViewGotoBookmark", CK_ViewGotoBookmark }, - { "ViewNewBookmark", CK_ViewNewBookmark }, - { "ViewMoveUp", CK_ViewMoveUp }, - { "ViewMoveDown", CK_ViewMoveDown }, - { "ViewMoveLeft", CK_ViewMoveLeft }, - { "ViewMoveRight", CK_ViewMoveRight }, - { "ViewMoveLeft10", CK_ViewMoveLeft10 }, - { "ViewMoveRight10", CK_ViewMoveRight10 }, - { "ViewMovePgDn", CK_ViewMovePgDn }, - { "ViewMovePgUp", CK_ViewMovePgUp }, - { "ViewMoveHalfPgDn", CK_ViewMoveHalfPgDn }, - { "ViewMoveHalfPgUp", CK_ViewMoveHalfPgUp }, - { "ViewMoveToBol", CK_ViewMoveToBol }, - { "ViewMoveToEol", CK_ViewMoveToEol }, - { "ViewMoveTop", CK_ViewMoveTop }, - { "ViewMoveBottom", CK_ViewMoveBottom }, - { "ViewNextFile", CK_ViewNextFile }, - { "ViewPrevFile", CK_ViewPrevFile }, - { "ViewToggleRuler", CK_ViewToggleRuler }, - { "ViewToggleHexNavMode", CK_ViewToggleHexNavMode }, - - /* help */ - { "HelpHelp", CK_HelpHelp }, - { "HelpIndex", CK_HelpIndex }, - { "HelpBack", CK_HelpBack }, - { "HelpQuit", CK_HelpQuit }, - { "HelpMoveUp", CK_HelpMoveUp }, - { "HelpMoveDown", CK_HelpMoveDown }, - { "HelpMovePgDn", CK_HelpMovePgDn }, - { "HelpMovePgUp", CK_HelpMovePgUp }, - { "HelpMoveHalfPgDn", CK_HelpMoveHalfPgDn }, - { "HelpMoveHalfPgUp", CK_HelpMoveHalfPgUp }, - { "HelpMoveTop", CK_HelpMoveTop }, - { "HelpMoveBottom", CK_HelpMoveBottom }, - { "HelpSelectLink", CK_HelpSelectLink }, - { "HelpNextLink", CK_HelpNextLink }, - { "HelpPrevLink", CK_HelpPrevLink }, - { "HelpNextNode", CK_HelpNextNode }, - { "HelpPrevNode", CK_HelpPrevNode }, - - /* tree */ - { "TreeHelp", CK_TreeHelp }, - { "TreeForget", CK_TreeForget }, - { "TreeToggleNav", CK_TreeToggleNav }, - { "TreeCopy", CK_TreeCopy }, - { "TreeMove", CK_TreeMove }, - { "TreeMake", CK_TreeMake }, - { "TreeMoveUp", CK_TreeMoveUp }, - { "TreeMoveDown", CK_TreeMoveDown }, - { "TreeMoveLeft", CK_TreeMoveLeft }, - { "TreeMoveRight", CK_TreeMoveRight }, - { "TreeMoveHome", CK_TreeMoveHome }, - { "TreeMoveEnd", CK_TreeMoveEnd }, - { "TreeMovePgUp", CK_TreeMovePgUp }, - { "TreeMovePgDn", CK_TreeMovePgDn }, - { "TreeOpen", CK_TreeOpen }, - { "TreeRescan", CK_TreeRescan }, - { "TreeStartSearch", CK_TreeStartSearch }, - { "TreeRemove", CK_TreeRemove }, - - /* main commands */ - { "CmdHelp", CK_HelpCmd }, - { "CmdMenu", CK_MenuCmd }, - { "CmdChmod", CK_ChmodCmd }, - { "CmdMenuLastSelected", CK_MenuLastSelectedCmd }, - { "CmdSingleDirsize", CK_SingleDirsizeCmd }, - { "CmdCopyCurrentPathname", CK_CopyCurrentPathname }, - { "CmdCopyOtherPathname", CK_CopyOtherPathname }, - { "CmdSuspend", CK_SuspendCmd }, - { "CmdToggleListing", CK_ToggleListingCmd }, - { "CmdChownAdvanced", CK_ChownAdvancedCmd }, - { "CmdChown", CK_ChownCmd }, - { "CmdCompareDirs", CK_CompareDirsCmd }, - { "CmdConfigureBox", CK_ConfigureBox }, - { "CmdConfigureVfs", CK_ConfigureVfs }, - { "CmdConfirmBox", CK_ConfirmBox }, - { "CmdCopy", CK_CopyCmd }, - { "CmdDelete", CK_DeleteCmd }, - { "CmdDirsizes", CK_DirsizesCmd }, - { "CmdDisplayBitsBox", CK_DisplayBitsBox }, - { "CmdEdit", CK_EditCmd }, -#ifdef USE_INTERNAL_EDIT - { "CmdEditForceInternal", CK_EditForceInternalCmd }, -#endif - { "CmdEditExtFile", CK_EditExtFileCmd }, - { "CmdEditFhlFile", CK_EditFhlFileCmd }, - { "CmdEditMcMenu", CK_EditMcMenuCmd }, - { "CmdEditSymlink", CK_EditSymlinkCmd }, - { "CmdEditSyntax", CK_EditSyntaxCmd }, - { "CmdEditUserMenu", CK_EditUserMenuCmd }, - { "CmdExternalPanelize", CK_ExternalPanelize }, - { "CmdFilter", CK_FilterCmd }, - { "CmdFilteredView", CK_FilteredViewCmd }, - { "CmdFind", CK_FindCmd }, -#ifdef ENABLE_VFS_FISH - { "CmdFishlink", CK_FishlinkCmd }, -#endif -#ifdef ENABLE_VFS_FTP - { "CmdFtplink", CK_FtplinkCmd }, -#endif - { "CmdHistory", CK_HistoryCmd }, - { "CmdInfo", CK_InfoCmd }, -#ifdef WITH_BACKGROUND - { "CmdJobs", CK_JobsCmd }, -#endif - { "CmdLayout", CK_LayoutBox }, - { "CmdLearnKeys", CK_LearnKeys }, - { "CmdLink", CK_LinkCmd }, - { "CmdChangeListing", CK_ChangeListingCmd }, - { "CmdListing", CK_ListingCmd }, -#ifdef LISTMODE_EDITOR - { "CmdListmodeCmd", CK_ListmodeCmd }. -#endif - { "CmdMkdir", CK_MkdirCmd }, - { "CmdPanelOptions", CK_PanelOptionsBox }, - { "CmdQuickCd", CK_QuickCdCmd }, - { "CmdQuickChdir", CK_QuickChdirCmd }, - { "CmdQuickView", CK_QuickViewCmd }, - { "CmdQuietQuit", CK_QuietQuitCmd }, - { "CmdRelativeSymlink", CK_RelativeSymlinkCmd }, - { "CmdRename", CK_RenameCmd }, - { "CmdReread", CK_RereadCmd }, - { "CmdReselectVfs", CK_ReselectVfs }, - { "CmdReverseSelection", CK_ReverseSelectionCmd }, - { "CmdSaveSetup", CK_SaveSetupCmd }, - { "CmdSelect", CK_SelectCmd }, -#ifdef ENABLE_VFS_SMB - { "CmdSmblinkCmd", CK_SmblinkCmd }, -#endif - { "CmdSwapPanel", CK_SwapCmd }, - { "CmdSymlink", CK_SymlinkCmd }, - { "CmdTree", CK_TreeCmd }, - { "CmdTreeBox", CK_TreeBoxCmd }, -#ifdef ENABLE_VFS_UNDELFS - { "CmdUndelete", CK_UndeleteCmd }, -#endif - { "CmdUnselect", CK_UnselectCmd }, - { "CmdUserMenu", CK_UserMenuCmd }, - { "CmdUserFileMenu", CK_UserFileMenuCmd }, - { "CmdView", CK_ViewCmd }, - { "CmdViewFile", CK_ViewFileCmd }, - { "CmdCopyCurrentReadlink", CK_CopyCurrentReadlink }, - { "CmdCopyOtherReadlink", CK_CopyOtherReadlink }, - { "CmdAddHotlist", CK_AddHotlist }, - { "CmdQuit", CK_QuitCmd }, - { "CmdCopyCurrentTagged", CK_CopyCurrentTagged }, - { "CmdCopyOtherTagged", CK_CopyOtherTagged }, - { "CmdToggleShowHidden", CK_ToggleShowHidden }, - { "CmdTogglePanelsSplit", CK_TogglePanelsSplit }, -#ifdef USE_DIFF_VIEW - { "CmdDiffView", CK_DiffViewCmd}, -#endif - { "CmdDialogList", CK_DialogListCmd }, - { "CmdDialogNext", CK_DialogNextCmd }, - { "CmdDialogPrev", CK_DialogPrevCmd }, - - /* panel */ - { "PanelChdirOtherPanel", CK_PanelChdirOtherPanel }, - { "PanelChdirToReadlink", CK_PanelChdirToReadlink }, - { "PanelCopyLocal", CK_PanelCmdCopyLocal }, - { "PanelDeleteLocal", CK_PanelCmdDeleteLocal }, - { "PanelDoEnter", CK_PanelCmdDoEnter }, - { "PanelEditNew", CK_PanelCmdEditNew }, - { "PanelRenameLocal", CK_PanelCmdRenameLocal }, - { "PanelReverseSelection", CK_PanelCmdReverseSelection }, - { "PanelSelect", CK_PanelCmdSelect }, - { "PanelUnselect", CK_PanelCmdUnselect }, - { "PanelViewSimple", CK_PanelCmdViewSimple }, - { "PanelCtrlNextPage", CK_PanelCtrlNextPage }, - { "PanelCtrlPrevPage", CK_PanelCtrlPrevPage }, - { "PanelDirectoryHistoryList", CK_PanelDirectoryHistoryList }, - { "PanelDirectoryHistoryNext", CK_PanelDirectoryHistoryNext }, - { "PanelDirectoryHistoryPrev", CK_PanelDirectoryHistoryPrev }, - { "PanelGotoBottomFile", CK_PanelGotoBottomFile }, - { "PanelGotoMiddleFile", CK_PanelGotoMiddleFile }, - { "PanelGotoTopFile", CK_PanelGotoTopFile }, - { "PanelMarkFile", CK_PanelMarkFile }, - { "PanelMarkFileDown", CK_PanelMarkFileDown }, - { "PanelMarkFileUp", CK_PanelMarkFileUp }, - { "PanelMoveUp", CK_PanelMoveUp }, - { "PanelMoveDown", CK_PanelMoveDown }, - { "PanelMoveLeft", CK_PanelMoveLeft }, - { "PanelMoveRight", CK_PanelMoveRight }, - { "PanelMoveEnd", CK_PanelMoveEnd }, - { "PanelMoveHome", CK_PanelMoveHome }, - { "PanelNextPage", CK_PanelNextPage }, - { "PanelPrevPage", CK_PanelPrevPage }, -#ifdef HAVE_CHARSET - { "PanelSetPanelEncoding", CK_PanelSetPanelEncoding }, -#endif - { "PanelStartSearch", CK_PanelStartSearch }, - { "PanelSyncOtherPanel", CK_PanelSyncOtherPanel }, - { "PanelToggleSortOrderNext", CK_PanelToggleSortOrderNext }, - { "PanelToggleSortOrderPrev", CK_PanelToggleSortOrderPrev }, - { "PanelSelectSortOrder", CK_PanelSelectSortOrder }, - { "PanelReverseSort", CK_PanelReverseSort }, - { "PanelSortOrderByName", CK_PanelSortOrderByName }, - { "PanelSortOrderByExt", CK_PanelSortOrderByExt }, - { "PanelSortOrderBySize", CK_PanelSortOrderBySize }, - { "PanelSortOrderByMTime", CK_PanelSortOrderByMTime }, - - /* input line */ - { "InputBol", CK_InputBol }, - { "InputEol", CK_InputEol }, - { "InputMoveLeft", CK_InputMoveLeft }, - { "InputWordLeft", CK_InputWordLeft }, - { "InputBackwardChar", CK_InputBackwardChar }, - { "InputBackwardWord", CK_InputBackwardWord }, - { "InputMoveRight", CK_InputMoveRight }, - { "InputWordRight", CK_InputWordRight }, - { "InputForwardChar", CK_InputForwardChar }, - { "InputForwardWord", CK_InputForwardWord }, - { "InputBackwardDelete", CK_InputBackwardDelete }, - { "InputDeleteChar", CK_InputDeleteChar }, - { "InputKillWord", CK_InputKillWord }, - { "InputBackwardKillWord", CK_InputBackwardKillWord }, - { "InputSetMark", CK_InputSetMark }, - { "InputKillRegion", CK_InputKillRegion }, - { "InputYank", CK_InputYank }, - { "InputKillLine", CK_InputKillLine }, - { "InputHistoryPrev", CK_InputHistoryPrev }, - { "InputHistoryNext", CK_InputHistoryNext }, - { "InputHistoryShow", CK_InputHistoryShow }, - { "InputComplete", CK_InputComplete }, - { "InputXCut", CK_InputKillSave }, - { "InputXStore", CK_InputCopyRegion }, - { "InputXPaste", CK_InputPaste }, - { "InputClearLine", CK_InputClearLine }, - { "InputLeftHighlight", CK_InputLeftHighlight }, - { "InputRightHighlight", CK_InputRightHighlight }, - { "InputWordLeftHighlight", CK_InputWordLeftHighlight }, - { "InputWordRightHighlight", CK_InputWordRightHighlight }, - { "InputBolHighlight", CK_InputBolHighlight }, - { "InputEolHighlight", CK_InputEolHighlight }, - - /* listbox */ - { "ListboxMoveUp", CK_ListboxMoveUp }, - { "ListboxMoveDown", CK_ListboxMoveDown }, - { "ListboxMoveHome", CK_ListboxMoveHome }, - { "ListboxMoveEnd", CK_ListboxMoveEnd }, - { "ListboxMovePgUp", CK_ListboxMovePgUp }, - { "ListboxMovePgDn", CK_ListboxMovePgDn }, - { "ListboxDeleteItem", CK_ListboxDeleteItem }, - { "ListboxDeleteAll", CK_ListboxDeleteAll }, - - /* common */ - { "ExtMap1", CK_StartExtMap1 }, - { "ExtMap2", CK_StartExtMap2 }, - { "ShowCommandLine", CK_ShowCommandLine }, - { "SelectCodepage", CK_SelectCodepage }, - - /* dialog */ - { "DialogOK", CK_DialogOK }, - { "DialogCancel", CK_DialogCancel }, - { "DialogPrevItem", CK_DialogPrevItem }, - { "DialogNextItem", CK_DialogNextItem }, - { "DialogHelp", CK_DialogHelp }, - { "DialogSuspend", CK_DialogSuspend }, - { "DialogRefresh", CK_DialogRefresh }, - -#ifdef USE_DIFF_VIEW - /* diff viewer */ - { "DiffDisplaySymbols", CK_DiffDisplaySymbols}, - { "DiffDisplayNumbers", CK_DiffDisplayNumbers}, - { "DiffFull", CK_DiffFull}, - { "DiffEqual", CK_DiffEqual}, - { "DiffSplitMore", CK_DiffSplitMore}, - { "DiffSplitLess", CK_DiffSplitLess}, - { "DiffShowDiff", CK_DiffShowDiff}, - { "DiffSetTab2", CK_DiffSetTab2}, - { "DiffSetTab3", CK_DiffSetTab3}, - { "DiffSetTab4", CK_DiffSetTab4}, - { "DiffSetTab8", CK_DiffSetTab8}, - { "DiffSwapPanel", CK_DiffSwapPanel}, - { "DiffRedo", CK_DiffRedo}, - { "DiffNextHunk", CK_DiffNextHunk}, - { "DiffPrevHunk", CK_DiffPrevHunk}, - { "DiffGoto", CK_DiffGoto}, - { "DiffEditCurrent", CK_DiffEditCurrent}, - { "DiffEditOther", CK_DiffEditOther}, - { "DiffSearch", CK_DiffSearch}, - { "DiffContinueSearch", CK_DiffContinueSearch}, - { "DiffEOF", CK_DiffEOF}, - { "DiffBOF", CK_DiffBOF}, - { "DiffDown", CK_DiffDown}, - { "DiffUp", CK_DiffUp}, - { "DiffLeft", CK_DiffLeft}, - { "DiffRight", CK_DiffRight}, - { "DiffPageDown", CK_DiffPageDown}, - { "DiffPageUp", CK_DiffPageUp}, - { "DiffHome", CK_DiffHome}, - { "DiffEnd", CK_DiffEnd}, - { "DiffQuit", CK_DiffQuit}, - { "DiffHelp", CK_DiffHelp}, - { "SelectCodepage", CK_SelectCodepage}, - { "DiffMergeCurrentHunk", CK_DiffMergeCurrentHunk}, - { "DiffSave", CK_DiffSave}, - { "DiffOptions", CK_DiffOptions}, -#endif - - { NULL, CK_Ignore_Key } -}; - -static const size_t num_command_names = sizeof (command_names) / - sizeof (command_names[0]) - 1; - /*** global variables ****************************************************************************/ /* viewer/actions_cmd.c */ const global_keymap_t default_viewer_keymap[] = { - { KEY_F (1), CK_ViewHelp, "F1" }, - { KEY_F (2), CK_ViewToggleWrapMode, "F2" }, - { KEY_F (3), CK_ViewQuit, "F3" }, - { KEY_F (4), CK_ViewToggleHexMode, "F4" }, - { KEY_F (5), CK_ViewGoto, "F5" }, - { KEY_F (7), CK_ViewSearch, "F7" }, - { KEY_F (8), CK_ViewToggleMagicMode, "F8" }, - { KEY_F (9), CK_ViewToggleNroffMode, "F9" }, - { KEY_F (10), CK_ViewQuit, "F10" }, + {KEY_F (1), CK_ViewHelp, "F1"}, + {KEY_F (2), CK_ViewToggleWrapMode, "F2"}, + {KEY_F (3), CK_ViewQuit, "F3"}, + {KEY_F (4), CK_ViewToggleHexMode, "F4"}, + {KEY_F (5), CK_ViewGoto, "F5"}, + {KEY_F (7), CK_ViewSearch, "F7"}, + {KEY_F (8), CK_ViewToggleMagicMode, "F8"}, + {KEY_F (9), CK_ViewToggleNroffMode, "F9"}, + {KEY_F (10), CK_ViewQuit, "F10"}, - { '?', CK_ViewSearch, "?" }, - { '/', CK_ViewSearch, "/" }, - { XCTRL ('r'), CK_ViewContinueSearch, "C-r" }, - { XCTRL ('s'), CK_ViewContinueSearch, "C-s" }, - { KEY_F (17), CK_ViewContinueSearch, "S-F7" }, - { 'n', CK_ViewContinueSearch, "n" }, - { ALT ('r'), CK_ViewToggleRuler, "M-r" }, + {'?', CK_ViewSearch, "?"}, + {'/', CK_ViewSearch, "/"}, + {XCTRL ('r'), CK_ViewContinueSearch, "C-r"}, + {XCTRL ('s'), CK_ViewContinueSearch, "C-s"}, + {KEY_F (17), CK_ViewContinueSearch, "S-F7"}, + {'n', CK_ViewContinueSearch, "n"}, + {ALT ('r'), CK_ViewToggleRuler, "M-r"}, - { XCTRL ('a'), CK_ViewMoveToBol, "C-a" }, - { XCTRL ('e'), CK_ViewMoveToEol, "C-e" }, + {XCTRL ('a'), CK_ViewMoveToBol, "C-a"}, + {XCTRL ('e'), CK_ViewMoveToEol, "C-e"}, - { 'h', CK_ViewMoveLeft, "h" }, - { KEY_LEFT, CK_ViewMoveLeft, "Left" }, + {'h', CK_ViewMoveLeft, "h"}, + {KEY_LEFT, CK_ViewMoveLeft, "Left"}, - { 'l', CK_ViewMoveRight, "l" }, - { KEY_RIGHT, CK_ViewMoveRight, "Right" }, + {'l', CK_ViewMoveRight, "l"}, + {KEY_RIGHT, CK_ViewMoveRight, "Right"}, - { KEY_M_CTRL | KEY_LEFT, CK_ViewMoveLeft10, "C-Left" }, - { KEY_M_CTRL | KEY_RIGHT, CK_ViewMoveRight10, "C-Right" }, + {KEY_M_CTRL | KEY_LEFT, CK_ViewMoveLeft10, "C-Left"}, + {KEY_M_CTRL | KEY_RIGHT, CK_ViewMoveRight10, "C-Right"}, - { 'k', CK_ViewMoveUp, "k" }, - { 'y', CK_ViewMoveUp, "y" }, - { XCTRL ('p'), CK_ViewMoveUp, "C-p" }, - { KEY_IC, CK_ViewMoveUp, "Insert" }, - { KEY_UP, CK_ViewMoveUp, "Up" }, + {'k', CK_ViewMoveUp, "k"}, + {'y', CK_ViewMoveUp, "y"}, + {XCTRL ('p'), CK_ViewMoveUp, "C-p"}, + {KEY_IC, CK_ViewMoveUp, "Insert"}, + {KEY_UP, CK_ViewMoveUp, "Up"}, - { 'j', CK_ViewMoveDown, "j" }, - { 'e', CK_ViewMoveDown, "e" }, - { XCTRL ('n'), CK_ViewMoveUp, "C-n" }, - { KEY_DOWN, CK_ViewMoveDown, "Down" }, - { KEY_DC, CK_ViewMoveDown, "Delete" }, - { '\n', CK_ViewMoveDown, "Endter" }, + {'j', CK_ViewMoveDown, "j"}, + {'e', CK_ViewMoveDown, "e"}, + {XCTRL ('n'), CK_ViewMoveUp, "C-n"}, + {KEY_DOWN, CK_ViewMoveDown, "Down"}, + {KEY_DC, CK_ViewMoveDown, "Delete"}, + {'\n', CK_ViewMoveDown, "Endter"}, - { ' ', CK_ViewMovePgDn, "Space" }, - { 'f', CK_ViewMovePgDn, "f" }, - { KEY_NPAGE, CK_ViewMovePgDn, "PgDn" }, - { XCTRL ('v'), CK_ViewMovePgDn, "C-v" }, + {' ', CK_ViewMovePgDn, "Space"}, + {'f', CK_ViewMovePgDn, "f"}, + {KEY_NPAGE, CK_ViewMovePgDn, "PgDn"}, + {XCTRL ('v'), CK_ViewMovePgDn, "C-v"}, - { 'b', CK_ViewMovePgUp, "b" }, - { KEY_PPAGE, CK_ViewMovePgUp, "PgUp" }, - { ALT ('v'), CK_ViewMovePgUp, "M-v" }, - { KEY_BACKSPACE, CK_ViewMovePgUp, "BackSpace" }, + {'b', CK_ViewMovePgUp, "b"}, + {KEY_PPAGE, CK_ViewMovePgUp, "PgUp"}, + {ALT ('v'), CK_ViewMovePgUp, "M-v"}, + {KEY_BACKSPACE, CK_ViewMovePgUp, "BackSpace"}, - { 'd', CK_ViewMoveHalfPgDn, "d" }, - { 'u', CK_ViewMoveHalfPgUp, "u" }, + {'d', CK_ViewMoveHalfPgDn, "d"}, + {'u', CK_ViewMoveHalfPgUp, "u"}, - { KEY_HOME, CK_ViewMoveTop, "Home" }, - { KEY_M_CTRL | KEY_HOME, CK_ViewMoveTop, "C-Home" }, - { KEY_M_CTRL | KEY_PPAGE, CK_ViewMoveTop, "C-PgUp" }, - { KEY_A1, CK_ViewMoveTop, "A1" }, - { ALT ('<'), CK_ViewMoveTop, "M-<" }, - { 'g', CK_ViewMoveTop, "g" }, + {KEY_HOME, CK_ViewMoveTop, "Home"}, + {KEY_M_CTRL | KEY_HOME, CK_ViewMoveTop, "C-Home"}, + {KEY_M_CTRL | KEY_PPAGE, CK_ViewMoveTop, "C-PgUp"}, + {KEY_A1, CK_ViewMoveTop, "A1"}, + {ALT ('<'), CK_ViewMoveTop, "M-<"}, + {'g', CK_ViewMoveTop, "g"}, - { KEY_END, CK_ViewMoveBottom, "End" }, - { KEY_M_CTRL | KEY_END, CK_ViewMoveBottom, "C-End" }, - { KEY_M_CTRL | KEY_NPAGE, CK_ViewMoveBottom, "C-PgDn" }, - { KEY_C1, CK_ViewMoveBottom, "C1" }, - { ALT ('>'), CK_ViewMoveBottom, "M->" }, - { 'G', CK_ViewMoveBottom, "G" }, + {KEY_END, CK_ViewMoveBottom, "End"}, + {KEY_M_CTRL | KEY_END, CK_ViewMoveBottom, "C-End"}, + {KEY_M_CTRL | KEY_NPAGE, CK_ViewMoveBottom, "C-PgDn"}, + {KEY_C1, CK_ViewMoveBottom, "C1"}, + {ALT ('>'), CK_ViewMoveBottom, "M->"}, + {'G', CK_ViewMoveBottom, "G"}, - { 'm', CK_ViewGotoBookmark, "m" }, - { 'r', CK_ViewNewBookmark, "r" }, + {'m', CK_ViewGotoBookmark, "m"}, + {'r', CK_ViewNewBookmark, "r"}, - { XCTRL ('f'), CK_ViewNextFile, "C-f" }, - { XCTRL ('b'), CK_ViewPrevFile, "C-b" }, + {XCTRL ('f'), CK_ViewNextFile, "C-f"}, + {XCTRL ('b'), CK_ViewPrevFile, "C-b"}, - { 'q', CK_ViewQuit, "q" }, - { XCTRL ('g'), CK_ViewQuit, "C-g" }, - { ESC_CHAR, CK_ViewQuit, "Esc" }, + {'q', CK_ViewQuit, "q"}, + {XCTRL ('g'), CK_ViewQuit, "C-g"}, + {ESC_CHAR, CK_ViewQuit, "Esc"}, - { ALT ('e'), CK_SelectCodepage, "M-e" }, - { XCTRL ('o'), CK_ShowCommandLine, "C-o" }, + {ALT ('e'), CK_SelectCodepage, "M-e"}, + {XCTRL ('o'), CK_ShowCommandLine, "C-o"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; const global_keymap_t default_viewer_hex_keymap[] = { - { KEY_F (1), CK_ViewHelp, "F1" }, - { KEY_F (2), CK_ViewToggleHexEditMode, "F2" }, - { KEY_F (3), CK_ViewQuit, "F3" }, - { KEY_F (4), CK_ViewToggleHexMode, "F4" }, - { KEY_F (5), CK_ViewGoto, "F5" }, - { KEY_F (6), CK_ViewHexEditSave, "F6" }, - { KEY_F (7), CK_ViewSearch, "F7" }, - { KEY_F (8), CK_ViewToggleMagicMode, "F8" }, - { KEY_F (9), CK_ViewToggleNroffMode, "F9" }, - { KEY_F (10), CK_ViewQuit, "F10" }, + {KEY_F (1), CK_ViewHelp, "F1"}, + {KEY_F (2), CK_ViewToggleHexEditMode, "F2"}, + {KEY_F (3), CK_ViewQuit, "F3"}, + {KEY_F (4), CK_ViewToggleHexMode, "F4"}, + {KEY_F (5), CK_ViewGoto, "F5"}, + {KEY_F (6), CK_ViewHexEditSave, "F6"}, + {KEY_F (7), CK_ViewSearch, "F7"}, + {KEY_F (8), CK_ViewToggleMagicMode, "F8"}, + {KEY_F (9), CK_ViewToggleNroffMode, "F9"}, + {KEY_F (10), CK_ViewQuit, "F10"}, - { '?', CK_ViewSearch, "?" }, - { '/', CK_ViewSearch, "/" }, - { XCTRL ('r'), CK_ViewContinueSearch, "C-r" }, - { XCTRL ('s'), CK_ViewContinueSearch, "C-s" }, - { KEY_F (17), CK_ViewContinueSearch, "S-F7" }, - { 'n', CK_ViewContinueSearch, "n" }, + {'?', CK_ViewSearch, "?"}, + {'/', CK_ViewSearch, "/"}, + {XCTRL ('r'), CK_ViewContinueSearch, "C-r"}, + {XCTRL ('s'), CK_ViewContinueSearch, "C-s"}, + {KEY_F (17), CK_ViewContinueSearch, "S-F7"}, + {'n', CK_ViewContinueSearch, "n"}, - { '\t', CK_ViewToggleHexNavMode, "Tab" }, - { XCTRL ('a'), CK_ViewMoveToBol, "C-a" }, - { XCTRL ('e'), CK_ViewMoveToEol, "C-e" }, + {'\t', CK_ViewToggleHexNavMode, "Tab"}, + {XCTRL ('a'), CK_ViewMoveToBol, "C-a"}, + {XCTRL ('e'), CK_ViewMoveToEol, "C-e"}, - { 'b', CK_ViewMoveLeft, "b" }, - { KEY_LEFT, CK_ViewMoveLeft, "Left" }, + {'b', CK_ViewMoveLeft, "b"}, + {KEY_LEFT, CK_ViewMoveLeft, "Left"}, - { 'f', CK_ViewMoveRight, "f" }, - { KEY_RIGHT, CK_ViewMoveRight, "Right" }, + {'f', CK_ViewMoveRight, "f"}, + {KEY_RIGHT, CK_ViewMoveRight, "Right"}, - { 'k', CK_ViewMoveUp, "k" }, - { 'y', CK_ViewMoveUp, "y" }, - { KEY_UP, CK_ViewMoveUp, "Up" }, + {'k', CK_ViewMoveUp, "k"}, + {'y', CK_ViewMoveUp, "y"}, + {KEY_UP, CK_ViewMoveUp, "Up"}, - { 'j', CK_ViewMoveDown, "j" }, - { KEY_DOWN, CK_ViewMoveDown, "Down" }, - { KEY_DC, CK_ViewMoveDown, "Delete" }, + {'j', CK_ViewMoveDown, "j"}, + {KEY_DOWN, CK_ViewMoveDown, "Down"}, + {KEY_DC, CK_ViewMoveDown, "Delete"}, - { KEY_NPAGE, CK_ViewMovePgDn, "PgDn" }, - { XCTRL ('v'), CK_ViewMovePgDn, "C-v" }, + {KEY_NPAGE, CK_ViewMovePgDn, "PgDn"}, + {XCTRL ('v'), CK_ViewMovePgDn, "C-v"}, - { KEY_PPAGE, CK_ViewMovePgUp, "PgUp" }, - { ALT ('v'), CK_ViewMovePgUp, "M-v" }, + {KEY_PPAGE, CK_ViewMovePgUp, "PgUp"}, + {ALT ('v'), CK_ViewMovePgUp, "M-v"}, - { KEY_HOME, CK_ViewMoveTop, "Home" }, - { KEY_M_CTRL | KEY_HOME, CK_ViewMoveTop, "C-Home" }, - { KEY_M_CTRL | KEY_PPAGE, CK_ViewMoveTop, "C-PgUp" }, - { KEY_A1, CK_ViewMoveTop, "A1" }, - { ALT ('<'), CK_ViewMoveTop, "M-<" }, - { 'g', CK_ViewMoveTop, "g" }, + {KEY_HOME, CK_ViewMoveTop, "Home"}, + {KEY_M_CTRL | KEY_HOME, CK_ViewMoveTop, "C-Home"}, + {KEY_M_CTRL | KEY_PPAGE, CK_ViewMoveTop, "C-PgUp"}, + {KEY_A1, CK_ViewMoveTop, "A1"}, + {ALT ('<'), CK_ViewMoveTop, "M-<"}, + {'g', CK_ViewMoveTop, "g"}, - { KEY_END, CK_ViewMoveBottom, "End" }, - { KEY_M_CTRL | KEY_END, CK_ViewMoveBottom, "C-End" }, - { KEY_M_CTRL | KEY_NPAGE, CK_ViewMoveBottom, "C-PgDn" }, - { KEY_C1, CK_ViewMoveBottom, "C1" }, - { ALT ('>'), CK_ViewMoveBottom, "M->" }, - { 'G', CK_ViewMoveBottom, "G" }, + {KEY_END, CK_ViewMoveBottom, "End"}, + {KEY_M_CTRL | KEY_END, CK_ViewMoveBottom, "C-End"}, + {KEY_M_CTRL | KEY_NPAGE, CK_ViewMoveBottom, "C-PgDn"}, + {KEY_C1, CK_ViewMoveBottom, "C1"}, + {ALT ('>'), CK_ViewMoveBottom, "M->"}, + {'G', CK_ViewMoveBottom, "G"}, - { 'q', CK_ViewQuit, "q" }, - { XCTRL ('g'), CK_ViewQuit, "C-g" }, - { ESC_CHAR, CK_ViewQuit, "Esc" }, + {'q', CK_ViewQuit, "q"}, + {XCTRL ('g'), CK_ViewQuit, "C-g"}, + {ESC_CHAR, CK_ViewQuit, "Esc"}, - { ALT ('e'), CK_SelectCodepage, "M-e" }, - { XCTRL ('o'), CK_ShowCommandLine, "C-o" }, + {ALT ('e'), CK_SelectCodepage, "M-e"}, + {XCTRL ('o'), CK_ShowCommandLine, "C-o"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; #ifdef USE_INTERNAL_EDIT /* ../edit/editkeys.c */ const global_keymap_t default_editor_keymap[] = { - { '\n', CK_Enter, "Enter" }, - { '\t', CK_Tab, "Tab" }, + {'\n', CK_Enter, "Enter"}, + {'\t', CK_Tab, "Tab"}, - { KEY_F (1), CK_Help, "F1" }, - { KEY_F (2), CK_Save, "F2" }, - { KEY_F (3), CK_Mark, "F3" }, - { KEY_F (4), CK_Replace, "F4" }, - { KEY_F (5), CK_Copy, "F5" }, - { KEY_F (6), CK_Move, "F6" }, - { KEY_F (7), CK_Find, "F7" }, - { KEY_F (8), CK_Remove, "F8" }, - { KEY_F (9), CK_Menu, "F9" }, - { KEY_F (10), CK_Quit, "F10" }, + {KEY_F (1), CK_Help, "F1"}, + {KEY_F (2), CK_Save, "F2"}, + {KEY_F (3), CK_Mark, "F3"}, + {KEY_F (4), CK_Replace, "F4"}, + {KEY_F (5), CK_Copy, "F5"}, + {KEY_F (6), CK_Move, "F6"}, + {KEY_F (7), CK_Find, "F7"}, + {KEY_F (8), CK_Remove, "F8"}, + {KEY_F (9), CK_Menu, "F9"}, + {KEY_F (10), CK_Quit, "F10"}, /* edit user menu */ - { KEY_F (11), CK_User_Menu, "S-F1" }, - { KEY_F (12), CK_Save_As, "S-F2" }, - { KEY_F (13), CK_Column_Mark, "S-F3" }, - { KEY_F (14), CK_Replace_Again, "S-F4" }, - { KEY_F (15), CK_Insert_File, "S-F5" }, - { KEY_F (17), CK_Find_Again, "S-F7" }, + {KEY_F (11), CK_User_Menu, "S-F1"}, + {KEY_F (12), CK_Save_As, "S-F2"}, + {KEY_F (13), CK_Column_Mark, "S-F3"}, + {KEY_F (14), CK_Replace_Again, "S-F4"}, + {KEY_F (15), CK_Insert_File, "S-F5"}, + {KEY_F (17), CK_Find_Again, "S-F7"}, /* C formatter */ - { KEY_F (19), CK_Pipe_Block (0), "S-F9" }, + {KEY_F (19), CK_Pipe_Block (0), "S-F9"}, - { ESC_CHAR, CK_Quit, "Esc" }, - { KEY_BACKSPACE, CK_BackSpace, "BackSpace" }, - { KEY_DC, CK_Delete, "Delete" }, - { KEY_DOWN, CK_Down, "Down" }, - { KEY_END, CK_End, "End" }, - { KEY_HOME, CK_Home, "Home" }, - { KEY_IC, CK_Toggle_Insert, "Insert" }, - { KEY_LEFT, CK_Left, "Left" }, - { KEY_NPAGE, CK_Page_Down, "PgDn" }, - { KEY_PPAGE, CK_Page_Up, "PgUp" }, - { KEY_RIGHT, CK_Right, "Right" }, - { KEY_UP, CK_Up, "Up" }, + {ESC_CHAR, CK_Quit, "Esc"}, + {KEY_BACKSPACE, CK_BackSpace, "BackSpace"}, + {KEY_DC, CK_Delete, "Delete"}, + {KEY_DOWN, CK_Down, "Down"}, + {KEY_END, CK_End, "End"}, + {KEY_HOME, CK_Home, "Home"}, + {KEY_IC, CK_Toggle_Insert, "Insert"}, + {KEY_LEFT, CK_Left, "Left"}, + {KEY_NPAGE, CK_Page_Down, "PgDn"}, + {KEY_PPAGE, CK_Page_Up, "PgUp"}, + {KEY_RIGHT, CK_Right, "Right"}, + {KEY_UP, CK_Up, "Up"}, /* Ctrl */ - { KEY_M_CTRL | (KEY_F (2)), CK_Save_As, "C-F2" }, - { KEY_M_CTRL | (KEY_F (4)), CK_Replace_Again, "C-F4" }, - { KEY_M_CTRL | (KEY_F (7)), CK_Find_Again, "C-F7" }, - { KEY_M_CTRL | KEY_BACKSPACE, CK_Undo, "C-BackSpace" }, - { KEY_M_CTRL | KEY_NPAGE, CK_End_Of_Text, "C-PgDn" }, - { KEY_M_CTRL | KEY_PPAGE, CK_Beginning_Of_Text, "C-PgUp" }, - { KEY_M_CTRL | KEY_HOME, CK_Beginning_Of_Text, "C-Home" }, - { KEY_M_CTRL | KEY_END, CK_End_Of_Text, "C-End" }, - { KEY_M_CTRL | KEY_UP, CK_Scroll_Up, "C-Up" }, - { KEY_M_CTRL | KEY_DOWN, CK_Scroll_Down, "C-Down" }, - { KEY_M_CTRL | KEY_LEFT, CK_Word_Left, "C-Left" }, - { XCTRL ('z'), CK_Word_Left, "C-z" }, - { KEY_M_CTRL | KEY_RIGHT, CK_Word_Right, "C-Right" }, - { XCTRL ('x'), CK_Word_Right, "C-x" }, - { KEY_M_CTRL | KEY_IC, CK_XStore, "C-Insert" }, - { KEY_M_CTRL | KEY_DC, CK_Remove, "C-Delete" }, + {KEY_M_CTRL | (KEY_F (2)), CK_Save_As, "C-F2"}, + {KEY_M_CTRL | (KEY_F (4)), CK_Replace_Again, "C-F4"}, + {KEY_M_CTRL | (KEY_F (7)), CK_Find_Again, "C-F7"}, + {KEY_M_CTRL | KEY_BACKSPACE, CK_Undo, "C-BackSpace"}, + {KEY_M_CTRL | KEY_NPAGE, CK_End_Of_Text, "C-PgDn"}, + {KEY_M_CTRL | KEY_PPAGE, CK_Beginning_Of_Text, "C-PgUp"}, + {KEY_M_CTRL | KEY_HOME, CK_Beginning_Of_Text, "C-Home"}, + {KEY_M_CTRL | KEY_END, CK_End_Of_Text, "C-End"}, + {KEY_M_CTRL | KEY_UP, CK_Scroll_Up, "C-Up"}, + {KEY_M_CTRL | KEY_DOWN, CK_Scroll_Down, "C-Down"}, + {KEY_M_CTRL | KEY_LEFT, CK_Word_Left, "C-Left"}, + {XCTRL ('z'), CK_Word_Left, "C-z"}, + {KEY_M_CTRL | KEY_RIGHT, CK_Word_Right, "C-Right"}, + {XCTRL ('x'), CK_Word_Right, "C-x"}, + {KEY_M_CTRL | KEY_IC, CK_XStore, "C-Insert"}, + {KEY_M_CTRL | KEY_DC, CK_Remove, "C-Delete"}, - { XCTRL ('n'), CK_New, "C-n" }, - { XCTRL ('k'), CK_Delete_To_Line_End, "C-k" }, - { XCTRL ('l'), CK_Refresh, "C-l" }, - { XCTRL ('o'), CK_Shell, "C-o" }, - { XCTRL ('s'), CK_Toggle_Syntax, "C-s" }, - { XCTRL ('u'), CK_Undo, "C-u" }, - { ALT ('e'), CK_SelectCodepage, "M-e" }, - { XCTRL ('q'), CK_Insert_Literal, "C-q" }, - { XCTRL ('r'), CK_Begin_End_Macro, "C-r" }, - { XCTRL ('r'), CK_Begin_Record_Macro, "C-r" }, - { XCTRL ('r'), CK_End_Record_Macro, "C-r" }, - { XCTRL ('a'), CK_Execute_Macro, "C-a" }, - { XCTRL ('f'), CK_Save_Block, "C-f" }, + {XCTRL ('n'), CK_New, "C-n"}, + {XCTRL ('k'), CK_Delete_To_Line_End, "C-k"}, + {XCTRL ('l'), CK_Refresh, "C-l"}, + {XCTRL ('o'), CK_Shell, "C-o"}, + {XCTRL ('s'), CK_Toggle_Syntax, "C-s"}, + {XCTRL ('u'), CK_Undo, "C-u"}, + {ALT ('e'), CK_SelectCodepage, "M-e"}, + {XCTRL ('q'), CK_Insert_Literal, "C-q"}, + {XCTRL ('r'), CK_Begin_End_Macro, "C-r"}, + {XCTRL ('r'), CK_Begin_Record_Macro, "C-r"}, + {XCTRL ('r'), CK_End_Record_Macro, "C-r"}, + {XCTRL ('a'), CK_Execute_Macro, "C-a"}, + {XCTRL ('f'), CK_Save_Block, "C-f"}, /* Spell check */ - { XCTRL ('p'), CK_Pipe_Block (1), "C-p" }, - { XCTRL ('y'), CK_Delete_Line, "C-y" }, + {XCTRL ('p'), CK_Pipe_Block (1), "C-p"}, + {XCTRL ('y'), CK_Delete_Line, "C-y"}, /* Shift */ - { KEY_M_SHIFT | KEY_NPAGE, CK_Page_Down_Highlight, "S-PgDn" }, - { KEY_M_SHIFT | KEY_PPAGE, CK_Page_Up_Highlight, "S-PgUp" }, - { KEY_M_SHIFT | KEY_LEFT, CK_Left_Highlight, "S-Left" }, - { KEY_M_SHIFT | KEY_RIGHT, CK_Right_Highlight, "S-Right" }, - { KEY_M_SHIFT | KEY_UP, CK_Up_Highlight, "S-Up" }, - { KEY_M_SHIFT | KEY_DOWN, CK_Down_Highlight, "S-Down" }, - { KEY_M_SHIFT | KEY_HOME, CK_Home_Highlight, "S-Home" }, - { KEY_M_SHIFT | KEY_END, CK_End_Highlight, "S-End" }, - { KEY_M_SHIFT | KEY_IC, CK_XPaste, "S-Insert" }, - { KEY_M_SHIFT | KEY_DC, CK_XCut, "S-Delete" }, + {KEY_M_SHIFT | KEY_NPAGE, CK_Page_Down_Highlight, "S-PgDn"}, + {KEY_M_SHIFT | KEY_PPAGE, CK_Page_Up_Highlight, "S-PgUp"}, + {KEY_M_SHIFT | KEY_LEFT, CK_Left_Highlight, "S-Left"}, + {KEY_M_SHIFT | KEY_RIGHT, CK_Right_Highlight, "S-Right"}, + {KEY_M_SHIFT | KEY_UP, CK_Up_Highlight, "S-Up"}, + {KEY_M_SHIFT | KEY_DOWN, CK_Down_Highlight, "S-Down"}, + {KEY_M_SHIFT | KEY_HOME, CK_Home_Highlight, "S-Home"}, + {KEY_M_SHIFT | KEY_END, CK_End_Highlight, "S-End"}, + {KEY_M_SHIFT | KEY_IC, CK_XPaste, "S-Insert"}, + {KEY_M_SHIFT | KEY_DC, CK_XCut, "S-Delete"}, /* useful for pasting multiline text */ - { KEY_M_SHIFT | '\n', CK_Return, "S-Enter" }, + {KEY_M_SHIFT | '\n', CK_Return, "S-Enter"}, /* Ctrl + Shift */ - { KEY_M_SHIFT | KEY_M_CTRL | KEY_NPAGE, CK_End_Of_Text_Highlight, "C-S-PgDn" }, - { KEY_M_SHIFT | KEY_M_CTRL | KEY_PPAGE, CK_Beginning_Of_Text_Highlight, "C-S-PgUp" }, - { KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, CK_Word_Left_Highlight, "C-S-Left" }, - { KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, CK_Word_Right_Highlight, "C-S-Right" }, - { KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, CK_Scroll_Up_Highlight, "C-S-Up" }, - { KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, CK_Scroll_Down_Highlight, "C-S-Down" }, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_NPAGE, CK_End_Of_Text_Highlight, "C-S-PgDn"}, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_PPAGE, CK_Beginning_Of_Text_Highlight, "C-S-PgUp"}, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, CK_Word_Left_Highlight, "C-S-Left"}, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, CK_Word_Right_Highlight, "C-S-Right"}, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, CK_Scroll_Up_Highlight, "C-S-Up"}, + {KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, CK_Scroll_Down_Highlight, "C-S-Down"}, /* Alt */ - { KEY_M_ALT | KEY_NPAGE, CK_Page_Down_Alt_Highlight, "M-PgDn" }, - { KEY_M_ALT | KEY_PPAGE, CK_Page_Up_Alt_Highlight, "M-PgUp" }, - { KEY_M_ALT | KEY_LEFT, CK_Left_Alt_Highlight, "M-Left" }, - { KEY_M_ALT | KEY_RIGHT, CK_Right_Alt_Highlight, "M-Right" }, - { KEY_M_ALT | KEY_UP, CK_Up_Alt_Highlight, "M-Up" }, - { KEY_M_ALT | KEY_DOWN, CK_Down_Alt_Highlight, "M-Down" }, - { KEY_M_ALT | KEY_HOME, CK_Home_Highlight, "M-Home" }, - { KEY_M_ALT | KEY_END, CK_End_Alt_Highlight, "M-End" }, + {KEY_M_ALT | KEY_NPAGE, CK_Page_Down_Alt_Highlight, "M-PgDn"}, + {KEY_M_ALT | KEY_PPAGE, CK_Page_Up_Alt_Highlight, "M-PgUp"}, + {KEY_M_ALT | KEY_LEFT, CK_Left_Alt_Highlight, "M-Left"}, + {KEY_M_ALT | KEY_RIGHT, CK_Right_Alt_Highlight, "M-Right"}, + {KEY_M_ALT | KEY_UP, CK_Up_Alt_Highlight, "M-Up"}, + {KEY_M_ALT | KEY_DOWN, CK_Down_Alt_Highlight, "M-Down"}, + {KEY_M_ALT | KEY_HOME, CK_Home_Highlight, "M-Home"}, + {KEY_M_ALT | KEY_END, CK_End_Alt_Highlight, "M-End"}, - { ALT ('\n'), CK_Find_Definition, "M-Enter" }, - { ALT ('\t'), CK_Complete_Word, "M-Tab" }, - { ALT ('l'), CK_Goto, "M-l" }, - { ALT ('L'), CK_Goto, "M-L" }, - { ALT ('p'), CK_Paragraph_Format, "M-p" }, - { ALT ('t'), CK_Sort, "M-t" }, - { ALT ('u'), CK_ExtCmd, "M-u" }, - { ALT ('<'), CK_Beginning_Of_Text, "M-<" }, - { ALT ('>'), CK_End_Of_Text, "M->" }, - { ALT ('-'), CK_Load_Prev_File, "M--" }, - { ALT ('+'), CK_Load_Next_File, "M-+" }, - { ALT ('d'), CK_Delete_Word_Right, "M-d" }, - { ALT (KEY_BACKSPACE), CK_Delete_Word_Left, "M-BackSpace" }, - { ALT ('n'), CK_Toggle_Line_State, "M-n" }, - { ALT ('_'), CK_Toggle_Tab_TWS, "M-_" }, - { ALT ('k'), CK_Toggle_Bookmark, "M-k" }, - { ALT ('i'), CK_Prev_Bookmark, "M-i" }, - { ALT ('j'), CK_Next_Bookmark, "M-j" }, - { ALT ('o'), CK_Flush_Bookmarks, "M-o" }, - { ALT ('b'), CK_Match_Bracket, "M-b" }, - { ALT ('m'), CK_Mail, "M-m" }, + {ALT ('\n'), CK_Find_Definition, "M-Enter"}, + {ALT ('\t'), CK_Complete_Word, "M-Tab"}, + {ALT ('l'), CK_Goto, "M-l"}, + {ALT ('L'), CK_Goto, "M-L"}, + {ALT ('p'), CK_Paragraph_Format, "M-p"}, + {ALT ('t'), CK_Sort, "M-t"}, + {ALT ('u'), CK_ExtCmd, "M-u"}, + {ALT ('<'), CK_Beginning_Of_Text, "M-<"}, + {ALT ('>'), CK_End_Of_Text, "M->"}, + {ALT ('-'), CK_Load_Prev_File, "M--"}, + {ALT ('+'), CK_Load_Next_File, "M-+"}, + {ALT ('d'), CK_Delete_Word_Right, "M-d"}, + {ALT (KEY_BACKSPACE), CK_Delete_Word_Left, "M-BackSpace"}, + {ALT ('n'), CK_Toggle_Line_State, "M-n"}, + {ALT ('_'), CK_Toggle_Tab_TWS, "M-_"}, + {ALT ('k'), CK_Toggle_Bookmark, "M-k"}, + {ALT ('i'), CK_Prev_Bookmark, "M-i"}, + {ALT ('j'), CK_Next_Bookmark, "M-j"}, + {ALT ('o'), CK_Flush_Bookmarks, "M-o"}, + {ALT ('b'), CK_Match_Bracket, "M-b"}, + {ALT ('m'), CK_Mail, "M-m"}, - { XCTRL ('x'), CK_Ext_Mode, "C-x" }, + {XCTRL ('x'), CK_Ext_Mode, "C-x"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; /* emacs keyboard layout emulation */ const global_keymap_t default_editor_x_keymap[] = { - { 'k', CK_New, "k"}, - { 'e', CK_Execute_Macro, "e"}, - { 0, CK_Ignore_Key, "" } + {'k', CK_New, "k"}, + {'e', CK_Execute_Macro, "e"}, + {0, CK_Ignore_Key, ""} }; -#endif /* USE_INTERNAL_EDIT */ +#endif /* USE_INTERNAL_EDIT */ /* dialog */ const global_keymap_t default_dialog_keymap[] = { - { '\n', CK_DialogOK, "Enter" }, - { KEY_ENTER, CK_DialogOK, "Enter" }, - { ESC_CHAR, CK_DialogCancel, "Esc" }, - { XCTRL('g'), CK_DialogCancel, "C-g" }, - { KEY_F (10), CK_DialogCancel, "F10" }, - { KEY_LEFT, CK_DialogPrevItem, "Left" }, - { KEY_UP, CK_DialogPrevItem, "Up" }, - { KEY_RIGHT, CK_DialogNextItem, "Right" }, - { KEY_DOWN, CK_DialogNextItem, "Down" }, - { KEY_F(1), CK_DialogHelp, "F1" }, - { XCTRL('z'), CK_DialogSuspend, "C-z" }, - { XCTRL('l'), CK_DialogRefresh, "C-l" }, - { 0, CK_Ignore_Key, "" } + {'\n', CK_DialogOK, "Enter"}, + {KEY_ENTER, CK_DialogOK, "Enter"}, + {ESC_CHAR, CK_DialogCancel, "Esc"}, + {XCTRL ('g'), CK_DialogCancel, "C-g"}, + {KEY_F (10), CK_DialogCancel, "F10"}, + {KEY_LEFT, CK_DialogPrevItem, "Left"}, + {KEY_UP, CK_DialogPrevItem, "Up"}, + {KEY_RIGHT, CK_DialogNextItem, "Right"}, + {KEY_DOWN, CK_DialogNextItem, "Down"}, + {KEY_F (1), CK_DialogHelp, "F1"}, + {XCTRL ('z'), CK_DialogSuspend, "C-z"}, + {XCTRL ('l'), CK_DialogRefresh, "C-l"}, + {0, CK_Ignore_Key, ""} }; /* tree */ const global_keymap_t default_tree_keymap[] = { - { KEY_F (1), CK_TreeHelp, "F1"}, - { KEY_F (2), CK_TreeRescan, "F2" }, - { KEY_F (3), CK_TreeForget, "F3" }, - { KEY_F (4), CK_TreeToggleNav, "F4" }, - { KEY_F (5), CK_TreeCopy, "F5" }, - { KEY_F (6), CK_TreeMove, "F6" }, + {KEY_F (1), CK_TreeHelp, "F1"}, + {KEY_F (2), CK_TreeRescan, "F2"}, + {KEY_F (3), CK_TreeForget, "F3"}, + {KEY_F (4), CK_TreeToggleNav, "F4"}, + {KEY_F (5), CK_TreeCopy, "F5"}, + {KEY_F (6), CK_TreeMove, "F6"}, #if 0 - { KEY_F (7), CK_TreeMake, "F7" }, + {KEY_F (7), CK_TreeMake, "F7"}, #endif - { KEY_F (8), CK_TreeRemove, "F8" }, - { KEY_UP, CK_TreeMoveUp, "Up" }, - { XCTRL ('p'), CK_TreeMoveUp, "C-p" }, - { KEY_DOWN, CK_TreeMoveDown, "Down" }, - { XCTRL ('n'), CK_TreeMoveDown, "C-n" }, - { KEY_LEFT, CK_TreeMoveLeft, "Left" }, - { KEY_RIGHT, CK_TreeMoveRight, "Right" }, - { KEY_HOME, CK_TreeMoveHome, "Home" }, - { ALT ('<'), CK_TreeMoveHome, "M-<" }, - { KEY_A1, CK_TreeMoveHome, "A1" }, - { KEY_END, CK_TreeMoveEnd , "End" }, - { ALT ('>'), CK_TreeMoveEnd , "M->" }, - { KEY_C1, CK_TreeMoveEnd , "C1" }, - { KEY_PPAGE, CK_TreeMovePgUp, "PgUp" }, - { ALT ('v'), CK_TreeMovePgUp, "M-v" }, - { KEY_NPAGE, CK_TreeMovePgDn, "PnDn" }, - { XCTRL ('v'), CK_TreeMovePgDn, "C-v" }, - { '\n', CK_TreeOpen, "Enter" }, - { KEY_ENTER, CK_TreeOpen, "Enter" }, - { XCTRL ('r'), CK_TreeRescan, "C-r" }, - { XCTRL ('s'), CK_TreeStartSearch, "C-s" }, - { ALT ('s'), CK_TreeStartSearch, "M-s" }, - { KEY_DC, CK_TreeRemove, "Delete" }, - { 0, CK_Ignore_Key, ""} + {KEY_F (8), CK_TreeRemove, "F8"}, + {KEY_UP, CK_TreeMoveUp, "Up"}, + {XCTRL ('p'), CK_TreeMoveUp, "C-p"}, + {KEY_DOWN, CK_TreeMoveDown, "Down"}, + {XCTRL ('n'), CK_TreeMoveDown, "C-n"}, + {KEY_LEFT, CK_TreeMoveLeft, "Left"}, + {KEY_RIGHT, CK_TreeMoveRight, "Right"}, + {KEY_HOME, CK_TreeMoveHome, "Home"}, + {ALT ('<'), CK_TreeMoveHome, "M-<"}, + {KEY_A1, CK_TreeMoveHome, "A1"}, + {KEY_END, CK_TreeMoveEnd, "End"}, + {ALT ('>'), CK_TreeMoveEnd, "M->"}, + {KEY_C1, CK_TreeMoveEnd, "C1"}, + {KEY_PPAGE, CK_TreeMovePgUp, "PgUp"}, + {ALT ('v'), CK_TreeMovePgUp, "M-v"}, + {KEY_NPAGE, CK_TreeMovePgDn, "PnDn"}, + {XCTRL ('v'), CK_TreeMovePgDn, "C-v"}, + {'\n', CK_TreeOpen, "Enter"}, + {KEY_ENTER, CK_TreeOpen, "Enter"}, + {XCTRL ('r'), CK_TreeRescan, "C-r"}, + {XCTRL ('s'), CK_TreeStartSearch, "C-s"}, + {ALT ('s'), CK_TreeStartSearch, "M-s"}, + {KEY_DC, CK_TreeRemove, "Delete"}, + {0, CK_Ignore_Key, ""} }; /* help */ const global_keymap_t default_help_keymap[] = { - { KEY_F (1), CK_HelpHelp, "F1" }, - { KEY_F (2), CK_HelpIndex, "F2" }, - { KEY_F (3), CK_HelpBack, "F3" }, - { KEY_F (10), CK_HelpQuit, "F10" }, - { KEY_LEFT, CK_HelpBack, "Left" }, - { 'l', CK_HelpBack, "l" }, - { KEY_DOWN, CK_HelpMoveDown, "Down" }, - { XCTRL ('n'), CK_HelpMoveDown, "C-n" }, - { KEY_UP, CK_HelpMoveUp, "Up" }, - { XCTRL ('p'), CK_HelpMoveUp, "C-p" }, - { KEY_NPAGE, CK_HelpMovePgDn, "PgDn" }, - { XCTRL ('v'), CK_HelpMovePgDn, "C-v" }, - { 'f', CK_HelpMovePgDn, "f" }, - { ' ', CK_HelpMovePgDn, "Space" }, - { KEY_PPAGE, CK_HelpMovePgUp, "PgUp" }, - { ALT ('v'), CK_HelpMovePgUp, "M-v" }, - { 'b', CK_HelpMovePgUp, "b" }, - { KEY_BACKSPACE, CK_HelpMovePgUp, "BackSpace" }, - { 'd', CK_HelpMoveHalfPgDn, "d" }, - { 'u', CK_HelpMoveHalfPgUp, "u" }, - { KEY_HOME, CK_HelpMoveTop, "Home" }, - { KEY_M_CTRL | KEY_HOME, CK_HelpMoveTop, "C-Home" }, - { KEY_M_CTRL | KEY_PPAGE, CK_HelpMoveTop, "C-PgUp" }, - { KEY_A1, CK_HelpMoveTop, "A1" }, - { ALT ('<'), CK_HelpMoveTop, "M-<" }, - { 'g', CK_HelpMoveTop, "g" }, - { KEY_END, CK_HelpMoveBottom, "End" }, - { KEY_M_CTRL | KEY_END, CK_HelpMoveBottom, "C-End" }, - { KEY_M_CTRL | KEY_NPAGE, CK_HelpMoveBottom, "C-PgDn" }, - { KEY_C1, CK_HelpMoveBottom, "C1" }, - { ALT ('>'), CK_HelpMoveBottom, "M->" }, - { 'G', CK_HelpMoveBottom, "G" }, - { KEY_RIGHT, CK_HelpSelectLink, "Right" }, - { KEY_ENTER, CK_HelpSelectLink, "Enter" }, - { '\n', CK_HelpSelectLink, "Enter" }, - { '\t', CK_HelpNextLink, "Tab" }, - { ALT ('\t'), CK_HelpPrevLink, "M-Tab" }, - { 'n', CK_HelpNextNode, "n" }, - { 'p', CK_HelpPrevNode, "p" }, - { ESC_CHAR, CK_HelpQuit, "Esc" }, - { XCTRL ('g'), CK_HelpQuit, "C-g" }, - { 0, CK_Ignore_Key, "" } + {KEY_F (1), CK_HelpHelp, "F1"}, + {KEY_F (2), CK_HelpIndex, "F2"}, + {KEY_F (3), CK_HelpBack, "F3"}, + {KEY_F (10), CK_HelpQuit, "F10"}, + {KEY_LEFT, CK_HelpBack, "Left"}, + {'l', CK_HelpBack, "l"}, + {KEY_DOWN, CK_HelpMoveDown, "Down"}, + {XCTRL ('n'), CK_HelpMoveDown, "C-n"}, + {KEY_UP, CK_HelpMoveUp, "Up"}, + {XCTRL ('p'), CK_HelpMoveUp, "C-p"}, + {KEY_NPAGE, CK_HelpMovePgDn, "PgDn"}, + {XCTRL ('v'), CK_HelpMovePgDn, "C-v"}, + {'f', CK_HelpMovePgDn, "f"}, + {' ', CK_HelpMovePgDn, "Space"}, + {KEY_PPAGE, CK_HelpMovePgUp, "PgUp"}, + {ALT ('v'), CK_HelpMovePgUp, "M-v"}, + {'b', CK_HelpMovePgUp, "b"}, + {KEY_BACKSPACE, CK_HelpMovePgUp, "BackSpace"}, + {'d', CK_HelpMoveHalfPgDn, "d"}, + {'u', CK_HelpMoveHalfPgUp, "u"}, + {KEY_HOME, CK_HelpMoveTop, "Home"}, + {KEY_M_CTRL | KEY_HOME, CK_HelpMoveTop, "C-Home"}, + {KEY_M_CTRL | KEY_PPAGE, CK_HelpMoveTop, "C-PgUp"}, + {KEY_A1, CK_HelpMoveTop, "A1"}, + {ALT ('<'), CK_HelpMoveTop, "M-<"}, + {'g', CK_HelpMoveTop, "g"}, + {KEY_END, CK_HelpMoveBottom, "End"}, + {KEY_M_CTRL | KEY_END, CK_HelpMoveBottom, "C-End"}, + {KEY_M_CTRL | KEY_NPAGE, CK_HelpMoveBottom, "C-PgDn"}, + {KEY_C1, CK_HelpMoveBottom, "C1"}, + {ALT ('>'), CK_HelpMoveBottom, "M->"}, + {'G', CK_HelpMoveBottom, "G"}, + {KEY_RIGHT, CK_HelpSelectLink, "Right"}, + {KEY_ENTER, CK_HelpSelectLink, "Enter"}, + {'\n', CK_HelpSelectLink, "Enter"}, + {'\t', CK_HelpNextLink, "Tab"}, + {ALT ('\t'), CK_HelpPrevLink, "M-Tab"}, + {'n', CK_HelpNextNode, "n"}, + {'p', CK_HelpPrevNode, "p"}, + {ESC_CHAR, CK_HelpQuit, "Esc"}, + {XCTRL ('g'), CK_HelpQuit, "C-g"}, + {0, CK_Ignore_Key, ""} }; /* panel */ const global_keymap_t default_panel_keymap[] = { - { ALT ('o'), CK_PanelChdirOtherPanel, "M-o" }, - { ALT ('l'), CK_PanelChdirToReadlink, "M-l" }, - { KEY_F (15), CK_PanelCmdCopyLocal, "S-F5" }, - { KEY_F (18), CK_PanelCmdDeleteLocal, "S-F8" }, - { KEY_ENTER, CK_PanelCmdDoEnter, "Enter" }, - { '\n', CK_PanelCmdDoEnter, "Enter" }, - { KEY_F (14), CK_PanelCmdEditNew, "S-F4" }, - { KEY_F (16), CK_PanelCmdRenameLocal, "S-F6" }, - { ALT ('*'), CK_PanelCmdReverseSelection, "M-*" }, - { KEY_KP_ADD, CK_PanelCmdSelect, "M-+" }, - { KEY_KP_SUBTRACT, CK_PanelCmdUnselect, "M--" }, - { KEY_F (13), CK_PanelCmdViewSimple, "S-F3" }, - { KEY_M_CTRL | KEY_NPAGE, CK_PanelCtrlNextPage, "C-PgDn" }, - { KEY_M_CTRL | KEY_PPAGE, CK_PanelCtrlPrevPage, "C-PgUp" }, - { ALT ('H'), CK_PanelDirectoryHistoryList, "M-H" }, - { ALT ('u'), CK_PanelDirectoryHistoryNext, "M-u" }, - { ALT ('y'), CK_PanelDirectoryHistoryPrev, "M-y" }, - { ALT ('j'), CK_PanelGotoBottomFile, "M-j" }, - { ALT ('r'), CK_PanelGotoMiddleFile, "M-r" }, - { ALT ('g'), CK_PanelGotoTopFile, "M-g" }, - { KEY_IC, CK_PanelMarkFile, "Insert" }, - { KEY_UP, CK_PanelMoveUp, "Up" }, - { KEY_DOWN, CK_PanelMoveDown, "Down" }, - { KEY_LEFT, CK_PanelMoveLeft, "Left" }, - { KEY_RIGHT, CK_PanelMoveRight, "Right" }, - { KEY_END, CK_PanelMoveEnd, "End" }, - { KEY_C1, CK_PanelMoveEnd, "C1" }, - { KEY_HOME, CK_PanelMoveHome, "Home" }, - { KEY_A1, CK_PanelMoveHome, "A1" }, - { KEY_NPAGE, CK_PanelNextPage, "PgDn" }, - { KEY_PPAGE, CK_PanelPrevPage, "PgUp" }, - { ALT ('e'), CK_PanelSetPanelEncoding, "M-e" }, - { XCTRL ('s'), CK_PanelStartSearch, "C-s" }, - { ALT ('s'), CK_PanelStartSearch, "M-s" }, - { ALT ('i'), CK_PanelSyncOtherPanel, "M-i" }, - { 0, CK_Ignore_Key , "" } + {ALT ('o'), CK_PanelChdirOtherPanel, "M-o"}, + {ALT ('l'), CK_PanelChdirToReadlink, "M-l"}, + {KEY_F (15), CK_PanelCmdCopyLocal, "S-F5"}, + {KEY_F (18), CK_PanelCmdDeleteLocal, "S-F8"}, + {KEY_ENTER, CK_PanelCmdDoEnter, "Enter"}, + {'\n', CK_PanelCmdDoEnter, "Enter"}, + {KEY_F (14), CK_PanelCmdEditNew, "S-F4"}, + {KEY_F (16), CK_PanelCmdRenameLocal, "S-F6"}, + {ALT ('*'), CK_PanelCmdReverseSelection, "M-*"}, + {KEY_KP_ADD, CK_PanelCmdSelect, "M-+"}, + {KEY_KP_SUBTRACT, CK_PanelCmdUnselect, "M--"}, + {KEY_F (13), CK_PanelCmdViewSimple, "S-F3"}, + {KEY_M_CTRL | KEY_NPAGE, CK_PanelCtrlNextPage, "C-PgDn"}, + {KEY_M_CTRL | KEY_PPAGE, CK_PanelCtrlPrevPage, "C-PgUp"}, + {ALT ('H'), CK_PanelDirectoryHistoryList, "M-H"}, + {ALT ('u'), CK_PanelDirectoryHistoryNext, "M-u"}, + {ALT ('y'), CK_PanelDirectoryHistoryPrev, "M-y"}, + {ALT ('j'), CK_PanelGotoBottomFile, "M-j"}, + {ALT ('r'), CK_PanelGotoMiddleFile, "M-r"}, + {ALT ('g'), CK_PanelGotoTopFile, "M-g"}, + {KEY_IC, CK_PanelMarkFile, "Insert"}, + {KEY_UP, CK_PanelMoveUp, "Up"}, + {KEY_DOWN, CK_PanelMoveDown, "Down"}, + {KEY_LEFT, CK_PanelMoveLeft, "Left"}, + {KEY_RIGHT, CK_PanelMoveRight, "Right"}, + {KEY_END, CK_PanelMoveEnd, "End"}, + {KEY_C1, CK_PanelMoveEnd, "C1"}, + {KEY_HOME, CK_PanelMoveHome, "Home"}, + {KEY_A1, CK_PanelMoveHome, "A1"}, + {KEY_NPAGE, CK_PanelNextPage, "PgDn"}, + {KEY_PPAGE, CK_PanelPrevPage, "PgUp"}, + {ALT ('e'), CK_PanelSetPanelEncoding, "M-e"}, + {XCTRL ('s'), CK_PanelStartSearch, "C-s"}, + {ALT ('s'), CK_PanelStartSearch, "M-s"}, + {ALT ('i'), CK_PanelSyncOtherPanel, "M-i"}, + {0, CK_Ignore_Key, ""} }; /* main.c */ const global_keymap_t default_main_map[] = { - { KEY_F (1), CK_HelpCmd, "F1" }, - { KEY_F (2), CK_UserMenuCmd, "F2" }, - { KEY_F (3), CK_ViewCmd, "F3" }, - { KEY_F (4), CK_EditCmd, "F4" }, - { KEY_F (5), CK_CopyCmd, "F5" }, - { KEY_F (6), CK_RenameCmd, "F6" }, - { KEY_F (7), CK_MkdirCmd, "F7" }, - { KEY_F (8), CK_DeleteCmd, "F8" }, - { KEY_F (9), CK_MenuCmd, "F9" }, - { KEY_F (10), CK_QuitCmd, "F10" }, - { KEY_F (13), CK_ViewFileCmd, "S-F3" }, - { KEY_F (19), CK_MenuLastSelectedCmd, "S-F9" }, - { KEY_F (20), CK_QuietQuitCmd, "S-10" }, - { ALT ('h'), CK_HistoryCmd, "M-h" }, - { XCTRL ('@'), CK_SingleDirsizeCmd, "C-Space" }, + {KEY_F (1), CK_HelpCmd, "F1"}, + {KEY_F (2), CK_UserMenuCmd, "F2"}, + {KEY_F (3), CK_ViewCmd, "F3"}, + {KEY_F (4), CK_EditCmd, "F4"}, + {KEY_F (5), CK_CopyCmd, "F5"}, + {KEY_F (6), CK_RenameCmd, "F6"}, + {KEY_F (7), CK_MkdirCmd, "F7"}, + {KEY_F (8), CK_DeleteCmd, "F8"}, + {KEY_F (9), CK_MenuCmd, "F9"}, + {KEY_F (10), CK_QuitCmd, "F10"}, + {KEY_F (13), CK_ViewFileCmd, "S-F3"}, + {KEY_F (19), CK_MenuLastSelectedCmd, "S-F9"}, + {KEY_F (20), CK_QuietQuitCmd, "S-10"}, + {ALT ('h'), CK_HistoryCmd, "M-h"}, + {XCTRL ('@'), CK_SingleDirsizeCmd, "C-Space"}, /* Copy useful information to the command line */ - { ALT ('a'), CK_CopyCurrentPathname, "M-a" }, - { ALT ('A'), CK_CopyOtherPathname, "M-A" }, - { ALT ('c'), CK_QuickCdCmd, "M-c" }, + {ALT ('a'), CK_CopyCurrentPathname, "M-a"}, + {ALT ('A'), CK_CopyOtherPathname, "M-A"}, + {ALT ('c'), CK_QuickCdCmd, "M-c"}, /* To access the directory hotlist */ - { XCTRL ('\\'), CK_QuickChdirCmd, "C-\\" }, + {XCTRL ('\\'), CK_QuickChdirCmd, "C-\\"}, /* Suspend */ - { XCTRL ('z'), CK_SuspendCmd, "C-z" }, + {XCTRL ('z'), CK_SuspendCmd, "C-z"}, /* The filtered view command */ - { ALT ('!'), CK_FilteredViewCmd, "M-!" }, + {ALT ('!'), CK_FilteredViewCmd, "M-!"}, /* Find file */ - { ALT ('?'), CK_FindCmd, "M-?" }, + {ALT ('?'), CK_FindCmd, "M-?"}, /* Panel refresh */ - { XCTRL ('r'), CK_RereadCmd, "C-r" }, + {XCTRL ('r'), CK_RereadCmd, "C-r"}, /* Toggle listing between long, user defined and full formats */ - { ALT ('t'), CK_ToggleListingCmd, "M-t" }, + {ALT ('t'), CK_ToggleListingCmd, "M-t"}, /* Swap panels */ - { XCTRL ('u'), CK_SwapCmd, "C-u" }, + {XCTRL ('u'), CK_SwapCmd, "C-u"}, /* View output */ - { XCTRL ('o'), CK_ShowCommandLine, "C-o" }, - { ALT ('.'), CK_ToggleShowHidden, "M-." }, - { ALT (','), CK_TogglePanelsSplit, "M-," }, - { XCTRL ('x'), CK_StartExtMap1, "C-x" }, + {XCTRL ('o'), CK_ShowCommandLine, "C-o"}, + {ALT ('.'), CK_ToggleShowHidden, "M-."}, + {ALT (','), CK_TogglePanelsSplit, "M-,"}, + {XCTRL ('x'), CK_StartExtMap1, "C-x"}, /* Select/unselect group */ - { KEY_KP_ADD, CK_SelectCmd, "+" }, - { KEY_KP_SUBTRACT, CK_UnselectCmd, "-" }, - { ALT ('*'), CK_ReverseSelectionCmd, "*" }, + {KEY_KP_ADD, CK_SelectCmd, "+"}, + {KEY_KP_SUBTRACT, CK_UnselectCmd, "-"}, + {ALT ('*'), CK_ReverseSelectionCmd, "*"}, - { ALT ('`'), CK_DialogListCmd, "M-`"}, - { ALT ('}'), CK_DialogNextCmd, "M-}"}, - { ALT ('{'), CK_DialogPrevCmd, "M-{"}, + {ALT ('`'), CK_DialogListCmd, "M-`"}, + {ALT ('}'), CK_DialogNextCmd, "M-}"}, + {ALT ('{'), CK_DialogPrevCmd, "M-{"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; const global_keymap_t default_main_x_map[] = { - { 'd', CK_CompareDirsCmd, "d" }, + {'d', CK_CompareDirsCmd, "d"}, #ifdef USE_DIFF_VIEW - { XCTRL ('d'), CK_DiffViewCmd, "C-d" }, -#endif /* USE_DIFF_VIEW */ + {XCTRL ('d'), CK_DiffViewCmd, "C-d"}, +#endif /* USE_DIFF_VIEW */ #ifdef ENABLE_VFS - { 'a', CK_ReselectVfs, "a"}, -#endif /* ENABLE_VFS */ - { 'p', CK_CopyCurrentPathname, "p" }, - { XCTRL ('p'), CK_CopyOtherPathname, "C-p" }, - { 't', CK_CopyCurrentTagged, "t" }, - { XCTRL ('t'), CK_CopyOtherTagged, "C-t" }, - { 'c', CK_ChmodCmd, "c" }, - { 'o', CK_ChownCmd, "o" }, - { 'r', CK_CopyCurrentReadlink, "r" }, - { XCTRL ('r'), CK_CopyOtherReadlink, "C-r" }, - { 'l', CK_LinkCmd, "l" }, - { 's', CK_SymlinkCmd, "s" }, - { 'v', CK_RelativeSymlinkCmd, "v" }, - { XCTRL ('s'), CK_EditSymlinkCmd, "C-s" }, - { 'i', CK_InfoCmd, "i" }, - { 'q', CK_QuickViewCmd, "q" }, - { 'h', CK_AddHotlist, "h" }, - { '!', CK_ExternalPanelize, "!" }, + {'a', CK_ReselectVfs, "a"}, +#endif /* ENABLE_VFS */ + {'p', CK_CopyCurrentPathname, "p"}, + {XCTRL ('p'), CK_CopyOtherPathname, "C-p"}, + {'t', CK_CopyCurrentTagged, "t"}, + {XCTRL ('t'), CK_CopyOtherTagged, "C-t"}, + {'c', CK_ChmodCmd, "c"}, + {'o', CK_ChownCmd, "o"}, + {'r', CK_CopyCurrentReadlink, "r"}, + {XCTRL ('r'), CK_CopyOtherReadlink, "C-r"}, + {'l', CK_LinkCmd, "l"}, + {'s', CK_SymlinkCmd, "s"}, + {'v', CK_RelativeSymlinkCmd, "v"}, + {XCTRL ('s'), CK_EditSymlinkCmd, "C-s"}, + {'i', CK_InfoCmd, "i"}, + {'q', CK_QuickViewCmd, "q"}, + {'h', CK_AddHotlist, "h"}, + {'!', CK_ExternalPanelize, "!"}, #ifdef WITH_BACKGROUND - { 'j', CK_JobsCmd, "j" }, -#endif /* WITH_BACKGROUND */ - { 0, CK_Ignore_Key, "" } + {'j', CK_JobsCmd, "j"}, +#endif /* WITH_BACKGROUND */ + {0, CK_Ignore_Key, ""} }; const global_keymap_t default_input_keymap[] = { /* Motion */ - { XCTRL ('a'), CK_InputBol, "C-a" }, - { KEY_HOME, CK_InputBol, "Home" }, - { KEY_A1, CK_InputBol, "A1" }, - { ALT ('<'), CK_InputBol, "M-<" }, - { XCTRL ('e'), CK_InputEol, "C-e" }, - { KEY_END, CK_InputEol, "End" }, - { ALT ('>'), CK_InputEol, "M->" }, - { KEY_C1, CK_InputEol, "C1" }, - { KEY_LEFT, CK_InputMoveLeft, "Left" }, - { KEY_M_CTRL | KEY_LEFT, CK_InputWordLeft, "C-Left" }, - { KEY_RIGHT, CK_InputMoveRight, "Right" }, - { KEY_M_CTRL | KEY_RIGHT, CK_InputWordRight, "C-Right" }, + {XCTRL ('a'), CK_InputBol, "C-a"}, + {KEY_HOME, CK_InputBol, "Home"}, + {KEY_A1, CK_InputBol, "A1"}, + {ALT ('<'), CK_InputBol, "M-<"}, + {XCTRL ('e'), CK_InputEol, "C-e"}, + {KEY_END, CK_InputEol, "End"}, + {ALT ('>'), CK_InputEol, "M->"}, + {KEY_C1, CK_InputEol, "C1"}, + {KEY_LEFT, CK_InputMoveLeft, "Left"}, + {KEY_M_CTRL | KEY_LEFT, CK_InputWordLeft, "C-Left"}, + {KEY_RIGHT, CK_InputMoveRight, "Right"}, + {KEY_M_CTRL | KEY_RIGHT, CK_InputWordRight, "C-Right"}, - { XCTRL ('b'), CK_InputBackwardChar, "C-b" }, - { ALT ('b'), CK_InputBackwardWord, "M-b" }, - { XCTRL ('f'), CK_InputForwardChar, "C-f" }, - { ALT ('f'), CK_InputForwardWord, "M-f" }, + {XCTRL ('b'), CK_InputBackwardChar, "C-b"}, + {ALT ('b'), CK_InputBackwardWord, "M-b"}, + {XCTRL ('f'), CK_InputForwardChar, "C-f"}, + {ALT ('f'), CK_InputForwardWord, "M-f"}, /* Editing */ - { KEY_BACKSPACE, CK_InputBackwardDelete, "BackSpace" }, - { KEY_DC, CK_InputDeleteChar, "Delete" }, - { ALT ('d'), CK_InputKillWord, "M-d" }, - { ALT (KEY_BACKSPACE), CK_InputBackwardKillWord, "M-BackSpace" }, + {KEY_BACKSPACE, CK_InputBackwardDelete, "BackSpace"}, + {KEY_DC, CK_InputDeleteChar, "Delete"}, + {ALT ('d'), CK_InputKillWord, "M-d"}, + {ALT (KEY_BACKSPACE), CK_InputBackwardKillWord, "M-BackSpace"}, /* Region manipulation */ - { XCTRL ('w'), CK_InputKillRegion, "C-w" }, - { ALT ('w'), CK_InputKillSave, "M-w" }, - { XCTRL ('y'), CK_InputYank, "C-y" }, - { XCTRL ('k'), CK_InputKillLine, "C-k" }, + {XCTRL ('w'), CK_InputKillRegion, "C-w"}, + {ALT ('w'), CK_InputKillSave, "M-w"}, + {XCTRL ('y'), CK_InputYank, "C-y"}, + {XCTRL ('k'), CK_InputKillLine, "C-k"}, /* History */ - { ALT ('p'), CK_InputHistoryPrev, "M-p" }, - { ALT ('n'), CK_InputHistoryNext, "M-n" }, - { ALT ('h'), CK_InputHistoryShow, "M-h" }, + {ALT ('p'), CK_InputHistoryPrev, "M-p"}, + {ALT ('n'), CK_InputHistoryNext, "M-n"}, + {ALT ('h'), CK_InputHistoryShow, "M-h"}, /* Completion */ - { ALT ('\t'), CK_InputComplete, "M-tab" }, + {ALT ('\t'), CK_InputComplete, "M-tab"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; const global_keymap_t default_listbox_keymap[] = { - { KEY_UP, CK_ListboxMoveUp, "Up" }, - { XCTRL ('p'), CK_ListboxMoveUp, "C-p" }, - { KEY_DOWN, CK_ListboxMoveDown, "Down" }, - { XCTRL ('n'), CK_ListboxMoveDown, "C-n" }, - { KEY_HOME, CK_ListboxMoveHome, "Home" }, - { ALT ('<'), CK_ListboxMoveHome, "M-<" }, - { KEY_A1, CK_ListboxMoveHome, "A1" }, - { KEY_END, CK_ListboxMoveEnd, "End" }, - { ALT ('>'), CK_ListboxMoveEnd, "M->" }, - { KEY_C1, CK_ListboxMoveEnd, "C1" }, - { KEY_PPAGE, CK_ListboxMovePgUp, "PgUp" }, - { ALT ('v'), CK_ListboxMovePgUp, "M-v" }, - { KEY_NPAGE, CK_ListboxMovePgDn, "PgDn" }, - { XCTRL ('v'), CK_ListboxMovePgDn, "C-v" }, - { KEY_DC, CK_ListboxDeleteItem, "Delete" }, - { 'd', CK_ListboxDeleteItem, "d" }, - { KEY_M_SHIFT | KEY_DC, CK_ListboxDeleteAll, "S-Delete" }, - { 'D', CK_ListboxDeleteAll, "D" }, + {KEY_UP, CK_ListboxMoveUp, "Up"}, + {XCTRL ('p'), CK_ListboxMoveUp, "C-p"}, + {KEY_DOWN, CK_ListboxMoveDown, "Down"}, + {XCTRL ('n'), CK_ListboxMoveDown, "C-n"}, + {KEY_HOME, CK_ListboxMoveHome, "Home"}, + {ALT ('<'), CK_ListboxMoveHome, "M-<"}, + {KEY_A1, CK_ListboxMoveHome, "A1"}, + {KEY_END, CK_ListboxMoveEnd, "End"}, + {ALT ('>'), CK_ListboxMoveEnd, "M->"}, + {KEY_C1, CK_ListboxMoveEnd, "C1"}, + {KEY_PPAGE, CK_ListboxMovePgUp, "PgUp"}, + {ALT ('v'), CK_ListboxMovePgUp, "M-v"}, + {KEY_NPAGE, CK_ListboxMovePgDn, "PgDn"}, + {XCTRL ('v'), CK_ListboxMovePgDn, "C-v"}, + {KEY_DC, CK_ListboxDeleteItem, "Delete"}, + {'d', CK_ListboxDeleteItem, "d"}, + {KEY_M_SHIFT | KEY_DC, CK_ListboxDeleteAll, "S-Delete"}, + {'D', CK_ListboxDeleteAll, "D"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; #ifdef USE_DIFF_VIEW /* diff viewer */ const global_keymap_t default_diff_keymap[] = { - { 's', CK_DiffDisplaySymbols, "s" }, - { 'l', CK_DiffDisplayNumbers, "l" }, - { 'f', CK_DiffFull, "f" }, - { '=', CK_DiffEqual, "=" }, - { '>', CK_DiffSplitMore, ">" }, - { '<', CK_DiffSplitLess, "<" }, - { '2', CK_DiffSetTab2, "2" }, - { '3', CK_DiffSetTab3, "3" }, - { '4', CK_DiffSetTab4, "4" }, - { '8', CK_DiffSetTab8, "8" }, - { XCTRL ('u'), CK_DiffSwapPanel, "C-u" }, - { XCTRL ('r'), CK_DiffRedo, "C-r" }, - { XCTRL ('o'), CK_ShowCommandLine, "C-o" }, - { 'n', CK_DiffNextHunk, "n" }, - { 'p', CK_DiffPrevHunk, "p" }, - { 'g', CK_DiffGoto, "g" }, - { 'G', CK_DiffGoto, "G" }, - { KEY_M_CTRL | KEY_HOME, CK_DiffBOF, "C-Home" }, - { KEY_M_CTRL | KEY_END, CK_DiffEOF, "C-End" }, - { KEY_DOWN, CK_DiffDown, "Down" }, - { KEY_UP, CK_DiffUp, "Up" }, - { KEY_M_CTRL | KEY_LEFT, CK_DiffQuickLeft, "C-Left" }, - { KEY_M_CTRL | KEY_RIGHT, CK_DiffQuickRight, "C-Right" }, - { KEY_LEFT, CK_DiffLeft, "Left" }, - { KEY_RIGHT, CK_DiffRight, "Right" }, - { KEY_NPAGE, CK_DiffPageDown, "Down" }, - { KEY_PPAGE, CK_DiffPageUp, "Up" }, - { KEY_HOME, CK_DiffHome, "Home" }, - { KEY_END, CK_DiffEnd, "End" }, - { 'q', CK_DiffQuit, "q" }, - { 'Q', CK_DiffQuit, "Q" }, - { XCTRL ('g'), CK_DiffQuit, "C-g" }, - { ESC_CHAR, CK_DiffQuit, "Esc" }, + {'s', CK_DiffDisplaySymbols, "s"}, + {'l', CK_DiffDisplayNumbers, "l"}, + {'f', CK_DiffFull, "f"}, + {'=', CK_DiffEqual, "="}, + {'>', CK_DiffSplitMore, ">"}, + {'<', CK_DiffSplitLess, "<"}, + {'2', CK_DiffSetTab2, "2"}, + {'3', CK_DiffSetTab3, "3"}, + {'4', CK_DiffSetTab4, "4"}, + {'8', CK_DiffSetTab8, "8"}, + {XCTRL ('u'), CK_DiffSwapPanel, "C-u"}, + {XCTRL ('r'), CK_DiffRedo, "C-r"}, + {XCTRL ('o'), CK_ShowCommandLine, "C-o"}, + {'n', CK_DiffNextHunk, "n"}, + {'p', CK_DiffPrevHunk, "p"}, + {'g', CK_DiffGoto, "g"}, + {'G', CK_DiffGoto, "G"}, + {KEY_M_CTRL | KEY_HOME, CK_DiffBOF, "C-Home"}, + {KEY_M_CTRL | KEY_END, CK_DiffEOF, "C-End"}, + {KEY_DOWN, CK_DiffDown, "Down"}, + {KEY_UP, CK_DiffUp, "Up"}, + {KEY_M_CTRL | KEY_LEFT, CK_DiffQuickLeft, "C-Left"}, + {KEY_M_CTRL | KEY_RIGHT, CK_DiffQuickRight, "C-Right"}, + {KEY_LEFT, CK_DiffLeft, "Left"}, + {KEY_RIGHT, CK_DiffRight, "Right"}, + {KEY_NPAGE, CK_DiffPageDown, "Down"}, + {KEY_PPAGE, CK_DiffPageUp, "Up"}, + {KEY_HOME, CK_DiffHome, "Home"}, + {KEY_END, CK_DiffEnd, "End"}, + {'q', CK_DiffQuit, "q"}, + {'Q', CK_DiffQuit, "Q"}, + {XCTRL ('g'), CK_DiffQuit, "C-g"}, + {ESC_CHAR, CK_DiffQuit, "Esc"}, - { KEY_F (1), CK_DiffHelp, "F1" }, - { KEY_F (4), CK_DiffEditCurrent, "F4" }, - { KEY_F (5), CK_DiffMergeCurrentHunk, "F5" }, - { KEY_F (7), CK_DiffSearch, "F7" }, - { KEY_F (17), CK_DiffContinueSearch, "S-F7" }, - { KEY_F (9), CK_DiffOptions, "F9" }, - { KEY_F (10), CK_DiffQuit, "F10" }, - { KEY_F (14), CK_DiffEditOther, "S-F4" }, + {KEY_F (1), CK_DiffHelp, "F1"}, + {KEY_F (4), CK_DiffEditCurrent, "F4"}, + {KEY_F (5), CK_DiffMergeCurrentHunk, "F5"}, + {KEY_F (7), CK_DiffSearch, "F7"}, + {KEY_F (17), CK_DiffContinueSearch, "S-F7"}, + {KEY_F (9), CK_DiffOptions, "F9"}, + {KEY_F (10), CK_DiffQuit, "F10"}, + {KEY_F (14), CK_DiffEditOther, "S-F4"}, - { 0, CK_Ignore_Key, "" } + {0, CK_Ignore_Key, ""} }; #endif +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +static name_keymap_t command_names[] = { +#ifdef USE_INTERNAL_EDIT + {"EditNoCommand", CK_Ignore_Key}, + {"EditIgnoreKey", CK_Ignore_Key}, + {"EditBackSpace", CK_BackSpace}, + {"EditDelete", CK_Delete}, + {"EditEnter", CK_Enter}, + {"EditPageUp", CK_Page_Up}, + {"EditPageDown", CK_Page_Down}, + {"EditLeft", CK_Left}, + {"EditRight", CK_Right}, + {"EditWordLeft", CK_Word_Left}, + {"EditWordRight", CK_Word_Right}, + {"EditUp", CK_Up}, + {"EditDown", CK_Down}, + {"EditHome", CK_Home}, + {"EditEnd", CK_End}, + {"EditTab", CK_Tab}, + {"EditUndo", CK_Undo}, + {"EditBeginningOfText", CK_Beginning_Of_Text}, + {"EditEndOfText", CK_End_Of_Text}, + {"EditScrollUp", CK_Scroll_Up}, + {"EditScrollDown", CK_Scroll_Down}, + {"EditReturn", CK_Return}, + {"EditBeginPage", CK_Begin_Page}, + {"EditEndPage", CK_End_Page}, + {"EditDeleteWordLeft", CK_Delete_Word_Left}, + {"EditDeleteWordRight", CK_Delete_Word_Right}, + {"EditParagraphUp", CK_Paragraph_Up}, + {"EditParagraphDown", CK_Paragraph_Down}, + {"EditMenu", CK_Menu}, + {"EditSave", CK_Save}, + {"EditLoad", CK_Load}, + {"EditNew", CK_New}, + {"EditSaveas", CK_Save_As}, + {"EditMark", CK_Mark}, + {"EditCopy", CK_Copy}, + {"EditMove", CK_Move}, + {"EditRemove", CK_Remove}, + {"EditMarkAll", CK_Mark_All}, + {"EditUnmark", CK_Unmark}, + {"EditSaveBlock", CK_Save_Block}, + {"EditColumnMark", CK_Column_Mark}, + {"EditFind", CK_Find}, + {"EditFindAgain", CK_Find_Again}, + {"EditReplace", CK_Replace}, + {"EditReplaceAgain", CK_Replace_Again}, + {"EditCompleteWord", CK_Complete_Word}, + +#if 0 + {"EditDebugStart", CK_Debug_Start}, + {"EditDebugStop", CK_Debug_Stop}, + {"EditDebugToggleBreak", CK_Debug_Toggle_Break}, + {"EditDebugClear", CK_Debug_Clear}, + {"EditDebugNext", CK_Debug_Next}, + {"EditDebugStep", CK_Debug_Step}, + {"EditDebugBackTrace", CK_Debug_Back_Trace}, + {"EditDebugContinue", CK_Debug_Continue}, + {"EditDebugEnterCommand", CK_Debug_Enter_Command}, + {"EditDebugUntilCurser", CK_Debug_Until_Curser}, +#endif + {"EditInsertFile", CK_Insert_File}, + {"EditQuit", CK_Quit}, + {"EditToggleInsert", CK_Toggle_Insert}, + {"EditHelp", CK_Help}, + {"EditDate", CK_Date}, + {"EditRefresh", CK_Refresh}, + {"EditGoto", CK_Goto}, + {"EditDeleteLine", CK_Delete_Line}, + {"EditDeleteToLineEnd", CK_Delete_To_Line_End}, + {"EditDeleteToLineBegin", CK_Delete_To_Line_Begin}, + {"EditManPage", CK_Man_Page}, + {"EditSort", CK_Sort}, + {"EditMail", CK_Mail}, + {"EditCancel", CK_Cancel}, + {"EditComplete", CK_Complete}, + {"EditParagraphFormat", CK_Paragraph_Format}, + {"EditUtil", CK_Util}, + {"EditTypeLoadPython", CK_Type_Load_Python}, + {"EditFindFile", CK_Find_File}, + {"EditCtags", CK_Ctags}, + {"EditMatchBracket", CK_Match_Bracket}, + {"EditTerminal", CK_Terminal}, + {"EditTerminalApp", CK_Terminal_App}, + {"EditExtCmd", CK_ExtCmd}, + {"EditUserMenu", CK_User_Menu}, + {"EditBeginRecordMacro", CK_Begin_Record_Macro}, + {"EditEndRecordMacro", CK_End_Record_Macro}, + {"EditDeleteMacro", CK_Delete_Macro}, + {"EditToggleBookmark", CK_Toggle_Bookmark}, + {"EditFlushBookmarks", CK_Flush_Bookmarks}, + {"EditNextBookmark", CK_Next_Bookmark}, + {"EditPrevBookmark", CK_Prev_Bookmark}, + {"EditPageUpHighlight", CK_Page_Up_Highlight}, + {"EditPageDownHighlight", CK_Page_Down_Highlight}, + {"EditLeftHighlight", CK_Left_Highlight}, + {"EditRightHighlight", CK_Right_Highlight}, + {"EditWordLeftHighlight", CK_Word_Left_Highlight}, + {"EditWordRightHighlight", CK_Word_Right_Highlight}, + {"EditUpHighlight", CK_Up_Highlight}, + {"EditDownHighlight", CK_Down_Highlight}, + {"EditHomeHighlight", CK_Home_Highlight}, + {"EditEndHighlight", CK_End_Highlight}, + {"EditBeginningOfTextHighlight", CK_Beginning_Of_Text_Highlight}, + {"EditEndOfTextHighlight", CK_End_Of_Text_Highlight}, + {"EditBeginPageHighlight", CK_Begin_Page_Highlight}, + {"EditEndPageHighlight", CK_End_Page_Highlight}, + {"EditScrollUpHighlight", CK_Scroll_Up_Highlight}, + {"EditScrollDownHighlight", CK_Scroll_Down_Highlight}, + {"EditParagraphUpHighlight", CK_Paragraph_Up_Highlight}, + {"EditParagraphDownHighlight", CK_Paragraph_Down_Highlight}, + + {"EditPageUpAltHighlight", CK_Page_Up_Alt_Highlight}, + {"EditPageDownAltHighlight", CK_Page_Down_Alt_Highlight}, + {"EditLeftAltHighlight", CK_Left_Alt_Highlight}, + {"EditRightAltHighlight", CK_Right_Alt_Highlight}, + {"EditWordLeftAltHighlight", CK_Word_Left_Alt_Highlight}, + {"EditWordRightAltHighlight", CK_Word_Right_Alt_Highlight}, + {"EditUpAltHighlight", CK_Up_Alt_Highlight}, + {"EditDownAltHighlight", CK_Down_Alt_Highlight}, + {"EditHomeAltHighlight", CK_Home_Alt_Highlight}, + {"EditEndAltHighlight", CK_End_Alt_Highlight}, + {"EditBeginningOfTextAltHighlight", CK_Beginning_Of_Text_Alt_Highlight}, + {"EditEndOfTextAltHighlight", CK_End_Of_Text_Alt_Highlight}, + {"EditBeginPageAltHighlight", CK_Begin_Page_Alt_Highlight}, + {"EditEndPageAltHighlight", CK_End_Page_Alt_Highlight}, + {"EditScrollUpAltHighlight", CK_Scroll_Up_Alt_Highlight}, + {"EditScrollDownAltHighlight", CK_Scroll_Down_Alt_Highlight}, + {"EditParagraphUpAltHighlight", CK_Paragraph_Up_Alt_Highlight}, + {"EditParagraphDownAltHighlight", CK_Paragraph_Down_Alt_Highlight}, + + {"EditShiftBlockLeft", CK_Shift_Block_Left}, + {"EditShiftBlockRight", CK_Shift_Block_Right}, + + {"EditXStore", CK_XStore}, + {"EditXCut", CK_XCut}, + {"EditXPaste", CK_XPaste}, + {"EditSelectionHistory", CK_Selection_History}, + {"EditShell", CK_Shell}, + {"EditInsertLiteral", CK_Insert_Literal}, + {"EditExecuteMacro", CK_Execute_Macro}, + {"EditBeginOrEndMacro", CK_Begin_End_Macro}, + {"EditExtMode", CK_Ext_Mode}, + {"EditToggleLineState", CK_Toggle_Line_State}, + {"EditToggleTabTWS", CK_Toggle_Tab_TWS}, + {"EditToggleSyntax", CK_Toggle_Syntax}, + {"EditToggleShowMargin", CK_Toggle_Show_Margin}, + {"EditFindDefinition", CK_Find_Definition}, + {"EditLoadPrevFile", CK_Load_Prev_File}, + {"EditLoadNextFile", CK_Load_Next_File}, + {"EditOptions", CK_Edit_Options}, + {"EditSaveMode", CK_Edit_Save_Mode}, + {"EditChooseSyntax", CK_Choose_Syntax}, + {"EditAbout", CK_About}, + +#if 0 + {"EditFocusNext", CK_Focus_Next}, + {"EditFocusPrev", CK_Focus_Prev}, + {"EditHeightInc", CK_Height_Inc}, + {"EditHeightDec", CK_Height_Dec}, + {"EditMake", CK_Make}, + {"EditErrorNext", CK_Error_Next}, + {"EditErrorPrev", CK_Error_Prev}, +#endif + +#if 0 + {"EditSaveDesktop", CK_Save_Desktop}, + {"EditNewWindow", CK_New_Window}, + {"EditCycle", CK_Cycle}, + {"EditSaveAndQuit", CK_Save_And_Quit}, + {"EditRunAnother", CK_Run_Another}, + {"EditCheckSaveAndQuit", CK_Check_Save_And_Quit}, + {"EditMaximize", CK_Maximize}, +#endif + +#endif /* USE_INTERNAL_EDIT */ + + /* viewer */ + {"ViewHelp", CK_ViewHelp}, + {"ViewToggleWrapMode", CK_ViewToggleWrapMode}, + {"ViewToggleHexEditMode", CK_ViewToggleHexEditMode}, + {"ViewQuit", CK_ViewQuit}, + {"ViewToggleHexMode", CK_ViewToggleHexMode}, + {"ViewGoto", CK_ViewGoto}, + {"ViewHexEditSave", CK_ViewHexEditSave}, + {"ViewSearch", CK_ViewSearch}, + {"ViewToggleMagicMode", CK_ViewToggleMagicMode}, + {"ViewToggleNroffMode", CK_ViewToggleNroffMode}, + {"ViewContinueSearch", CK_ViewContinueSearch}, + {"ViewGotoBookmark", CK_ViewGotoBookmark}, + {"ViewNewBookmark", CK_ViewNewBookmark}, + {"ViewMoveUp", CK_ViewMoveUp}, + {"ViewMoveDown", CK_ViewMoveDown}, + {"ViewMoveLeft", CK_ViewMoveLeft}, + {"ViewMoveRight", CK_ViewMoveRight}, + {"ViewMoveLeft10", CK_ViewMoveLeft10}, + {"ViewMoveRight10", CK_ViewMoveRight10}, + {"ViewMovePgDn", CK_ViewMovePgDn}, + {"ViewMovePgUp", CK_ViewMovePgUp}, + {"ViewMoveHalfPgDn", CK_ViewMoveHalfPgDn}, + {"ViewMoveHalfPgUp", CK_ViewMoveHalfPgUp}, + {"ViewMoveToBol", CK_ViewMoveToBol}, + {"ViewMoveToEol", CK_ViewMoveToEol}, + {"ViewMoveTop", CK_ViewMoveTop}, + {"ViewMoveBottom", CK_ViewMoveBottom}, + {"ViewNextFile", CK_ViewNextFile}, + {"ViewPrevFile", CK_ViewPrevFile}, + {"ViewToggleRuler", CK_ViewToggleRuler}, + {"ViewToggleHexNavMode", CK_ViewToggleHexNavMode}, + + /* help */ + {"HelpHelp", CK_HelpHelp}, + {"HelpIndex", CK_HelpIndex}, + {"HelpBack", CK_HelpBack}, + {"HelpQuit", CK_HelpQuit}, + {"HelpMoveUp", CK_HelpMoveUp}, + {"HelpMoveDown", CK_HelpMoveDown}, + {"HelpMovePgDn", CK_HelpMovePgDn}, + {"HelpMovePgUp", CK_HelpMovePgUp}, + {"HelpMoveHalfPgDn", CK_HelpMoveHalfPgDn}, + {"HelpMoveHalfPgUp", CK_HelpMoveHalfPgUp}, + {"HelpMoveTop", CK_HelpMoveTop}, + {"HelpMoveBottom", CK_HelpMoveBottom}, + {"HelpSelectLink", CK_HelpSelectLink}, + {"HelpNextLink", CK_HelpNextLink}, + {"HelpPrevLink", CK_HelpPrevLink}, + {"HelpNextNode", CK_HelpNextNode}, + {"HelpPrevNode", CK_HelpPrevNode}, + + /* tree */ + {"TreeHelp", CK_TreeHelp}, + {"TreeForget", CK_TreeForget}, + {"TreeToggleNav", CK_TreeToggleNav}, + {"TreeCopy", CK_TreeCopy}, + {"TreeMove", CK_TreeMove}, + {"TreeMake", CK_TreeMake}, + {"TreeMoveUp", CK_TreeMoveUp}, + {"TreeMoveDown", CK_TreeMoveDown}, + {"TreeMoveLeft", CK_TreeMoveLeft}, + {"TreeMoveRight", CK_TreeMoveRight}, + {"TreeMoveHome", CK_TreeMoveHome}, + {"TreeMoveEnd", CK_TreeMoveEnd}, + {"TreeMovePgUp", CK_TreeMovePgUp}, + {"TreeMovePgDn", CK_TreeMovePgDn}, + {"TreeOpen", CK_TreeOpen}, + {"TreeRescan", CK_TreeRescan}, + {"TreeStartSearch", CK_TreeStartSearch}, + {"TreeRemove", CK_TreeRemove}, + + /* main commands */ + {"CmdHelp", CK_HelpCmd}, + {"CmdMenu", CK_MenuCmd}, + {"CmdChmod", CK_ChmodCmd}, + {"CmdMenuLastSelected", CK_MenuLastSelectedCmd}, + {"CmdSingleDirsize", CK_SingleDirsizeCmd}, + {"CmdCopyCurrentPathname", CK_CopyCurrentPathname}, + {"CmdCopyOtherPathname", CK_CopyOtherPathname}, + {"CmdSuspend", CK_SuspendCmd}, + {"CmdToggleListing", CK_ToggleListingCmd}, + {"CmdChownAdvanced", CK_ChownAdvancedCmd}, + {"CmdChown", CK_ChownCmd}, + {"CmdCompareDirs", CK_CompareDirsCmd}, + {"CmdConfigureBox", CK_ConfigureBox}, + {"CmdConfigureVfs", CK_ConfigureVfs}, + {"CmdConfirmBox", CK_ConfirmBox}, + {"CmdCopy", CK_CopyCmd}, + {"CmdDelete", CK_DeleteCmd}, + {"CmdDirsizes", CK_DirsizesCmd}, + {"CmdDisplayBitsBox", CK_DisplayBitsBox}, + {"CmdEdit", CK_EditCmd}, +#ifdef USE_INTERNAL_EDIT + {"CmdEditForceInternal", CK_EditForceInternalCmd}, +#endif + {"CmdEditExtFile", CK_EditExtFileCmd}, + {"CmdEditFhlFile", CK_EditFhlFileCmd}, + {"CmdEditMcMenu", CK_EditMcMenuCmd}, + {"CmdEditSymlink", CK_EditSymlinkCmd}, + {"CmdEditSyntax", CK_EditSyntaxCmd}, + {"CmdEditUserMenu", CK_EditUserMenuCmd}, + {"CmdExternalPanelize", CK_ExternalPanelize}, + {"CmdFilter", CK_FilterCmd}, + {"CmdFilteredView", CK_FilteredViewCmd}, + {"CmdFind", CK_FindCmd}, +#ifdef ENABLE_VFS_FISH + {"CmdFishlink", CK_FishlinkCmd}, +#endif +#ifdef ENABLE_VFS_FTP + {"CmdFtplink", CK_FtplinkCmd}, +#endif + {"CmdHistory", CK_HistoryCmd}, + {"CmdInfo", CK_InfoCmd}, +#ifdef WITH_BACKGROUND + {"CmdJobs", CK_JobsCmd}, +#endif + {"CmdLayout", CK_LayoutBox}, + {"CmdLearnKeys", CK_LearnKeys}, + {"CmdLink", CK_LinkCmd}, + {"CmdChangeListing", CK_ChangeListingCmd}, + {"CmdListing", CK_ListingCmd}, +#ifdef LISTMODE_EDITOR + {"CmdListmodeCmd", CK_ListmodeCmd}. +#endif + {"CmdMkdir", CK_MkdirCmd}, + {"CmdPanelOptions", CK_PanelOptionsBox}, + {"CmdQuickCd", CK_QuickCdCmd}, + {"CmdQuickChdir", CK_QuickChdirCmd}, + {"CmdQuickView", CK_QuickViewCmd}, + {"CmdQuietQuit", CK_QuietQuitCmd}, + {"CmdRelativeSymlink", CK_RelativeSymlinkCmd}, + {"CmdRename", CK_RenameCmd}, + {"CmdReread", CK_RereadCmd}, + {"CmdReselectVfs", CK_ReselectVfs}, + {"CmdReverseSelection", CK_ReverseSelectionCmd}, + {"CmdSaveSetup", CK_SaveSetupCmd}, + {"CmdSelect", CK_SelectCmd}, +#ifdef ENABLE_VFS_SMB + {"CmdSmblinkCmd", CK_SmblinkCmd}, +#endif + {"CmdSwapPanel", CK_SwapCmd}, + {"CmdSymlink", CK_SymlinkCmd}, + {"CmdTree", CK_TreeCmd}, + {"CmdTreeBox", CK_TreeBoxCmd}, +#ifdef ENABLE_VFS_UNDELFS + {"CmdUndelete", CK_UndeleteCmd}, +#endif + {"CmdUnselect", CK_UnselectCmd}, + {"CmdUserMenu", CK_UserMenuCmd}, + {"CmdUserFileMenu", CK_UserFileMenuCmd}, + {"CmdView", CK_ViewCmd}, + {"CmdViewFile", CK_ViewFileCmd}, + {"CmdCopyCurrentReadlink", CK_CopyCurrentReadlink}, + {"CmdCopyOtherReadlink", CK_CopyOtherReadlink}, + {"CmdAddHotlist", CK_AddHotlist}, + {"CmdQuit", CK_QuitCmd}, + {"CmdCopyCurrentTagged", CK_CopyCurrentTagged}, + {"CmdCopyOtherTagged", CK_CopyOtherTagged}, + {"CmdToggleShowHidden", CK_ToggleShowHidden}, + {"CmdTogglePanelsSplit", CK_TogglePanelsSplit}, +#ifdef USE_DIFF_VIEW + {"CmdDiffView", CK_DiffViewCmd}, +#endif + {"CmdDialogList", CK_DialogListCmd}, + {"CmdDialogNext", CK_DialogNextCmd}, + {"CmdDialogPrev", CK_DialogPrevCmd}, + + /* panel */ + {"PanelChdirOtherPanel", CK_PanelChdirOtherPanel}, + {"PanelChdirToReadlink", CK_PanelChdirToReadlink}, + {"PanelCopyLocal", CK_PanelCmdCopyLocal}, + {"PanelDeleteLocal", CK_PanelCmdDeleteLocal}, + {"PanelDoEnter", CK_PanelCmdDoEnter}, + {"PanelEditNew", CK_PanelCmdEditNew}, + {"PanelRenameLocal", CK_PanelCmdRenameLocal}, + {"PanelReverseSelection", CK_PanelCmdReverseSelection}, + {"PanelSelect", CK_PanelCmdSelect}, + {"PanelUnselect", CK_PanelCmdUnselect}, + {"PanelViewSimple", CK_PanelCmdViewSimple}, + {"PanelCtrlNextPage", CK_PanelCtrlNextPage}, + {"PanelCtrlPrevPage", CK_PanelCtrlPrevPage}, + {"PanelDirectoryHistoryList", CK_PanelDirectoryHistoryList}, + {"PanelDirectoryHistoryNext", CK_PanelDirectoryHistoryNext}, + {"PanelDirectoryHistoryPrev", CK_PanelDirectoryHistoryPrev}, + {"PanelGotoBottomFile", CK_PanelGotoBottomFile}, + {"PanelGotoMiddleFile", CK_PanelGotoMiddleFile}, + {"PanelGotoTopFile", CK_PanelGotoTopFile}, + {"PanelMarkFile", CK_PanelMarkFile}, + {"PanelMarkFileDown", CK_PanelMarkFileDown}, + {"PanelMarkFileUp", CK_PanelMarkFileUp}, + {"PanelMoveUp", CK_PanelMoveUp}, + {"PanelMoveDown", CK_PanelMoveDown}, + {"PanelMoveLeft", CK_PanelMoveLeft}, + {"PanelMoveRight", CK_PanelMoveRight}, + {"PanelMoveEnd", CK_PanelMoveEnd}, + {"PanelMoveHome", CK_PanelMoveHome}, + {"PanelNextPage", CK_PanelNextPage}, + {"PanelPrevPage", CK_PanelPrevPage}, +#ifdef HAVE_CHARSET + {"PanelSetPanelEncoding", CK_PanelSetPanelEncoding}, +#endif + {"PanelStartSearch", CK_PanelStartSearch}, + {"PanelSyncOtherPanel", CK_PanelSyncOtherPanel}, + {"PanelToggleSortOrderNext", CK_PanelToggleSortOrderNext}, + {"PanelToggleSortOrderPrev", CK_PanelToggleSortOrderPrev}, + {"PanelSelectSortOrder", CK_PanelSelectSortOrder}, + {"PanelReverseSort", CK_PanelReverseSort}, + {"PanelSortOrderByName", CK_PanelSortOrderByName}, + {"PanelSortOrderByExt", CK_PanelSortOrderByExt}, + {"PanelSortOrderBySize", CK_PanelSortOrderBySize}, + {"PanelSortOrderByMTime", CK_PanelSortOrderByMTime}, + + /* input line */ + {"InputBol", CK_InputBol}, + {"InputEol", CK_InputEol}, + {"InputMoveLeft", CK_InputMoveLeft}, + {"InputWordLeft", CK_InputWordLeft}, + {"InputBackwardChar", CK_InputBackwardChar}, + {"InputBackwardWord", CK_InputBackwardWord}, + {"InputMoveRight", CK_InputMoveRight}, + {"InputWordRight", CK_InputWordRight}, + {"InputForwardChar", CK_InputForwardChar}, + {"InputForwardWord", CK_InputForwardWord}, + {"InputBackwardDelete", CK_InputBackwardDelete}, + {"InputDeleteChar", CK_InputDeleteChar}, + {"InputKillWord", CK_InputKillWord}, + {"InputBackwardKillWord", CK_InputBackwardKillWord}, + {"InputSetMark", CK_InputSetMark}, + {"InputKillRegion", CK_InputKillRegion}, + {"InputYank", CK_InputYank}, + {"InputKillLine", CK_InputKillLine}, + {"InputHistoryPrev", CK_InputHistoryPrev}, + {"InputHistoryNext", CK_InputHistoryNext}, + {"InputHistoryShow", CK_InputHistoryShow}, + {"InputComplete", CK_InputComplete}, + {"InputXStore", CK_InputKillSave}, + {"InputXPaste", CK_InputPaste}, + {"InputClearLine", CK_InputClearLine}, + {"InputLeftHighlight", CK_InputLeftHighlight}, + {"InputRightHighlight", CK_InputRightHighlight}, + {"InputWordLeftHighlight", CK_InputWordLeftHighlight}, + {"InputWordRightHighlight", CK_InputWordRightHighlight}, + {"InputBolHighlight", CK_InputBolHighlight}, + {"InputEolHighlight", CK_InputEolHighlight}, + + /* listbox */ + {"ListboxMoveUp", CK_ListboxMoveUp}, + {"ListboxMoveDown", CK_ListboxMoveDown}, + {"ListboxMoveHome", CK_ListboxMoveHome}, + {"ListboxMoveEnd", CK_ListboxMoveEnd}, + {"ListboxMovePgUp", CK_ListboxMovePgUp}, + {"ListboxMovePgDn", CK_ListboxMovePgDn}, + {"ListboxDeleteItem", CK_ListboxDeleteItem}, + {"ListboxDeleteAll", CK_ListboxDeleteAll}, + + /* common */ + {"ExtMap1", CK_StartExtMap1}, + {"ExtMap2", CK_StartExtMap2}, + {"ShowCommandLine", CK_ShowCommandLine}, + {"SelectCodepage", CK_SelectCodepage}, + + /* dialog */ + {"DialogOK", CK_DialogOK}, + {"DialogCancel", CK_DialogCancel}, + {"DialogPrevItem", CK_DialogPrevItem}, + {"DialogNextItem", CK_DialogNextItem}, + {"DialogHelp", CK_DialogHelp}, + {"DialogSuspend", CK_DialogSuspend}, + {"DialogRefresh", CK_DialogRefresh}, + +#ifdef USE_DIFF_VIEW + /* diff viewer */ + {"DiffDisplaySymbols", CK_DiffDisplaySymbols}, + {"DiffDisplayNumbers", CK_DiffDisplayNumbers}, + {"DiffFull", CK_DiffFull}, + {"DiffEqual", CK_DiffEqual}, + {"DiffSplitMore", CK_DiffSplitMore}, + {"DiffSplitLess", CK_DiffSplitLess}, + {"DiffShowDiff", CK_DiffShowDiff}, + {"DiffSetTab2", CK_DiffSetTab2}, + {"DiffSetTab3", CK_DiffSetTab3}, + {"DiffSetTab4", CK_DiffSetTab4}, + {"DiffSetTab8", CK_DiffSetTab8}, + {"DiffSwapPanel", CK_DiffSwapPanel}, + {"DiffRedo", CK_DiffRedo}, + {"DiffNextHunk", CK_DiffNextHunk}, + {"DiffPrevHunk", CK_DiffPrevHunk}, + {"DiffGoto", CK_DiffGoto}, + {"DiffEditCurrent", CK_DiffEditCurrent}, + {"DiffEditOther", CK_DiffEditOther}, + {"DiffSearch", CK_DiffSearch}, + {"DiffContinueSearch", CK_DiffContinueSearch}, + {"DiffEOF", CK_DiffEOF}, + {"DiffBOF", CK_DiffBOF}, + {"DiffDown", CK_DiffDown}, + {"DiffUp", CK_DiffUp}, + {"DiffLeft", CK_DiffLeft}, + {"DiffRight", CK_DiffRight}, + {"DiffPageDown", CK_DiffPageDown}, + {"DiffPageUp", CK_DiffPageUp}, + {"DiffHome", CK_DiffHome}, + {"DiffEnd", CK_DiffEnd}, + {"DiffQuit", CK_DiffQuit}, + {"DiffHelp", CK_DiffHelp}, + {"SelectCodepage", CK_SelectCodepage}, + {"DiffMergeCurrentHunk", CK_DiffMergeCurrentHunk}, + {"DiffSave", CK_DiffSave}, + {"DiffOptions", CK_DiffOptions}, +#endif + + {NULL, CK_Ignore_Key} +}; + +static const size_t num_command_names = sizeof (command_names) / sizeof (command_names[0]) - 1; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static int name_keymap_comparator (const void *p1, const void *p2) { @@ -1219,22 +1229,28 @@ name_keymap_comparator (const void *p1, const void *p2) return str_casecmp (m1->name, m2->name); } +/* --------------------------------------------------------------------------------------------- */ + static inline void sort_command_names (void) { static gboolean has_been_sorted = FALSE; - if (!has_been_sorted) { - qsort (command_names, num_command_names, - sizeof (command_names[0]), &name_keymap_comparator); - has_been_sorted = TRUE; + if (!has_been_sorted) + { + qsort (command_names, num_command_names, + sizeof (command_names[0]), &name_keymap_comparator); + has_been_sorted = TRUE; } } +/* --------------------------------------------------------------------------------------------- */ + static void -keymap_add (GArray *keymap, long key, unsigned long cmd, const char *caption) +keymap_add (GArray * keymap, long key, unsigned long cmd, const char *caption) { - if (key != 0 && cmd != CK_Ignore_Key) { + if (key != 0 && cmd != CK_Ignore_Key) + { global_keymap_t new_bind; new_bind.key = key; @@ -1244,8 +1260,12 @@ keymap_add (GArray *keymap, long key, unsigned long cmd, const char *caption) } } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void -keybind_cmd_bind (GArray *keymap, const char *keybind, unsigned long action) +keybind_cmd_bind (GArray * keymap, const char *keybind, unsigned long action) { char *caption = NULL; long key; @@ -1255,6 +1275,8 @@ keybind_cmd_bind (GArray *keymap, const char *keybind, unsigned long action) g_free (caption); } +/* --------------------------------------------------------------------------------------------- */ + unsigned long lookup_action (const char *name) { @@ -1264,31 +1286,37 @@ lookup_action (const char *name) sort_command_names (); res = bsearch (&key, command_names, num_command_names, - sizeof (command_names[0]), name_keymap_comparator); + sizeof (command_names[0]), name_keymap_comparator); return (res != NULL) ? res->val : CK_Ignore_Key; } +/* --------------------------------------------------------------------------------------------- */ + const char * -lookup_keymap_shortcut (const global_keymap_t *keymap, unsigned long action) +lookup_keymap_shortcut (const global_keymap_t * keymap, unsigned long action) { size_t i; for (i = 0; keymap[i].key != 0; i++) - if (keymap[i].command == action) - return (keymap[i].caption[0] != '\0') ? keymap[i].caption : NULL; + if (keymap[i].command == action) + return (keymap[i].caption[0] != '\0') ? keymap[i].caption : NULL; return NULL; } +/* --------------------------------------------------------------------------------------------- */ + unsigned long -lookup_keymap_command (const global_keymap_t *keymap, long key) +lookup_keymap_command (const global_keymap_t * keymap, long key) { size_t i; for (i = 0; keymap[i].key != 0; i++) - if (keymap[i].key == key) - return keymap[i].command; + if (keymap[i].key == key) + return keymap[i].command; return CK_Ignore_Key; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/keybind.h b/src/keybind.h index fc624ef8b..07307ca52 100644 --- a/src/keybind.h +++ b/src/keybind.h @@ -1,33 +1,39 @@ - -#ifndef MC_KEYBIND_H -#define MC_KEYBIND_H +#ifndef MC__KEYBIND_H +#define MC__KEYBIND_H #include "lib/global.h" -typedef struct name_keymap_t { +/*** typedefs(not structures) and defined constants **********************************************/ + +#define KEYMAP_SHORTCUT_LENGTH 32 /* FIXME: is 32 bytes enough for shortcut? */ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef struct name_keymap_t +{ const char *name; unsigned long val; } name_keymap_t; -typedef struct key_config_t { - time_t mtime; /* mtime at the moment we read config file */ +typedef struct key_config_t +{ + time_t mtime; /* mtime at the moment we read config file */ GArray *keymap; GArray *ext_keymap; gchar *labels[10]; } key_config_t; /* The global keymaps are of this type */ -#define KEYMAP_SHORTCUT_LENGTH 32 /* FIXME: is 32 bytes enough for shortcut? */ -typedef struct global_keymap_t { +typedef struct global_keymap_t +{ long key; unsigned long command; char caption[KEYMAP_SHORTCUT_LENGTH]; } global_keymap_t; -void keybind_cmd_bind (GArray *keymap, const char *keybind, unsigned long action); -unsigned long lookup_action (const char *name); -const char *lookup_keymap_shortcut (const global_keymap_t *keymap, unsigned long action); -unsigned long lookup_keymap_command (const global_keymap_t *keymap, long key); +/*** global variables defined in .c file *********************************************************/ #ifdef USE_INTERNAL_EDIT extern GArray *editor_keymap; @@ -98,4 +104,12 @@ extern const global_keymap_t default_dialog_keymap[]; extern const global_keymap_t default_diff_keymap[]; #endif -#endif /* MC_KEYBIND_H */ +/*** declarations of public functions ************************************************************/ + +void keybind_cmd_bind (GArray * keymap, const char *keybind, unsigned long action); +unsigned long lookup_action (const char *name); +const char *lookup_keymap_shortcut (const global_keymap_t * keymap, unsigned long action); +unsigned long lookup_keymap_command (const global_keymap_t * keymap, long key); + +/*** inline functions ****************************************************************************/ +#endif /* MC__KEYBIND_H */ diff --git a/src/layout.c b/src/layout.c index 410507713..7000c738b 100644 --- a/src/layout.c +++ b/src/layout.c @@ -39,7 +39,7 @@ * resizing code depends on it... */ #ifdef HAVE_SYS_IOCTL_H -# include +#include #endif #include #include @@ -74,6 +74,8 @@ #include "setup.h" /* For save_setup() */ +/*** global variables ****************************************************************************/ + /* Controls the display of the rotating dash on the verbose mode */ int nice_rotating_dash = 1; @@ -110,11 +112,30 @@ int free_space = 1; /* The starting line for the output of the subprogram */ int output_start_y = 0; +/*** file scope macro definitions ****************************************************************/ + /* The maximum number of views managed by the set_display_type routine */ /* Must be at least two (for current and other). Please note that until */ /* Janne gets around this, we will only manage two of them :-) */ #define MAX_VIEWS 2 +/* Width 12 for a wee Quick (Hex) View */ +#define MINWIDTH 12 +#define MINHEIGHT 5 + +#define B_2LEFT B_USER +#define B_2RIGHT (B_USER + 1) +#define B_PLUS (B_USER + 2) +#define B_MINUS (B_USER + 3) + + +#define LAYOUT_OPTIONS_COUNT (sizeof (check_options) / sizeof (check_options[0])) +#define OTHER_OPTIONS_COUNT (LAYOUT_OPTIONS_COUNT - 1) + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + static struct { panel_view_mode_t type; @@ -149,15 +170,6 @@ static int _free_space; static int height; -/* Width 12 for a wee Quick (Hex) View */ -#define MINWIDTH 12 -#define MINHEIGHT 5 - -#define B_2LEFT B_USER -#define B_2RIGHT (B_USER + 1) -#define B_PLUS (B_USER + 2) -#define B_MINUS (B_USER + 3) - static const char *s_split_direction[2] = { N_("&Vertical"), N_("&Horizontal") @@ -184,15 +196,17 @@ static struct /* *INDENT-ON* */ }; -#define LAYOUT_OPTIONS_COUNT (sizeof (check_options) / sizeof (check_options[0])) -#define OTHER_OPTIONS_COUNT (LAYOUT_OPTIONS_COUNT - 1) - static gsize first_width; static const char *output_lines_label = NULL; static int output_lines_label_len; static WButton *bleft_widget, *bright_widget; +static int ok_to_refresh = 1; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static inline void _check_split (void) { @@ -219,8 +233,10 @@ _check_split (void) old_horizontal_split = _horizontal_split; } +/* --------------------------------------------------------------------------------------------- */ + static void -update_split (const Dlg_head *h) +update_split (const Dlg_head * h) { /* Check split has to be done before testing if it changed, since it can change due to calling _check_split() as well */ @@ -241,8 +257,10 @@ update_split (const Dlg_head *h) tty_print_char ('='); } +/* --------------------------------------------------------------------------------------------- */ + static int -b_left_right_cback (WButton *button, int action) +b_left_right_cback (WButton * button, int action) { (void) action; @@ -255,8 +273,10 @@ b_left_right_cback (WButton *button, int action) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int -bplus_cback (WButton *button, int action) +bplus_cback (WButton * button, int action) { (void) button; (void) action; @@ -266,8 +286,10 @@ bplus_cback (WButton *button, int action) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int -bminus_cback (WButton *button, int action) +bminus_cback (WButton * button, int action) { (void) button; (void) action; @@ -277,6 +299,8 @@ bminus_cback (WButton *button, int action) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t layout_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -380,6 +404,8 @@ layout_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *d } } +/* --------------------------------------------------------------------------------------------- */ + static Dlg_head * init_layout (void) { @@ -525,6 +551,86 @@ init_layout (void) return layout_dlg; } +/* --------------------------------------------------------------------------------------------- */ + +static void +check_split (void) +{ + if (horizontal_split) + { + if (equal_split) + first_panel_size = height / 2; + else if (first_panel_size < MINHEIGHT) + first_panel_size = MINHEIGHT; + else if (first_panel_size > height - MINHEIGHT) + first_panel_size = height - MINHEIGHT; + } + else + { + if (equal_split) + first_panel_size = COLS / 2; + else if (first_panel_size < MINWIDTH) + first_panel_size = MINWIDTH; + else if (first_panel_size > COLS - MINWIDTH) + first_panel_size = COLS - MINWIDTH; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +panel_do_cols (int idx) +{ + if (get_display_type (idx) == view_listing) + set_panel_formats ((WPanel *) panels[idx].widget); + else + panel_update_cols (panels[idx].widget, frame_half); +} + +/* --------------------------------------------------------------------------------------------- */ + +static inline void +low_level_change_screen_size (void) +{ +#if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 +#if defined TIOCGWINSZ + struct winsize winsz; + + winsz.ws_col = winsz.ws_row = 0; + /* Ioctl on the STDIN_FILENO */ + ioctl (0, TIOCGWINSZ, &winsz); + if (winsz.ws_col && winsz.ws_row) + { +#if defined(NCURSES_VERSION) && defined(HAVE_RESIZETERM) + resizeterm (winsz.ws_row, winsz.ws_col); + clearok (stdscr, TRUE); /* sigwinch's should use a semaphore! */ +#else + COLS = winsz.ws_col; + LINES = winsz.ws_row; +#endif +#ifdef HAVE_SUBSHELL_SUPPORT + resize_subshell (); +#endif + } +#endif /* TIOCGWINSZ */ +#endif /* defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 */ +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +dlg_resize_cb (void *data, void *user_data) +{ + Dlg_head *d = data; + + (void) user_data; + d->callback (d, NULL, DLG_RESIZE, 0, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void layout_change (void) { @@ -537,6 +643,8 @@ layout_change (void) load_hint (1); } +/* --------------------------------------------------------------------------------------------- */ + void layout_box (void) { @@ -569,28 +677,7 @@ layout_box (void) layout_change (); } -static void -check_split (void) -{ - if (horizontal_split) - { - if (equal_split) - first_panel_size = height / 2; - else if (first_panel_size < MINHEIGHT) - first_panel_size = MINHEIGHT; - else if (first_panel_size > height - MINHEIGHT) - first_panel_size = height - MINHEIGHT; - } - else - { - if (equal_split) - first_panel_size = COLS / 2; - else if (first_panel_size < MINWIDTH) - first_panel_size = MINWIDTH; - else if (first_panel_size > COLS - MINWIDTH) - first_panel_size = COLS - MINWIDTH; - } -} +/* --------------------------------------------------------------------------------------------- */ void clr_scr (void) @@ -600,6 +687,8 @@ clr_scr (void) tty_refresh (); } +/* --------------------------------------------------------------------------------------------- */ + void repaint_screen (void) { @@ -607,6 +696,8 @@ repaint_screen (void) tty_refresh (); } +/* --------------------------------------------------------------------------------------------- */ + void mc_refresh (void) { @@ -624,14 +715,7 @@ mc_refresh (void) } } -static void -panel_do_cols (int idx) -{ - if (get_display_type (idx) == view_listing) - set_panel_formats ((WPanel *) panels[idx].widget); - else - panel_update_cols (panels[idx].widget, frame_half); -} +/* --------------------------------------------------------------------------------------------- */ void setup_panels (void) @@ -717,41 +801,7 @@ setup_panels (void) update_xterm_title_path (); } -static inline void -low_level_change_screen_size (void) -{ -#if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 -#if defined TIOCGWINSZ - struct winsize winsz; - - winsz.ws_col = winsz.ws_row = 0; - /* Ioctl on the STDIN_FILENO */ - ioctl (0, TIOCGWINSZ, &winsz); - if (winsz.ws_col && winsz.ws_row) - { -#if defined(NCURSES_VERSION) && defined(HAVE_RESIZETERM) - resizeterm (winsz.ws_row, winsz.ws_col); - clearok (stdscr, TRUE); /* sigwinch's should use a semaphore! */ -#else - COLS = winsz.ws_col; - LINES = winsz.ws_row; -#endif -#ifdef HAVE_SUBSHELL_SUPPORT - resize_subshell (); -#endif - } -#endif /* TIOCGWINSZ */ -#endif /* defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 */ -} - -static void -dlg_resize_cb (void *data, void *user_data) -{ - Dlg_head *d = data; - - (void) user_data; - d->callback (d, NULL, DLG_RESIZE, 0, NULL); -} +/* --------------------------------------------------------------------------------------------- */ void sigwinch_handler (int dummy) @@ -763,6 +813,8 @@ sigwinch_handler (int dummy) winch_flag = 1; } +/* --------------------------------------------------------------------------------------------- */ + void change_screen_size (void) { @@ -799,7 +851,8 @@ change_screen_size (void) #endif /* defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 */ } -static int ok_to_refresh = 1; + +/* --------------------------------------------------------------------------------------------- */ void use_dash (gboolean flag) @@ -810,6 +863,8 @@ use_dash (gboolean flag) ok_to_refresh--; } +/* --------------------------------------------------------------------------------------------- */ + void set_hintbar (const char *str) { @@ -818,6 +873,8 @@ set_hintbar (const char *str) mc_refresh (); } +/* --------------------------------------------------------------------------------------------- */ + void print_vfs_message (const char *msg, ...) { @@ -855,6 +912,8 @@ print_vfs_message (const char *msg, ...) set_hintbar (str); } +/* --------------------------------------------------------------------------------------------- */ + void rotate_dash (void) { @@ -873,6 +932,8 @@ rotate_dash (void) pos++; } +/* --------------------------------------------------------------------------------------------- */ + const char * get_nth_panel_name (int num) { @@ -889,6 +950,7 @@ get_nth_panel_name (int num) } } +/* --------------------------------------------------------------------------------------------- */ /* I wonder if I should start to use the folding mode than Dugan uses */ /* */ /* This is the centralized managing of the panel display types */ @@ -900,6 +962,7 @@ get_nth_panel_name (int num) /* Set the num-th panel to the view type: type */ /* This routine also keeps at least one WPanel object in the screen */ /* since a lot of routines depend on the current_panel variable */ + void set_display_type (int num, panel_view_mode_t type) { @@ -965,7 +1028,7 @@ set_display_type (int num, panel_view_mode_t type) case view_info: new_widget = (Widget *) info_new (y, x, lines, cols); - break; + break; case view_tree: new_widget = (Widget *) tree_new (y, x, lines, cols, TRUE); @@ -973,7 +1036,7 @@ set_display_type (int num, panel_view_mode_t type) case view_quick: new_widget = (Widget *) mcview_new (y, x, lines, cols, TRUE); - the_other_panel = (WPanel *) panels [the_other].widget; + the_other_panel = (WPanel *) panels[the_other].widget; if (the_other_panel != NULL) file_name = the_other_panel->dir.list[the_other_panel->selected].fname; else @@ -1022,9 +1085,11 @@ set_display_type (int num, panel_view_mode_t type) g_free (old_widget); } -/* This routine is deeply sticked to the two panels idea. +/* --------------------------------------------------------------------------------------------- */ +/** This routine is deeply sticked to the two panels idea. What should it do in more panels. ANSWER - don't use it in any multiple panels environment. */ + void swap_panels (void) { @@ -1118,18 +1183,24 @@ swap_panels (void) } } +/* --------------------------------------------------------------------------------------------- */ + panel_view_mode_t get_display_type (int idx) { return panels[idx].type; } +/* --------------------------------------------------------------------------------------------- */ + struct Widget * get_panel_widget (int idx) { return panels[idx].widget; } +/* --------------------------------------------------------------------------------------------- */ + int get_current_index (void) { @@ -1139,19 +1210,25 @@ get_current_index (void) return 1; } +/* --------------------------------------------------------------------------------------------- */ + int get_other_index (void) { return !get_current_index (); } +/* --------------------------------------------------------------------------------------------- */ + struct WPanel * get_other_panel (void) { return (struct WPanel *) get_panel_widget (get_other_index ()); } -/* Returns the view type for the current panel/view */ +/* --------------------------------------------------------------------------------------------- */ +/** Returns the view type for the current panel/view */ + panel_view_mode_t get_current_type (void) { @@ -1161,7 +1238,9 @@ get_current_type (void) return panels[1].type; } -/* Returns the view type of the unselected panel */ +/* --------------------------------------------------------------------------------------------- */ +/** Returns the view type of the unselected panel */ + panel_view_mode_t get_other_type (void) { @@ -1171,7 +1250,9 @@ get_other_type (void) return panels[0].type; } -/* Save current list_view widget directory into panel */ +/* --------------------------------------------------------------------------------------------- */ +/** Save current list_view widget directory into panel */ + void save_panel_dir (int idx) { @@ -1189,7 +1270,9 @@ save_panel_dir (int idx) } } -/* Save current list_view widget directory into panel */ +/* --------------------------------------------------------------------------------------------- */ +/** Save current list_view widget directory into panel */ + Widget * restore_into_right_dir_panel (int idx, Widget * from_widget) { @@ -1206,8 +1289,10 @@ restore_into_right_dir_panel (int idx, Widget * from_widget) return new_widget; } -/* Return working dir, if it's view_listing - cwd, +/* --------------------------------------------------------------------------------------------- */ +/** Return working dir, if it's view_listing - cwd, but for other types - last_saved_dir */ + const char * get_panel_dir_for (const WPanel * widget) { @@ -1225,3 +1310,5 @@ get_panel_dir_for (const WPanel * widget) return panels[i].last_saved_dir; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/layout.h b/src/layout.h index 2df85c9b0..02aca8ca5 100644 --- a/src/layout.h +++ b/src/layout.h @@ -1,15 +1,38 @@ - /** \file layout.h * \brief Header: panel layout module */ -#ifndef MC_LAYOUT_H -#define MC_LAYOUT_H +#ifndef MC__LAYOUT_H +#define MC__LAYOUT_H #include "lib/global.h" #include "panel.h" #include "widget.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +extern int winch_flag; +extern int equal_split; +extern int first_panel_size; +extern int output_lines; +extern int command_prompt; +extern int keybar_visible; +extern int output_start_y; +extern int message_visible; +extern int xterm_title; +extern int free_space; + +extern int horizontal_split; +extern int nice_rotating_dash; + +/*** declarations of public functions ************************************************************/ + void layout_change (void); void layout_box (void); void setup_panels (void); @@ -30,8 +53,8 @@ struct Widget *get_panel_widget (int idx); struct WPanel *get_other_panel (void); void save_panel_dir (int idx); -Widget *restore_into_right_dir_panel (int idx, Widget *from_widget); -const char *get_panel_dir_for (const WPanel *widget); +Widget *restore_into_right_dir_panel (int idx, Widget * from_widget); +const char *get_panel_dir_for (const WPanel * widget); void set_hintbar (const char *str); @@ -44,18 +67,5 @@ void clr_scr (void); void repaint_screen (void); void mc_refresh (void); -extern int winch_flag; -extern int equal_split; -extern int first_panel_size; -extern int output_lines; -extern int command_prompt; -extern int keybar_visible; -extern int output_start_y; -extern int message_visible; -extern int xterm_title; -extern int free_space; - -extern int horizontal_split; -extern int nice_rotating_dash; - -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__LAYOUT_H */ diff --git a/src/learn.c b/src/learn.c index 2fb94fc9a..a889d816f 100644 --- a/src/learn.c +++ b/src/learn.c @@ -1,7 +1,7 @@ /* Learn keys Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. - + Written by: 1995 Jakub Jelinek This program is free software; you can redistribute it and/or modify @@ -38,17 +38,21 @@ #include "lib/tty/tty.h" #include "lib/tty/key.h" -#include "lib/mcconfig.h" /* Save profile */ +#include "lib/mcconfig.h" /* Save profile */ #include "lib/strescape.h" #include "lib/strutil.h" #include "dialog.h" #include "widget.h" #include "setup.h" -#include "layout.h" /* repaint_screen() */ +#include "layout.h" /* repaint_screen() */ #include "learn.h" #include "wtools.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define UX 4 #define UY 3 @@ -59,31 +63,45 @@ #define BUTTONS 2 -static struct { - int ret_cmd, flags, y, x; - const char *text; -} learn_but[BUTTONS] = { - /* *INDENT-OFF */ - { B_CANCEL, NORMAL_BUTTON, 0, 39, N_("&Cancel") }, - { B_ENTER, DEFPUSH_BUTTON, 0, 25, N_("&Save") } - /* *INDENT-ON */ -}; +/*** file scope type declarations ****************************************************************/ -static Dlg_head *learn_dlg; -typedef struct { +typedef struct +{ Widget *button; Widget *label; int ok; char *sequence; } learnkey; + +/*** file scope variables ************************************************************************/ + +static struct +{ + int ret_cmd, flags, y, x; + const char *text; +} learn_but[BUTTONS] = +{ + /* *INDENT-OFF */ + { + B_CANCEL, NORMAL_BUTTON, 0, 39, N_("&Cancel")}, + { + B_ENTER, DEFPUSH_BUTTON, 0, 25, N_("&Save")} + /* *INDENT-ON */ +}; + +static Dlg_head *learn_dlg; + static learnkey *learnkeys = NULL; static int learn_total; static int learnok; static int learnchanged; -static const char* learn_title = N_("Learn keys"); +static const char *learn_title = N_("Learn keys"); +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ -static int learn_button (WButton *button, int action) +static int +learn_button (WButton * button, int action) { Dlg_head *d; char *seq; @@ -91,63 +109,69 @@ static int learn_button (WButton *button, int action) (void) button; d = create_message (D_ERROR, _("Teach me a key"), -_("Please press the %s\n" -"and then wait until this message disappears.\n\n" -"Then, press it again to see if OK appears\n" -"next to its button.\n\n" -"If you want to escape, press a single Escape key\n" -"and wait as well."), - _(key_name_conv_tab [action - B_USER].longname)); + _("Please press the %s\n" + "and then wait until this message disappears.\n\n" + "Then, press it again to see if OK appears\n" + "next to its button.\n\n" + "If you want to escape, press a single Escape key\n" + "and wait as well."), _(key_name_conv_tab[action - B_USER].longname)); mc_refresh (); - if (learnkeys [action - B_USER].sequence != NULL) { - g_free (learnkeys [action - B_USER].sequence); - learnkeys [action - B_USER].sequence = NULL; + if (learnkeys[action - B_USER].sequence != NULL) + { + g_free (learnkeys[action - B_USER].sequence); + learnkeys[action - B_USER].sequence = NULL; } seq = learn_key (); - if (seq){ - /* Esc hides the dialog and do not allow definitions of - * regular characters - */ - gboolean seq_ok = FALSE; + if (seq) + { + /* Esc hides the dialog and do not allow definitions of + * regular characters + */ + gboolean seq_ok = FALSE; - if (*seq && strcmp (seq, "\\e") && strcmp (seq, "\\e\\e") - && strcmp (seq, "^m" ) && strcmp (seq, "^i" ) - && (seq [1] || (*seq < ' ' || *seq > '~'))){ + if (*seq && strcmp (seq, "\\e") && strcmp (seq, "\\e\\e") + && strcmp (seq, "^m") && strcmp (seq, "^i") && (seq[1] || (*seq < ' ' || *seq > '~'))) + { - learnchanged = 1; - learnkeys [action - B_USER].sequence = seq; - seq = convert_controls (seq); - seq_ok = define_sequence (key_name_conv_tab [action - B_USER].code, - seq, MCKEY_NOACTION); - } + learnchanged = 1; + learnkeys[action - B_USER].sequence = seq; + seq = convert_controls (seq); + seq_ok = define_sequence (key_name_conv_tab[action - B_USER].code, seq, MCKEY_NOACTION); + } - if (!seq_ok) - message (D_NORMAL, _("Cannot accept this key"), - _("You have entered \"%s\""), seq); + if (!seq_ok) + message (D_NORMAL, _("Cannot accept this key"), _("You have entered \"%s\""), seq); - g_free (seq); + g_free (seq); } dlg_run_done (d); destroy_dlg (d); - dlg_select_widget (learnkeys [action - B_USER].button); - return 0; /* Do not kill learn_dlg */ + dlg_select_widget (learnkeys[action - B_USER].button); + return 0; /* Do not kill learn_dlg */ } -static int learn_move (int right) +/* --------------------------------------------------------------------------------------------- */ + +static int +learn_move (int right) { int i, totalcols; - + totalcols = (learn_total - 1) / ROWS + 1; for (i = 0; i < learn_total; i++) - if (learnkeys [i].button == (Widget *) learn_dlg->current->data) { - if (right) { + if (learnkeys[i].button == (Widget *) learn_dlg->current->data) + { + if (right) + { if (i < learn_total - ROWS) i += ROWS; - else + else i %= ROWS; - } else { + } + else + { if (i / ROWS) i -= ROWS; else if (i + (totalcols - 1) * ROWS >= learn_total) @@ -155,85 +179,97 @@ static int learn_move (int right) else i += (totalcols - 1) * ROWS; } - dlg_select_widget (learnkeys [i].button); + dlg_select_widget (learnkeys[i].button); return 1; } return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int learn_check_key (int c) { int i; - for (i = 0; i < learn_total; i++) { - if (key_name_conv_tab[i].code != c || learnkeys[i].ok) - continue; + for (i = 0; i < learn_total; i++) + { + if (key_name_conv_tab[i].code != c || learnkeys[i].ok) + continue; - dlg_select_widget (learnkeys[i].button); - /* TRANSLATORS: This label appears near learned keys. Keep it short. */ - label_set_text ((WLabel *) learnkeys[i].label, _("OK")); - learnkeys[i].ok = 1; - learnok++; - if (learnok >= learn_total) { - learn_dlg->ret_value = B_CANCEL; - if (learnchanged) { - if (query_dialog (learn_title, - _ - ("It seems that all your keys already\n" - "work fine. That's great."), D_ERROR, 2, - _("&Save"), _("&Discard")) == 0) - learn_dlg->ret_value = B_ENTER; - } else { - message (D_ERROR, learn_title, - _ - ("Great! You have a complete terminal database!\n" - "All your keys work well.")); - } - dlg_stop (learn_dlg); - } - return 1; + dlg_select_widget (learnkeys[i].button); + /* TRANSLATORS: This label appears near learned keys. Keep it short. */ + label_set_text ((WLabel *) learnkeys[i].label, _("OK")); + learnkeys[i].ok = 1; + learnok++; + if (learnok >= learn_total) + { + learn_dlg->ret_value = B_CANCEL; + if (learnchanged) + { + if (query_dialog (learn_title, + _ + ("It seems that all your keys already\n" + "work fine. That's great."), D_ERROR, 2, + _("&Save"), _("&Discard")) == 0) + learn_dlg->ret_value = B_ENTER; + } + else + { + message (D_ERROR, learn_title, + _ + ("Great! You have a complete terminal database!\n" + "All your keys work well.")); + } + dlg_stop (learn_dlg); + } + return 1; } - switch (c) { + switch (c) + { case KEY_LEFT: case 'h': - return learn_move (0); + return learn_move (0); case KEY_RIGHT: case 'l': - return learn_move (1); + return learn_move (1); case 'j': - dlg_one_down (learn_dlg); - return 1; + dlg_one_down (learn_dlg); + return 1; case 'k': - dlg_one_up (learn_dlg); - return 1; + dlg_one_up (learn_dlg); + return 1; } /* Prevent from disappearing if a non-defined sequence is pressed and contains a button hotkey. Only recognize hotkeys with ALT. */ if (c < 255 && g_ascii_isalnum (c)) - return 1; + return 1; return 0; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t -learn_callback (Dlg_head *h, Widget *sender, - dlg_msg_t msg, int parm, void *data) +learn_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { - switch (msg) { + switch (msg) + { case DLG_DRAW: - common_dialog_repaint (h); - return MSG_HANDLED; + common_dialog_repaint (h); + return MSG_HANDLED; case DLG_KEY: - return learn_check_key (parm); + return learn_check_key (parm); default: - return default_dlg_callback (h, sender, msg, parm, data); + return default_dlg_callback (h, sender, msg, parm, data); } } +/* --------------------------------------------------------------------------------------------- */ + static void init_learn (void) { @@ -243,78 +279,79 @@ init_learn (void) #ifdef ENABLE_NLS static int i18n_flag = 0; - if (!i18n_flag) { - learn_but[0].text = _(learn_but[0].text); - learn_but[0].x = 78 / 2 + 4; + if (!i18n_flag) + { + learn_but[0].text = _(learn_but[0].text); + learn_but[0].x = 78 / 2 + 4; - learn_but[1].text = _(learn_but[1].text); - learn_but[1].x = 78 / 2 - (str_term_width1 (learn_but[1].text) + 9); + learn_but[1].text = _(learn_but[1].text); + learn_but[1].x = 78 / 2 - (str_term_width1 (learn_but[1].text) + 9); - learn_title = _(learn_title); - i18n_flag = 1; + learn_title = _(learn_title); + i18n_flag = 1; } -#endif /* ENABLE_NLS */ +#endif /* ENABLE_NLS */ do_refresh (); learn_dlg = - create_dlg (TRUE, 0, 0, 23, 78, dialog_colors, learn_callback, - "[Learn keys]", learn_title, DLG_CENTER | DLG_REVERSE); + create_dlg (TRUE, 0, 0, 23, 78, dialog_colors, learn_callback, + "[Learn keys]", learn_title, DLG_CENTER | DLG_REVERSE); for (i = 0; i < BUTTONS; i++) - add_widget (learn_dlg, - button_new (BY + learn_but[i].y, learn_but[i].x, - learn_but[i].ret_cmd, learn_but[i].flags, - _(learn_but[i].text), 0)); + add_widget (learn_dlg, + button_new (BY + learn_but[i].y, learn_but[i].x, + learn_but[i].ret_cmd, learn_but[i].flags, _(learn_but[i].text), 0)); x = UX; y = UY; for (key = key_name_conv_tab, j = 0; - key->name != NULL && strcmp (key->name, "kpleft"); - key++, j++) - ; + key->name != NULL && strcmp (key->name, "kpleft"); key++, j++) + ; learnkeys = g_new (learnkey, j); x += ((j - 1) / ROWS) * COLSHIFT; y += (j - 1) % ROWS; learn_total = j; learnok = 0; learnchanged = 0; - for (i = j - 1, key = key_name_conv_tab + j - 1; i >= 0; i--, key--) { - learnkeys[i].ok = 0; - learnkeys[i].sequence = NULL; - g_snprintf (buffer, sizeof (buffer), "%-16s", _(key->longname)); - add_widget (learn_dlg, learnkeys[i].button = (Widget *) - button_new (y, x, B_USER + i, NARROW_BUTTON, buffer, - learn_button)); - add_widget (learn_dlg, learnkeys[i].label = (Widget *) - label_new (y, x + 19, "")); - if (i % 13) - y--; - else { - x -= COLSHIFT; - y = UY + ROWS - 1; - } + for (i = j - 1, key = key_name_conv_tab + j - 1; i >= 0; i--, key--) + { + learnkeys[i].ok = 0; + learnkeys[i].sequence = NULL; + g_snprintf (buffer, sizeof (buffer), "%-16s", _(key->longname)); + add_widget (learn_dlg, learnkeys[i].button = (Widget *) + button_new (y, x, B_USER + i, NARROW_BUTTON, buffer, learn_button)); + add_widget (learn_dlg, learnkeys[i].label = (Widget *) label_new (y, x + 19, "")); + if (i % 13) + y--; + else + { + x -= COLSHIFT; + y = UY + ROWS - 1; + } } add_widget (learn_dlg, - label_new (UY + 14, 5, - _ - ("Press all the keys mentioned here. After you have done it, check"))); + label_new (UY + 14, 5, + _("Press all the keys mentioned here. After you have done it, check"))); add_widget (learn_dlg, - label_new (UY + 15, 5, - _ - ("which keys are not marked with OK. Press space on the missing"))); + label_new (UY + 15, 5, + _("which keys are not marked with OK. Press space on the missing"))); add_widget (learn_dlg, - label_new (UY + 16, 5, - _ - ("key, or click with the mouse to define it. Move around with Tab."))); + label_new (UY + 16, 5, + _("key, or click with the mouse to define it. Move around with Tab."))); } -static void learn_done (void) +/* --------------------------------------------------------------------------------------------- */ + +static void +learn_done (void) { destroy_dlg (learn_dlg); repaint_screen (); } +/* --------------------------------------------------------------------------------------------- */ + static void learn_save (void) { @@ -323,17 +360,19 @@ learn_save (void) char *section = g_strconcat ("terminal:", getenv ("TERM"), (char *) NULL); char *esc_str; - for (i = 0; i < learn_total; i++) { - if (learnkeys [i].sequence != NULL) { - profile_changed = 1; + for (i = 0; i < learn_total; i++) + { + if (learnkeys[i].sequence != NULL) + { + profile_changed = 1; - esc_str = strutils_escape (learnkeys [i].sequence, -1, ";\\", TRUE); + esc_str = strutils_escape (learnkeys[i].sequence, -1, ";\\", TRUE); - mc_config_direct_set_string(mc_main_config, section, - key_name_conv_tab [i].name, esc_str); + mc_config_direct_set_string (mc_main_config, section, + key_name_conv_tab[i].name, esc_str); - g_free(esc_str); - } + g_free (esc_str); + } } /* On the one hand no good idea to save the complete setup but @@ -343,32 +382,38 @@ learn_save (void) * disk is much worse. */ if (profile_changed) - mc_config_save_file (mc_main_config, NULL); + mc_config_save_file (mc_main_config, NULL); g_free (section); } -void learn_keys (void) +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +learn_keys (void) { int save_old_esc_mode = old_esc_mode; int save_alternate_plus_minus = alternate_plus_minus; - - old_esc_mode = 0; /* old_esc_mode cannot work in learn keys dialog */ - alternate_plus_minus = 1; /* don't translate KP_ADD, KP_SUBTRACT and - KP_MULTIPLY to '+', '-' and '*' in - correct_key_code */ + + old_esc_mode = 0; /* old_esc_mode cannot work in learn keys dialog */ + alternate_plus_minus = 1; /* don't translate KP_ADD, KP_SUBTRACT and + KP_MULTIPLY to '+', '-' and '*' in + correct_key_code */ application_keypad_mode (); init_learn (); run_dlg (learn_dlg); - + old_esc_mode = save_old_esc_mode; alternate_plus_minus = save_alternate_plus_minus; if (!alternate_plus_minus) numeric_keypad_mode (); - - switch (learn_dlg->ret_value) { + + switch (learn_dlg->ret_value) + { case B_ENTER: learn_save (); break; @@ -377,3 +422,4 @@ void learn_keys (void) learn_done (); } +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/learn.h b/src/learn.h index 0cc521201..d0eb056a7 100644 --- a/src/learn.h +++ b/src/learn.h @@ -1,11 +1,21 @@ - /** \file learn.h * \brief Header: learn keys module */ -#ifndef MC_LEARN_H -#define MC_LEARN_H +#ifndef MC__LEARN_H +#define MC__LEARN_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ void learn_keys (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__LEARN_H */ diff --git a/src/listmode.c b/src/listmode.c index 429e8c92a..06c4c6669 100644 --- a/src/listmode.c +++ b/src/listmode.c @@ -3,7 +3,7 @@ 2006, 2007 Free Software Foundation, Inc. Written by: 1994 Radek Doulik - 1995 Janne Kukonlehto + 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 @@ -45,12 +45,16 @@ /* Needed for the extern declarations of integer parameters */ #include "dir.h" -#include "panel.h" /* Needed for the externs */ +#include "panel.h" /* Needed for the externs */ #include "file.h" -#include "layout.h" /* repaint_screen() */ +#include "layout.h" /* repaint_screen() */ #include "main.h" #include "listmode.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define UX 5 #define UY 2 @@ -60,6 +64,26 @@ #define B_ADD B_USER #define B_REMOVE (B_USER + 1) +#define B_PLUS B_USER +#define B_MINUS (B_USER+1) + +/*** file scope type declarations ****************************************************************/ + +struct listmode_button +{ + int ret_cmd, flags, y, x; + char *text; + bcback callback; +}; + +struct listmode_label +{ + int y, x; + char *text; +}; + +/*** file scope variables ************************************************************************/ + static WListbox *l_listmode; static WLabel *pname; @@ -67,29 +91,20 @@ static WLabel *pname; static char *listmode_section = "[Listing format edit]"; static char *s_genwidth[2] = { "Half width", "Full width" }; + static WRadio *radio_genwidth; static char *s_columns[2] = { "One column", "Two columns" }; + static WRadio *radio_columns; -static char *s_justify[3] = - { "Left justified", "Default justification", "Right justified" }; +static char *s_justify[3] = { "Left justified", "Default justification", "Right justified" }; + static WRadio *radio_justify; -static char *s_itemwidth[3] = - { "Free width", "Fixed width", "Growable width" }; +static char *s_itemwidth[3] = { "Free width", "Fixed width", "Growable width" }; + static WRadio *radio_itemwidth; -struct listmode_button { - int ret_cmd, flags, y, x; - char *text; - bcback callback; -}; - -#define B_PLUS B_USER -#define B_MINUS (B_USER+1) - -struct listmode_label { - int y, x; - char *text; -}; +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static char * select_new_item (void) @@ -99,46 +114,54 @@ select_new_item (void) int i; Listbox *mylistbox; - possible_items = panel_get_user_possible_fields(NULL); + possible_items = panel_get_user_possible_fields (NULL); - mylistbox = - create_listbox_window (20, 12, "Add listing format item", - listmode_section); - for (i = 0; possible_items[i]; i++) { - listbox_add_item (mylistbox->list, LISTBOX_APPEND_AT_END, 0, possible_items[i], NULL); + mylistbox = create_listbox_window (20, 12, "Add listing format item", listmode_section); + for (i = 0; possible_items[i]; i++) + { + listbox_add_item (mylistbox->list, LISTBOX_APPEND_AT_END, 0, possible_items[i], NULL); } i = run_listbox (mylistbox); if (i >= 0) - ret = g_strdup(possible_items[i]); + ret = g_strdup (possible_items[i]); g_strfreev (possible_items); return ret; } +/* --------------------------------------------------------------------------------------------- */ + static int bplus_cback (int action) { return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int bminus_cback (int action) { return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int badd_cback (int action) { char *s = select_new_item (); - if (s) { - listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL); - g_free(s); + if (s) + { + listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL); + g_free (s); } return 0; } +/* --------------------------------------------------------------------------------------------- */ + static int bremove_cback (int action) { @@ -146,6 +169,8 @@ bremove_cback (int action) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static Dlg_head * init_listmode (char *oldlistformat) { @@ -156,47 +181,40 @@ init_listmode (char *oldlistformat) Dlg_head *listmode_dlg; static struct listmode_label listmode_labels[] = { - {UY + 13, UX + 22, "Item width:"} + {UY + 13, UX + 22, "Item width:"} }; static struct listmode_button listmode_but[] = { - {B_CANCEL, NORMAL_BUTTON, BY, BX + 53, "&Cancel", NULL}, - {B_ADD, NORMAL_BUTTON, BY, BX + 22, "&Add item", badd_cback}, - {B_REMOVE, NORMAL_BUTTON, BY, BX + 10, "&Remove", bremove_cback}, - {B_ENTER, DEFPUSH_BUTTON, BY, BX, "&OK", NULL}, - {B_PLUS, NARROW_BUTTON, UY + 13, UX + 37, "&+", bplus_cback}, - {B_MINUS, NARROW_BUTTON, UY + 13, UX + 34, "&-", bminus_cback}, + {B_CANCEL, NORMAL_BUTTON, BY, BX + 53, "&Cancel", NULL}, + {B_ADD, NORMAL_BUTTON, BY, BX + 22, "&Add item", badd_cback}, + {B_REMOVE, NORMAL_BUTTON, BY, BX + 10, "&Remove", bremove_cback}, + {B_ENTER, DEFPUSH_BUTTON, BY, BX, "&OK", NULL}, + {B_PLUS, NARROW_BUTTON, UY + 13, UX + 37, "&+", bplus_cback}, + {B_MINUS, NARROW_BUTTON, UY + 13, UX + 34, "&-", bminus_cback}, }; do_refresh (); listmode_dlg = - create_dlg (TRUE, 0, 0, 22, 74, dialog_colors, NULL, listmode_section, - "Listing format edit", DLG_CENTER | DLG_REVERSE); + create_dlg (TRUE, 0, 0, 22, 74, dialog_colors, NULL, listmode_section, + "Listing format edit", DLG_CENTER | DLG_REVERSE); - add_widget (listmode_dlg, - groupbox_new (UY, UX, 4, 63, "General options")); + add_widget (listmode_dlg, groupbox_new (UY, UX, 4, 63, "General options")); add_widget (listmode_dlg, groupbox_new (UY + 4, UX, 11, 18, "Items")); - add_widget (listmode_dlg, - groupbox_new (UY + 4, UX + 20, 11, 43, "Item options")); + add_widget (listmode_dlg, groupbox_new (UY + 4, UX + 20, 11, 43, "Item options")); - for (i = 0; - i < sizeof (listmode_but) / sizeof (struct listmode_button); i++) - add_widget (listmode_dlg, - button_new (listmode_but[i].y, listmode_but[i].x, - listmode_but[i].ret_cmd, - listmode_but[i].flags, - listmode_but[i].text, - listmode_but[i].callback)); + for (i = 0; i < sizeof (listmode_but) / sizeof (struct listmode_button); i++) + add_widget (listmode_dlg, + button_new (listmode_but[i].y, listmode_but[i].x, + listmode_but[i].ret_cmd, + listmode_but[i].flags, + listmode_but[i].text, listmode_but[i].callback)); /* We add the labels. */ - for (i = 0; - i < sizeof (listmode_labels) / sizeof (struct listmode_label); - i++) { - pname = - label_new (listmode_labels[i].y, listmode_labels[i].x, - listmode_labels[i].text); - add_widget (listmode_dlg, pname); + for (i = 0; i < sizeof (listmode_labels) / sizeof (struct listmode_label); i++) + { + pname = label_new (listmode_labels[i].y, listmode_labels[i].x, listmode_labels[i].text); + add_widget (listmode_dlg, pname); } radio_itemwidth = radio_new (UY + 9, UX + 22, 3, s_itemwidth); @@ -209,25 +227,30 @@ init_listmode (char *oldlistformat) /* get new listbox */ l_listmode = listbox_new (UY + 5, UX + 1, 9, 16, FALSE, NULL); - if (strncmp (oldlistformat, "full ", 5) == 0) { - format_width = 1; - oldlistformat += 5; + if (strncmp (oldlistformat, "full ", 5) == 0) + { + format_width = 1; + oldlistformat += 5; } - if (strncmp (oldlistformat, "half ", 5) == 0) { - oldlistformat += 5; + if (strncmp (oldlistformat, "half ", 5) == 0) + { + oldlistformat += 5; } - if (strncmp (oldlistformat, "2 ", 2) == 0) { - format_columns = 1; - oldlistformat += 2; + if (strncmp (oldlistformat, "2 ", 2) == 0) + { + format_columns = 1; + oldlistformat += 2; } - if (strncmp (oldlistformat, "1 ", 2) == 0) { - oldlistformat += 2; + if (strncmp (oldlistformat, "1 ", 2) == 0) + { + oldlistformat += 2; } s = strtok (oldlistformat, ","); - while (s) { - listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL); - s = strtok (NULL, ","); + while (s) + { + listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL); + s = strtok (NULL, ","); } /* add listbox to the dialogs */ @@ -243,15 +266,19 @@ init_listmode (char *oldlistformat) return listmode_dlg; } +/* --------------------------------------------------------------------------------------------- */ + static void -listmode_done (Dlg_head *h) +listmode_done (Dlg_head * h) { destroy_dlg (h); if (0) - update_panels (UP_OPTIMIZE, UP_KEEPSEL); + update_panels (UP_OPTIMIZE, UP_KEEPSEL); repaint_screen (); } +/* --------------------------------------------------------------------------------------------- */ + static char * collect_new_format (void) { @@ -262,26 +289,31 @@ collect_new_format (void) newformat = g_malloc (1024); if (radio_genwidth->sel) - strcpy (newformat, "full "); + strcpy (newformat, "full "); else - strcpy (newformat, "half "); + strcpy (newformat, "half "); if (radio_columns->sel) - strcat (newformat, "2 "); + strcat (newformat, "2 "); last = NULL; - for (i = 0;; i++) { - listbox_select_entry (l_listmode, i); - listbox_get_current (l_listmode, &text, &extra); - if (text == last) - break; - if (last != NULL) - strcat (newformat, ","); - strcat (newformat, text); - last = text; + for (i = 0;; i++) + { + listbox_select_entry (l_listmode, i); + listbox_get_current (l_listmode, &text, &extra); + if (text == last) + break; + if (last != NULL) + strcat (newformat, ","); + strcat (newformat, text); + last = text; } return newformat; } -/* Return new format or NULL if the user cancelled the dialog */ +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** Return new format or NULL if the user cancelled the dialog */ char * listmode_edit (char *oldlistformat) { @@ -293,11 +325,15 @@ listmode_edit (char *oldlistformat) listmode_dlg = init_listmode (s); g_free (s); - if (run_dlg (listmode_dlg) == B_ENTER) { - newformat = collect_new_format (); + if (run_dlg (listmode_dlg) == B_ENTER) + { + newformat = collect_new_format (); } listmode_done (listmode_dlg); return newformat; } -#endif /* LISTMODE_EDITOR */ + +/* --------------------------------------------------------------------------------------------- */ + +#endif /* LISTMODE_EDITOR */ diff --git a/src/listmode.h b/src/listmode.h index d6b5e9df7..a27ab380a 100644 --- a/src/listmode.h +++ b/src/listmode.h @@ -1,13 +1,22 @@ - /** \file listmode.h * \brief Header: directory panel listing format editor */ -#ifndef MC_LISTMODE_H -#define MC_LISTMODE_H +#ifndef MC__LISTMODE_H +#define MC__LISTMODE_H +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ #ifdef LISTMODE_EDITOR -char *listmode_edit (char*); +char *listmode_edit (char *); #endif /* LISTMODE_EDITOR */ -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__LISTMODE_H */ diff --git a/src/main-widgets.h b/src/main-widgets.h index 146fc251a..bdb2d9c61 100644 --- a/src/main-widgets.h +++ b/src/main-widgets.h @@ -1,19 +1,29 @@ - /** \file main-widgets.h * \brief Header: provides definitions for some widgets */ -#ifndef MC_MAIN_WIDGETS_H -#define MC_MAIN_WIDGETS_H +#ifndef MC__MAIN_WIDGETS_H +#define MC__MAIN_WIDGETS_H #include "widget.h" #include "dialog.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + extern WButtonBar *the_bar; -extern WLabel *the_prompt; -extern WLabel *the_hint; -extern Dlg_head *midnight_dlg; +extern WLabel *the_prompt; +extern WLabel *the_hint; +extern Dlg_head *midnight_dlg; extern struct WMenuBar *the_menubar; -#endif +/*** declarations of public functions ************************************************************/ + +/*** inline functions ****************************************************************************/ +#endif /* MC__MAIN_WIDGETS_H */ diff --git a/src/main.c b/src/main.c index a208cd648..ed9968301 100644 --- a/src/main.c +++ b/src/main.c @@ -102,9 +102,10 @@ #include "selcodepage.h" #endif /* HAVE_CHARSET */ - #include "keybind.h" /* type global_keymap_t */ +/*** global variables ****************************************************************************/ + /* When the modes are active, left_panel, right_panel and tree_panel */ /* Point to a proper data structure. You should check with the functions */ /* get_current_type and get_other_type the types of the panels before using */ @@ -154,14 +155,7 @@ int pause_after_run = pause_on_dumb_terminals; /* It true saves the setup when quitting */ int auto_save_setup = 1; -#ifdef HAVE_CHARSET -/* - * Don't restrict the output on the screen manager level, - * the translation tables take care of it. - */ -#define full_eight_bits (1) -#define eight_bit_clean (1) -#else /* HAVE_CHARSET */ +#ifndef HAVE_CHARSET /* If true, allow characters in the range 160-255 */ int eight_bit_clean = 1; /* @@ -247,13 +241,8 @@ int boot_current_is_left = 1; int xtree_mode = 0; /* path to X clipboard utility */ -char* clipboard_store_path = NULL; -char* clipboard_paste_path = NULL; - -/* If set, then print to the given file the last directory we were at */ -static char *last_wd_string = NULL; -/* Set to 1 to suppress printing the last directory */ -static int print_last_revert = 0; +char *clipboard_store_path = NULL; +char *clipboard_paste_path = NULL; mc_run_mode_t mc_run_mode = MC_RUN_FULL; char *mc_run_param0 = NULL; @@ -272,48 +261,34 @@ char *mc_home = NULL; /* mc_home_alt: Alternative home of MC - deprecated /usr/share/mc */ char *mc_home_alt = NULL; -/* Define this function for glib-style error handling */ -GQuark -mc_main_error_quark (void) -{ - return g_quark_from_static_string (PACKAGE); -} +/*** file scope macro definitions ****************************************************************/ -/* Save current stat of directories to avoid reloading the panels */ -/* when no modifications have taken place */ -void -save_cwds_stat (void) -{ - if (panels_options.fast_reload) - { - mc_stat (current_panel->cwd, &(current_panel->dir_stat)); - if (get_other_type () == view_listing) - mc_stat (other_panel->cwd, &(other_panel->dir_stat)); - } -} +#ifdef HAVE_CHARSET +/* + * Don't restrict the output on the screen manager level, + * the translation tables take care of it. + */ +#define full_eight_bits (1) +#define eight_bit_clean (1) +#endif /* !HAVE_CHARSET */ -#ifdef HAVE_SUBSHELL_SUPPORT -void -do_update_prompt (void) -{ - if (update_prompt) - { - printf ("\r\n%s", subshell_prompt); - fflush (stdout); - update_prompt = 0; - } -} -#endif /* HAVE_SUBSHELL_SUPPORT */ +/*** file scope type declarations ****************************************************************/ -void -change_panel (void) -{ - free_completions (cmdline); - dlg_one_down (midnight_dlg); -} +/*** file scope variables ************************************************************************/ -/* Stop MC main dialog and the current dialog if it exists. +/* If set, then print to the given file the last directory we were at */ +static char *last_wd_string = NULL; +/* Set to 1 to suppress printing the last directory */ +static int print_last_revert = 0; + +static gboolean ctl_x_map_enabled = FALSE; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** Stop MC main dialog and the current dialog if it exists. * Needed to provide fast exit from MC viewer or editor on shell exit */ + static void stop_dialogs (void) { @@ -323,6 +298,8 @@ stop_dialogs (void) ((Dlg_head *) top_dlg->data)->state = DLG_CLOSED; } +/* --------------------------------------------------------------------------------------------- */ + static gboolean quit_cmd_internal (int quiet) { @@ -335,14 +312,13 @@ quit_cmd_internal (int quiet) g_snprintf (msg, sizeof (msg), ngettext ("You have %zd opened screen. Quit anyway?", - "You have %zd opened screens. Quit anyway?", n), - n); + "You have %zd opened screens. Quit anyway?", n), n); - if (query_dialog (_("The Midnight Commander"), msg, - D_NORMAL, 2, _("&Yes"), _("&No")) != 0) + if (query_dialog (_("The Midnight Commander"), msg, D_NORMAL, 2, _("&Yes"), _("&No")) != 0) return FALSE; q = 1; - } else if (quiet || !confirm_exit) + } + else if (quiet || !confirm_exit) q = 1; else if (query_dialog (_("The Midnight Commander"), _("Do you really want to quit the Midnight Commander?"), @@ -364,111 +340,15 @@ quit_cmd_internal (int quiet) return (quit != 0); } +/* --------------------------------------------------------------------------------------------- */ + static gboolean quit_cmd (void) { return quit_cmd_internal (0); } -gboolean -quiet_quit_cmd (void) -{ - print_last_revert = 1; - return quit_cmd_internal (1); -} - -/* Wrapper for do_subshell_chdir, check for availability of subshell */ -void -subshell_chdir (const char *directory) -{ -#ifdef HAVE_SUBSHELL_SUPPORT - if (use_subshell) - { - if (vfs_current_is_local ()) - do_subshell_chdir (directory, 0, 1); - } -#endif /* HAVE_SUBSHELL_SUPPORT */ -} - -int -do_cd (const char *new_dir, enum cd_enum exact) -{ - gboolean res; - - res = do_panel_cd (current_panel, new_dir, exact); - -#if HAVE_CHARSET - if (res) - { - const char *enc_name; - - enc_name = vfs_get_encoding (current_panel->cwd); - if (enc_name != NULL) - current_panel->codepage = get_codepage_index (enc_name); - else - current_panel->codepage = SELECT_CHARSET_NO_TRANSLATE; - } -#endif /* HAVE_CHARSET */ - - return res ? 1 : 0; -} - -#ifdef HAVE_SUBSHELL_SUPPORT -int -load_prompt (int fd, void *unused) -{ - (void) fd; - (void) unused; - - if (!read_subshell_prompt ()) - return 0; - - /* Don't actually change the prompt if it's invisible */ - if (((Dlg_head *) top_dlg->data == midnight_dlg) && command_prompt) - { - char *tmp_prompt; - int prompt_len; - - tmp_prompt = strip_ctrl_codes (subshell_prompt); - prompt_len = str_term_width1 (tmp_prompt); - - /* Check for prompts too big */ - if (COLS > 8 && prompt_len > COLS - 8) - { - prompt_len = COLS - 8; - tmp_prompt[prompt_len] = '\0'; - } - mc_prompt = tmp_prompt; - label_set_text (the_prompt, mc_prompt); - winput_set_origin ((WInput *) cmdline, prompt_len, COLS - prompt_len); - - /* since the prompt has changed, and we are called from one of the - * tty_get_event channels, the prompt updating does not take place - * automatically: force a cursor update and a screen refresh - */ - update_cursor (midnight_dlg); - mc_refresh (); - } - update_prompt = 1; - return 0; -} -#endif /* HAVE_SUBSHELL_SUPPORT */ - -void -sort_cmd (void) -{ - WPanel *p; - const panel_field_t *sort_order; - - if (!SELECTED_IS_PANEL) - return; - - p = MENU_PANEL; - sort_order = sort_box (p->current_sort_field, &p->reverse, &p->case_sensitive, &p->exec_first); - - panel_set_sort_order (p, sort_order); - -} +/* --------------------------------------------------------------------------------------------- */ static void treebox_cmd (void) @@ -483,6 +363,8 @@ treebox_cmd (void) } } +/* --------------------------------------------------------------------------------------------- */ + #ifdef LISTMODE_EDITOR static void listmode_cmd (void) @@ -505,22 +387,26 @@ listmode_cmd (void) } #endif /* LISTMODE_EDITOR */ +/* --------------------------------------------------------------------------------------------- */ /* NOTICE: hotkeys specified here are overriden in menubar_paint_idx (alex) */ + static GList * create_panel_menu (void) { GList *entries = NULL; - entries = g_list_append (entries, menu_entry_create (_("File listin&g"), CK_ListingCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Quick view"), CK_QuickViewCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Info"), CK_InfoCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Tree"), CK_TreeCmd)); + entries = g_list_append (entries, menu_entry_create (_("File listin&g"), CK_ListingCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Quick view"), CK_QuickViewCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Info"), CK_InfoCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Tree"), CK_TreeCmd)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Listing mode..."), CK_ChangeListingCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Sort order..."), CK_Sort)); - entries = g_list_append (entries, menu_entry_create (_("&Filter..."), CK_FilterCmd)); + entries = + g_list_append (entries, menu_entry_create (_("&Listing mode..."), CK_ChangeListingCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Sort order..."), CK_Sort)); + entries = g_list_append (entries, menu_entry_create (_("&Filter..."), CK_FilterCmd)); #ifdef HAVE_CHARSET - entries = g_list_append (entries, menu_entry_create (_("&Encoding..."), CK_PanelSetPanelEncoding)); + entries = + g_list_append (entries, menu_entry_create (_("&Encoding..."), CK_PanelSetPanelEncoding)); #endif #ifdef ENABLE_VFS_NET entries = g_list_append (entries, menu_separator_create ()); @@ -540,6 +426,8 @@ create_panel_menu (void) return entries; } +/* --------------------------------------------------------------------------------------------- */ + static GList * create_file_menu (void) { @@ -553,7 +441,8 @@ create_file_menu (void) entries = g_list_append (entries, menu_entry_create (_("C&hmod"), CK_ChmodCmd)); entries = g_list_append (entries, menu_entry_create (_("&Link"), CK_LinkCmd)); entries = g_list_append (entries, menu_entry_create (_("&Symlink"), CK_SymlinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("Relative symlin&k"), CK_RelativeSymlinkCmd)); + entries = + g_list_append (entries, menu_entry_create (_("Relative symlin&k"), CK_RelativeSymlinkCmd)); entries = g_list_append (entries, menu_entry_create (_("Edit s&ymlink"), CK_EditSymlinkCmd)); entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd)); entries = @@ -574,6 +463,8 @@ create_file_menu (void) return entries; } +/* --------------------------------------------------------------------------------------------- */ + static GList * create_command_menu (void) { @@ -633,17 +524,20 @@ create_command_menu (void) return entries; } +/* --------------------------------------------------------------------------------------------- */ + static GList * create_options_menu (void) { GList *entries = NULL; entries = g_list_append (entries, menu_entry_create (_("&Configuration..."), CK_ConfigureBox)); - entries = g_list_append (entries, menu_entry_create (_("&Layout..."), CK_LayoutBox)); - entries = g_list_append (entries, menu_entry_create (_("&Panel options..."), CK_PanelOptionsBox)); - entries = g_list_append (entries, menu_entry_create (_("C&onfirmation..."), CK_ConfirmBox)); - entries = g_list_append (entries, menu_entry_create (_("&Display bits..."), CK_DisplayBitsBox)); - entries = g_list_append (entries, menu_entry_create (_("Learn &keys..."), CK_LearnKeys)); + entries = g_list_append (entries, menu_entry_create (_("&Layout..."), CK_LayoutBox)); + entries = + g_list_append (entries, menu_entry_create (_("&Panel options..."), CK_PanelOptionsBox)); + entries = g_list_append (entries, menu_entry_create (_("C&onfirmation..."), CK_ConfirmBox)); + entries = g_list_append (entries, menu_entry_create (_("&Display bits..."), CK_DisplayBitsBox)); + entries = g_list_append (entries, menu_entry_create (_("Learn &keys..."), CK_LearnKeys)); #ifdef ENABLE_VFS entries = g_list_append (entries, menu_entry_create (_("&Virtual FS..."), CK_ConfigureVfs)); #endif @@ -653,27 +547,7 @@ create_options_menu (void) return entries; } -void -init_menu (void) -{ - menubar_add_menu (the_menubar, - create_menu (horizontal_split ? _("&Above") : _("&Left"), - create_panel_menu (), "[Left and Right Menus]")); - menubar_add_menu (the_menubar, create_menu (_("&File"), create_file_menu (), "[File Menu]")); - menubar_add_menu (the_menubar, - create_menu (_("&Command"), create_command_menu (), "[Command Menu]")); - menubar_add_menu (the_menubar, - create_menu (_("&Options"), create_options_menu (), "[Options Menu]")); - menubar_add_menu (the_menubar, - create_menu (horizontal_split ? _("&Below") : _("&Right"), - create_panel_menu (), "[Left and Right Menus]")); -} - -void -done_menu (void) -{ - menubar_set_menu (the_menubar, NULL); -} +/* --------------------------------------------------------------------------------------------- */ static void menu_last_selected_cmd (void) @@ -684,6 +558,8 @@ menu_last_selected_cmd (void) dlg_select_widget (the_menubar); } +/* --------------------------------------------------------------------------------------------- */ + static void menu_cmd (void) { @@ -697,6 +573,8 @@ menu_cmd (void) menu_last_selected_cmd (); } +/* --------------------------------------------------------------------------------------------- */ + static char * midnight_get_shortcut (unsigned long command) { @@ -720,8 +598,10 @@ midnight_get_shortcut (unsigned long command) return NULL; } +/* --------------------------------------------------------------------------------------------- */ + static char * -midnight_get_title (const Dlg_head *h, size_t len) +midnight_get_title (const Dlg_head * h, size_t len) { /* TODO: share code with update_xterm_title_path() */ @@ -739,7 +619,7 @@ midnight_get_title (const Dlg_head *h, size_t len) if (res != 0) host[0] = '\0'; else - host [sizeof (host) - 1] = '\0'; + host[sizeof (host) - 1] = '\0'; pw = getpwuid (getuid ()); if (pw != NULL) @@ -755,12 +635,7 @@ midnight_get_title (const Dlg_head *h, size_t len) return g_strdup (path); } -void -toggle_show_hidden (void) -{ - panels_options.show_dot_files = !panels_options.show_dot_files; - update_panels (UP_RELOAD, UP_KEEPSEL); -} +/* --------------------------------------------------------------------------------------------- */ static void toggle_panels_split (void) @@ -770,10 +645,12 @@ toggle_panels_split (void) do_refresh (); } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Just a hack for allowing url-like pathnames to be accepted from the * command line. */ + static void translated_mc_chdir (char *dir) { @@ -785,6 +662,8 @@ translated_mc_chdir (char *dir) g_free (newdir); } +/* --------------------------------------------------------------------------------------------- */ + static void create_panels (void) { @@ -857,6 +736,8 @@ create_panels (void) the_menubar = menubar_new (0, 0, COLS, NULL); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_current_pathname (void) { @@ -872,6 +753,8 @@ copy_current_pathname (void) g_free (cwd_path); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_other_pathname (void) { @@ -891,6 +774,8 @@ copy_other_pathname (void) g_free (cwd_path); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_readlink (WPanel * panel) { @@ -912,12 +797,16 @@ copy_readlink (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void copy_current_readlink (void) { copy_readlink (current_panel); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_other_readlink (void) { @@ -925,7 +814,9 @@ copy_other_readlink (void) copy_readlink (other_panel); } -/* Insert the selected file name into the input line */ +/* --------------------------------------------------------------------------------------------- */ +/** Insert the selected file name into the input line */ + static void copy_prog_name (void) { @@ -944,6 +835,8 @@ copy_prog_name (void) command_insert (cmdline, tmp, 1); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_tagged (WPanel * panel) { @@ -967,12 +860,16 @@ copy_tagged (WPanel * panel) input_enable_update (cmdline); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_current_tagged (void) { copy_tagged (current_panel); } +/* --------------------------------------------------------------------------------------------- */ + static void copy_other_tagged (void) { @@ -980,22 +877,7 @@ copy_other_tagged (void) copy_tagged (other_panel); } -void -midnight_set_buttonbar (WButtonBar * b) -{ - buttonbar_set_label (b, 1, Q_ ("ButtonBar|Help"), main_map, NULL); - buttonbar_set_label (b, 2, Q_ ("ButtonBar|Menu"), main_map, NULL); - buttonbar_set_label (b, 3, Q_ ("ButtonBar|View"), main_map, NULL); - buttonbar_set_label (b, 4, Q_ ("ButtonBar|Edit"), main_map, NULL); - buttonbar_set_label (b, 5, Q_ ("ButtonBar|Copy"), main_map, NULL); - buttonbar_set_label (b, 6, Q_ ("ButtonBar|RenMov"), main_map, NULL); - buttonbar_set_label (b, 7, Q_ ("ButtonBar|Mkdir"), main_map, NULL); - buttonbar_set_label (b, 8, Q_ ("ButtonBar|Delete"), main_map, NULL); - buttonbar_set_label (b, 9, Q_ ("ButtonBar|PullDn"), main_map, NULL); - buttonbar_set_label (b, 10, Q_ ("ButtonBar|Quit"), main_map, NULL); -} - -static gboolean ctl_x_map_enabled = FALSE; +/* --------------------------------------------------------------------------------------------- */ static void ctl_x_cmd (void) @@ -1003,6 +885,8 @@ ctl_x_cmd (void) ctl_x_map_enabled = TRUE; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t midnight_execute_cmd (Widget * sender, unsigned long command) { @@ -1278,6 +1162,8 @@ midnight_execute_cmd (Widget * sender, unsigned long command) return res; } +/* --------------------------------------------------------------------------------------------- */ + static void init_xterm_support (void) { @@ -1330,6 +1216,8 @@ init_xterm_support (void) } } +/* --------------------------------------------------------------------------------------------- */ + static void setup_mc (void) { @@ -1353,6 +1241,8 @@ setup_mc (void) init_mouse (); } +/* --------------------------------------------------------------------------------------------- */ + static void setup_dummy_mc (void) { @@ -1364,6 +1254,8 @@ setup_dummy_mc (void) ret = mc_chdir (d); } +/* --------------------------------------------------------------------------------------------- */ + static void check_codeset () { @@ -1395,6 +1287,8 @@ check_codeset () utf8_display = str_isutf8 (current_system_codepage); } +/* --------------------------------------------------------------------------------------------- */ + static void done_screen (void) { @@ -1406,6 +1300,8 @@ done_screen (void) tty_colors_done (); } +/* --------------------------------------------------------------------------------------------- */ + static void done_mc (void) { @@ -1435,6 +1331,8 @@ done_mc (void) vfs_stamp_path (other_panel->cwd); } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t midnight_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -1574,7 +1472,7 @@ midnight_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void case DLG_HOTKEY_HANDLED: if ((get_current_type () == view_listing) && current_panel->searching) { - current_panel->dirty = 1; /* FIXME: unneeded? */ + current_panel->dirty = 1; /* FIXME: unneeded? */ send_message ((Widget *) current_panel, WIDGET_COMMAND, CK_PanelStopSearch); } return MSG_HANDLED; @@ -1626,84 +1524,7 @@ midnight_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void } } -/* Show current directory in the xterm title */ -void -update_xterm_title_path (void) -{ - /* TODO: share code with midnight_get_title () */ - - const char *path; - char host[BUF_TINY]; - char *p; - struct passwd *pw = NULL; - char *login = NULL; - int res = 0; - - if (xterm_flag && xterm_title) - { - path = strip_home_and_password (current_panel->cwd); - res = gethostname (host, sizeof (host)); - if (res) - { /* On success, res = 0 */ - host[0] = '\0'; - } - else - { - host[sizeof (host) - 1] = '\0'; - } - pw = getpwuid (getuid ()); - if (pw) - { - login = g_strdup_printf ("%s@%s", pw->pw_name, host); - } - else - { - login = g_strdup (host); - } - p = g_strdup_printf ("mc [%s]:%s", login, path); - fprintf (stdout, "\33]0;%s\7", str_term_form (p)); - g_free (login); - g_free (p); - if (!alternate_plus_minus) - numeric_keypad_mode (); - fflush (stdout); - } -} - -/* - * Load new hint and display it. - * IF force is not 0, ignore the timeout. - */ -void -load_hint (int force) -{ - char *hint; - - if (!the_hint->widget.owner) - return; - - if (!message_visible) - { - label_set_text (the_hint, NULL); - return; - } - - hint = get_random_hint (force); - - if (hint != NULL) - { - if (*hint) - set_hintbar (hint); - g_free (hint); - } - else - { - char text[BUF_SMALL]; - - g_snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"), VERSION); - set_hintbar (text); - } -} +/* --------------------------------------------------------------------------------------------- */ static void create_panels_and_run_mc (void) @@ -1730,7 +1551,9 @@ create_panels_and_run_mc (void) run_dlg (midnight_dlg); } -/* result must be free'd (I think this should go in util.c) */ +/* --------------------------------------------------------------------------------------------- */ +/** result must be free'd (I think this should go in util.c) */ + static char * prepend_cwd_on_local (const char *filename) { @@ -1749,9 +1572,11 @@ prepend_cwd_on_local (const char *filename) return d; } -/* Invoke the internal view/edit routine with: +/* --------------------------------------------------------------------------------------------- */ +/** Invoke the internal view/edit routine with: * the default processing and forcing the internal viewer/editor */ + static void mc_maybe_editor_or_viewer (void) { @@ -1781,7 +1606,9 @@ mc_maybe_editor_or_viewer (void) midnight_shutdown = 1; } -/* Run the main dialog that occupies the whole screen */ +/* --------------------------------------------------------------------------------------------- */ +/** Run the main dialog that occupies the whole screen */ + static void do_nc (void) { @@ -1829,7 +1656,9 @@ do_nc (void) done_setup (); } -/* POSIX version. The only version we support. */ +/* --------------------------------------------------------------------------------------------- */ +/** POSIX version. The only version we support. */ + static void OS_Setup (void) { @@ -1873,6 +1702,8 @@ OS_Setup (void) home_dir = mc_home; } +/* --------------------------------------------------------------------------------------------- */ + static void sigchld_handler_no_subshell (int sig) { @@ -1912,6 +1743,8 @@ sigchld_handler_no_subshell (int sig) (void) sig; } +/* --------------------------------------------------------------------------------------------- */ + static void init_sigchld (void) { @@ -1943,6 +1776,304 @@ init_sigchld (void) } } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** Define this function for glib-style error handling */ +GQuark +mc_main_error_quark (void) +{ + return g_quark_from_static_string (PACKAGE); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Save current stat of directories to avoid reloading the panels + * when no modifications have taken place + */ + +void +save_cwds_stat (void) +{ + if (panels_options.fast_reload) + { + mc_stat (current_panel->cwd, &(current_panel->dir_stat)); + if (get_other_type () == view_listing) + mc_stat (other_panel->cwd, &(other_panel->dir_stat)); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +#ifdef HAVE_SUBSHELL_SUPPORT +void +do_update_prompt (void) +{ + if (update_prompt) + { + printf ("\r\n%s", subshell_prompt); + fflush (stdout); + update_prompt = 0; + } +} +#endif /* HAVE_SUBSHELL_SUPPORT */ + +/* --------------------------------------------------------------------------------------------- */ + +void +change_panel (void) +{ + free_completions (cmdline); + dlg_one_down (midnight_dlg); +} + +/* --------------------------------------------------------------------------------------------- */ + +gboolean +quiet_quit_cmd (void) +{ + print_last_revert = 1; + return quit_cmd_internal (1); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Wrapper for do_subshell_chdir, check for availability of subshell */ + +void +subshell_chdir (const char *directory) +{ +#ifdef HAVE_SUBSHELL_SUPPORT + if (use_subshell) + { + if (vfs_current_is_local ()) + do_subshell_chdir (directory, 0, 1); + } +#endif /* HAVE_SUBSHELL_SUPPORT */ +} + +/* --------------------------------------------------------------------------------------------- */ + +int +do_cd (const char *new_dir, enum cd_enum exact) +{ + gboolean res; + + res = do_panel_cd (current_panel, new_dir, exact); + +#if HAVE_CHARSET + if (res) + { + const char *enc_name; + + enc_name = vfs_get_encoding (current_panel->cwd); + if (enc_name != NULL) + current_panel->codepage = get_codepage_index (enc_name); + else + current_panel->codepage = SELECT_CHARSET_NO_TRANSLATE; + } +#endif /* HAVE_CHARSET */ + + return res ? 1 : 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +#ifdef HAVE_SUBSHELL_SUPPORT +int +load_prompt (int fd, void *unused) +{ + (void) fd; + (void) unused; + + if (!read_subshell_prompt ()) + return 0; + + /* Don't actually change the prompt if it's invisible */ + if (((Dlg_head *) top_dlg->data == midnight_dlg) && command_prompt) + { + char *tmp_prompt; + int prompt_len; + + tmp_prompt = strip_ctrl_codes (subshell_prompt); + prompt_len = str_term_width1 (tmp_prompt); + + /* Check for prompts too big */ + if (COLS > 8 && prompt_len > COLS - 8) + { + prompt_len = COLS - 8; + tmp_prompt[prompt_len] = '\0'; + } + mc_prompt = tmp_prompt; + label_set_text (the_prompt, mc_prompt); + winput_set_origin ((WInput *) cmdline, prompt_len, COLS - prompt_len); + + /* since the prompt has changed, and we are called from one of the + * tty_get_event channels, the prompt updating does not take place + * automatically: force a cursor update and a screen refresh + */ + update_cursor (midnight_dlg); + mc_refresh (); + } + update_prompt = 1; + return 0; +} +#endif /* HAVE_SUBSHELL_SUPPORT */ + +/* --------------------------------------------------------------------------------------------- */ + +void +sort_cmd (void) +{ + WPanel *p; + const panel_field_t *sort_order; + + if (!SELECTED_IS_PANEL) + return; + + p = MENU_PANEL; + sort_order = sort_box (p->current_sort_field, &p->reverse, &p->case_sensitive, &p->exec_first); + + panel_set_sort_order (p, sort_order); + +} + +/* --------------------------------------------------------------------------------------------- */ + +void +init_menu (void) +{ + menubar_add_menu (the_menubar, + create_menu (horizontal_split ? _("&Above") : _("&Left"), + create_panel_menu (), "[Left and Right Menus]")); + menubar_add_menu (the_menubar, create_menu (_("&File"), create_file_menu (), "[File Menu]")); + menubar_add_menu (the_menubar, + create_menu (_("&Command"), create_command_menu (), "[Command Menu]")); + menubar_add_menu (the_menubar, + create_menu (_("&Options"), create_options_menu (), "[Options Menu]")); + menubar_add_menu (the_menubar, + create_menu (horizontal_split ? _("&Below") : _("&Right"), + create_panel_menu (), "[Left and Right Menus]")); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +done_menu (void) +{ + menubar_set_menu (the_menubar, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +toggle_show_hidden (void) +{ + panels_options.show_dot_files = !panels_options.show_dot_files; + update_panels (UP_RELOAD, UP_KEEPSEL); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +midnight_set_buttonbar (WButtonBar * b) +{ + buttonbar_set_label (b, 1, Q_ ("ButtonBar|Help"), main_map, NULL); + buttonbar_set_label (b, 2, Q_ ("ButtonBar|Menu"), main_map, NULL); + buttonbar_set_label (b, 3, Q_ ("ButtonBar|View"), main_map, NULL); + buttonbar_set_label (b, 4, Q_ ("ButtonBar|Edit"), main_map, NULL); + buttonbar_set_label (b, 5, Q_ ("ButtonBar|Copy"), main_map, NULL); + buttonbar_set_label (b, 6, Q_ ("ButtonBar|RenMov"), main_map, NULL); + buttonbar_set_label (b, 7, Q_ ("ButtonBar|Mkdir"), main_map, NULL); + buttonbar_set_label (b, 8, Q_ ("ButtonBar|Delete"), main_map, NULL); + buttonbar_set_label (b, 9, Q_ ("ButtonBar|PullDn"), main_map, NULL); + buttonbar_set_label (b, 10, Q_ ("ButtonBar|Quit"), main_map, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Show current directory in the xterm title */ + +void +update_xterm_title_path (void) +{ + /* TODO: share code with midnight_get_title () */ + + const char *path; + char host[BUF_TINY]; + char *p; + struct passwd *pw = NULL; + char *login = NULL; + int res = 0; + + if (xterm_flag && xterm_title) + { + path = strip_home_and_password (current_panel->cwd); + res = gethostname (host, sizeof (host)); + if (res) + { /* On success, res = 0 */ + host[0] = '\0'; + } + else + { + host[sizeof (host) - 1] = '\0'; + } + pw = getpwuid (getuid ()); + if (pw) + { + login = g_strdup_printf ("%s@%s", pw->pw_name, host); + } + else + { + login = g_strdup (host); + } + p = g_strdup_printf ("mc [%s]:%s", login, path); + fprintf (stdout, "\33]0;%s\7", str_term_form (p)); + g_free (login); + g_free (p); + if (!alternate_plus_minus) + numeric_keypad_mode (); + fflush (stdout); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Load new hint and display it. + * IF force is not 0, ignore the timeout. + */ + +void +load_hint (int force) +{ + char *hint; + + if (!the_hint->widget.owner) + return; + + if (!message_visible) + { + label_set_text (the_hint, NULL); + return; + } + + hint = get_random_hint (force); + + if (hint != NULL) + { + if (*hint) + set_hintbar (hint); + g_free (hint); + } + else + { + char text[BUF_SMALL]; + + g_snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"), VERSION); + set_hintbar (text); + } +} + +/* --------------------------------------------------------------------------------------------- */ + int main (int argc, char *argv[]) { @@ -2122,3 +2253,5 @@ main (int argc, char *argv[]) return 0; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/main.h b/src/main.h index 385b6d10e..ddf3fe218 100644 --- a/src/main.h +++ b/src/main.h @@ -1,14 +1,21 @@ - /** \file main.h * \brief Header: this is a main module header */ -#ifndef MC_MAIN_H -#define MC_MAIN_H +#ifndef MC__MAIN_H +#define MC__MAIN_H #include "lib/global.h" #include "keybind.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +#define MENU_PANEL (is_right ? right_panel : left_panel) +#define MENU_PANEL_IDX (is_right ? 1 : 0) +#define SELECTED_IS_PANEL (get_display_type (is_right ? 1 : 0) == view_listing) + +/*** enums ***************************************************************************************/ + /* run mode and params */ typedef enum { @@ -18,6 +25,25 @@ typedef enum MC_RUN_DIFFVIEWER } mc_run_mode_t; +/* If true, after executing a command, wait for a keystroke */ +enum +{ pause_never, pause_on_dumb_terminals, pause_always }; + +enum cd_enum +{ + cd_parse_command, + cd_exact +}; + + +/*** structures declarations (and typedefs of structures)*****************************************/ + +struct WButtonBar; + +struct mc_fhl_struct; + +/*** global variables defined in .c file *********************************************************/ + extern mc_run_mode_t mc_run_mode; /* * MC_RUN_FULL: dir for left panel @@ -34,20 +60,9 @@ extern char *mc_run_param0; */ extern char *mc_run_param1; -void toggle_show_hidden (void); - extern int quote; extern volatile int quit; -/* If true, after executing a command, wait for a keystroke */ -enum { pause_never, pause_on_dumb_terminals, pause_always }; - -void subshell_chdir (const char *command); - -struct WButtonBar; - -void midnight_set_buttonbar (struct WButtonBar *b); - /* See main.c for details on these variables */ extern int auto_menu; extern int pause_after_run; @@ -95,26 +110,31 @@ extern char *shell; extern int auto_fill_mkdir_name; /* Ugly hack in order to distinguish between left and right panel in menubar */ extern int is_right; /* If the selected menu was the right */ -#define MENU_PANEL (is_right ? right_panel : left_panel) -#define MENU_PANEL_IDX (is_right ? 1 : 0) -#define SELECTED_IS_PANEL (get_display_type (is_right ? 1 : 0) == view_listing) + +extern const char *mc_prompt; +extern char *mc_home; +extern char *mc_home_alt; + +extern struct mc_fhl_struct *mc_filehighlight; + +/*** declarations of public functions ************************************************************/ + +void toggle_show_hidden (void); + +void subshell_chdir (const char *command); + +void midnight_set_buttonbar (struct WButtonBar *b); #ifdef HAVE_SUBSHELL_SUPPORT void do_update_prompt (void); int load_prompt (int fd, void *unused); #endif -enum cd_enum -{ - cd_parse_command, - cd_exact -}; - int do_cd (const char *new_dir, enum cd_enum cd_type); void sort_cmd (void); void change_panel (void); void save_cwds_stat (void); -gboolean quiet_quit_cmd (void); /* For cmd.c and command.c */ +gboolean quiet_quit_cmd (void); /* For cmd.c and command.c */ void touch_bar (void); void update_xterm_title_path (void); @@ -122,13 +142,6 @@ void load_hint (int force); void print_vfs_message (const char *msg, ...) __attribute__ ((format (__printf__, 1, 2))); -extern const char *mc_prompt; -extern char *mc_home; -extern char *mc_home_alt; - -struct mc_fhl_struct; -extern struct mc_fhl_struct *mc_filehighlight; - char *get_mc_lib_dir (void); void done_menu (void); @@ -136,4 +149,5 @@ void init_menu (void); char *remove_encoding_from_path (const char *); -#endif /* MC_MAIN_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__MAIN_H */ diff --git a/src/menu.c b/src/menu.c index 50ab4eecf..c840f23f9 100644 --- a/src/menu.c +++ b/src/menu.c @@ -41,34 +41,20 @@ #include "main.h" /* is_right */ #include "menu.h" +/*** global variables ****************************************************************************/ + int menubar_visible = 1; /* This is the new default */ +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + static cb_ret_t menubar_callback (Widget * w, widget_msg_t msg, int parm); -menu_entry_t * -menu_entry_create (const char *name, unsigned long command) -{ - menu_entry_t *entry; - - entry = g_new (menu_entry_t, 1); - entry->first_letter = ' '; - entry->text = parse_hotkey (name); - entry->command = command; - entry->shortcut = NULL; - - return entry; -} - -void -menu_entry_free (menu_entry_t * entry) -{ - if (entry != NULL) - { - release_hotkey (entry->text); - g_free (entry->shortcut); - g_free (entry); - } -} +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ static void menu_arrange (Menu * menu, dlg_shortcut_str get_shortcut) @@ -107,32 +93,7 @@ menu_arrange (Menu * menu, dlg_shortcut_str get_shortcut) } } -Menu * -create_menu (const char *name, GList * entries, const char *help_node) -{ - Menu *menu; - - menu = g_new (Menu, 1); - menu->start_x = 0; - menu->text = parse_hotkey (name); - menu->entries = entries; - menu->max_entry_len = 1; - menu->max_hotkey_len = 0; - menu->selected = 0; - menu->help_node = g_strdup (help_node); - - return menu; -} - -void -destroy_menu (Menu * menu) -{ - release_hotkey (menu->text); - g_list_foreach (menu->entries, (GFunc) menu_entry_free, NULL); - g_list_free (menu->entries); - g_free (menu->help_node); - g_free (menu); -} +/* --------------------------------------------------------------------------------------------- */ static void menubar_paint_idx (WMenuBar * menubar, unsigned int idx, int color) @@ -189,6 +150,8 @@ menubar_paint_idx (WMenuBar * menubar, unsigned int idx, int color) } } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_draw_drop (WMenuBar * menubar) { @@ -210,6 +173,8 @@ menubar_draw_drop (WMenuBar * menubar) i == menu->selected ? MENU_SELECTED_COLOR : MENU_ENTRY_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_set_color (WMenuBar * menubar, gboolean current, gboolean hotkey) { @@ -221,6 +186,8 @@ menubar_set_color (WMenuBar * menubar, gboolean current, gboolean hotkey) tty_setcolor (hotkey ? MENU_HOT_COLOR : MENU_ENTRY_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_draw (WMenuBar * menubar) { @@ -262,6 +229,8 @@ menubar_draw (WMenuBar * menubar) ((Menu *) g_list_nth_data (menubar->menu, menubar->selected))->start_x); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_remove (WMenuBar * menubar) { @@ -273,6 +242,8 @@ menubar_remove (WMenuBar * menubar) } } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_left (WMenuBar * menubar) { @@ -284,6 +255,8 @@ menubar_left (WMenuBar * menubar) menubar_draw (menubar); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_right (WMenuBar * menubar) { @@ -292,6 +265,8 @@ menubar_right (WMenuBar * menubar) menubar_draw (menubar); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_finish (WMenuBar * menubar) { @@ -304,6 +279,8 @@ menubar_finish (WMenuBar * menubar) do_refresh (); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_drop (WMenuBar * menubar, unsigned int selected) { @@ -312,6 +289,8 @@ menubar_drop (WMenuBar * menubar, unsigned int selected) menubar_draw (menubar); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_execute (WMenuBar * menubar) { @@ -328,6 +307,8 @@ menubar_execute (WMenuBar * menubar) } } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_down (WMenuBar * menubar) { @@ -347,6 +328,8 @@ menubar_down (WMenuBar * menubar) menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_up (WMenuBar * menubar) { @@ -369,6 +352,8 @@ menubar_up (WMenuBar * menubar) menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_first (WMenuBar * menubar) { @@ -395,6 +380,8 @@ menubar_first (WMenuBar * menubar) menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static void menubar_last (WMenuBar * menubar) { @@ -419,6 +406,8 @@ menubar_last (WMenuBar * menubar) menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); } +/* --------------------------------------------------------------------------------------------- */ + static int menubar_handle_key (WMenuBar * menubar, int key) { @@ -530,6 +519,8 @@ menubar_handle_key (WMenuBar * menubar, int key) return 0; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t menubar_callback (Widget * w, widget_msg_t msg, int parm) { @@ -590,6 +581,8 @@ menubar_callback (Widget * w, widget_msg_t msg, int parm) } } +/* --------------------------------------------------------------------------------------------- */ + static int menubar_event (Gpm_Event * event, void *data) { @@ -714,6 +707,70 @@ menubar_event (Gpm_Event * event, void *data) return MOU_NORMAL; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +menu_entry_t * +menu_entry_create (const char *name, unsigned long command) +{ + menu_entry_t *entry; + + entry = g_new (menu_entry_t, 1); + entry->first_letter = ' '; + entry->text = parse_hotkey (name); + entry->command = command; + entry->shortcut = NULL; + + return entry; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +menu_entry_free (menu_entry_t * entry) +{ + if (entry != NULL) + { + release_hotkey (entry->text); + g_free (entry->shortcut); + g_free (entry); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +Menu * +create_menu (const char *name, GList * entries, const char *help_node) +{ + Menu *menu; + + menu = g_new (Menu, 1); + menu->start_x = 0; + menu->text = parse_hotkey (name); + menu->entries = entries; + menu->max_entry_len = 1; + menu->max_hotkey_len = 0; + menu->selected = 0; + menu->help_node = g_strdup (help_node); + + return menu; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +destroy_menu (Menu * menu) +{ + release_hotkey (menu->text); + g_list_foreach (menu->entries, (GFunc) menu_entry_free, NULL); + g_list_free (menu->entries); + g_free (menu->help_node); + g_free (menu); +} + +/* --------------------------------------------------------------------------------------------- */ + WMenuBar * menubar_new (int y, int x, int cols, GList * menu) { @@ -725,6 +782,8 @@ menubar_new (int y, int x, int cols, GList * menu) return menubar; } +/* --------------------------------------------------------------------------------------------- */ + void menubar_set_menu (WMenuBar * menubar, GList * menu) { @@ -742,6 +801,8 @@ menubar_set_menu (WMenuBar * menubar, GList * menu) menubar_arrange (menubar); } +/* --------------------------------------------------------------------------------------------- */ + void menubar_add_menu (WMenuBar * menubar, Menu * menu) { @@ -754,10 +815,12 @@ menubar_add_menu (WMenuBar * menubar, Menu * menu) menubar_arrange (menubar); } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Properly space menubar items. Should be called when menubar is created * and also when widget width is changed (i.e. upon xterm resize). */ + void menubar_arrange (WMenuBar * menubar) { @@ -811,9 +874,13 @@ menubar_arrange (WMenuBar * menubar) #endif /* RESIZABLE_MENUBAR */ } -/* Find MenuBar widget in the dialog */ +/* --------------------------------------------------------------------------------------------- */ +/** Find MenuBar widget in the dialog */ + WMenuBar * find_menubar (const Dlg_head * h) { return (WMenuBar *) find_widget_type (h, menubar_callback); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/menu.h b/src/menu.h index 3a075c4a2..457a3eb58 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,4 +1,3 @@ - /* Header file for pulldown menu engine for Midnignt Commander Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. @@ -21,56 +20,70 @@ * \brief Header: pulldown menu code */ -#ifndef MC_MENU_H -#define MC_MENU_H +#ifndef MC__MENU_H +#define MC__MENU_H #include "lib/global.h" #include "widget.h" -extern int menubar_visible; +/*** typedefs(not structures) and defined constants **********************************************/ -typedef struct menu_entry_t { +#define menu_separator_create() NULL + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef struct menu_entry_t +{ unsigned char first_letter; struct hotkey_t text; unsigned long command; char *shortcut; } menu_entry_t; -menu_entry_t *menu_entry_create (const char *name, unsigned long command); -void menu_entry_free (menu_entry_t *me); -#define menu_separator_create() NULL - -typedef struct Menu { - int start_x; /* position relative to menubar start */ +typedef struct Menu +{ + int start_x; /* position relative to menubar start */ struct hotkey_t text; GList *entries; - size_t max_entry_len; /* cached max length of entry texts (text + shortcut) */ - size_t max_hotkey_len; /* cached max length of shortcuts */ - unsigned int selected; /* pointer to current menu entry */ + size_t max_entry_len; /* cached max length of entry texts (text + shortcut) */ + size_t max_hotkey_len; /* cached max length of shortcuts */ + unsigned int selected; /* pointer to current menu entry */ char *help_node; } Menu; -Menu *create_menu (const char *name, GList *entries, - const char *help_node); - -void destroy_menu (Menu *menu); - /* The button bar menu */ -typedef struct WMenuBar { +typedef struct WMenuBar +{ Widget widget; - gboolean is_active; /* If the menubar is in use */ - gboolean is_dropped; /* If the menubar has dropped */ - GList *menu; /* The actual menus */ - size_t selected; /* Selected menu on the top bar */ - int previous_widget; /* Selected widget ID before activating menu */ + gboolean is_active; /* If the menubar is in use */ + gboolean is_dropped; /* If the menubar has dropped */ + GList *menu; /* The actual menus */ + size_t selected; /* Selected menu on the top bar */ + int previous_widget; /* Selected widget ID before activating menu */ } WMenuBar; -WMenuBar *menubar_new (int y, int x, int cols, GList *menu); -void menubar_set_menu (WMenuBar *menubar, GList *menu); -void menubar_add_menu (WMenuBar *menubar, Menu *menu); -void menubar_arrange (WMenuBar *menubar); +/*** global variables defined in .c file *********************************************************/ -WMenuBar *find_menubar (const Dlg_head *h); +extern int menubar_visible; -#endif /* MC_MENU_H */ +/*** declarations of public functions ************************************************************/ + +menu_entry_t *menu_entry_create (const char *name, unsigned long command); +void menu_entry_free (menu_entry_t * me); + +Menu *create_menu (const char *name, GList * entries, const char *help_node); + +void destroy_menu (Menu * menu); + +WMenuBar *menubar_new (int y, int x, int cols, GList * menu); +void menubar_set_menu (WMenuBar * menubar, GList * menu); +void menubar_add_menu (WMenuBar * menubar, Menu * menu); +void menubar_arrange (WMenuBar * menubar); + +WMenuBar *find_menubar (const Dlg_head * h); + +/*** inline functions ****************************************************************************/ +#endif /* MC__MENU_H */ diff --git a/src/mfmt.c b/src/mfmt.c index d79f00c93..02fc23531 100644 --- a/src/mfmt.c +++ b/src/mfmt.c @@ -22,7 +22,14 @@ #include -enum states { +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +enum states +{ header, definition, plain, @@ -34,104 +41,130 @@ enum states { seen_m }; +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + int main (void) { int c; int state = newline; int space_seen = 0; - - while ((c = getchar ()) != EOF){ - switch (state){ - case plain: - if (c == '\n') - state = newline; - putchar (c); - break; - - case newline: - if (c == 'F') - state = seen_f; + + while ((c = getchar ()) != EOF) + { + switch (state) + { + case plain: + if (c == '\n') + state = newline; + putchar (c); + break; + + case newline: + if (c == 'F') + state = seen_f; else if (c == '\n') putchar ('\n'); - else { - state = plain; - putchar (c); - } - break; - - case seen_f: - if (c == 'r') - state = seen_r; - else { - printf ("F%c", c); - state = plain; - } - break; + else + { + state = plain; + putchar (c); + } + break; - case seen_r: - if (c == 'o') - state = seen_o; - else { - state = plain; - printf ("Fr%c", c); - } - break; + case seen_f: + if (c == 'r') + state = seen_r; + else + { + printf ("F%c", c); + state = plain; + } + break; - case seen_o: - if (c == 'm'){ - state = seen_m; - } else { - state = plain; - printf ("Fro%c", c); - } - break; + case seen_r: + if (c == 'o') + state = seen_o; + else + { + state = plain; + printf ("Fr%c", c); + } + break; - case seen_m: - if (c == ' '){ - state = definition; - printf ("_\bF_\br_\bo_\bm "); - } else { - state = plain; - printf ("From%c", c); - } - break; - - case header_new: - space_seen = 0; - if (c == ' ' || c == '\t') { + case seen_o: + if (c == 'm') + { + state = seen_m; + } + else + { + state = plain; + printf ("Fro%c", c); + } + break; + + case seen_m: + if (c == ' ') + { + state = definition; + printf ("_\bF_\br_\bo_\bm "); + } + else + { + state = plain; + printf ("From%c", c); + } + break; + + case header_new: + space_seen = 0; + if (c == ' ' || c == '\t') + { state = definition; putchar (c); break; } - if (c == '\n'){ - state = plain; - putchar (c); - break; - } - - case header: - if (c == '\n'){ - putchar (c); - state = header_new; - break; - } - printf ("_\b%c", c); - if (c == ' ') - space_seen = 1; - if (c == ':' && !space_seen) - state = definition; - break; + if (c == '\n') + { + state = plain; + putchar (c); + break; + } - case definition: - if (c == '\n'){ - putchar (c); - state = header_new; - break; - } - printf ("%c\b%c", c, c); - break; - } + case header: + if (c == '\n') + { + putchar (c); + state = header_new; + break; + } + printf ("_\b%c", c); + if (c == ' ') + space_seen = 1; + if (c == ':' && !space_seen) + state = definition; + break; + + case definition: + if (c == '\n') + { + putchar (c); + state = header_new; + break; + } + printf ("%c\b%c", c, c); + break; + } } return (0); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/mountlist.c b/src/mountlist.c index af4a6cd88..29d6f50b3 100644 --- a/src/mountlist.c +++ b/src/mountlist.c @@ -113,6 +113,10 @@ #include "lib/global.h" #include "mountlist.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #ifdef DOLPHIN /* So special that it's not worth putting this in autoconf. */ #undef MOUNTED_FREAD_FSTYP @@ -120,13 +124,15 @@ #endif #if defined (__QNX__) && !defined(__QNXNTO__) && !defined (HAVE_INFOMOUNT_LIST) -# define HAVE_INFOMOUNT_QNX +#define HAVE_INFOMOUNT_QNX #endif #if defined(HAVE_INFOMOUNT_LIST) || defined(HAVE_INFOMOUNT_QNX) -# define HAVE_INFOMOUNT +#define HAVE_INFOMOUNT #endif +/*** file scope type declarations ****************************************************************/ + /* A mount table entry. */ struct mount_entry { @@ -146,12 +152,18 @@ struct fs_usage fsfilcnt_t fsu_ffree; /* Free file nodes. */ }; +/*** file scope variables ************************************************************************/ + static int get_fs_usage (char *path, struct fs_usage *fsp); #ifdef HAVE_INFOMOUNT_LIST - static struct mount_entry *mount_list = NULL; +#endif /* HAVE_INFOMOUNT_LIST */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +#ifdef HAVE_INFOMOUNT_LIST static void free_mount_entry (struct mount_entry *me) { @@ -167,6 +179,8 @@ free_mount_entry (struct mount_entry *me) } #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ + +/* --------------------------------------------------------------------------------------------- */ /* Return the value of the hexadecimal number represented by CP. No prefix (like '0x') or suffix (like 'h') is expected to be part of CP. */ @@ -195,6 +209,8 @@ xatoi (const char *cp) #ifdef MOUNTED_GETMNTINFO +/* --------------------------------------------------------------------------------------------- */ + #ifndef HAVE_STRUCT_STATFS_F_FSTYPENAME static char * fstype_to_string (short t) @@ -293,6 +309,8 @@ fstype_to_string (short t) #endif /* MOUNTED_GETMNTINFO */ +/* --------------------------------------------------------------------------------------------- */ + #ifdef MOUNTED_VMOUNT /* AIX. */ static char * fstype_to_string (int t) @@ -307,7 +325,8 @@ fstype_to_string (int t) } #endif /* MOUNTED_VMOUNT */ -/* Return a list of the currently mounted filesystems, or NULL on error. +/* --------------------------------------------------------------------------------------------- */ +/** Return a list of the currently mounted filesystems, or NULL on error. Add each entry to the tail of the list so that they stay in order. If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in the returned list are valid. Otherwise, they might not be. @@ -612,8 +631,10 @@ read_filesystem_list (int need_fs_type, int all_fs) } #endif /* HAVE_INFOMOUNT_LIST */ +/* --------------------------------------------------------------------------------------------- */ + #ifdef HAVE_INFOMOUNT_QNX -/* +/** ** QNX has no [gs]etmnt*(), [gs]etfs*(), or /etc/mnttab, but can do ** this via the following code. ** Note that, as this is based on CWD, it only fills one mount_entry @@ -707,109 +728,8 @@ read_filesystem_list (int need_fs_type, int all_fs) } #endif /* HAVE_INFOMOUNT_QNX */ -void -free_my_statfs (void) -{ -#ifdef HAVE_INFOMOUNT_LIST - while (mount_list) - { - struct mount_entry *next = mount_list->me_next; - free_mount_entry (mount_list); - mount_list = next; - } - mount_list = NULL; -#endif /* HAVE_INFOMOUNT_LIST */ -} - - -void -init_my_statfs (void) -{ -#ifdef HAVE_INFOMOUNT_LIST - free_my_statfs (); - mount_list = read_filesystem_list (1, 1); -#endif /* HAVE_INFOMOUNT_LIST */ -} - -void -my_statfs (struct my_statfs *myfs_stats, const char *path) -{ -#ifdef HAVE_INFOMOUNT_LIST - size_t i, len = 0; - struct mount_entry *entry = NULL; - struct mount_entry *temp = mount_list; - struct fs_usage fs_use; - - while (temp) - { - i = strlen (temp->me_mountdir); - if (i > len && (strncmp (path, temp->me_mountdir, i) == 0)) - if (!entry || (path[i] == PATH_SEP || path[i] == '\0')) - { - len = i; - entry = temp; - } - temp = temp->me_next; - } - - if (entry) - { - memset (&fs_use, 0, sizeof (struct fs_usage)); - get_fs_usage (entry->me_mountdir, &fs_use); - - myfs_stats->type = entry->me_dev; - myfs_stats->typename = entry->me_type; - myfs_stats->mpoint = entry->me_mountdir; - myfs_stats->device = entry->me_devname; - myfs_stats->avail = getuid ()? fs_use.fsu_bavail / 2 : fs_use.fsu_bfree / 2; - myfs_stats->total = fs_use.fsu_blocks / 2; - myfs_stats->nfree = fs_use.fsu_ffree; - myfs_stats->nodes = fs_use.fsu_files; - } - else -#endif /* HAVE_INFOMOUNT_LIST */ - -#ifdef HAVE_INFOMOUNT_QNX - /* - ** This is the "other side" of the hack to read_filesystem_list() in - ** mountlist.c. - ** It's not the most efficient approach, but consumes less memory. It - ** also accomodates QNX's ability to mount filesystems on the fly. - */ - struct mount_entry *entry; - struct fs_usage fs_use; - - entry = read_filesystem_list (0, 0); - if (entry != NULL) - { - get_fs_usage (entry->me_mountdir, &fs_use); - - myfs_stats->type = entry->me_dev; - myfs_stats->typename = entry->me_type; - myfs_stats->mpoint = entry->me_mountdir; - myfs_stats->device = entry->me_devname; - - myfs_stats->avail = fs_use.fsu_bfree / 2; - myfs_stats->total = fs_use.fsu_blocks / 2; - myfs_stats->nfree = fs_use.fsu_ffree; - myfs_stats->nodes = fs_use.fsu_files; - } - else -#endif /* HAVE_INFOMOUNT_QNX */ - { - myfs_stats->type = 0; - myfs_stats->mpoint = "unknown"; - myfs_stats->device = "unknown"; - myfs_stats->avail = 0; - myfs_stats->total = 0; - myfs_stats->nfree = 0; - myfs_stats->nodes = 0; - } -} - #ifdef HAVE_INFOMOUNT - -/* Return the number of TOSIZE-byte blocks used by +/** Return the number of TOSIZE-byte blocks used by BLOCKS FROMSIZE-byte blocks, rounding away from zero. TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */ @@ -829,6 +749,7 @@ fs_adjust_blocks (fsblkcnt_t blocks, int fromsize, int tosize) return blocks / (tosize / fromsize); } +/* --------------------------------------------------------------------------------------------- */ #if defined(_AIX) && defined(_I386) /* AIX PS/2 does not supply statfs. */ static int @@ -860,6 +781,7 @@ aix_statfs (char *path, struct statfs *fsb) the filesystem on which PATH resides. Return 0 if successful, -1 if not. */ +/* --------------------------------------------------------------------------------------------- */ static int get_fs_usage (char *path, struct fs_usage *fsp) { @@ -942,3 +864,112 @@ get_fs_usage (char *path, struct fs_usage *fsp) } #endif /* HAVE_INFOMOUNT */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +free_my_statfs (void) +{ +#ifdef HAVE_INFOMOUNT_LIST + while (mount_list) + { + struct mount_entry *next = mount_list->me_next; + free_mount_entry (mount_list); + mount_list = next; + } + mount_list = NULL; +#endif /* HAVE_INFOMOUNT_LIST */ +} + +/* --------------------------------------------------------------------------------------------- */ + +void +init_my_statfs (void) +{ +#ifdef HAVE_INFOMOUNT_LIST + free_my_statfs (); + mount_list = read_filesystem_list (1, 1); +#endif /* HAVE_INFOMOUNT_LIST */ +} + +/* --------------------------------------------------------------------------------------------- */ + +void +my_statfs (struct my_statfs *myfs_stats, const char *path) +{ +#ifdef HAVE_INFOMOUNT_LIST + size_t i, len = 0; + struct mount_entry *entry = NULL; + struct mount_entry *temp = mount_list; + struct fs_usage fs_use; + + while (temp) + { + i = strlen (temp->me_mountdir); + if (i > len && (strncmp (path, temp->me_mountdir, i) == 0)) + if (!entry || (path[i] == PATH_SEP || path[i] == '\0')) + { + len = i; + entry = temp; + } + temp = temp->me_next; + } + + if (entry) + { + memset (&fs_use, 0, sizeof (struct fs_usage)); + get_fs_usage (entry->me_mountdir, &fs_use); + + myfs_stats->type = entry->me_dev; + myfs_stats->typename = entry->me_type; + myfs_stats->mpoint = entry->me_mountdir; + myfs_stats->device = entry->me_devname; + myfs_stats->avail = getuid ()? fs_use.fsu_bavail / 2 : fs_use.fsu_bfree / 2; + myfs_stats->total = fs_use.fsu_blocks / 2; + myfs_stats->nfree = fs_use.fsu_ffree; + myfs_stats->nodes = fs_use.fsu_files; + } + else +#endif /* HAVE_INFOMOUNT_LIST */ + +#ifdef HAVE_INFOMOUNT_QNX + /* + ** This is the "other side" of the hack to read_filesystem_list() in + ** mountlist.c. + ** It's not the most efficient approach, but consumes less memory. It + ** also accomodates QNX's ability to mount filesystems on the fly. + */ + struct mount_entry *entry; + struct fs_usage fs_use; + + entry = read_filesystem_list (0, 0); + if (entry != NULL) + { + get_fs_usage (entry->me_mountdir, &fs_use); + + myfs_stats->type = entry->me_dev; + myfs_stats->typename = entry->me_type; + myfs_stats->mpoint = entry->me_mountdir; + myfs_stats->device = entry->me_devname; + + myfs_stats->avail = fs_use.fsu_bfree / 2; + myfs_stats->total = fs_use.fsu_blocks / 2; + myfs_stats->nfree = fs_use.fsu_ffree; + myfs_stats->nodes = fs_use.fsu_files; + } + else +#endif /* HAVE_INFOMOUNT_QNX */ + { + myfs_stats->type = 0; + myfs_stats->mpoint = "unknown"; + myfs_stats->device = "unknown"; + myfs_stats->avail = 0; + myfs_stats->total = 0; + myfs_stats->nfree = 0; + myfs_stats->nodes = 0; + } +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/mountlist.h b/src/mountlist.h index cf878f871..1259e69c9 100644 --- a/src/mountlist.h +++ b/src/mountlist.h @@ -19,8 +19,14 @@ * \brief Header: list of mounted filesystems */ -#ifndef MC_MOUNTLIST_H -#define MC_MOUNTLIST_H +#ifndef MC__MOUNTLIST_H +#define MC__MOUNTLIST_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ /* Filesystem status */ struct my_statfs @@ -35,8 +41,14 @@ struct my_statfs int nodes; }; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +/*** inline functions ****************************************************************************/ + void init_my_statfs (void); void my_statfs (struct my_statfs *myfs_stats, const char *path); void free_my_statfs (void); -#endif +#endif /* MC__MOUNTLIST_H */ diff --git a/src/option.c b/src/option.c index 64ccfab23..411fe4352 100644 --- a/src/option.c +++ b/src/option.c @@ -47,36 +47,51 @@ #include "option.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t configure_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { switch (msg) { - case DLG_ACTION: - if (sender->id == 18) - { - /* message from "Single press" checkbutton */ - const gboolean not_single = !(((WCheck *) sender)->state & C_BOOL); - Widget *w; + case DLG_ACTION: + if (sender->id == 18) + { + /* message from "Single press" checkbutton */ + const gboolean not_single = !(((WCheck *) sender)->state & C_BOOL); + Widget *w; - /* label */ - w = dlg_find_by_id (h, sender->id - 1); - widget_disable (*w, not_single); - send_message (w, WIDGET_DRAW, 0); - /* input */ - w = dlg_find_by_id (h, sender->id - 2); - widget_disable (*w, not_single); - send_message (w, WIDGET_DRAW, 0); + /* label */ + w = dlg_find_by_id (h, sender->id - 1); + widget_disable (*w, not_single); + send_message (w, WIDGET_DRAW, 0); + /* input */ + w = dlg_find_by_id (h, sender->id - 2); + widget_disable (*w, not_single); + send_message (w, WIDGET_DRAW, 0); - return MSG_HANDLED; - } - return MSG_NOT_HANDLED; + return MSG_HANDLED; + } + return MSG_NOT_HANDLED; - default: - return default_dlg_callback (h, sender, msg, parm, data); + default: + return default_dlg_callback (h, sender, msg, parm, data); } } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void configure_box (void) { @@ -128,14 +143,15 @@ configure_box (void) /* Esc key mode */ QUICK_INPUT (10, dlg_width, 10, dlg_height, (const char *) time_out, 8, 0, - MC_HISTORY_ESC_TIMEOUT, &time_out_new), + MC_HISTORY_ESC_TIMEOUT, &time_out_new), QUICK_LABEL (5, dlg_width, 10, dlg_height, N_("Timeout:")), QUICK_CHECKBOX (5, dlg_width, 9, dlg_height, N_("S&ingle press"), &old_esc_mode), QUICK_GROUPBOX (3, dlg_width, 8, dlg_height, dlg_width / 2 - 4, 4, N_("Esc key mode")), /* file operation options */ QUICK_CHECKBOX (5, dlg_width, 6, dlg_height, N_("Mkdi&r autoname"), &auto_fill_mkdir_name), - QUICK_CHECKBOX (5, dlg_width, 5, dlg_height, N_("Classic pro&gressbar"), &classic_progressbar), + QUICK_CHECKBOX (5, dlg_width, 5, dlg_height, N_("Classic pro&gressbar"), + &classic_progressbar), QUICK_CHECKBOX (5, dlg_width, 4, dlg_height, N_("Compute tota&ls"), &file_op_compute_totals), QUICK_CHECKBOX (5, dlg_width, 3, dlg_height, N_("&Verbose operation"), &verbose), @@ -260,6 +276,8 @@ configure_box (void) } } +/* --------------------------------------------------------------------------------------------- */ + void panel_options_box (void) { @@ -280,7 +298,8 @@ panel_options_box (void) /* quick search */ QUICK_RADIO (dlg_width / 2 + 2, dlg_width, 12, dlg_height, QSEARCH_NUM, qsearch_options, (int *) &panels_options.qsearch_mode), - QUICK_GROUPBOX (dlg_width / 2, dlg_width, 11, dlg_height, dlg_width / 2 - 4, QSEARCH_NUM + 2, + QUICK_GROUPBOX (dlg_width / 2, dlg_width, 11, dlg_height, dlg_width / 2 - 4, + QSEARCH_NUM + 2, N_("Quick search")), /* file highlighting */ QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 9, dlg_height, N_("&Permissions"), @@ -315,7 +334,8 @@ panel_options_box (void) &panels_options.mix_all_files), QUICK_CHECKBOX (5, dlg_width, 3, dlg_height, N_("Use SI si&ze units"), &panels_options.kilobyte_si), - QUICK_GROUPBOX (3, dlg_width, 2, dlg_height, dlg_width / 2 - 4, 14, N_("Main panel options")), + QUICK_GROUPBOX (3, dlg_width, 2, dlg_height, dlg_width / 2 - 4, 14, + N_("Main panel options")), QUICK_END }; @@ -377,7 +397,7 @@ panel_options_box (void) c_len = max (c_len, str_term_width1 (qsearch_options[i]) + 3); /* groupboxes */ g_len = max (c_len + 2, str_term_width1 (quick_widgets[4].u.groupbox.title) + 4); - g_len = max (g_len, str_term_width1 (quick_widgets[ 7].u.groupbox.title) + 4); + g_len = max (g_len, str_term_width1 (quick_widgets[7].u.groupbox.title) + 4); g_len = max (g_len, str_term_width1 (quick_widgets[11].u.groupbox.title) + 4); g_len = max (g_len, str_term_width1 (quick_widgets[20].u.groupbox.title) + 4); /* dialog width */ @@ -392,14 +412,13 @@ panel_options_box (void) /* groupboxes */ quick_widgets[4].u.groupbox.width = - quick_widgets[ 7].u.groupbox.width = + quick_widgets[7].u.groupbox.width = quick_widgets[11].u.groupbox.width = Quick_input.xlen / 2 - 3; quick_widgets[20].u.groupbox.width = Quick_input.xlen / 2 - 4; /* right column */ quick_widgets[4].relative_x = - quick_widgets[ 7].relative_x = - quick_widgets[11].relative_x = Quick_input.xlen / 2; + quick_widgets[7].relative_x = quick_widgets[11].relative_x = Quick_input.xlen / 2; for (i = 3; i < 11; i++) if ((i != 4) && (i != 7)) quick_widgets[i].relative_x = quick_widgets[4].relative_x + 2; @@ -418,8 +437,7 @@ panel_options_box (void) message (D_NORMAL, _("Information"), _("Using the fast reload option may not reflect the exact\n" "directory contents. In this case you'll need to do a\n" - "manual reload of the directory. See the man page for\n" - "the details.")); + "manual reload of the directory. See the man page for\n" "the details.")); panels_options.fast_reload_msg_shown = TRUE; } update_panels (UP_RELOAD, UP_KEEPSEL); @@ -432,3 +450,5 @@ panel_options_box (void) mc_config_save_file (mc_main_config, NULL); } } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/option.h b/src/option.h index e9855c5d5..2d24be1fd 100644 --- a/src/option.h +++ b/src/option.h @@ -1,12 +1,22 @@ - /** \file option.h * \brief Header: configure box module */ -#ifndef MC_OPTION_H -#define MC_OPTION_H +#ifndef MC__OPTION_H +#define MC__OPTION_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ void configure_box (void); void panel_options_box (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__OPTION_H */ diff --git a/src/panel.h b/src/panel.h index 00545ee51..dce404008 100644 --- a/src/panel.h +++ b/src/panel.h @@ -1,162 +1,177 @@ - /** \file panel.h * \brief Header: defines WPanel structure */ -#ifndef MC_PANEL_H -#define MC_PANEL_H +#ifndef MC__PANEL_H +#define MC__PANEL_H -#include "lib/global.h" /* gboolean */ -#include "lib/fs.h" /* MC_MAXPATHLEN */ +#include "lib/global.h" /* gboolean */ +#include "lib/fs.h" /* MC_MAXPATHLEN */ #include "lib/strutil.h" -#include "dir.h" /* dir_list */ -#include "dialog.h" /* Widget */ -#include "main.h" /* cd_enum */ +#include "dir.h" /* dir_list */ +#include "dialog.h" /* Widget */ +#include "main.h" /* cd_enum */ + +/*** typedefs(not structures) and defined constants **********************************************/ #define selection(p) (&(p->dir.list[p->selected])) #define DEFAULT_USER_FORMAT "half type name | size | perm" #define LIST_TYPES 4 -enum list_types { - list_full, /* Name, size, perm/date */ - list_brief, /* Name */ - list_long, /* Like ls -l */ - list_user /* User defined */ -}; - -typedef enum { - view_listing = 0, /* Directory listing */ - view_info = 1, /* Information panel */ - view_tree = 2, /* Tree view */ - view_quick = 3, /* Quick view */ - view_nothing = 4, /* Undefined */ -} panel_view_mode_t; - -enum panel_display_enum { - frame_full, /* full screen frame */ - frame_half /* half screen frame */ -}; - -struct format_e; - -typedef struct panel_format_struct { - const char *id; - int min_size; - int expands; - align_crt_t default_just; - const char *hotkey; - const char *title_hotkey; - gboolean is_user_choice; - gboolean use_in_user_format; - const char *(*string_fn)(file_entry *, int); - sortfn *sort_routine; /* used by mouse_sort_col() */ -} panel_field_t; - -extern panel_field_t panel_fields []; - -typedef struct WPanel { - Widget widget; - dir_list dir; /* Directory contents */ - - int list_type; /* listing type (was view_type) */ - int active; /* If panel is currently selected */ - char cwd [MC_MAXPATHLEN];/* Current Working Directory */ - char lwd [MC_MAXPATHLEN];/* Last Working Directory */ - GList *dir_history; /* directory history */ - char *hist_name; /* directory history name for history file */ - int count; /* Number of files in dir structure */ - int marked; /* Count of marked files */ - int dirs_marked; /* Count of marked directories */ - double total; /* Bytes in marked files */ - int top_file; /* The file showed on the top of the panel */ - int selected; /* Index to the selected file */ - int reverse; /* Show listing in reverse? */ - int case_sensitive; /* Listing is case sensitive? */ - int exec_first; /* Show executable top in list? */ - int split; /* Split panel to allow two columns */ - int is_panelized; /* Flag: special filelisting, can't reload */ - int frame_size; /* half or full frame */ - const panel_field_t *current_sort_field; - char *filter; /* File name filter */ - - int dirty; /* Should we redisplay the panel? */ - - int user_mini_status; /* Is user_status_format used */ - char *user_format; /* User format */ - char *user_status_format[LIST_TYPES];/* User format for status line */ - - struct format_e *format; /* Display format */ - struct format_e *status_format; /* Mini status format */ - - int format_modified; /* If the format was changed this is set */ - - char *panel_name; /* The panel name */ - struct stat dir_stat; /* Stat of current dir: used by execute () */ - - int codepage; /* panel codepage */ - - gboolean searching; - char search_buffer [MC_MAXFILENAMELEN]; - char prev_search_buffer [MC_MAXFILENAMELEN]; - char search_char [MB_LEN_MAX]; /*buffer for multibytes characters*/ - int search_chpoint; /*point after last characters in search_char*/ -} WPanel; - -WPanel *panel_new (const char *panel_name); -WPanel *panel_new_with_dir (const char *panel_name, const char *dr); -void panel_clean_dir (WPanel *panel); - -extern int torben_fj_mode; -extern int show_mini_info; - -void panel_reload (WPanel *panel); -void panel_set_sort_order (WPanel *panel, const panel_field_t *sort_order); -void panel_re_sort (WPanel *panel); -void panel_change_encoding (WPanel * panel); - #define UP_OPTIMIZE 0 #define UP_RELOAD 1 #define UP_ONLY_CURRENT 2 #define UP_KEEPSEL ((char *) -1) -void update_dirty_panels (void); -void update_panels (int force_update, const char *current_file); -void panel_update_cols (Widget *widget, int frame_size); -int set_panel_formats (WPanel *p); - #define other_panel get_other_panel() +/*** enums ***************************************************************************************/ + +enum list_types +{ + list_full, /* Name, size, perm/date */ + list_brief, /* Name */ + list_long, /* Like ls -l */ + list_user /* User defined */ +}; + +typedef enum +{ + view_listing = 0, /* Directory listing */ + view_info = 1, /* Information panel */ + view_tree = 2, /* Tree view */ + view_quick = 3, /* Quick view */ + view_nothing = 4, /* Undefined */ +} panel_view_mode_t; + +enum panel_display_enum +{ + frame_full, /* full screen frame */ + frame_half /* half screen frame */ +}; + +/*** structures declarations (and typedefs of structures)*****************************************/ + +struct format_e; + +typedef struct panel_format_struct +{ + const char *id; + int min_size; + int expands; + align_crt_t default_just; + const char *hotkey; + const char *title_hotkey; + gboolean is_user_choice; + gboolean use_in_user_format; + const char *(*string_fn) (file_entry *, int); + sortfn *sort_routine; /* used by mouse_sort_col() */ +} panel_field_t; + +typedef struct WPanel +{ + Widget widget; + dir_list dir; /* Directory contents */ + + int list_type; /* listing type (was view_type) */ + int active; /* If panel is currently selected */ + char cwd[MC_MAXPATHLEN]; /* Current Working Directory */ + char lwd[MC_MAXPATHLEN]; /* Last Working Directory */ + GList *dir_history; /* directory history */ + char *hist_name; /* directory history name for history file */ + int count; /* Number of files in dir structure */ + int marked; /* Count of marked files */ + int dirs_marked; /* Count of marked directories */ + double total; /* Bytes in marked files */ + int top_file; /* The file showed on the top of the panel */ + int selected; /* Index to the selected file */ + int reverse; /* Show listing in reverse? */ + int case_sensitive; /* Listing is case sensitive? */ + int exec_first; /* Show executable top in list? */ + int split; /* Split panel to allow two columns */ + int is_panelized; /* Flag: special filelisting, can't reload */ + int frame_size; /* half or full frame */ + const panel_field_t *current_sort_field; + char *filter; /* File name filter */ + + int dirty; /* Should we redisplay the panel? */ + + int user_mini_status; /* Is user_status_format used */ + char *user_format; /* User format */ + char *user_status_format[LIST_TYPES]; /* User format for status line */ + + struct format_e *format; /* Display format */ + struct format_e *status_format; /* Mini status format */ + + int format_modified; /* If the format was changed this is set */ + + char *panel_name; /* The panel name */ + struct stat dir_stat; /* Stat of current dir: used by execute () */ + + int codepage; /* panel codepage */ + + gboolean searching; + char search_buffer[MC_MAXFILENAMELEN]; + char prev_search_buffer[MC_MAXFILENAMELEN]; + char search_char[MB_LEN_MAX]; /*buffer for multibytes characters */ + int search_chpoint; /*point after last characters in search_char */ +} WPanel; + +/*** global variables defined in .c file *********************************************************/ + +extern panel_field_t panel_fields[]; + +extern int torben_fj_mode; +extern int show_mini_info; + extern WPanel *left_panel; extern WPanel *right_panel; extern WPanel *current_panel; -void try_to_select (WPanel *panel, const char *name); - -void unmark_files (WPanel *panel); -void select_item (WPanel *panel); - extern hook_t *select_file_hook; -void recalculate_panel_summary (WPanel *panel); -void file_mark (WPanel *panel, int idx, int val); -void do_file_mark (WPanel *panel, int idx, int val); +/*** declarations of public functions ************************************************************/ + +WPanel *panel_new (const char *panel_name); +WPanel *panel_new_with_dir (const char *panel_name, const char *dr); +void panel_clean_dir (WPanel * panel); + +void panel_reload (WPanel * panel); +void panel_set_sort_order (WPanel * panel, const panel_field_t * sort_order); +void panel_re_sort (WPanel * panel); +void panel_change_encoding (WPanel * panel); + +void update_dirty_panels (void); +void update_panels (int force_update, const char *current_file); +void panel_update_cols (Widget * widget, int frame_size); +int set_panel_formats (WPanel * p); + +void try_to_select (WPanel * panel, const char *name); + +void unmark_files (WPanel * panel); +void select_item (WPanel * panel); + +void recalculate_panel_summary (WPanel * panel); +void file_mark (WPanel * panel, int idx, int val); +void do_file_mark (WPanel * panel, int idx, int val); gboolean do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type); void directory_history_add (struct WPanel *panel, const char *dir); -gsize panel_get_num_of_sortable_fields(void); -const char **panel_get_sortable_fields(gsize *); -const panel_field_t *panel_get_field_by_id(const char *); -const panel_field_t *panel_get_field_by_title(const char *); -const panel_field_t *panel_get_field_by_title_hotkey(const char *); -gsize panel_get_num_of_user_possible_fields(void); -const char **panel_get_user_possible_fields(gsize *); +gsize panel_get_num_of_sortable_fields (void); +const char **panel_get_sortable_fields (gsize *); +const panel_field_t *panel_get_field_by_id (const char *); +const panel_field_t *panel_get_field_by_title (const char *); +const panel_field_t *panel_get_field_by_title_hotkey (const char *); +gsize panel_get_num_of_user_possible_fields (void); +const char **panel_get_user_possible_fields (gsize *); -void panel_init(void); -void panel_deinit(void); +void panel_init (void); +void panel_deinit (void); -#endif /* MC_PANEL_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__PANEL_H */ diff --git a/src/panelize.c b/src/panelize.c index 077343f66..39a899616 100644 --- a/src/panelize.c +++ b/src/panelize.c @@ -51,6 +51,10 @@ #include "panelize.h" #include "history.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define UX 5 #define UY 2 @@ -62,6 +66,10 @@ #define B_ADD B_USER #define B_REMOVE (B_USER + 1) +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + static WListbox *l_panelize; static Dlg_head *panelize_dlg; static int last_listitem; @@ -82,7 +90,6 @@ static struct }; static const char *panelize_section = "Panelize"; -static void do_external_panelize (char *command); /* Directory panelize */ static struct panelize @@ -92,6 +99,13 @@ static struct panelize struct panelize *next; } *panelize = NULL; +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static void do_external_panelize (char *command); + +/* --------------------------------------------------------------------------------------------- */ + static void update_command (void) { @@ -107,6 +121,8 @@ update_command (void) } } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t panelize_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -129,6 +145,8 @@ panelize_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void } } +/* --------------------------------------------------------------------------------------------- */ + static void init_panelize (void) { @@ -176,7 +194,7 @@ init_panelize (void) panelize_but[i].flags, panelize_but[i].text, 0)); pname = - input_new (UY + 14, UX, input_get_default_colors(), + input_new (UY + 14, UX, input_get_default_colors (), panelize_dlg->cols - 10, "", "in", INPUT_COMPLETE_DEFAULT); add_widget (panelize_dlg, pname); @@ -197,6 +215,8 @@ init_panelize (void) listbox_select_entry (l_panelize, listbox_search_text (l_panelize, _("Other command"))); } +/* --------------------------------------------------------------------------------------------- */ + static void panelize_done (void) { @@ -204,6 +224,8 @@ panelize_done (void) repaint_screen (); } +/* --------------------------------------------------------------------------------------------- */ + static void add2panelize (char *label, char *command) { @@ -235,6 +257,8 @@ add2panelize (char *label, char *command) } } +/* --------------------------------------------------------------------------------------------- */ + static void add2panelize_cmd (void) { @@ -256,6 +280,8 @@ add2panelize_cmd (void) } } +/* --------------------------------------------------------------------------------------------- */ + static void remove_from_panelize (struct panelize *entry) { @@ -282,139 +308,7 @@ remove_from_panelize (struct panelize *entry) } } -void -external_panelize (void) -{ - char *target = NULL; - - if (!vfs_current_is_local ()) - { - message (D_ERROR, MSG_ERROR, _("Cannot run external panelize in a non-local directory")); - return; - } - - init_panelize (); - - /* display file info */ - tty_setcolor (SELECTED_COLOR); - - run_dlg (panelize_dlg); - - switch (panelize_dlg->ret_value) - { - case B_CANCEL: - break; - - case B_ADD: - add2panelize_cmd (); - break; - - case B_REMOVE: - { - struct panelize *entry; - - listbox_get_current (l_panelize, NULL, (void **) &entry); - remove_from_panelize (entry); - break; - } - - case B_ENTER: - target = pname->buffer; - if (target != NULL && *target) - { - char *cmd = g_strdup (target); - destroy_dlg (panelize_dlg); - do_external_panelize (cmd); - g_free (cmd); - repaint_screen (); - return; - } - break; - } - - panelize_done (); -} - -void -load_panelize (void) -{ - gchar **profile_keys, **keys; - gsize len; - GIConv conv; - GString *buffer; - - conv = str_crt_conv_from ("UTF-8"); - - profile_keys = keys = mc_config_get_keys (mc_main_config, panelize_section, &len); - - add2panelize (g_strdup (_("Other command")), g_strdup ("")); - - if (!profile_keys || *profile_keys == NULL) - { - add2panelize (g_strdup (_("Find rejects after patching")), - g_strdup ("find . -name \\*.rej -print")); - add2panelize (g_strdup (_("Find *.orig after patching")), - g_strdup ("find . -name \\*.orig -print")); - add2panelize (g_strdup (_("Find SUID and SGID programs")), - g_strdup - ("find . \\( \\( -perm -04000 -a -perm +011 \\) -o \\( -perm -02000 -a -perm +01 \\) \\) -print")); - return; - } - - while (*profile_keys) - { - - if (utf8_display || conv == INVALID_CONV) - { - buffer = g_string_new (*profile_keys); - } - else - { - buffer = g_string_new (""); - if (str_convert (conv, *profile_keys, buffer) == ESTR_FAILURE) - { - g_string_free (buffer, TRUE); - buffer = g_string_new (*profile_keys); - } - } - - add2panelize (g_string_free (buffer, FALSE), - mc_config_get_string (mc_main_config, panelize_section, *profile_keys, "")); - profile_keys++; - } - g_strfreev (keys); - str_close_conv (conv); -} - -void -save_panelize (void) -{ - struct panelize *current = panelize; - - mc_config_del_group (mc_main_config, panelize_section); - for (; current; current = current->next) - { - if (strcmp (current->label, _("Other command"))) - mc_config_set_string (mc_main_config, - panelize_section, current->label, current->command); - } - mc_config_save_file (mc_main_config, NULL); -} - -void -done_panelize (void) -{ - struct panelize *current = panelize; - struct panelize *next; - - for (; current; current = next) - { - next = current->next; - g_free (current->label); - g_free (current->command); - g_free (current); - } -} +/* --------------------------------------------------------------------------------------------- */ static void do_external_panelize (char *command) @@ -495,3 +389,149 @@ do_external_panelize (char *command) try_to_select (current_panel, NULL); panel_re_sort (current_panel); } + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +external_panelize (void) +{ + char *target = NULL; + + if (!vfs_current_is_local ()) + { + message (D_ERROR, MSG_ERROR, _("Cannot run external panelize in a non-local directory")); + return; + } + + init_panelize (); + + /* display file info */ + tty_setcolor (SELECTED_COLOR); + + run_dlg (panelize_dlg); + + switch (panelize_dlg->ret_value) + { + case B_CANCEL: + break; + + case B_ADD: + add2panelize_cmd (); + break; + + case B_REMOVE: + { + struct panelize *entry; + + listbox_get_current (l_panelize, NULL, (void **) &entry); + remove_from_panelize (entry); + break; + } + + case B_ENTER: + target = pname->buffer; + if (target != NULL && *target) + { + char *cmd = g_strdup (target); + destroy_dlg (panelize_dlg); + do_external_panelize (cmd); + g_free (cmd); + repaint_screen (); + return; + } + break; + } + + panelize_done (); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +load_panelize (void) +{ + gchar **profile_keys, **keys; + gsize len; + GIConv conv; + GString *buffer; + + conv = str_crt_conv_from ("UTF-8"); + + profile_keys = keys = mc_config_get_keys (mc_main_config, panelize_section, &len); + + add2panelize (g_strdup (_("Other command")), g_strdup ("")); + + if (!profile_keys || *profile_keys == NULL) + { + add2panelize (g_strdup (_("Find rejects after patching")), + g_strdup ("find . -name \\*.rej -print")); + add2panelize (g_strdup (_("Find *.orig after patching")), + g_strdup ("find . -name \\*.orig -print")); + add2panelize (g_strdup (_("Find SUID and SGID programs")), + g_strdup + ("find . \\( \\( -perm -04000 -a -perm +011 \\) -o \\( -perm -02000 -a -perm +01 \\) \\) -print")); + return; + } + + while (*profile_keys) + { + + if (utf8_display || conv == INVALID_CONV) + { + buffer = g_string_new (*profile_keys); + } + else + { + buffer = g_string_new (""); + if (str_convert (conv, *profile_keys, buffer) == ESTR_FAILURE) + { + g_string_free (buffer, TRUE); + buffer = g_string_new (*profile_keys); + } + } + + add2panelize (g_string_free (buffer, FALSE), + mc_config_get_string (mc_main_config, panelize_section, *profile_keys, "")); + profile_keys++; + } + g_strfreev (keys); + str_close_conv (conv); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +save_panelize (void) +{ + struct panelize *current = panelize; + + mc_config_del_group (mc_main_config, panelize_section); + for (; current; current = current->next) + { + if (strcmp (current->label, _("Other command"))) + mc_config_set_string (mc_main_config, + panelize_section, current->label, current->command); + } + mc_config_save_file (mc_main_config, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +done_panelize (void) +{ + struct panelize *current = panelize; + struct panelize *next; + + for (; current; current = next) + { + next = current->next; + g_free (current->label); + g_free (current->command); + g_free (current); + } +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/panelize.h b/src/panelize.h index 72a5ba4a9..313d488c3 100644 --- a/src/panelize.h +++ b/src/panelize.h @@ -1,14 +1,24 @@ - /** \file panelize.h * \brief Header: External panelization module */ -#ifndef MC_PANELIZE_H -#define MC_PANELIZE_H +#ifndef MC__PANELIZE_H +#define MC__PANELIZE_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ void external_panelize (void); void load_panelize (void); void save_panelize (void); void done_panelize (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__PANELIZE_H */ diff --git a/src/screen.c b/src/screen.c index bd50bb305..7d35f8f85 100644 --- a/src/screen.c +++ b/src/screen.c @@ -68,37 +68,7 @@ #include "cmddef.h" /* CK_ cmd name const */ #include "keybind.h" /* global_keymap_t */ -#define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) ) - -#define NORMAL 0 -#define SELECTED 1 -#define MARKED 2 -#define MARKED_SELECTED 3 -#define STATUS 5 - -typedef enum -{ - MARK_DONT_MOVE = 0, - MARK_DOWN = 1, - MARK_FORCE_DOWN = 2, - MARK_FORCE_UP = 3 -} mark_act_t; - -/* - * This describes a format item. The parse_display_format routine parses - * the user specified format and creates a linked list of format_e structures. - */ -typedef struct format_e -{ - struct format_e *next; - int requested_field_len; - int field_len; - align_crt_t just_mode; - int expand; - const char *(*string_fn) (file_entry *, int len); - char *title; - const char *id; -} format_e; +/*** global variables ****************************************************************************/ /* If true, show the mini-info on the panel */ int show_mini_info = 1; @@ -109,338 +79,26 @@ int torben_fj_mode = 0; /* The hook list for the select file function */ hook_t *select_file_hook = NULL; -static cb_ret_t panel_callback (Widget *, widget_msg_t msg, int parm); -static int panel_event (Gpm_Event * event, void *); -static void paint_frame (WPanel * panel); -static const char *panel_format (WPanel * panel); -static const char *mini_status_format (WPanel * panel); -static char *panel_sort_up_sign = NULL; -static char *panel_sort_down_sign = NULL; -static char *panel_hiddenfiles_sign_show = NULL; -static char *panel_hiddenfiles_sign_hide = NULL; -static char *panel_history_prev_item_sign = NULL; -static char *panel_history_next_item_sign = NULL; -static char *panel_history_show_list_sign = NULL; - -/* This macro extracts the number of available lines in a panel */ -#define llines(p) (p->widget.lines-3 - (show_mini_info ? 2 : 0)) - -static void -set_colors (WPanel * panel) -{ - (void) panel; - tty_set_normal_attrs (); - tty_setcolor (NORMAL_COLOR); -} - -/* Delete format string, it is a linked list */ -static void -delete_format (format_e * format) -{ - while (format != NULL) - { - format_e *next = format->next; - g_free (format->title); - g_free (format); - format = next; - } -} - -/* This code relies on the default justification!!! */ -static void -add_permission_string (char *dest, int width, file_entry * fe, int attr, int color, int is_octal) -{ - int i, r, l; - - l = get_user_permissions (&fe->st); - - if (is_octal) - { - /* Place of the access bit in octal mode */ - l = width + l - 3; - r = l + 1; - } - else - { - /* The same to the triplet in string mode */ - l = l * 3 + 1; - r = l + 3; - } - - for (i = 0; i < width; i++) - { - if (i >= l && i < r) - { - if (attr == SELECTED || attr == MARKED_SELECTED) - tty_setcolor (MARKED_SELECTED_COLOR); - else - tty_setcolor (MARKED_COLOR); - } - else if (color >= 0) - tty_setcolor (color); - else - tty_lowlevel_setcolor (-color); - - tty_print_char (dest[i]); - } -} - -/* String representations of various file attributes */ -/* name */ -static const char * -string_file_name (file_entry * fe, int len) -{ - static char buffer[MC_MAXPATHLEN * MB_LEN_MAX + 1]; - - (void) len; - g_strlcpy (buffer, fe->fname, sizeof (buffer)); - return buffer; -} - -static unsigned int -ilog10 (dev_t n) -{ - unsigned int digits = 0; - do - { - digits++, n /= 10; - } - while (n != 0); - return digits; -} - -static void -format_device_number (char *buf, size_t bufsize, dev_t dev) -{ - dev_t major_dev = major (dev); - dev_t minor_dev = minor (dev); - unsigned int major_digits = ilog10 (major_dev); - unsigned int minor_digits = ilog10 (minor_dev); - - g_assert (bufsize >= 1); - if (major_digits + 1 + minor_digits + 1 <= bufsize) - { - g_snprintf (buf, bufsize, "%lu,%lu", (unsigned long) major_dev, (unsigned long) minor_dev); - } - else - { - g_strlcpy (buf, _("[dev]"), bufsize); - } -} - -/* size */ -static const char * -string_file_size (file_entry * fe, int len) -{ - static char buffer[BUF_TINY]; - - /* Don't ever show size of ".." since we don't calculate it */ - if (!strcmp (fe->fname, "..")) - { - return _("UP--DIR"); - } - -#ifdef HAVE_STRUCT_STAT_ST_RDEV - if (S_ISBLK (fe->st.st_mode) || S_ISCHR (fe->st.st_mode)) - format_device_number (buffer, len + 1, fe->st.st_rdev); - else -#endif - { - size_trunc_len (buffer, (unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si); - } - return buffer; -} - -/* bsize */ -static const char * -string_file_size_brief (file_entry * fe, int len) -{ - if (S_ISLNK (fe->st.st_mode) && !fe->f.link_to_dir) - { - return _("SYMLINK"); - } - - if ((S_ISDIR (fe->st.st_mode) || fe->f.link_to_dir) && strcmp (fe->fname, "..")) - { - return _("SUB-DIR"); - } - - return string_file_size (fe, len); -} - -/* This functions return a string representation of a file entry */ -/* type */ -static const char * -string_file_type (file_entry * fe, int len) -{ - static char buffer[2]; - - (void) len; - if (S_ISDIR (fe->st.st_mode)) - buffer[0] = PATH_SEP; - else if (S_ISLNK (fe->st.st_mode)) - { - if (fe->f.link_to_dir) - buffer[0] = '~'; - else if (fe->f.stale_link) - buffer[0] = '!'; - else - buffer[0] = '@'; - } - else if (S_ISCHR (fe->st.st_mode)) - buffer[0] = '-'; - else if (S_ISSOCK (fe->st.st_mode)) - buffer[0] = '='; - else if (S_ISDOOR (fe->st.st_mode)) - buffer[0] = '>'; - else if (S_ISBLK (fe->st.st_mode)) - buffer[0] = '+'; - else if (S_ISFIFO (fe->st.st_mode)) - buffer[0] = '|'; - else if (S_ISNAM (fe->st.st_mode)) - buffer[0] = '#'; - else if (!S_ISREG (fe->st.st_mode)) - buffer[0] = '?'; /* non-regular of unknown kind */ - else if (is_exe (fe->st.st_mode)) - buffer[0] = '*'; - else - buffer[0] = ' '; - buffer[1] = '\0'; - return buffer; -} - -/* mtime */ -static const char * -string_file_mtime (file_entry * fe, int len) -{ - (void) len; - return file_date (fe->st.st_mtime); -} - -/* atime */ -static const char * -string_file_atime (file_entry * fe, int len) -{ - (void) len; - return file_date (fe->st.st_atime); -} - -/* ctime */ -static const char * -string_file_ctime (file_entry * fe, int len) -{ - (void) len; - return file_date (fe->st.st_ctime); -} - -/* perm */ -static const char * -string_file_permission (file_entry * fe, int len) -{ - (void) len; - return string_perm (fe->st.st_mode); -} - -/* mode */ -static const char * -string_file_perm_octal (file_entry * fe, int len) -{ - static char buffer[10]; - - (void) len; - g_snprintf (buffer, sizeof (buffer), "0%06lo", (unsigned long) fe->st.st_mode); - return buffer; -} - -/* nlink */ -static const char * -string_file_nlinks (file_entry * fe, int len) -{ - static char buffer[BUF_TINY]; - - (void) len; - g_snprintf (buffer, sizeof (buffer), "%16d", (int) fe->st.st_nlink); - return buffer; -} - -/* inode */ -static const char * -string_inode (file_entry * fe, int len) -{ - static char buffer[10]; - - (void) len; - g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_ino); - return buffer; -} - -/* nuid */ -static const char * -string_file_nuid (file_entry * fe, int len) -{ - static char buffer[10]; - - (void) len; - g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_uid); - return buffer; -} - -/* ngid */ -static const char * -string_file_ngid (file_entry * fe, int len) -{ - static char buffer[10]; - - (void) len; - g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_gid); - return buffer; -} - -/* owner */ -static const char * -string_file_owner (file_entry * fe, int len) -{ - (void) len; - return get_owner (fe->st.st_uid); -} - -/* group */ -static const char * -string_file_group (file_entry * fe, int len) -{ - (void) len; - return get_group (fe->st.st_gid); -} - -/* mark */ -static const char * -string_marked (file_entry * fe, int len) -{ - (void) len; - return fe->f.marked ? "*" : " "; -} - -/* space */ -static const char * -string_space (file_entry * fe, int len) -{ - (void) fe; - (void) len; - return " "; -} - -/* dot */ -static const char * -string_dot (file_entry * fe, int len) -{ - (void) fe; - (void) len; - return "."; -} - -#define GT 1 +static const char *string_file_name (file_entry *, int); +static const char *string_file_size (file_entry *, int); +static const char *string_file_size_brief (file_entry *, int); +static const char *string_file_type (file_entry *, int); +static const char *string_file_mtime (file_entry *, int); +static const char *string_file_atime (file_entry *, int); +static const char *string_file_ctime (file_entry *, int); +static const char *string_file_permission (file_entry *, int); +static const char *string_file_perm_octal (file_entry *, int); +static const char *string_file_nlinks (file_entry *, int); +static const char *string_inode (file_entry *, int); +static const char *string_file_nuid (file_entry *, int); +static const char *string_file_ngid (file_entry *, int); +static const char *string_file_owner (file_entry *, int); +static const char *string_file_group (file_entry *, int); +static const char *string_marked (file_entry *, int); +static const char *string_space (file_entry *, int); +static const char *string_dot (file_entry *, int); /* *INDENT-OFF* */ panel_field_t panel_fields[] = { @@ -503,7 +161,7 @@ panel_field_t panel_fields[] = { } , { - "type", GT, 0, J_LEFT, + "type", 1, 0, J_LEFT, "", "", FALSE, TRUE, string_file_type, @@ -643,6 +301,426 @@ panel_field_t panel_fields[] = { }; /* *INDENT-ON* */ +extern int saving_setup; + +/*** file scope macro definitions ****************************************************************/ + +#define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) ) + +#define NORMAL 0 +#define SELECTED 1 +#define MARKED 2 +#define MARKED_SELECTED 3 +#define STATUS 5 + +/* This macro extracts the number of available lines in a panel */ +#define llines(p) (p->widget.lines-3 - (show_mini_info ? 2 : 0)) + +/*** file scope type declarations ****************************************************************/ + +typedef enum +{ + MARK_DONT_MOVE = 0, + MARK_DOWN = 1, + MARK_FORCE_DOWN = 2, + MARK_FORCE_UP = 3 +} mark_act_t; + +/* + * This describes a format item. The parse_display_format routine parses + * the user specified format and creates a linked list of format_e structures. + */ +typedef struct format_e +{ + struct format_e *next; + int requested_field_len; + int field_len; + align_crt_t just_mode; + int expand; + const char *(*string_fn) (file_entry *, int len); + char *title; + const char *id; +} format_e; + +/*** file scope variables ************************************************************************/ + +static cb_ret_t panel_callback (Widget *, widget_msg_t msg, int parm); +static int panel_event (Gpm_Event * event, void *); +static void paint_frame (WPanel * panel); +static const char *panel_format (WPanel * panel); +static const char *mini_status_format (WPanel * panel); + +static char *panel_sort_up_sign = NULL; +static char *panel_sort_down_sign = NULL; + +static char *panel_hiddenfiles_sign_show = NULL; +static char *panel_hiddenfiles_sign_hide = NULL; +static char *panel_history_prev_item_sign = NULL; +static char *panel_history_next_item_sign = NULL; +static char *panel_history_show_list_sign = NULL; + +static int mouse_marking = 0; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static void +set_colors (WPanel * panel) +{ + (void) panel; + tty_set_normal_attrs (); + tty_setcolor (NORMAL_COLOR); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Delete format string, it is a linked list */ + +static void +delete_format (format_e * format) +{ + while (format != NULL) + { + format_e *next = format->next; + g_free (format->title); + g_free (format); + format = next; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** This code relies on the default justification!!! */ + +static void +add_permission_string (char *dest, int width, file_entry * fe, int attr, int color, int is_octal) +{ + int i, r, l; + + l = get_user_permissions (&fe->st); + + if (is_octal) + { + /* Place of the access bit in octal mode */ + l = width + l - 3; + r = l + 1; + } + else + { + /* The same to the triplet in string mode */ + l = l * 3 + 1; + r = l + 3; + } + + for (i = 0; i < width; i++) + { + if (i >= l && i < r) + { + if (attr == SELECTED || attr == MARKED_SELECTED) + tty_setcolor (MARKED_SELECTED_COLOR); + else + tty_setcolor (MARKED_COLOR); + } + else if (color >= 0) + tty_setcolor (color); + else + tty_lowlevel_setcolor (-color); + + tty_print_char (dest[i]); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** String representations of various file attributes name */ + +static const char * +string_file_name (file_entry * fe, int len) +{ + static char buffer[MC_MAXPATHLEN * MB_LEN_MAX + 1]; + + (void) len; + g_strlcpy (buffer, fe->fname, sizeof (buffer)); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ + +static unsigned int +ilog10 (dev_t n) +{ + unsigned int digits = 0; + do + { + digits++, n /= 10; + } + while (n != 0); + return digits; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +format_device_number (char *buf, size_t bufsize, dev_t dev) +{ + dev_t major_dev = major (dev); + dev_t minor_dev = minor (dev); + unsigned int major_digits = ilog10 (major_dev); + unsigned int minor_digits = ilog10 (minor_dev); + + g_assert (bufsize >= 1); + if (major_digits + 1 + minor_digits + 1 <= bufsize) + { + g_snprintf (buf, bufsize, "%lu,%lu", (unsigned long) major_dev, (unsigned long) minor_dev); + } + else + { + g_strlcpy (buf, _("[dev]"), bufsize); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** size */ + +static const char * +string_file_size (file_entry * fe, int len) +{ + static char buffer[BUF_TINY]; + + /* Don't ever show size of ".." since we don't calculate it */ + if (!strcmp (fe->fname, "..")) + { + return _("UP--DIR"); + } + +#ifdef HAVE_STRUCT_STAT_ST_RDEV + if (S_ISBLK (fe->st.st_mode) || S_ISCHR (fe->st.st_mode)) + format_device_number (buffer, len + 1, fe->st.st_rdev); + else +#endif + { + size_trunc_len (buffer, (unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si); + } + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** bsize */ + +static const char * +string_file_size_brief (file_entry * fe, int len) +{ + if (S_ISLNK (fe->st.st_mode) && !fe->f.link_to_dir) + { + return _("SYMLINK"); + } + + if ((S_ISDIR (fe->st.st_mode) || fe->f.link_to_dir) && strcmp (fe->fname, "..")) + { + return _("SUB-DIR"); + } + + return string_file_size (fe, len); +} + +/* --------------------------------------------------------------------------------------------- */ +/** This functions return a string representation of a file entry type */ + +static const char * +string_file_type (file_entry * fe, int len) +{ + static char buffer[2]; + + (void) len; + if (S_ISDIR (fe->st.st_mode)) + buffer[0] = PATH_SEP; + else if (S_ISLNK (fe->st.st_mode)) + { + if (fe->f.link_to_dir) + buffer[0] = '~'; + else if (fe->f.stale_link) + buffer[0] = '!'; + else + buffer[0] = '@'; + } + else if (S_ISCHR (fe->st.st_mode)) + buffer[0] = '-'; + else if (S_ISSOCK (fe->st.st_mode)) + buffer[0] = '='; + else if (S_ISDOOR (fe->st.st_mode)) + buffer[0] = '>'; + else if (S_ISBLK (fe->st.st_mode)) + buffer[0] = '+'; + else if (S_ISFIFO (fe->st.st_mode)) + buffer[0] = '|'; + else if (S_ISNAM (fe->st.st_mode)) + buffer[0] = '#'; + else if (!S_ISREG (fe->st.st_mode)) + buffer[0] = '?'; /* non-regular of unknown kind */ + else if (is_exe (fe->st.st_mode)) + buffer[0] = '*'; + else + buffer[0] = ' '; + buffer[1] = '\0'; + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** mtime */ + +static const char * +string_file_mtime (file_entry * fe, int len) +{ + (void) len; + return file_date (fe->st.st_mtime); +} + +/* --------------------------------------------------------------------------------------------- */ +/** atime */ + +static const char * +string_file_atime (file_entry * fe, int len) +{ + (void) len; + return file_date (fe->st.st_atime); +} + +/* --------------------------------------------------------------------------------------------- */ +/** ctime */ + +static const char * +string_file_ctime (file_entry * fe, int len) +{ + (void) len; + return file_date (fe->st.st_ctime); +} + +/* --------------------------------------------------------------------------------------------- */ +/** perm */ + +static const char * +string_file_permission (file_entry * fe, int len) +{ + (void) len; + return string_perm (fe->st.st_mode); +} + +/* --------------------------------------------------------------------------------------------- */ +/** mode */ + +static const char * +string_file_perm_octal (file_entry * fe, int len) +{ + static char buffer[10]; + + (void) len; + g_snprintf (buffer, sizeof (buffer), "0%06lo", (unsigned long) fe->st.st_mode); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** nlink */ + +static const char * +string_file_nlinks (file_entry * fe, int len) +{ + static char buffer[BUF_TINY]; + + (void) len; + g_snprintf (buffer, sizeof (buffer), "%16d", (int) fe->st.st_nlink); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** inode */ + +static const char * +string_inode (file_entry * fe, int len) +{ + static char buffer[10]; + + (void) len; + g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_ino); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** nuid */ + +static const char * +string_file_nuid (file_entry * fe, int len) +{ + static char buffer[10]; + + (void) len; + g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_uid); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** ngid */ + +static const char * +string_file_ngid (file_entry * fe, int len) +{ + static char buffer[10]; + + (void) len; + g_snprintf (buffer, sizeof (buffer), "%lu", (unsigned long) fe->st.st_gid); + return buffer; +} + +/* --------------------------------------------------------------------------------------------- */ +/** owner */ + +static const char * +string_file_owner (file_entry * fe, int len) +{ + (void) len; + return get_owner (fe->st.st_uid); +} + +/* --------------------------------------------------------------------------------------------- */ +/** group */ + +static const char * +string_file_group (file_entry * fe, int len) +{ + (void) len; + return get_group (fe->st.st_gid); +} + +/* --------------------------------------------------------------------------------------------- */ +/** mark */ + +static const char * +string_marked (file_entry * fe, int len) +{ + (void) len; + return fe->f.marked ? "*" : " "; +} + +/* --------------------------------------------------------------------------------------------- */ +/** space */ + +static const char * +string_space (file_entry * fe, int len) +{ + (void) fe; + (void) len; + return " "; +} + +/* --------------------------------------------------------------------------------------------- */ +/** dot */ + +static const char * +string_dot (file_entry * fe, int len) +{ + (void) fe; + (void) len; + return "."; +} + +/* --------------------------------------------------------------------------------------------- */ + static int file_compute_color (int attr, file_entry * fe) { @@ -665,7 +743,9 @@ file_compute_color (int attr, file_entry * fe) return mc_fhl_get_color (mc_filehighlight, fe); } -/* Formats the file number file_index of panel in the buffer dest */ +/* --------------------------------------------------------------------------------------------- */ +/** Formats the file number file_index of panel in the buffer dest */ + static void format_file (char *dest, int limit, WPanel * panel, int file_index, int width, int attr, int isstatus) @@ -745,6 +825,8 @@ format_file (char *dest, int limit, WPanel * panel, int file_index, int width, i tty_draw_hline (-1, -1, ' ', width - length); } +/* --------------------------------------------------------------------------------------------- */ + static void repaint_file (WPanel * panel, int file_index, int mv, int attr, int isstatus) { @@ -797,6 +879,8 @@ repaint_file (WPanel * panel, int file_index, int mv, int attr, int isstatus) } } +/* --------------------------------------------------------------------------------------------- */ + static void display_mini_info (WPanel * panel) { @@ -847,6 +931,8 @@ display_mini_info (WPanel * panel) repaint_file (panel, panel->selected, 0, STATUS, 1); } +/* --------------------------------------------------------------------------------------------- */ + static void paint_dir (WPanel * panel) { @@ -870,6 +956,8 @@ paint_dir (WPanel * panel) tty_set_normal_attrs (); } +/* --------------------------------------------------------------------------------------------- */ + static void display_total_marked_size (WPanel * panel, int y, int x, gboolean size_only) { @@ -910,6 +998,8 @@ display_total_marked_size (WPanel * panel, int y, int x, gboolean size_only) tty_printf (" %s ", buf); } +/* --------------------------------------------------------------------------------------------- */ + static void mini_info_separator (WPanel * panel) { @@ -926,6 +1016,8 @@ mini_info_separator (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void show_free_space (WPanel * panel) { @@ -955,11 +1047,13 @@ show_free_space (WPanel * panel) if (myfs_stats.avail > 0 || myfs_stats.total > 0) { char buffer1[6], buffer2[6], tmp[BUF_SMALL]; - size_trunc_len (buffer1, sizeof (buffer1) - 1, myfs_stats.avail, 1, panels_options.kilobyte_si); - size_trunc_len (buffer2, sizeof (buffer2) - 1, myfs_stats.total, 1, panels_options.kilobyte_si); + size_trunc_len (buffer1, sizeof (buffer1) - 1, myfs_stats.avail, 1, + panels_options.kilobyte_si); + size_trunc_len (buffer2, sizeof (buffer2) - 1, myfs_stats.total, 1, + panels_options.kilobyte_si); g_snprintf (tmp, sizeof (tmp), " %s/%s (%d%%) ", buffer1, buffer2, - myfs_stats.total > 0 ? - (int) (100 * (double) myfs_stats.avail / myfs_stats.total) : 0); + myfs_stats.total > + 0 ? (int) (100 * (double) myfs_stats.avail / myfs_stats.total) : 0); widget_move (&panel->widget, panel->widget.lines - 1, panel->widget.cols - 2 - (int) strlen (tmp)); tty_setcolor (NORMAL_COLOR); @@ -967,6 +1061,8 @@ show_free_space (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void show_dir (WPanel * panel) { @@ -988,7 +1084,7 @@ show_dir (WPanel * panel) tmp = panels_options.show_dot_files ? panel_hiddenfiles_sign_show : panel_hiddenfiles_sign_hide; tmp = g_strdup_printf ("%s[%s]%s", tmp, panel_history_show_list_sign, - panel_history_next_item_sign); + panel_history_next_item_sign); widget_move (&panel->widget, 0, panel->widget.cols - 6); tty_print_string (tmp); @@ -1035,7 +1131,9 @@ show_dir (WPanel * panel) tty_set_normal_attrs (); } -/* To be used only by long_frame and full_frame to adjust top_file */ +/* --------------------------------------------------------------------------------------------- */ +/** To be used only by long_frame and full_frame to adjust top_file */ + static void adjust_top_file (WPanel * panel) { @@ -1047,7 +1145,9 @@ adjust_top_file (WPanel * panel) panel->top_file = panel->count - llines (panel); } -/* Repaint everything, including frame and separator */ +/* --------------------------------------------------------------------------------------------- */ +/** Repaint everything, including frame and separator */ + static void paint_panel (WPanel * panel) { @@ -1058,11 +1158,13 @@ paint_panel (WPanel * panel) panel->dirty = 0; } -/* add "#enc:encodning" to end of path */ +/* --------------------------------------------------------------------------------------------- */ +/** add "#enc:encodning" to end of path */ /* if path end width a previous #enc:, only encoding is changed no additional * #enc: is appended * retun new string */ + static char * add_encoding_to_path (const char *path, const char *encoding) { @@ -1094,153 +1196,8 @@ add_encoding_to_path (const char *path, const char *encoding) return result; } -char * -remove_encoding_from_path (const char *path) -{ - GString *ret; - GString *tmp_path, *tmp_conv; - char *tmp, *tmp2; - const char *enc; - GIConv converter; +/* --------------------------------------------------------------------------------------------- */ - ret = g_string_new (""); - tmp_conv = g_string_new (""); - - tmp_path = g_string_new (path); - - while ((tmp = g_strrstr (tmp_path->str, PATH_SEP_STR VFS_ENCODING_PREFIX)) != NULL) - { - enc = vfs_get_encoding ((const char *) tmp); - converter = enc ? str_crt_conv_to (enc) : str_cnv_to_term; - if (converter == INVALID_CONV) - converter = str_cnv_to_term; - - tmp2 = tmp + 1; - while (*tmp2 && *tmp2 != PATH_SEP) - tmp2++; - - if (*tmp2) - { - str_vfs_convert_from (converter, tmp2, tmp_conv); - g_string_prepend (ret, tmp_conv->str); - g_string_set_size (tmp_conv, 0); - } - g_string_set_size (tmp_path, tmp - tmp_path->str); - str_close_conv (converter); - } - g_string_prepend (ret, tmp_path->str); - g_string_free (tmp_path, TRUE); - g_string_free (tmp_conv, TRUE); - - tmp = ret->str; - g_string_free (ret, FALSE); - return tmp; -} - -/* - * Repaint the contents of the panels without frames. To schedule panel - * for repainting, set panel->dirty to 1. There are many reasons why - * the panels need to be repainted, and this is a costly operation, so - * it's done once per event. - */ -void -update_dirty_panels (void) -{ - if (current_panel->dirty) - paint_panel (current_panel); - - if ((get_other_type () == view_listing) && other_panel->dirty) - paint_panel (other_panel); -} - -static void -do_select (WPanel * panel, int i) -{ - if (i != panel->selected) - { - panel->dirty = 1; - panel->selected = i; - panel->top_file = panel->selected - (panel->widget.lines - 2) / 2; - if (panel->top_file < 0) - panel->top_file = 0; - } -} - -static void -do_try_to_select (WPanel * panel, const char *name) -{ - int i; - char *subdir; - - if (!name) - { - do_select (panel, 0); - return; - } - - /* We only want the last component of the directory, - * and from this only the name without suffix. */ - subdir = vfs_strip_suffix_from_filename (x_basename (name)); - - /* Search that subdirectory, if found select it */ - for (i = 0; i < panel->count; i++) - { - if (strcmp (subdir, panel->dir.list[i].fname) == 0) - { - do_select (panel, i); - g_free (subdir); - return; - } - } - - /* Try to select a file near the file that is missing */ - if (panel->selected >= panel->count) - do_select (panel, panel->count - 1); - g_free (subdir); -} - -void -try_to_select (WPanel * panel, const char *name) -{ - do_try_to_select (panel, name); - select_item (panel); -} - -void -panel_update_cols (Widget * widget, int frame_size) -{ - int cols, origin; - - if (horizontal_split) - { - widget->cols = COLS; - return; - } - - if (frame_size == frame_full) - { - cols = COLS; - origin = 0; - } - else - { - if (widget == get_panel_widget (0)) - { - cols = first_panel_size; - origin = 0; - } - else - { - cols = COLS - first_panel_size; - origin = first_panel_size; - } - } - - widget->cols = cols; - widget->x = origin; -} - -extern int saving_setup; static char * panel_save_name (WPanel * panel) { @@ -1251,23 +1208,7 @@ panel_save_name (WPanel * panel) return g_strconcat ("Temporal:", panel->panel_name, (char *) NULL); } -void -panel_clean_dir (WPanel * panel) -{ - int count = panel->count; - - panel->count = 0; - panel->top_file = 0; - panel->selected = 0; - panel->marked = 0; - panel->dirs_marked = 0; - panel->total = 0; - panel->searching = FALSE; - panel->is_panelized = 0; - panel->dirty = 1; - - clean_dir (&panel->dir, count); -} +/* --------------------------------------------------------------------------------------------- */ static void panel_destroy (WPanel * p) @@ -1302,167 +1243,15 @@ panel_destroy (WPanel * p) g_free (name); } +/* --------------------------------------------------------------------------------------------- */ + static void panel_format_modified (WPanel * panel) { panel->format_modified = 1; } -/** Panel creation. - * @param panel_name the name of the panel for setup retieving - * @returns new instance of WPanel - */ -WPanel * -panel_new (const char *panel_name) -{ - return panel_new_with_dir (panel_name, NULL); -} - -/** Panel creation for specified directory. - * @param panel_name specifies the name of the panel for setup retieving - * @param the path of working panel directory. If path is NULL then panel will be created for current directory - * @returns new instance of WPanel - */ -WPanel * -panel_new_with_dir (const char *panel_name, const char *wpath) -{ - WPanel *panel; - char *section; - int i, err; - char curdir[MC_MAXPATHLEN] = "\0"; - - panel = g_new0 (WPanel, 1); - - /* No know sizes of the panel at startup */ - init_widget (&panel->widget, 0, 0, 0, 0, panel_callback, panel_event); - - /* We do not want the cursor */ - widget_want_cursor (panel->widget, 0); - - if (wpath != NULL) - { - g_strlcpy (panel->cwd, wpath, sizeof (panel->cwd)); - mc_get_current_wd (curdir, sizeof (curdir) - 2); - } - else - mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); - - strcpy (panel->lwd, "."); - - panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); - panel->dir_history = history_get (panel->hist_name); - directory_history_add (panel, panel->cwd); - - panel->dir.list = g_new (file_entry, MIN_FILES); - panel->dir.size = MIN_FILES; - panel->active = 0; - panel->filter = 0; - panel->split = 0; - panel->top_file = 0; - panel->selected = 0; - panel->marked = 0; - panel->total = 0; - panel->reverse = 0; - panel->dirty = 1; - panel->searching = FALSE; - panel->dirs_marked = 0; - panel->is_panelized = 0; - panel->format = 0; - panel->status_format = 0; - panel->format_modified = 1; - - panel->panel_name = g_strdup (panel_name); - panel->user_format = g_strdup (DEFAULT_USER_FORMAT); - - panel->codepage = SELECT_CHARSET_NO_TRANSLATE; - - for (i = 0; i < LIST_TYPES; i++) - panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT); - - panel->search_buffer[0] = '\0'; - panel->prev_search_buffer[0] = '\0'; - panel->frame_size = frame_half; - - section = g_strconcat ("Temporal:", panel->panel_name, (char *) NULL); - if (!mc_config_has_group (mc_main_config, section)) - { - g_free (section); - section = g_strdup (panel->panel_name); - } - panel_load_setup (panel, section); - g_free (section); - - /* Load format strings */ - err = set_panel_formats (panel); - if (err != 0) - set_panel_formats (panel); - -#ifdef HAVE_CHARSET - { - const char *enc = vfs_get_encoding (panel->cwd); - if (enc != NULL) - panel->codepage = get_codepage_index (enc); - } -#endif - - if (mc_chdir (panel->cwd) != 0) - { - panel->codepage = SELECT_CHARSET_NO_TRANSLATE; - mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); - } - - /* Load the default format */ - panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, - panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); - - /* Restore old right path */ - if (curdir[0] != '\0') - err = mc_chdir (curdir); - - return panel; -} - -void -panel_reload (WPanel * panel) -{ - struct stat current_stat; - - if (panels_options.fast_reload && !stat (panel->cwd, ¤t_stat) - && current_stat.st_ctime == panel->dir_stat.st_ctime - && current_stat.st_mtime == panel->dir_stat.st_mtime) - return; - - while (mc_chdir (panel->cwd) == -1) - { - char *last_slash; - - if (panel->cwd[0] == PATH_SEP && panel->cwd[1] == 0) - { - panel_clean_dir (panel); - panel->count = set_zero_dir (&panel->dir) ? 1 : 0; - return; - } - last_slash = strrchr (panel->cwd, PATH_SEP); - if (!last_slash || last_slash == panel->cwd) - strcpy (panel->cwd, PATH_SEP_STR); - else - *last_slash = 0; - memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); - show_dir (panel); - } - - panel->count = - do_reload_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, - panel->count, panel->reverse, panel->case_sensitive, - panel->exec_first, panel->filter); - - panel->dirty = 1; - if (panel->selected >= panel->count) - do_select (panel, panel->count - 1); - - recalculate_panel_summary (panel); -} +/* --------------------------------------------------------------------------------------------- */ static void panel_paint_sort_info (WPanel * panel) @@ -1480,6 +1269,8 @@ panel_paint_sort_info (WPanel * panel) g_free (str); } +/* --------------------------------------------------------------------------------------------- */ + static gchar * panel_get_title_without_hotkey (const char *title) { @@ -1500,6 +1291,8 @@ panel_get_title_without_hotkey (const char *title) return translated_title; } +/* --------------------------------------------------------------------------------------------- */ + static void paint_frame (WPanel * panel) { @@ -1571,6 +1364,8 @@ paint_frame (WPanel * panel) panel_paint_sort_info (panel); } +/* --------------------------------------------------------------------------------------------- */ + static const char * parse_panel_size (WPanel * panel, const char *format, int isstatus) { @@ -1625,6 +1420,8 @@ parse_panel_size (WPanel * panel, const char *format, int isstatus) */ +/* --------------------------------------------------------------------------------------------- */ + static format_e * parse_display_format (WPanel * panel, const char *format, char **error, int isstatus, int *res_total_cols) @@ -1752,7 +1549,8 @@ parse_display_format (WPanel * panel, const char *format, char **error, int isst int pos = min (8, strlen (format)); delete_format (home); tmp_format[pos] = 0; - *error = g_strconcat (_("Unknown tag on display format:"), " ", tmp_format, (char *) NULL); + *error = + g_strconcat (_("Unknown tag on display format:"), " ", tmp_format, (char *) NULL); g_free (tmp_format); return 0; } @@ -1763,6 +1561,8 @@ parse_display_format (WPanel * panel, const char *format, char **error, int isst return home; } +/* --------------------------------------------------------------------------------------------- */ + static format_e * use_display_format (WPanel * panel, const char *format, char **error, int isstatus) { @@ -1837,66 +1637,9 @@ use_display_format (WPanel * panel, const char *format, char **error, int isstat return home; } -/* Switches the panel to the mode specified in the format */ -/* Seting up both format and status string. Return: 0 - on success; */ -/* 1 - format error; 2 - status error; 3 - errors in both formats. */ -int -set_panel_formats (WPanel * p) -{ - format_e *form; - char *err = NULL; - int retcode = 0; +/* --------------------------------------------------------------------------------------------- */ +/** Given the panel->view_type returns the format string to be parsed */ - form = use_display_format (p, panel_format (p), &err, 0); - - if (err != NULL) - { - g_free (err); - retcode = 1; - } - else - { - delete_format (p->format); - p->format = form; - } - - if (show_mini_info) - { - form = use_display_format (p, mini_status_format (p), &err, 1); - - if (err != NULL) - { - g_free (err); - retcode += 2; - } - else - { - delete_format (p->status_format); - p->status_format = form; - } - } - - panel_format_modified (p); - panel_update_cols (&(p->widget), p->frame_size); - - if (retcode) - message (D_ERROR, _("Warning"), - _("User supplied format looks invalid, reverting to default.")); - if (retcode & 0x01) - { - g_free (p->user_format); - p->user_format = g_strdup (DEFAULT_USER_FORMAT); - } - if (retcode & 0x02) - { - g_free (p->user_status_format[p->list_type]); - p->user_status_format[p->list_type] = g_strdup (DEFAULT_USER_FORMAT); - } - - return retcode; -} - -/* Given the panel->view_type returns the format string to be parsed */ static const char * panel_format (WPanel * panel) { @@ -1918,6 +1661,8 @@ panel_format (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static const char * mini_status_format (WPanel * panel) { @@ -1946,7 +1691,9 @@ mini_status_format (WPanel * panel) /* Panel operation commands */ /* */ -/* Used to emulate Lynx's entering leaving a directory with the arrow keys */ +/* --------------------------------------------------------------------------------------------- */ +/** Used to emulate Lynx's entering leaving a directory with the arrow keys */ + static cb_ret_t maybe_cd (int move_up_dir) { @@ -1968,7 +1715,9 @@ maybe_cd (int move_up_dir) return MSG_NOT_HANDLED; } -/* Returns the number of items in the given panel */ +/* --------------------------------------------------------------------------------------------- */ +/** Returns the number of items in the given panel */ + static int ITEMS (WPanel * p) { @@ -1978,61 +1727,7 @@ ITEMS (WPanel * p) return llines (p); } -/* Select current item and readjust the panel */ -void -select_item (WPanel * panel) -{ - 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 */ - - if (panel->top_file < 0) - panel->top_file = 0; - - if (panel->selected < 0) - panel->selected = 0; - - if (panel->selected > panel->count - 1) - panel->selected = panel->count - 1; - - if (panel->top_file > panel->count - 1) - panel->top_file = panel->count - 1; - - if ((panel->count - panel->top_file) < items) - { - panel->top_file = panel->count - items; - if (panel->top_file < 0) - panel->top_file = 0; - } - - if (panel->selected < panel->top_file) - panel->top_file = panel->selected; - - if ((panel->selected - panel->top_file) >= items) - panel->top_file = panel->selected - items + 1; - - panel->dirty = 1; - - execute_hooks (select_file_hook); -} - -/* Clears all files in the panel, used only when one file was marked */ -void -unmark_files (WPanel * panel) -{ - int i; - - if (!panel->marked) - return; - for (i = 0; i < panel->count; i++) - file_mark (panel, i, 0); - - panel->dirs_marked = 0; - panel->marked = 0; - panel->total = 0; -} +/* --------------------------------------------------------------------------------------------- */ static void unselect_item (WPanel * panel) @@ -2040,6 +1735,8 @@ unselect_item (WPanel * panel) repaint_file (panel, panel->selected, 1, 2 * selection (panel)->f.marked, 0); } +/* --------------------------------------------------------------------------------------------- */ + static void move_down (WPanel * panel) { @@ -2059,6 +1756,8 @@ move_down (WPanel * panel) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void move_up (WPanel * panel) { @@ -2078,7 +1777,9 @@ move_up (WPanel * panel) select_item (panel); } -/* Changes the selection by lines (may be negative) */ +/* --------------------------------------------------------------------------------------------- */ +/** Changes the selection by lines (may be negative) */ + static void move_selection (WPanel * panel, int lines) { @@ -2118,6 +1819,8 @@ move_selection (WPanel * panel, int lines) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t move_left (WPanel * panel) { @@ -2130,6 +1833,8 @@ move_left (WPanel * panel) return maybe_cd (1); /* cd .. */ } +/* --------------------------------------------------------------------------------------------- */ + static int move_right (WPanel * panel) { @@ -2142,6 +1847,8 @@ move_right (WPanel * panel) return maybe_cd (0); /* cd (selection) */ } +/* --------------------------------------------------------------------------------------------- */ + static void prev_page (WPanel * panel) { @@ -2163,6 +1870,8 @@ prev_page (WPanel * panel) paint_dir (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void ctrl_prev_page (WPanel * panel) { @@ -2170,6 +1879,8 @@ ctrl_prev_page (WPanel * panel) do_cd ("..", cd_exact); } +/* --------------------------------------------------------------------------------------------- */ + static void next_page (WPanel * panel) { @@ -2193,6 +1904,8 @@ next_page (WPanel * panel) paint_dir (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void ctrl_next_page (WPanel * panel) { @@ -2202,6 +1915,8 @@ ctrl_next_page (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void goto_top_file (WPanel * panel) { @@ -2210,6 +1925,8 @@ goto_top_file (WPanel * panel) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void goto_middle_file (WPanel * panel) { @@ -2218,6 +1935,8 @@ goto_middle_file (WPanel * panel) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void goto_bottom_file (WPanel * panel) { @@ -2226,6 +1945,8 @@ goto_bottom_file (WPanel * panel) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void move_home (WPanel * panel) { @@ -2256,6 +1977,8 @@ move_home (WPanel * panel) select_item (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void move_end (WPanel * panel) { @@ -2283,66 +2006,7 @@ move_end (WPanel * panel) select_item (panel); } -/* Recalculate the panels summary information, used e.g. when marked - files might have been removed by an external command */ -void -recalculate_panel_summary (WPanel * panel) -{ - int i; - - panel->marked = 0; - panel->dirs_marked = 0; - panel->total = 0; - - for (i = 0; i < panel->count; i++) - if (panel->dir.list[i].f.marked) - { - /* do_file_mark will return immediately if newmark == oldmark. - So we have to first unmark it to get panel's summary information - updated. (Norbert) */ - panel->dir.list[i].f.marked = 0; - do_file_mark (panel, i, 1); - } -} - -/* This routine marks a file or a directory */ -void -do_file_mark (WPanel * panel, int idx, int mark) -{ - if (panel->dir.list[idx].f.marked == mark) - return; - - /* Only '..' can't be marked, '.' isn't visible */ - if (!strcmp (panel->dir.list[idx].fname, "..")) - return; - - file_mark (panel, idx, mark); - if (panel->dir.list[idx].f.marked) - { - panel->marked++; - if (S_ISDIR (panel->dir.list[idx].st.st_mode)) - { - if (panel->dir.list[idx].f.dir_size_computed) - panel->total += panel->dir.list[idx].st.st_size; - panel->dirs_marked++; - } - else - panel->total += panel->dir.list[idx].st.st_size; - set_colors (panel); - } - else - { - if (S_ISDIR (panel->dir.list[idx].st.st_mode)) - { - if (panel->dir.list[idx].f.dir_size_computed) - panel->total -= panel->dir.list[idx].st.st_size; - panel->dirs_marked--; - } - else - panel->total -= panel->dir.list[idx].st.st_size; - panel->marked--; - } -} +/* --------------------------------------------------------------------------------------------- */ static void do_mark_file (WPanel * panel, mark_act_t do_move) @@ -2354,28 +2018,36 @@ do_mark_file (WPanel * panel, mark_act_t do_move) move_up (panel); } +/* --------------------------------------------------------------------------------------------- */ + static void mark_file (WPanel * panel) { do_mark_file (panel, MARK_DOWN); } +/* --------------------------------------------------------------------------------------------- */ + static void mark_file_up (WPanel * panel) { do_mark_file (panel, MARK_FORCE_UP); } +/* --------------------------------------------------------------------------------------------- */ + static void mark_file_down (WPanel * panel) { do_mark_file (panel, MARK_FORCE_DOWN); } +/* --------------------------------------------------------------------------------------------- */ /** Incremental search of a file name in the panel. * @param panel instance of WPanel structure * @param c_code key code */ + static void do_search (WPanel * panel, int c_code) { @@ -2479,9 +2151,11 @@ do_search (WPanel * panel, int c_code) g_free (esc_str); } +/* --------------------------------------------------------------------------------------------- */ /** Start new search. * @param panel instance of WPanel structure */ + static void start_search (WPanel * panel) { @@ -2511,6 +2185,8 @@ start_search (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void stop_search (WPanel * panel) { @@ -2525,7 +2201,9 @@ stop_search (WPanel * panel) display_mini_info (panel); } -/* Return 1 if the Enter key has been processed, 0 otherwise */ +/* --------------------------------------------------------------------------------------------- */ +/** Return 1 if the Enter key has been processed, 0 otherwise */ + static int do_enter_on_file_entry (file_entry * fe) { @@ -2591,12 +2269,16 @@ do_enter_on_file_entry (file_entry * fe) return 1; } +/* --------------------------------------------------------------------------------------------- */ + static int do_enter (WPanel * panel) { return do_enter_on_file_entry (selection (panel)); } +/* --------------------------------------------------------------------------------------------- */ + static void chdir_other_panel (WPanel * panel) { @@ -2627,12 +2309,14 @@ chdir_other_panel (WPanel * panel) g_free (new_dir); } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Make the current directory of the current panel also the current * directory of the other panel. Put the other panel to the listing * mode if needed. If the current panel is panelized, the other panel * doesn't become panelized. */ + static void sync_other_panel (WPanel * panel) { @@ -2650,6 +2334,8 @@ sync_other_panel (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static void chdir_to_readlink (WPanel * panel) { @@ -2697,6 +2383,8 @@ chdir_to_readlink (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static gsize panel_get_format_field_count (WPanel * panel) { @@ -2706,9 +2394,11 @@ panel_get_format_field_count (WPanel * panel) return lc_index; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** function return 0 if not found and REAL_INDEX+1 if found */ + static gsize panel_get_format_field_index_by_name (WPanel * panel, const char *name) { @@ -2723,6 +2413,8 @@ panel_get_format_field_index_by_name (WPanel * panel, const char *name) return lc_index; } +/* --------------------------------------------------------------------------------------------- */ + static format_e * panel_get_format_field_by_index (WPanel * panel, gsize lc_index) { @@ -2732,6 +2424,8 @@ panel_get_format_field_by_index (WPanel * panel, gsize lc_index) return format; } +/* --------------------------------------------------------------------------------------------- */ + static const panel_field_t * panel_get_sortable_field_by_format (WPanel * panel, gsize lc_index) { @@ -2749,6 +2443,8 @@ panel_get_sortable_field_by_format (WPanel * panel, gsize lc_index) return pfield; } +/* --------------------------------------------------------------------------------------------- */ + static void panel_toggle_sort_order_prev (WPanel * panel) { @@ -2780,6 +2476,7 @@ panel_toggle_sort_order_prev (WPanel * panel) panel_set_sort_order (panel, panel->current_sort_field); } +/* --------------------------------------------------------------------------------------------- */ static void panel_toggle_sort_order_next (WPanel * panel) @@ -2814,6 +2511,8 @@ panel_toggle_sort_order_next (WPanel * panel) panel_set_sort_order (panel, panel->current_sort_field); } +/* --------------------------------------------------------------------------------------------- */ + static void panel_select_sort_order (WPanel * panel) { @@ -2827,6 +2526,8 @@ panel_select_sort_order (WPanel * panel) } +/* --------------------------------------------------------------------------------------------- */ + static void panel_set_sort_type_by_id (WPanel * panel, const char *name) { @@ -2846,12 +2547,14 @@ panel_set_sort_type_by_id (WPanel * panel, const char *name) panel_set_sort_order (panel, panel->current_sort_field); } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * If we moved to the parent directory move the selection pointer to * the old directory name; If we leave VFS dir, remove FS specificator. * * You do _NOT_ want to add any vfs aware code here. */ + static const char * get_parent_dir_name (const char *cwd, const char *lwd) { @@ -2876,10 +2579,12 @@ get_parent_dir_name (const char *cwd, const char *lwd) return NULL; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Changes the current directory of the panel. * Don't record change in the directory history. */ + static gboolean _do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) { @@ -2943,20 +2648,7 @@ _do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) return TRUE; } -/* - * Changes the current directory of the panel. - * Record change in the directory history. - */ -gboolean -do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type) -{ - gboolean r; - - r = _do_panel_cd (panel, new_dir, cd_type); - if (r) - directory_history_add (panel, panel->cwd); - return r; -} +/* --------------------------------------------------------------------------------------------- */ static void directory_history_next (WPanel * panel) @@ -2969,6 +2661,8 @@ directory_history_next (WPanel * panel) panel->dir_history = nextdir; } +/* --------------------------------------------------------------------------------------------- */ + static void directory_history_prev (WPanel * panel) { @@ -2980,6 +2674,8 @@ directory_history_prev (WPanel * panel) panel->dir_history = prevdir; } +/* --------------------------------------------------------------------------------------------- */ + static void directory_history_list (WPanel * panel) { @@ -2997,6 +2693,8 @@ directory_history_list (WPanel * panel) } } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t panel_execute_cmd (WPanel * panel, unsigned long command) { @@ -3137,6 +2835,8 @@ panel_execute_cmd (WPanel * panel, unsigned long command) return res; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t panel_key (WPanel * panel, int key) { @@ -3178,6 +2878,8 @@ panel_key (WPanel * panel, int key) return MSG_NOT_HANDLED; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t panel_callback (Widget * w, widget_msg_t msg, int parm) { @@ -3238,20 +2940,10 @@ panel_callback (Widget * w, widget_msg_t msg, int parm) } } -void -file_mark (WPanel * panel, int lc_index, int val) -{ - if (panel->dir.list[lc_index].f.marked != val) - { - panel->dir.list[lc_index].f.marked = val; - panel->dirty = 1; - } -} - +/* --------------------------------------------------------------------------------------------- */ /* */ /* Panel mouse events support routines */ /* */ -static int mouse_marking = 0; static void mouse_toggle_mark (WPanel * panel) @@ -3260,6 +2952,8 @@ mouse_toggle_mark (WPanel * panel) mouse_marking = selection (panel)->f.marked; } +/* --------------------------------------------------------------------------------------------- */ + static void mouse_set_mark (WPanel * panel) { @@ -3269,6 +2963,8 @@ mouse_set_mark (WPanel * panel) do_mark_file (panel, MARK_DONT_MOVE); } +/* --------------------------------------------------------------------------------------------- */ + static int mark_if_marking (WPanel * panel, Gpm_Event * event) { @@ -3283,10 +2979,12 @@ mark_if_marking (WPanel * panel, Gpm_Event * event) return 0; } -/* Determine which column was clicked, and sort the panel on +/* --------------------------------------------------------------------------------------------- */ +/** Determine which column was clicked, and sort the panel on * that column, or reverse sort on that column if already * sorted on that column. */ + static void mouse_sort_col (Gpm_Event * event, WPanel * panel) { @@ -3339,7 +3037,8 @@ mouse_sort_col (Gpm_Event * event, WPanel * panel) } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Mouse callback of the panel minus repainting. * If the event is redirected to the menu, *redir is set to TRUE. */ @@ -3420,8 +3119,7 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir) { if (is_active) { - if (panels_options.mouse_move_pages - && (panel->top_file + ITEMS (panel) < panel->count)) + if (panels_options.mouse_move_pages && (panel->top_file + ITEMS (panel) < panel->count)) next_page (panel); else /* We are in last page */ move_down (panel); @@ -3467,7 +3165,9 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir) return MOU_NORMAL; } -/* Mouse callback of the panel */ +/* --------------------------------------------------------------------------------------------- */ +/** Mouse callback of the panel */ + static int panel_event (Gpm_Event * event, void *data) { @@ -3482,6 +3182,662 @@ panel_event (Gpm_Event * event, void *data) return ret; } +/* --------------------------------------------------------------------------------------------- */ + +static void +reload_panelized (WPanel * panel) +{ + int i, j; + dir_list *list = &panel->dir; + + if (panel != current_panel) + { + int ret; + ret = mc_chdir (panel->cwd); + } + + for (i = 0, j = 0; i < panel->count; i++) + { + if (list->list[i].f.marked) + { + /* Unmark the file in advance. In case the following mc_lstat + * fails we are done, else we have to mark the file again + * (Note: do_file_mark depends on a valid "list->list [i].buf"). + * IMO that's the best way to update the panel's summary status + * -- Norbert + */ + do_file_mark (panel, i, 0); + } + if (mc_lstat (list->list[i].fname, &list->list[i].st)) + { + g_free (list->list[i].fname); + continue; + } + if (list->list[i].f.marked) + do_file_mark (panel, i, 1); + if (j != i) + list->list[j] = list->list[i]; + j++; + } + if (j == 0) + panel->count = set_zero_dir (list) ? 1 : 0; + else + panel->count = j; + + if (panel != current_panel) + { + int ret; + ret = mc_chdir (current_panel->cwd); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +update_one_panel_widget (WPanel * panel, int force_update, const char *current_file) +{ + int free_pointer; + char *my_current_file = NULL; + + if (force_update & UP_RELOAD) + { + panel->is_panelized = 0; + mc_setctl (panel->cwd, VFS_SETCTL_FLUSH, 0); + memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); + } + + /* If current_file == -1 (an invalid pointer) then preserve selection */ + if (current_file == UP_KEEPSEL) + { + free_pointer = 1; + my_current_file = g_strdup (panel->dir.list[panel->selected].fname); + current_file = my_current_file; + } + else + free_pointer = 0; + + if (panel->is_panelized) + reload_panelized (panel); + else + panel_reload (panel); + + try_to_select (panel, current_file); + panel->dirty = 1; + + if (free_pointer) + g_free (my_current_file); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +update_one_panel (int which, int force_update, const char *current_file) +{ + if (get_display_type (which) == view_listing) + { + WPanel *panel; + panel = (WPanel *) get_panel_widget (which); + update_one_panel_widget (panel, force_update, current_file); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +char * +remove_encoding_from_path (const char *path) +{ + GString *ret; + GString *tmp_path, *tmp_conv; + char *tmp, *tmp2; + const char *enc; + GIConv converter; + + ret = g_string_new (""); + tmp_conv = g_string_new (""); + + tmp_path = g_string_new (path); + + while ((tmp = g_strrstr (tmp_path->str, PATH_SEP_STR VFS_ENCODING_PREFIX)) != NULL) + { + enc = vfs_get_encoding ((const char *) tmp); + converter = enc ? str_crt_conv_to (enc) : str_cnv_to_term; + if (converter == INVALID_CONV) + converter = str_cnv_to_term; + + tmp2 = tmp + 1; + while (*tmp2 && *tmp2 != PATH_SEP) + tmp2++; + + if (*tmp2) + { + str_vfs_convert_from (converter, tmp2, tmp_conv); + g_string_prepend (ret, tmp_conv->str); + g_string_set_size (tmp_conv, 0); + } + g_string_set_size (tmp_path, tmp - tmp_path->str); + str_close_conv (converter); + } + g_string_prepend (ret, tmp_path->str); + g_string_free (tmp_path, TRUE); + g_string_free (tmp_conv, TRUE); + + tmp = ret->str; + g_string_free (ret, FALSE); + return tmp; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Repaint the contents of the panels without frames. To schedule panel + * for repainting, set panel->dirty to 1. There are many reasons why + * the panels need to be repainted, and this is a costly operation, so + * it's done once per event. + */ + +void +update_dirty_panels (void) +{ + if (current_panel->dirty) + paint_panel (current_panel); + + if ((get_other_type () == view_listing) && other_panel->dirty) + paint_panel (other_panel); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +do_select (WPanel * panel, int i) +{ + if (i != panel->selected) + { + panel->dirty = 1; + panel->selected = i; + panel->top_file = panel->selected - (panel->widget.lines - 2) / 2; + if (panel->top_file < 0) + panel->top_file = 0; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +do_try_to_select (WPanel * panel, const char *name) +{ + int i; + char *subdir; + + if (!name) + { + do_select (panel, 0); + return; + } + + /* We only want the last component of the directory, + * and from this only the name without suffix. */ + subdir = vfs_strip_suffix_from_filename (x_basename (name)); + + /* Search that subdirectory, if found select it */ + for (i = 0; i < panel->count; i++) + { + if (strcmp (subdir, panel->dir.list[i].fname) == 0) + { + do_select (panel, i); + g_free (subdir); + return; + } + } + + /* Try to select a file near the file that is missing */ + if (panel->selected >= panel->count) + do_select (panel, panel->count - 1); + g_free (subdir); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +try_to_select (WPanel * panel, const char *name) +{ + do_try_to_select (panel, name); + select_item (panel); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +panel_update_cols (Widget * widget, int frame_size) +{ + int cols, origin; + + if (horizontal_split) + { + widget->cols = COLS; + return; + } + + if (frame_size == frame_full) + { + cols = COLS; + origin = 0; + } + else + { + if (widget == get_panel_widget (0)) + { + cols = first_panel_size; + origin = 0; + } + else + { + cols = COLS - first_panel_size; + origin = first_panel_size; + } + } + + widget->cols = cols; + widget->x = origin; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +panel_clean_dir (WPanel * panel) +{ + int count = panel->count; + + panel->count = 0; + panel->top_file = 0; + panel->selected = 0; + panel->marked = 0; + panel->dirs_marked = 0; + panel->total = 0; + panel->searching = FALSE; + panel->is_panelized = 0; + panel->dirty = 1; + + clean_dir (&panel->dir, count); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Panel creation. + * @param panel_name the name of the panel for setup retieving + * @returns new instance of WPanel + */ + +WPanel * +panel_new (const char *panel_name) +{ + return panel_new_with_dir (panel_name, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Panel creation for specified directory. + * @param panel_name specifies the name of the panel for setup retieving + * @param the path of working panel directory. If path is NULL then panel will be created for current directory + * @returns new instance of WPanel + */ + +WPanel * +panel_new_with_dir (const char *panel_name, const char *wpath) +{ + WPanel *panel; + char *section; + int i, err; + char curdir[MC_MAXPATHLEN] = "\0"; + + panel = g_new0 (WPanel, 1); + + /* No know sizes of the panel at startup */ + init_widget (&panel->widget, 0, 0, 0, 0, panel_callback, panel_event); + + /* We do not want the cursor */ + widget_want_cursor (panel->widget, 0); + + if (wpath != NULL) + { + g_strlcpy (panel->cwd, wpath, sizeof (panel->cwd)); + mc_get_current_wd (curdir, sizeof (curdir) - 2); + } + else + mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + + strcpy (panel->lwd, "."); + + panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); + panel->dir_history = history_get (panel->hist_name); + directory_history_add (panel, panel->cwd); + + panel->dir.list = g_new (file_entry, MIN_FILES); + panel->dir.size = MIN_FILES; + panel->active = 0; + panel->filter = 0; + panel->split = 0; + panel->top_file = 0; + panel->selected = 0; + panel->marked = 0; + panel->total = 0; + panel->reverse = 0; + panel->dirty = 1; + panel->searching = FALSE; + panel->dirs_marked = 0; + panel->is_panelized = 0; + panel->format = 0; + panel->status_format = 0; + panel->format_modified = 1; + + panel->panel_name = g_strdup (panel_name); + panel->user_format = g_strdup (DEFAULT_USER_FORMAT); + + panel->codepage = SELECT_CHARSET_NO_TRANSLATE; + + for (i = 0; i < LIST_TYPES; i++) + panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT); + + panel->search_buffer[0] = '\0'; + panel->prev_search_buffer[0] = '\0'; + panel->frame_size = frame_half; + + section = g_strconcat ("Temporal:", panel->panel_name, (char *) NULL); + if (!mc_config_has_group (mc_main_config, section)) + { + g_free (section); + section = g_strdup (panel->panel_name); + } + panel_load_setup (panel, section); + g_free (section); + + /* Load format strings */ + err = set_panel_formats (panel); + if (err != 0) + set_panel_formats (panel); + +#ifdef HAVE_CHARSET + { + const char *enc = vfs_get_encoding (panel->cwd); + if (enc != NULL) + panel->codepage = get_codepage_index (enc); + } +#endif + + if (mc_chdir (panel->cwd) != 0) + { + panel->codepage = SELECT_CHARSET_NO_TRANSLATE; + mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + } + + /* Load the default format */ + panel->count = + do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, + panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); + + /* Restore old right path */ + if (curdir[0] != '\0') + err = mc_chdir (curdir); + + return panel; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +panel_reload (WPanel * panel) +{ + struct stat current_stat; + + if (panels_options.fast_reload && !stat (panel->cwd, ¤t_stat) + && current_stat.st_ctime == panel->dir_stat.st_ctime + && current_stat.st_mtime == panel->dir_stat.st_mtime) + return; + + while (mc_chdir (panel->cwd) == -1) + { + char *last_slash; + + if (panel->cwd[0] == PATH_SEP && panel->cwd[1] == 0) + { + panel_clean_dir (panel); + panel->count = set_zero_dir (&panel->dir) ? 1 : 0; + return; + } + last_slash = strrchr (panel->cwd, PATH_SEP); + if (!last_slash || last_slash == panel->cwd) + strcpy (panel->cwd, PATH_SEP_STR); + else + *last_slash = 0; + memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); + show_dir (panel); + } + + panel->count = + do_reload_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, + panel->count, panel->reverse, panel->case_sensitive, + panel->exec_first, panel->filter); + + panel->dirty = 1; + if (panel->selected >= panel->count) + do_select (panel, panel->count - 1); + + recalculate_panel_summary (panel); +} + +/* --------------------------------------------------------------------------------------------- */ +/* Switches the panel to the mode specified in the format */ +/* Seting up both format and status string. Return: 0 - on success; */ +/* 1 - format error; 2 - status error; 3 - errors in both formats. */ + +int +set_panel_formats (WPanel * p) +{ + format_e *form; + char *err = NULL; + int retcode = 0; + + form = use_display_format (p, panel_format (p), &err, 0); + + if (err != NULL) + { + g_free (err); + retcode = 1; + } + else + { + delete_format (p->format); + p->format = form; + } + + if (show_mini_info) + { + form = use_display_format (p, mini_status_format (p), &err, 1); + + if (err != NULL) + { + g_free (err); + retcode += 2; + } + else + { + delete_format (p->status_format); + p->status_format = form; + } + } + + panel_format_modified (p); + panel_update_cols (&(p->widget), p->frame_size); + + if (retcode) + message (D_ERROR, _("Warning"), + _("User supplied format looks invalid, reverting to default.")); + if (retcode & 0x01) + { + g_free (p->user_format); + p->user_format = g_strdup (DEFAULT_USER_FORMAT); + } + if (retcode & 0x02) + { + g_free (p->user_status_format[p->list_type]); + p->user_status_format[p->list_type] = g_strdup (DEFAULT_USER_FORMAT); + } + + return retcode; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* Select current item and readjust the panel */ +void +select_item (WPanel * panel) +{ + 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 */ + + if (panel->top_file < 0) + panel->top_file = 0; + + if (panel->selected < 0) + panel->selected = 0; + + if (panel->selected > panel->count - 1) + panel->selected = panel->count - 1; + + if (panel->top_file > panel->count - 1) + panel->top_file = panel->count - 1; + + if ((panel->count - panel->top_file) < items) + { + panel->top_file = panel->count - items; + if (panel->top_file < 0) + panel->top_file = 0; + } + + if (panel->selected < panel->top_file) + panel->top_file = panel->selected; + + if ((panel->selected - panel->top_file) >= items) + panel->top_file = panel->selected - items + 1; + + panel->dirty = 1; + + execute_hooks (select_file_hook); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Clears all files in the panel, used only when one file was marked */ +void +unmark_files (WPanel * panel) +{ + int i; + + if (!panel->marked) + return; + for (i = 0; i < panel->count; i++) + file_mark (panel, i, 0); + + panel->dirs_marked = 0; + panel->marked = 0; + panel->total = 0; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Recalculate the panels summary information, used e.g. when marked + files might have been removed by an external command */ + +void +recalculate_panel_summary (WPanel * panel) +{ + int i; + + panel->marked = 0; + panel->dirs_marked = 0; + panel->total = 0; + + for (i = 0; i < panel->count; i++) + if (panel->dir.list[i].f.marked) + { + /* do_file_mark will return immediately if newmark == oldmark. + So we have to first unmark it to get panel's summary information + updated. (Norbert) */ + panel->dir.list[i].f.marked = 0; + do_file_mark (panel, i, 1); + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** This routine marks a file or a directory */ + +void +do_file_mark (WPanel * panel, int idx, int mark) +{ + if (panel->dir.list[idx].f.marked == mark) + return; + + /* Only '..' can't be marked, '.' isn't visible */ + if (!strcmp (panel->dir.list[idx].fname, "..")) + return; + + file_mark (panel, idx, mark); + if (panel->dir.list[idx].f.marked) + { + panel->marked++; + if (S_ISDIR (panel->dir.list[idx].st.st_mode)) + { + if (panel->dir.list[idx].f.dir_size_computed) + panel->total += panel->dir.list[idx].st.st_size; + panel->dirs_marked++; + } + else + panel->total += panel->dir.list[idx].st.st_size; + set_colors (panel); + } + else + { + if (S_ISDIR (panel->dir.list[idx].st.st_mode)) + { + if (panel->dir.list[idx].f.dir_size_computed) + panel->total -= panel->dir.list[idx].st.st_size; + panel->dirs_marked--; + } + else + panel->total -= panel->dir.list[idx].st.st_size; + panel->marked--; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Changes the current directory of the panel. + * Record change in the directory history. + */ +gboolean +do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type) +{ + gboolean r; + + r = _do_panel_cd (panel, new_dir, cd_type); + if (r) + directory_history_add (panel, panel->cwd); + return r; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +file_mark (WPanel * panel, int lc_index, int val) +{ + if (panel->dir.list[lc_index].f.marked != val) + { + panel->dir.list[lc_index].f.marked = val; + panel->dirty = 1; + } +} + +/* --------------------------------------------------------------------------------------------- */ + void panel_re_sort (WPanel * panel) { @@ -3510,6 +3866,8 @@ panel_re_sort (WPanel * panel) panel->dirty = 1; } +/* --------------------------------------------------------------------------------------------- */ + void panel_set_sort_order (WPanel * panel, const panel_field_t * sort_order) { @@ -3531,10 +3889,12 @@ panel_set_sort_order (WPanel * panel, const panel_field_t * sort_order) panel_re_sort (panel); } +/* --------------------------------------------------------------------------------------------- */ /** * Change panel encoding. * @param panel WPanel object */ + void panel_change_encoding (WPanel * panel) { @@ -3588,100 +3948,9 @@ panel_change_encoding (WPanel * panel) } } -static void -reload_panelized (WPanel * panel) -{ - int i, j; - dir_list *list = &panel->dir; - - if (panel != current_panel) - { - int ret; - ret = mc_chdir (panel->cwd); - } - - for (i = 0, j = 0; i < panel->count; i++) - { - if (list->list[i].f.marked) - { - /* Unmark the file in advance. In case the following mc_lstat - * fails we are done, else we have to mark the file again - * (Note: do_file_mark depends on a valid "list->list [i].buf"). - * IMO that's the best way to update the panel's summary status - * -- Norbert - */ - do_file_mark (panel, i, 0); - } - if (mc_lstat (list->list[i].fname, &list->list[i].st)) - { - g_free (list->list[i].fname); - continue; - } - if (list->list[i].f.marked) - do_file_mark (panel, i, 1); - if (j != i) - list->list[j] = list->list[i]; - j++; - } - if (j == 0) - panel->count = set_zero_dir (list) ? 1 : 0; - else - panel->count = j; - - if (panel != current_panel) - { - int ret; - ret = mc_chdir (current_panel->cwd); - } -} - -static void -update_one_panel_widget (WPanel * panel, int force_update, const char *current_file) -{ - int free_pointer; - char *my_current_file = NULL; - - if (force_update & UP_RELOAD) - { - panel->is_panelized = 0; - mc_setctl (panel->cwd, VFS_SETCTL_FLUSH, 0); - memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); - } - - /* If current_file == -1 (an invalid pointer) then preserve selection */ - if (current_file == UP_KEEPSEL) - { - free_pointer = 1; - my_current_file = g_strdup (panel->dir.list[panel->selected].fname); - current_file = my_current_file; - } - else - free_pointer = 0; - - if (panel->is_panelized) - reload_panelized (panel); - else - panel_reload (panel); - - try_to_select (panel, current_file); - panel->dirty = 1; - - if (free_pointer) - g_free (my_current_file); -} - -static void -update_one_panel (int which, int force_update, const char *current_file) -{ - if (get_display_type (which) == view_listing) - { - WPanel *panel; - panel = (WPanel *) get_panel_widget (which); - update_one_panel_widget (panel, force_update, current_file); - } -} - -/* This routine reloads the directory in both panels. It tries to +/* --------------------------------------------------------------------------------------------- */ +/** + * This routine reloads the directory in both panels. It tries to * select current_file in current_panel and other_file in other_panel. * If current_file == -1 then it automatically sets current_file and * other_file to the currently selected files in the panels. @@ -3689,6 +3958,7 @@ update_one_panel (int which, int force_update, const char *current_file) * if force_update has the UP_ONLY_CURRENT bit toggled on, then it * will not reload the other panel. */ + void update_panels (int force_update, const char *current_file) { @@ -3708,6 +3978,8 @@ update_panels (int force_update, const char *current_file) ret = mc_chdir (panel->cwd); } +/* --------------------------------------------------------------------------------------------- */ + void directory_history_add (struct WPanel *panel, const char *dir) { @@ -3719,6 +3991,8 @@ directory_history_add (struct WPanel *panel, const char *dir) panel->dir_history = list_append_unique (panel->dir_history, tmp); } +/* --------------------------------------------------------------------------------------------- */ + gsize panel_get_num_of_sortable_fields (void) { @@ -3730,6 +4004,8 @@ panel_get_num_of_sortable_fields (void) return ret; } +/* --------------------------------------------------------------------------------------------- */ + const char ** panel_get_sortable_fields (gsize * array_size) { @@ -3753,6 +4029,8 @@ panel_get_sortable_fields (gsize * array_size) return (const char **) ret; } +/* --------------------------------------------------------------------------------------------- */ + const panel_field_t * panel_get_field_by_id (const char *name) { @@ -3763,6 +4041,8 @@ panel_get_field_by_id (const char *name) return NULL; } +/* --------------------------------------------------------------------------------------------- */ + const panel_field_t * panel_get_field_by_title_hotkey (const char *name) { @@ -3774,6 +4054,8 @@ panel_get_field_by_title_hotkey (const char *name) return NULL; } +/* --------------------------------------------------------------------------------------------- */ + const panel_field_t * panel_get_field_by_title (const char *name) { @@ -3793,6 +4075,8 @@ panel_get_field_by_title (const char *name) return NULL; } +/* --------------------------------------------------------------------------------------------- */ + gsize panel_get_num_of_user_possible_fields (void) { @@ -3804,6 +4088,8 @@ panel_get_num_of_user_possible_fields (void) return ret; } +/* --------------------------------------------------------------------------------------------- */ + const char ** panel_get_user_possible_fields (gsize * array_size) { @@ -3827,6 +4113,8 @@ panel_get_user_possible_fields (gsize * array_size) return (const char **) ret; } +/* --------------------------------------------------------------------------------------------- */ + void panel_init (void) { @@ -3841,6 +4129,8 @@ panel_init (void) } +/* --------------------------------------------------------------------------------------------- */ + void panel_deinit (void) { @@ -3854,3 +4144,5 @@ panel_deinit (void) g_free (panel_history_show_list_sign); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/selcodepage.c b/src/selcodepage.c index 4a028d714..134352360 100644 --- a/src/selcodepage.c +++ b/src/selcodepage.c @@ -36,21 +36,37 @@ #include "selcodepage.h" #include "main.h" -#define ENTRY_LEN 30 +/*** global variables ****************************************************************************/ /* Numbers of (file I/O) and (input/display) codepages. -1 if not selected */ int source_codepage = -1; int default_source_codepage = -1; int display_codepage = -1; -char* autodetect_codeset = NULL; +char *autodetect_codeset = NULL; gboolean is_autodetect_codeset_enabled = FALSE; +/*** file scope macro definitions ****************************************************************/ + +#define ENTRY_LEN 30 + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + + static unsigned char get_hotkey (int n) { return (n <= 9) ? '0' + n : 'a' + n - 10; } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /* Return value: * -2 (SELECT_CHARSET_CANCEL) : Cancel * -1 (SELECT_CHARSET_OTHER_8BIT) : "Other 8 bit" if seldisplay == TRUE @@ -66,54 +82,61 @@ select_charset (int center_y, int center_x, int current_charset, gboolean seldis /* Create listbox */ Listbox *listbox = create_listbox_window_centered (center_y, center_x, - codepages->len + 1, ENTRY_LEN + 2, - _("Choose codepage"), - "[Codepages Translation]"); + codepages->len + 1, ENTRY_LEN + 2, + _("Choose codepage"), + "[Codepages Translation]"); if (!seldisplay) - LISTBOX_APPEND_TEXT (listbox, '-', _("- < No translation >"), - NULL); + LISTBOX_APPEND_TEXT (listbox, '-', _("- < No translation >"), NULL); /* insert all the items found */ - for (i = 0; i < codepages->len; i++) { - const char *name = ((codepage_desc *) g_ptr_array_index (codepages, i))->name; - g_snprintf (buffer, sizeof (buffer), "%c %s", get_hotkey (i), - name); - LISTBOX_APPEND_TEXT (listbox, get_hotkey (i), buffer, NULL); + for (i = 0; i < codepages->len; i++) + { + const char *name = ((codepage_desc *) g_ptr_array_index (codepages, i))->name; + g_snprintf (buffer, sizeof (buffer), "%c %s", get_hotkey (i), name); + LISTBOX_APPEND_TEXT (listbox, get_hotkey (i), buffer, NULL); } - if (seldisplay) { + if (seldisplay) + { unsigned char hotkey = get_hotkey (codepages->len); - g_snprintf (buffer, sizeof (buffer), "%c %s", hotkey, _("Other 8 bit")); - LISTBOX_APPEND_TEXT (listbox, hotkey, buffer, NULL); + g_snprintf (buffer, sizeof (buffer), "%c %s", hotkey, _("Other 8 bit")); + LISTBOX_APPEND_TEXT (listbox, hotkey, buffer, NULL); } /* Select the default entry */ i = (seldisplay) - ? ((current_charset < 0) ? codepages->len : (size_t) current_charset) - : ((size_t)current_charset + 1); + ? ((current_charset < 0) ? codepages->len : (size_t) current_charset) + : ((size_t) current_charset + 1); listbox_select_entry (listbox->list, i); listbox_result = run_listbox (listbox); - if (listbox_result < 0) { - /* Cancel dialog */ - return SELECT_CHARSET_CANCEL; - } else { - /* some charset has been selected */ - if (seldisplay) { - /* charset list is finished with "Other 8 bit" item */ - return (listbox_result >= (int) codepages->len) - ? SELECT_CHARSET_OTHER_8BIT - : listbox_result; - } else { - /* charset list is began with "- < No translation >" item */ - return (listbox_result - 1); - } + if (listbox_result < 0) + { + /* Cancel dialog */ + return SELECT_CHARSET_CANCEL; + } + else + { + /* some charset has been selected */ + if (seldisplay) + { + /* charset list is finished with "Other 8 bit" item */ + return (listbox_result >= (int) codepages->len) + ? SELECT_CHARSET_OTHER_8BIT : listbox_result; + } + else + { + /* charset list is began with "- < No translation >" item */ + return (listbox_result - 1); + } } } -/* Set codepage */ + +/* --------------------------------------------------------------------------------------------- */ +/** Set codepage */ gboolean do_set_codepage (int codepage) { @@ -122,19 +145,20 @@ do_set_codepage (int codepage) source_codepage = codepage; errmsg = init_translation_table (codepage == SELECT_CHARSET_NO_TRANSLATE ? - display_codepage : source_codepage, - display_codepage); + display_codepage : source_codepage, display_codepage); ret = errmsg == NULL; - if (!ret) { - message (D_ERROR, MSG_ERROR, "%s", errmsg); - g_free (errmsg); + if (!ret) + { + message (D_ERROR, MSG_ERROR, "%s", errmsg); + g_free (errmsg); } return ret; } -/* Show menu selecting codepage */ +/* --------------------------------------------------------------------------------------------- */ +/** Show menu selecting codepage */ gboolean do_select_codepage (void) @@ -143,10 +167,12 @@ do_select_codepage (void) r = select_charset (-1, -1, default_source_codepage, FALSE); if (r == SELECT_CHARSET_CANCEL) - return FALSE; + return FALSE; default_source_codepage = r; return do_set_codepage (default_source_codepage); } -#endif /* HAVE_CHARSET */ +/* --------------------------------------------------------------------------------------------- */ + +#endif /* HAVE_CHARSET */ diff --git a/src/selcodepage.h b/src/selcodepage.h index d2563982f..188b6cc1b 100644 --- a/src/selcodepage.h +++ b/src/selcodepage.h @@ -3,14 +3,12 @@ * \brief Header: user %interface for charset %selection */ -#ifndef MC_SELCODEPAGE_H -#define MC_SELCODEPAGE_H +#ifndef MC__SELCODEPAGE_H +#define MC__SELCODEPAGE_H #include "lib/global.h" -int select_charset (int center_y, int center_x, int current_charset, gboolean seldisplay); -gboolean do_set_codepage (int); -gboolean do_select_codepage (void); +/*** typedefs(not structures) and defined constants **********************************************/ /* some results of select_charset() */ #define SELECT_CHARSET_CANCEL -2 @@ -24,4 +22,18 @@ gboolean do_select_codepage (void); /* In other cases select_charset() returns non-negative value * which is number of codepage in codepage list */ -#endif /* MC_SELCODEPAGE_H */ +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +/*** inline functions ****************************************************************************/ + +int select_charset (int center_y, int center_x, int current_charset, gboolean seldisplay); +gboolean do_set_codepage (int); +gboolean do_select_codepage (void); + +#endif /* MC__SELCODEPAGE_H */ diff --git a/src/setup.c b/src/setup.c index b3f7b17ac..c8544291d 100644 --- a/src/setup.c +++ b/src/setup.c @@ -71,8 +71,7 @@ #include "setup.h" -/*** global variables **************************************************/ - +/*** global variables ****************************************************************************/ char *profile_name; /* .mc/ini */ char *global_profile_name; /* mc.lib */ @@ -112,15 +111,15 @@ panels_options_t panels_options = { int easy_patterns = 1; -/*** file scope macro definitions **************************************/ +/*** file scope macro definitions ****************************************************************/ /* In order to use everywhere the same setup for the locale we use defines */ #define FMTYEAR _("%b %e %Y") #define FMTTIME _("%b %e %H:%M") -/*** file scope type declarations **************************************/ +/*** file scope type declarations ****************************************************************/ -/*** file scope variables **********************************************/ +/*** file scope variables ************************************************************************/ static char *panels_profile_name = NULL; /* .mc/panels.ini */ @@ -301,7 +300,9 @@ static const struct static const char *panels_section = "Panels"; -/*** file scope functions **********************************************/ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /** Get name of config file. @@ -377,6 +378,8 @@ load_setup_get_full_config_name (const char *subdir, const char *config_file_nam } +/* --------------------------------------------------------------------------------------------- */ + static const char * setup__is_cfg_group_must_panel_config (const char *grp) { @@ -387,6 +390,8 @@ setup__is_cfg_group_must_panel_config (const char *grp) ? grp : NULL; } +/* --------------------------------------------------------------------------------------------- */ + static void setup__move_panels_config_into_separate_file (const char *profile) { @@ -442,11 +447,13 @@ setup__move_panels_config_into_separate_file (const char *profile) mc_config_deinit (tmp_cfg); } +/* --------------------------------------------------------------------------------------------- */ /** Create new mc_config object from specified ini-file or append data to existing mc_config object from ini-file */ + static void load_setup_init_config_from_file (mc_config_t ** config, const char *fname) { @@ -462,6 +469,8 @@ load_setup_init_config_from_file (mc_config_t ** config, const char *fname) } } +/* --------------------------------------------------------------------------------------------- */ + static void load_layout (void) { @@ -472,6 +481,8 @@ load_layout (void) layout[i].opt_name, *layout[i].opt_addr); } +/* --------------------------------------------------------------------------------------------- */ + static void load_keys_from_section (const char *terminal, mc_config_t * cfg) { @@ -536,6 +547,8 @@ load_keys_from_section (const char *terminal, mc_config_t * cfg) g_free (section_name); } +/* --------------------------------------------------------------------------------------------- */ + static void load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg) { @@ -587,6 +600,8 @@ load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t g_strfreev (keys); } +/* --------------------------------------------------------------------------------------------- */ + static mc_config_t * load_setup_get_keymap_profile_config (void) { @@ -642,6 +657,8 @@ load_setup_get_keymap_profile_config (void) return keymap_config; } +/* --------------------------------------------------------------------------------------------- */ + static panel_view_mode_t setup__load_panel_state (const char *section) { @@ -664,6 +681,8 @@ setup__load_panel_state (const char *section) return mode; } +/* --------------------------------------------------------------------------------------------- */ + static void panel_save_type (const char *section, panel_view_mode_t type) { @@ -677,7 +696,9 @@ panel_save_type (const char *section, panel_view_mode_t type) } } -/*** public functions **************************************************/ +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ char * setup_init (void) @@ -716,6 +737,8 @@ setup_init (void) return profile; } +/* --------------------------------------------------------------------------------------------- */ + void load_setup (void) { @@ -850,6 +873,8 @@ load_setup (void) clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", ""); } +/* --------------------------------------------------------------------------------------------- */ + gboolean save_setup (void) { @@ -890,6 +915,8 @@ save_setup (void) return ret; } +/* --------------------------------------------------------------------------------------------- */ + void done_setup (void) { @@ -915,6 +942,8 @@ done_setup (void) /* directory_history_free (); */ } +/* --------------------------------------------------------------------------------------------- */ + void save_config (void) { @@ -940,6 +969,8 @@ save_config (void) g_free (profile); } +/* --------------------------------------------------------------------------------------------- */ + void setup_save_config_show_error (const char *filename, GError ** error) { @@ -951,6 +982,8 @@ setup_save_config_show_error (const char *filename, GError ** error) } } +/* --------------------------------------------------------------------------------------------- */ + void save_layout (void) { @@ -965,6 +998,8 @@ save_layout (void) g_free (profile); } +/* --------------------------------------------------------------------------------------------- */ + void load_key_defs (void) { @@ -986,6 +1021,8 @@ load_key_defs (void) load_keys_from_section (getenv ("TERM"), mc_main_config); } +/* --------------------------------------------------------------------------------------------- */ + #ifdef ENABLE_VFS_FTP char * load_anon_passwd (void) @@ -1002,6 +1039,8 @@ load_anon_passwd (void) } #endif /* ENABLE_VFS_FTP */ +/* --------------------------------------------------------------------------------------------- */ + void load_keymap_defs (void) { @@ -1097,6 +1136,8 @@ load_keymap_defs (void) } +/* --------------------------------------------------------------------------------------------- */ + void free_keymap_defs (void) { @@ -1132,6 +1173,8 @@ free_keymap_defs (void) #endif } +/* --------------------------------------------------------------------------------------------- */ + void panel_load_setup (WPanel * panel, const char *section) { @@ -1179,6 +1222,8 @@ panel_load_setup (WPanel * panel, const char *section) panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0); } +/* --------------------------------------------------------------------------------------------- */ + void panel_save_setup (struct WPanel *panel, const char *section) { @@ -1209,6 +1254,8 @@ panel_save_setup (struct WPanel *panel, const char *section) mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status); } +/* --------------------------------------------------------------------------------------------- */ + void save_panel_types (void) { @@ -1244,6 +1291,8 @@ save_panel_types (void) mc_config_save_file (mc_panels_config, NULL); } +/* --------------------------------------------------------------------------------------------- */ + /** Load panels options from [Panels] section. */ @@ -1258,11 +1307,12 @@ panels_load_options (void) *panels_ini_options[i].opt_addr = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, panels_ini_options[i].opt_old_name != NULL - ? panels_ini_options[i].opt_old_name : panels_ini_options[i].opt_name, + ? panels_ini_options[i]. + opt_old_name : panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr); qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, - "quick_search_case_sensitive", (int) panels_options.qsearch_mode); + "quick_search_case_sensitive", (int) panels_options.qsearch_mode); if (qmode < 0) panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE; else if (qmode >= QSEARCH_NUM) @@ -1280,7 +1330,7 @@ panels_load_options (void) *panels_ini_options[i].opt_addr); qmode = mc_config_get_int (mc_main_config, panels_section, - "quick_search_mode", (int) panels_options.qsearch_mode); + "quick_search_mode", (int) panels_options.qsearch_mode); if (qmode < 0) panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE; else if (qmode >= QSEARCH_NUM) @@ -1290,6 +1340,8 @@ panels_load_options (void) } } +/* --------------------------------------------------------------------------------------------- */ + /** Save panels options in [Panels] section. */ @@ -1303,5 +1355,7 @@ panels_save_options (void) panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr); mc_config_set_int (mc_main_config, panels_section, - "quick_search_mode", (int) panels_options.qsearch_mode); + "quick_search_mode", (int) panels_options.qsearch_mode); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/setup.h b/src/setup.h index 2e6ce3df6..7354174ab 100644 --- a/src/setup.h +++ b/src/setup.h @@ -1,17 +1,57 @@ - /** \file setup.h * \brief Header: setup loading/saving */ -#ifndef MC_SETUP_H -#define MC_SETUP_H +#ifndef MC__SETUP_H +#define MC__SETUP_H #include #include "lib/global.h" /* GError */ - #include "panel.h" /* WPanel, panel_view_mode_t */ +/*** typedefs(not structures) and defined constants **********************************************/ + +/* TAB length for editor and viewer */ +#define DEFAULT_TAB_SPACING 8 + +/*** enums ***************************************************************************************/ + +typedef enum +{ + QSEARCH_CASE_INSENSITIVE = 0, /* quick search in case insensitive mode */ + QSEARCH_CASE_SENSITIVE = 1, /* quick search in case sensitive mode */ + QSEARCH_PANEL_CASE = 2, /* quick search get value from panel case_sensitive */ + QSEARCH_NUM +} qsearch_mode_t; + + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/* panels ini options; [Panels] section */ +typedef struct +{ + gboolean kilobyte_si; /* If TRUE, SI units (1000 based) will be used for larger units + * (kilobyte, megabyte, ...). If FALSE, binary units (1024 based) will be used */ + gboolean mix_all_files; /* If FALSE then directories are shown separately from files */ + gboolean show_backups; /* If TRUE, show files ending in ~ */ + gboolean show_dot_files; /* If TRUE, show files starting with a dot */ + gboolean fast_reload; /* If TRUE then use stat() on the cwd to determine directory changes */ + gboolean fast_reload_msg_shown; /* Have we shown the fast-reload warning in the past? */ + gboolean mark_moves_down; /* If TRUE, marking a files moves the cursor down */ + gboolean reverse_files_only; /* If TRUE, only selection of files is inverted */ + gboolean auto_save_setup; + gboolean navigate_with_arrows; /* If TRUE: l&r arrows are used to chdir if the input line is empty */ + gboolean scroll_pages; /* If TRUE, panel is scrolled by half the display when the cursor reaches + the end or the beginning of the panel */ + gboolean mouse_move_pages; /* Scroll page/item using mouse wheel */ + gboolean filetype_mode; /* If TRUE then add per file type hilighting */ + gboolean permission_mode; /* If TRUE, we use permission hilighting */ + qsearch_mode_t qsearch_mode; /* Quick search mode */ +} panels_options_t; + +/*** global variables defined in .c file *********************************************************/ + /* global paremeters */ extern char *profile_name; extern char *global_profile_name; @@ -25,17 +65,21 @@ extern int setup_copymove_persistent_attr; extern int num_history_items_recorded; extern int classic_progressbar; extern int easy_patterns; - -/* TAB length for editor and viewer */ -#define DEFAULT_TAB_SPACING 8 extern int option_tab_spacing; +extern panels_options_t panels_options; + +extern panel_view_mode_t startup_left_mode; +extern panel_view_mode_t startup_right_mode; + +/*** declarations of public functions ************************************************************/ + char *setup_init (void); void load_setup (void); gboolean save_setup (void); void done_setup (void); void save_config (void); -void setup_save_config_show_error (const char *filename, GError **error); +void setup_save_config_show_error (const char *filename, GError ** error); void save_layout (void); @@ -47,41 +91,6 @@ char *load_anon_passwd (void); void load_keymap_defs (void); void free_keymap_defs (void); -typedef enum -{ - QSEARCH_CASE_INSENSITIVE = 0, /* quick search in case insensitive mode */ - QSEARCH_CASE_SENSITIVE = 1, /* quick search in case sensitive mode */ - QSEARCH_PANEL_CASE = 2, /* quick search get value from panel case_sensitive */ - QSEARCH_NUM -} qsearch_mode_t; - -/* panels ini options; [Panels] section */ -typedef struct -{ - gboolean kilobyte_si; /* If TRUE, SI units (1000 based) will be used for larger units - * (kilobyte, megabyte, ...). If FALSE, binary units (1024 based) will be used */ - gboolean mix_all_files; /* If FALSE then directories are shown separately from files */ - gboolean show_backups; /* If TRUE, show files ending in ~ */ - gboolean show_dot_files; /* If TRUE, show files starting with a dot */ - gboolean fast_reload; /* If TRUE then use stat() on the cwd to determine directory changes */ - gboolean fast_reload_msg_shown; /* Have we shown the fast-reload warning in the past? */ - gboolean mark_moves_down; /* If TRUE, marking a files moves the cursor down */ - gboolean reverse_files_only; /* If TRUE, only selection of files is inverted */ - gboolean auto_save_setup; - gboolean navigate_with_arrows; /* If TRUE: l&r arrows are used to chdir if the input line is empty */ - gboolean scroll_pages; /* If TRUE, panel is scrolled by half the display when the cursor reaches - the end or the beginning of the panel */ - gboolean mouse_move_pages; /* Scroll page/item using mouse wheel */ - gboolean filetype_mode; /* If TRUE then add per file type hilighting */ - gboolean permission_mode; /* If TRUE, we use permission hilighting */ - qsearch_mode_t qsearch_mode; /* Quick search mode */ -} panels_options_t; - -extern panels_options_t panels_options; - -extern panel_view_mode_t startup_left_mode; -extern panel_view_mode_t startup_right_mode; - void panel_load_setup (struct WPanel *panel, const char *section); void panel_save_setup (struct WPanel *panel, const char *section); void save_panel_types (void); @@ -89,4 +98,5 @@ void save_panel_types (void); void panels_load_options (void); void panels_save_options (void); -#endif /* MC_SETUP_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__SETUP_H */ diff --git a/src/subshell.c b/src/subshell.c index 35fa942c6..65fc72f49 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -25,7 +25,7 @@ #ifdef HAVE_SUBSHELL_SUPPORT #ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 +#define _GNU_SOURCE 1 #endif #include @@ -38,13 +38,13 @@ #include #include #ifdef HAVE_SYS_IOCTL_H -# include +#include #endif #include #include #ifdef HAVE_STROPTS_H -# include /* For I_PUSH */ +#include /* For I_PUSH */ #endif /* HAVE_STROPTS_H */ #include "lib/global.h" @@ -60,36 +60,7 @@ #include "consaver/cons.saver.h" /* handle_console() */ #include "subshell.h" -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#endif - -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -/* tcsh closes all non-standard file descriptors, so we have to use a pipe */ -static char tcsh_fifo[128]; - -/* Local functions */ -static void init_raw_mode (void); -static gboolean feed_subshell (int how, int fail_on_error); -static void synchronize (void); -static int pty_open_master (char *pty_name); -static int pty_open_slave (const char *pty_name); -static int resize_tty (int fd); - -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif - -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif - -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif +/*** global variables ****************************************************************************/ /* If using a subshell for evaluating commands this is true */ int use_subshell = @@ -101,10 +72,6 @@ int use_subshell = /* File descriptors of the pseudoterminal used by the subshell */ int subshell_pty = 0; -static int subshell_pty_slave = -1; - -/* The key for switching back to MC from the subshell */ -static const char subshell_switch_key = XCTRL ('o') & 255; /* State of the subshell: * INACTIVE: the default state; awaiting a command @@ -115,6 +82,28 @@ enum subshell_state_enum subshell_state; /* Holds the latest prompt captured from the subshell */ char *subshell_prompt = NULL; +/*** file scope macro definitions ****************************************************************/ + +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif + +#ifndef WIFEXITED +#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + /* Initial length of the buffer for the subshell's prompt */ #define INITIAL_PROMPT_SIZE 10 @@ -124,6 +113,8 @@ char *subshell_prompt = NULL; /* Length of the buffer for all I/O with the subshell */ #define PTY_BUFFER_SIZE BUF_SMALL /* Arbitrary; but keep it >= 80 */ +/*** file scope type declarations ****************************************************************/ + /* For pipes */ enum { @@ -131,11 +122,6 @@ enum WRITE = 1 }; -static char pty_buffer[PTY_BUFFER_SIZE] = "\0"; /* For reading/writing on the subshell's pty */ -static int subshell_pipe[2]; /* To pass CWD info from the subshell to MC */ -static pid_t subshell_pid = 1; /* The subshell's process ID */ -static char subshell_cwd[MC_MAXPATHLEN + 1]; /* One extra char for final '\n' */ - /* Subshell type (gleaned from the SHELL environment variable, if available) */ static enum { @@ -145,6 +131,30 @@ static enum FISH } subshell_type; +/*** file scope variables ************************************************************************/ + +/* tcsh closes all non-standard file descriptors, so we have to use a pipe */ +static char tcsh_fifo[128]; + +static int subshell_pty_slave = -1; + +/* The key for switching back to MC from the subshell */ +/* *INDENT-OFF* */ +static const char subshell_switch_key = XCTRL ('o') & 255; +/* *INDENT-ON* */ + +/* For reading/writing on the subshell's pty */ +static char pty_buffer[PTY_BUFFER_SIZE] = "\0"; + +/* To pass CWD info from the subshell to MC */ +static int subshell_pipe[2]; + +/* The subshell's process ID */ +static pid_t subshell_pid = 1; + +/* One extra char for final '\n' */ +static char subshell_cwd[MC_MAXPATHLEN + 1]; + /* Flag to indicate whether the subshell is ready for next command */ static int subshell_ready; @@ -167,9 +177,21 @@ static struct termios raw_mode; static int prompt_pos; -/* +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static void init_raw_mode (void); +static gboolean feed_subshell (int how, int fail_on_error); +static void synchronize (void); +static int pty_open_master (char *pty_name); +static int pty_open_slave (const char *pty_name); +static int resize_tty (int fd); + +/* --------------------------------------------------------------------------------------------- */ +/** * Write all data, even if the write() call is interrupted. */ + static ssize_t write_all (int fd, const void *buf, size_t count) { @@ -195,7 +217,8 @@ write_all (int fd, const void *buf, size_t count) return written; } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Prepare child process to running the shell and run it. * * Modifies the global variables (in the child process only): @@ -203,6 +226,7 @@ write_all (int fd, const void *buf, size_t count) * * Returns: never. */ + static void init_subshell_child (const char *pty_name) { @@ -326,13 +350,15 @@ init_subshell_child (const char *pty_name) } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Check MC_SID to prevent running one mc from another. * Return: * 0 if no parent mc in our session was found, * 1 if parent mc was found and the user wants to continue, * 2 if parent mc was found and the user wants to quit mc. */ + static int check_sid (void) { @@ -368,8 +394,358 @@ check_sid (void) return 1; } +/* --------------------------------------------------------------------------------------------- */ -/* +static void +init_raw_mode () +{ + static int initialized = 0; + + /* MC calls tty_reset_shell_mode() in pre_exec() to set the real tty to its */ + /* original settings. However, here we need to make this tty very raw, */ + /* so that all keyboard signals, XON/XOFF, etc. will get through to the */ + /* pty. So, instead of changing the code for execute(), pre_exec(), */ + /* etc, we just set up the modes we need here, before each command. */ + + if (initialized == 0) /* First time: initialise `raw_mode' */ + { + tcgetattr (STDOUT_FILENO, &raw_mode); + raw_mode.c_lflag &= ~ICANON; /* Disable line-editing chars, etc. */ + raw_mode.c_lflag &= ~ISIG; /* Disable intr, quit & suspend chars */ + raw_mode.c_lflag &= ~ECHO; /* Disable input echoing */ + raw_mode.c_iflag &= ~IXON; /* Pass ^S/^Q to subshell undisturbed */ + raw_mode.c_iflag &= ~ICRNL; /* Don't translate CRs into LFs */ + raw_mode.c_oflag &= ~OPOST; /* Don't postprocess output */ + raw_mode.c_cc[VTIME] = 0; /* IE: wait forever, and return as */ + raw_mode.c_cc[VMIN] = 1; /* soon as a character is available */ + initialized = 1; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** Feed the subshell our keyboard input until it says it's finished */ + +static gboolean +feed_subshell (int how, int fail_on_error) +{ + fd_set read_set; /* For `select' */ + int maxfdp; + int bytes; /* For the return value from `read' */ + int i; /* Loop counter */ + + struct timeval wtime; /* Maximum time we wait for the subshell */ + struct timeval *wptr; + + /* we wait up to 10 seconds if fail_on_error, forever otherwise */ + wtime.tv_sec = 10; + wtime.tv_usec = 0; + wptr = fail_on_error ? &wtime : NULL; + + while (TRUE) + { + if (!subshell_alive) + return FALSE; + + /* Prepare the file-descriptor set and call `select' */ + + FD_ZERO (&read_set); + FD_SET (subshell_pty, &read_set); + FD_SET (subshell_pipe[READ], &read_set); + maxfdp = max (subshell_pty, subshell_pipe[READ]); + if (how == VISIBLY) + { + FD_SET (STDIN_FILENO, &read_set); + maxfdp = max (maxfdp, STDIN_FILENO); + } + + if (select (maxfdp + 1, &read_set, NULL, NULL, wptr) == -1) + { + + /* Despite using SA_RESTART, we still have to check for this */ + if (errno == EINTR) + continue; /* try all over again */ + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "select (FD_SETSIZE, &read_set...): %s\r\n", + unix_error_string (errno)); + exit (EXIT_FAILURE); + } + + if (FD_ISSET (subshell_pty, &read_set)) + /* Read from the subshell, write to stdout */ + + /* This loop improves performance by reducing context switches + by a factor of 20 or so... unfortunately, it also hangs MC + randomly, because of an apparent Linux bug. Investigate. */ + /* for (i=0; i<5; ++i) * FIXME -- experimental */ + { + bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); + + /* The subshell has died */ + if (bytes == -1 && errno == EIO && !subshell_alive) + return FALSE; + + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "read (subshell_pty...): %s\r\n", unix_error_string (errno)); + exit (EXIT_FAILURE); + } + + if (how == VISIBLY) + write_all (STDOUT_FILENO, pty_buffer, bytes); + } + + else if (FD_ISSET (subshell_pipe[READ], &read_set)) + /* Read the subshell's CWD and capture its prompt */ + { + bytes = read (subshell_pipe[READ], subshell_cwd, MC_MAXPATHLEN + 1); + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "read (subshell_pipe[READ]...): %s\r\n", + unix_error_string (errno)); + exit (EXIT_FAILURE); + } + + subshell_cwd[bytes - 1] = 0; /* Squash the final '\n' */ + + synchronize (); + + subshell_ready = TRUE; + if (subshell_state == RUNNING_COMMAND) + { + subshell_state = INACTIVE; + return TRUE; + } + } + + else if (FD_ISSET (STDIN_FILENO, &read_set)) + /* Read from stdin, write to the subshell */ + { + bytes = read (STDIN_FILENO, pty_buffer, sizeof (pty_buffer)); + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, + "read (STDIN_FILENO, pty_buffer...): %s\r\n", unix_error_string (errno)); + exit (EXIT_FAILURE); + } + + for (i = 0; i < bytes; ++i) + if (pty_buffer[i] == subshell_switch_key) + { + write_all (subshell_pty, pty_buffer, i); + if (subshell_ready) + subshell_state = INACTIVE; + return TRUE; + } + + write_all (subshell_pty, pty_buffer, bytes); + + if (pty_buffer[bytes - 1] == '\n' || pty_buffer[bytes - 1] == '\r') + subshell_ready = FALSE; + } + else + return FALSE; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Wait until the subshell dies or stops. If it stops, make it resume. + * Possibly modifies the globals `subshell_alive' and `subshell_stopped' + */ + +static void +synchronize (void) +{ + sigset_t sigchld_mask, old_mask; + + sigemptyset (&sigchld_mask); + sigaddset (&sigchld_mask, SIGCHLD); + sigprocmask (SIG_BLOCK, &sigchld_mask, &old_mask); + + /* + * SIGCHLD should not be blocked, but we unblock it just in case. + * This is known to be useful for cygwin 1.3.12 and older. + */ + sigdelset (&old_mask, SIGCHLD); + + /* Wait until the subshell has stopped */ + while (subshell_alive && !subshell_stopped) + sigsuspend (&old_mask); + + if (subshell_state != ACTIVE) + { + /* Discard all remaining data from stdin to the subshell */ + tcflush (subshell_pty_slave, TCIFLUSH); + } + + subshell_stopped = FALSE; + kill (subshell_pid, SIGCONT); + + sigprocmask (SIG_SETMASK, &old_mask, NULL); + /* We can't do any better without modifying the shell(s) */ +} + +/* pty opening functions */ + +#ifdef HAVE_GRANTPT + +/* System V version of pty_open_master */ + +static int +pty_open_master (char *pty_name) +{ + char *slave_name; + int pty_master; + +#ifdef HAVE_POSIX_OPENPT + pty_master = posix_openpt (O_RDWR); +#elif HAVE_GETPT + /* getpt () is a GNU extension (glibc 2.1.x) */ + pty_master = getpt (); +#elif IS_AIX + strcpy (pty_name, "/dev/ptc"); + pty_master = open (pty_name, O_RDWR); +#else + strcpy (pty_name, "/dev/ptmx"); + pty_master = open (pty_name, O_RDWR); +#endif + + if (pty_master == -1) + return -1; + + if (grantpt (pty_master) == -1 /* Grant access to slave */ + || unlockpt (pty_master) == -1 /* Clear slave's lock flag */ + || !(slave_name = ptsname (pty_master))) /* Get slave's name */ + { + close (pty_master); + return -1; + } + strcpy (pty_name, slave_name); + return pty_master; +} + +/* --------------------------------------------------------------------------------------------- */ +/** System V version of pty_open_slave */ + +static int +pty_open_slave (const char *pty_name) +{ + int pty_slave = open (pty_name, O_RDWR); + + if (pty_slave == -1) + { + fprintf (stderr, "open (%s, O_RDWR): %s\r\n", pty_name, unix_error_string (errno)); + return -1; + } +#if !defined(__osf__) && !defined(__linux__) +#if defined (I_FIND) && defined (I_PUSH) + if (!ioctl (pty_slave, I_FIND, "ptem")) + if (ioctl (pty_slave, I_PUSH, "ptem") == -1) + { + fprintf (stderr, "ioctl (%d, I_PUSH, \"ptem\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } + + if (!ioctl (pty_slave, I_FIND, "ldterm")) + if (ioctl (pty_slave, I_PUSH, "ldterm") == -1) + { + fprintf (stderr, + "ioctl (%d, I_PUSH, \"ldterm\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } +#if !defined(sgi) && !defined(__sgi) + if (!ioctl (pty_slave, I_FIND, "ttcompat")) + if (ioctl (pty_slave, I_PUSH, "ttcompat") == -1) + { + fprintf (stderr, + "ioctl (%d, I_PUSH, \"ttcompat\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } +#endif /* sgi || __sgi */ +#endif /* I_FIND && I_PUSH */ +#endif /* __osf__ || __linux__ */ + + fcntl (pty_slave, F_SETFD, FD_CLOEXEC); + return pty_slave; +} + +#else /* !HAVE_GRANTPT */ + +/* --------------------------------------------------------------------------------------------- */ +/** BSD version of pty_open_master */ +static int +pty_open_master (char *pty_name) +{ + int pty_master; + const char *ptr1, *ptr2; + + strcpy (pty_name, "/dev/ptyXX"); + for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1; ++ptr1) + { + pty_name[8] = *ptr1; + for (ptr2 = "0123456789abcdef"; *ptr2 != '\0'; ++ptr2) + { + pty_name[9] = *ptr2; + + /* Try to open master */ + pty_master = open (pty_name, O_RDWR); + if (pty_master == -1) + { + if (errno == ENOENT) /* Different from EIO */ + return -1; /* Out of pty devices */ + continue; /* Try next pty device */ + } + pty_name[5] = 't'; /* Change "pty" to "tty" */ + if (access (pty_name, 6) != 0) + { + close (pty_master); + pty_name[5] = 'p'; + continue; + } + return pty_master; + } + } + return -1; /* Ran out of pty devices */ +} + +/* --------------------------------------------------------------------------------------------- */ +/** BSD version of pty_open_slave */ + +static int +pty_open_slave (const char *pty_name) +{ + int pty_slave; + struct group *group_info = getgrnam ("tty"); + + if (group_info != NULL) + { + /* The following two calls will only succeed if we are root */ + /* [Commented out while permissions problem is investigated] */ + /* chown (pty_name, getuid (), group_info->gr_gid); FIXME */ + /* chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP); FIXME */ + } + pty_slave = open (pty_name, O_RDWR); + if (pty_slave == -1) + fprintf (stderr, "open (pty_name, O_RDWR): %s\r\n", pty_name); + fcntl (pty_slave, F_SETFD, FD_CLOEXEC); + return pty_slave; +} +#endif /* !HAVE_GRANTPT */ +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/** * Fork the subshell, and set up many, many things. * * Possibly modifies the global variables: @@ -533,33 +909,7 @@ init_subshell (void) use_subshell = FALSE; /* Subshell died instantly, so don't use it */ } - -static void -init_raw_mode () -{ - static int initialized = 0; - - /* MC calls tty_reset_shell_mode() in pre_exec() to set the real tty to its */ - /* original settings. However, here we need to make this tty very raw, */ - /* so that all keyboard signals, XON/XOFF, etc. will get through to the */ - /* pty. So, instead of changing the code for execute(), pre_exec(), */ - /* etc, we just set up the modes we need here, before each command. */ - - if (initialized == 0) /* First time: initialise `raw_mode' */ - { - tcgetattr (STDOUT_FILENO, &raw_mode); - raw_mode.c_lflag &= ~ICANON; /* Disable line-editing chars, etc. */ - raw_mode.c_lflag &= ~ISIG; /* Disable intr, quit & suspend chars */ - raw_mode.c_lflag &= ~ECHO; /* Disable input echoing */ - raw_mode.c_iflag &= ~IXON; /* Pass ^S/^Q to subshell undisturbed */ - raw_mode.c_iflag &= ~ICRNL; /* Don't translate CRs into LFs */ - raw_mode.c_oflag &= ~OPOST; /* Don't postprocess output */ - raw_mode.c_cc[VTIME] = 0; /* IE: wait forever, and return as */ - raw_mode.c_cc[VMIN] = 1; /* soon as a character is available */ - initialized = 1; - } -} - +/* --------------------------------------------------------------------------------------------- */ int invoke_subshell (const char *command, int how, char **new_dir) @@ -612,6 +962,8 @@ invoke_subshell (const char *command, int how, char **new_dir) } +/* --------------------------------------------------------------------------------------------- */ + int read_subshell_prompt (void) { @@ -670,7 +1022,9 @@ read_subshell_prompt (void) return TRUE; } -/* Resize given terminal using TIOCSWINSZ, return ioctl() result */ +/* --------------------------------------------------------------------------------------------- */ +/** Resize given terminal using TIOCSWINSZ, return ioctl() result */ + static int resize_tty (int fd) { @@ -687,7 +1041,9 @@ resize_tty (int fd) #endif } -/* Resize subshell_pty */ +/* --------------------------------------------------------------------------------------------- */ +/** Resize subshell_pty */ + void resize_subshell (void) { @@ -697,6 +1053,8 @@ resize_subshell (void) resize_tty (subshell_pty); } +/* --------------------------------------------------------------------------------------------- */ + int exit_subshell (void) { @@ -726,7 +1084,8 @@ exit_subshell (void) } -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Carefully quote directory name to allow entering any directory safely, * no matter what weird characters it may contain in its name. * NOTE: Treat directory name an untrusted data, don't allow it to cause @@ -742,6 +1101,7 @@ exit_subshell (void) * cd "`printf "%b" 'ABC\0nnnDEF\0nnnXYZ'`" * */ + static char * subshell_name_quote (const char *s) { @@ -809,7 +1169,9 @@ subshell_name_quote (const char *s) } -/* If it actually changed the directory it returns true */ +/* --------------------------------------------------------------------------------------------- */ +/** If it actually changed the directory it returns true */ + void do_subshell_chdir (const char *directory, int do_update, int reset_prompt) { @@ -903,6 +1265,7 @@ do_subshell_chdir (const char *directory, int do_update, int reset_prompt) /* like /usr////lib/../bin, or the strcmp() above will fail */ } +/* --------------------------------------------------------------------------------------------- */ void subshell_get_console_attributes (void) @@ -917,9 +1280,11 @@ subshell_get_console_attributes (void) } } +/* --------------------------------------------------------------------------------------------- */ +/** + * Figure out whether the subshell has stopped, exited or been killed + * Possibly modifies: `subshell_alive', `subshell_stopped' and `quit' */ -/* Figure out whether the subshell has stopped, exited or been killed */ -/* Possibly modifies: `subshell_alive', `subshell_stopped' and `quit' */ void sigchld_handler (int sig) { @@ -978,314 +1343,6 @@ sigchld_handler (int sig) /* If we got here, some other child exited; ignore it */ } +/* --------------------------------------------------------------------------------------------- */ -/* Feed the subshell our keyboard input until it says it's finished */ -static gboolean -feed_subshell (int how, int fail_on_error) -{ - fd_set read_set; /* For `select' */ - int maxfdp; - int bytes; /* For the return value from `read' */ - int i; /* Loop counter */ - - struct timeval wtime; /* Maximum time we wait for the subshell */ - struct timeval *wptr; - - /* we wait up to 10 seconds if fail_on_error, forever otherwise */ - wtime.tv_sec = 10; - wtime.tv_usec = 0; - wptr = fail_on_error ? &wtime : NULL; - - while (TRUE) - { - if (!subshell_alive) - return FALSE; - - /* Prepare the file-descriptor set and call `select' */ - - FD_ZERO (&read_set); - FD_SET (subshell_pty, &read_set); - FD_SET (subshell_pipe[READ], &read_set); - maxfdp = max (subshell_pty, subshell_pipe[READ]); - if (how == VISIBLY) - { - FD_SET (STDIN_FILENO, &read_set); - maxfdp = max (maxfdp, STDIN_FILENO); - } - - if (select (maxfdp + 1, &read_set, NULL, NULL, wptr) == -1) - { - - /* Despite using SA_RESTART, we still have to check for this */ - if (errno == EINTR) - continue; /* try all over again */ - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "select (FD_SETSIZE, &read_set...): %s\r\n", - unix_error_string (errno)); - exit (EXIT_FAILURE); - } - - if (FD_ISSET (subshell_pty, &read_set)) - /* Read from the subshell, write to stdout */ - - /* This loop improves performance by reducing context switches - by a factor of 20 or so... unfortunately, it also hangs MC - randomly, because of an apparent Linux bug. Investigate. */ - /* for (i=0; i<5; ++i) * FIXME -- experimental */ - { - bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); - - /* The subshell has died */ - if (bytes == -1 && errno == EIO && !subshell_alive) - return FALSE; - - if (bytes <= 0) - { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "read (subshell_pty...): %s\r\n", unix_error_string (errno)); - exit (EXIT_FAILURE); - } - - if (how == VISIBLY) - write_all (STDOUT_FILENO, pty_buffer, bytes); - } - - else if (FD_ISSET (subshell_pipe[READ], &read_set)) - /* Read the subshell's CWD and capture its prompt */ - { - bytes = read (subshell_pipe[READ], subshell_cwd, MC_MAXPATHLEN + 1); - if (bytes <= 0) - { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "read (subshell_pipe[READ]...): %s\r\n", - unix_error_string (errno)); - exit (EXIT_FAILURE); - } - - subshell_cwd[bytes - 1] = 0; /* Squash the final '\n' */ - - synchronize (); - - subshell_ready = TRUE; - if (subshell_state == RUNNING_COMMAND) - { - subshell_state = INACTIVE; - return TRUE; - } - } - - else if (FD_ISSET (STDIN_FILENO, &read_set)) - /* Read from stdin, write to the subshell */ - { - bytes = read (STDIN_FILENO, pty_buffer, sizeof (pty_buffer)); - if (bytes <= 0) - { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, - "read (STDIN_FILENO, pty_buffer...): %s\r\n", unix_error_string (errno)); - exit (EXIT_FAILURE); - } - - for (i = 0; i < bytes; ++i) - if (pty_buffer[i] == subshell_switch_key) - { - write_all (subshell_pty, pty_buffer, i); - if (subshell_ready) - subshell_state = INACTIVE; - return TRUE; - } - - write_all (subshell_pty, pty_buffer, bytes); - - if (pty_buffer[bytes - 1] == '\n' || pty_buffer[bytes - 1] == '\r') - subshell_ready = FALSE; - } - else - return FALSE; - } -} - - -/* Wait until the subshell dies or stops. If it stops, make it resume. */ -/* Possibly modifies the globals `subshell_alive' and `subshell_stopped' */ -static void -synchronize (void) -{ - sigset_t sigchld_mask, old_mask; - - sigemptyset (&sigchld_mask); - sigaddset (&sigchld_mask, SIGCHLD); - sigprocmask (SIG_BLOCK, &sigchld_mask, &old_mask); - - /* - * SIGCHLD should not be blocked, but we unblock it just in case. - * This is known to be useful for cygwin 1.3.12 and older. - */ - sigdelset (&old_mask, SIGCHLD); - - /* Wait until the subshell has stopped */ - while (subshell_alive && !subshell_stopped) - sigsuspend (&old_mask); - - if (subshell_state != ACTIVE) - { - /* Discard all remaining data from stdin to the subshell */ - tcflush (subshell_pty_slave, TCIFLUSH); - } - - subshell_stopped = FALSE; - kill (subshell_pid, SIGCONT); - - sigprocmask (SIG_SETMASK, &old_mask, NULL); - /* We can't do any better without modifying the shell(s) */ -} - -/* pty opening functions */ - -#ifdef HAVE_GRANTPT - -/* System V version of pty_open_master */ - -static int -pty_open_master (char *pty_name) -{ - char *slave_name; - int pty_master; - -#ifdef HAVE_POSIX_OPENPT - pty_master = posix_openpt (O_RDWR); -#elif HAVE_GETPT - /* getpt () is a GNU extension (glibc 2.1.x) */ - pty_master = getpt (); -#elif IS_AIX - strcpy (pty_name, "/dev/ptc"); - pty_master = open (pty_name, O_RDWR); -#else - strcpy (pty_name, "/dev/ptmx"); - pty_master = open (pty_name, O_RDWR); -#endif - - if (pty_master == -1) - return -1; - - if (grantpt (pty_master) == -1 /* Grant access to slave */ - || unlockpt (pty_master) == -1 /* Clear slave's lock flag */ - || !(slave_name = ptsname (pty_master))) /* Get slave's name */ - { - close (pty_master); - return -1; - } - strcpy (pty_name, slave_name); - return pty_master; -} - -/* System V version of pty_open_slave */ -static int -pty_open_slave (const char *pty_name) -{ - int pty_slave = open (pty_name, O_RDWR); - - if (pty_slave == -1) - { - fprintf (stderr, "open (%s, O_RDWR): %s\r\n", pty_name, unix_error_string (errno)); - return -1; - } -#if !defined(__osf__) && !defined(__linux__) -#if defined (I_FIND) && defined (I_PUSH) - if (!ioctl (pty_slave, I_FIND, "ptem")) - if (ioctl (pty_slave, I_PUSH, "ptem") == -1) - { - fprintf (stderr, "ioctl (%d, I_PUSH, \"ptem\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } - - if (!ioctl (pty_slave, I_FIND, "ldterm")) - if (ioctl (pty_slave, I_PUSH, "ldterm") == -1) - { - fprintf (stderr, - "ioctl (%d, I_PUSH, \"ldterm\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } -#if !defined(sgi) && !defined(__sgi) - if (!ioctl (pty_slave, I_FIND, "ttcompat")) - if (ioctl (pty_slave, I_PUSH, "ttcompat") == -1) - { - fprintf (stderr, - "ioctl (%d, I_PUSH, \"ttcompat\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } -#endif /* sgi || __sgi */ -#endif /* I_FIND && I_PUSH */ -#endif /* __osf__ || __linux__ */ - - fcntl (pty_slave, F_SETFD, FD_CLOEXEC); - return pty_slave; -} - -#else /* !HAVE_GRANTPT */ - -/* BSD version of pty_open_master */ -static int -pty_open_master (char *pty_name) -{ - int pty_master; - const char *ptr1, *ptr2; - - strcpy (pty_name, "/dev/ptyXX"); - for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1; ++ptr1) - { - pty_name[8] = *ptr1; - for (ptr2 = "0123456789abcdef"; *ptr2 != '\0'; ++ptr2) - { - pty_name[9] = *ptr2; - - /* Try to open master */ - pty_master = open (pty_name, O_RDWR); - if (pty_master == -1) - { - if (errno == ENOENT) /* Different from EIO */ - return -1; /* Out of pty devices */ - continue; /* Try next pty device */ - } - pty_name[5] = 't'; /* Change "pty" to "tty" */ - if (access (pty_name, 6) != 0) - { - close (pty_master); - pty_name[5] = 'p'; - continue; - } - return pty_master; - } - } - return -1; /* Ran out of pty devices */ -} - -/* BSD version of pty_open_slave */ -static int -pty_open_slave (const char *pty_name) -{ - int pty_slave; - struct group *group_info = getgrnam ("tty"); - - if (group_info != NULL) - { - /* The following two calls will only succeed if we are root */ - /* [Commented out while permissions problem is investigated] */ - /* chown (pty_name, getuid (), group_info->gr_gid); FIXME */ - /* chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP); FIXME */ - } - pty_slave = open (pty_name, O_RDWR); - if (pty_slave == -1) - fprintf (stderr, "open (pty_name, O_RDWR): %s\r\n", pty_name); - fcntl (pty_slave, F_SETFD, FD_CLOEXEC); - return pty_slave; -} - -#endif /* !HAVE_GRANTPT */ #endif /* HAVE_SUBSHELL_SUPPORT */ diff --git a/src/subshell.h b/src/subshell.h index 6bb003a4a..ca17d516c 100644 --- a/src/subshell.h +++ b/src/subshell.h @@ -1,10 +1,11 @@ - /** \file subshell.h * \brief Header: concurrent shell support */ -#ifndef MC_SUBSHELL_H -#define MC_SUBSHELL_H +#ifndef MC__SUBSHELL_H +#define MC__SUBSHELL_H + +/*** typedefs(not structures) and defined constants **********************************************/ /* Used to distinguish between a normal MC termination and */ /* one caused by typing `exit' or `logout' in the subshell */ @@ -12,23 +13,34 @@ #ifdef HAVE_SUBSHELL_SUPPORT +/*** enums ***************************************************************************************/ + +/* State of the subshell; see subshell.c for an explanation */ + +enum subshell_state_enum +{ INACTIVE, ACTIVE, RUNNING_COMMAND }; + +/* For the `how' argument to various functions */ +enum +{ QUIETLY, VISIBLY }; + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + /* If using a subshell for evaluating commands this is true */ extern int use_subshell; /* File descriptor of the pseudoterminal used by the subshell */ extern int subshell_pty; -/* State of the subshell; see subshell.c for an explanation */ -enum subshell_state_enum {INACTIVE, ACTIVE, RUNNING_COMMAND}; extern enum subshell_state_enum subshell_state; /* Holds the latest prompt captured from the subshell */ extern char *subshell_prompt; -/* For the `how' argument to various functions */ -enum {QUIETLY, VISIBLY}; +/*** declarations of public functions ************************************************************/ -/* Exported functions */ void init_subshell (void); int invoke_subshell (const char *command, int how, char **new_dir); int read_subshell_prompt (void); @@ -38,8 +50,9 @@ void do_subshell_chdir (const char *directory, int update_prompt, int reset_prom void subshell_get_console_attributes (void); void sigchld_handler (int sig); -#else +#else /* not HAVE_SUBSHELL_SUPPORT */ #define use_subshell 0 #endif /* not HAVE_SUBSHELL_SUPPORT */ -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__SUBSHELL_H */ diff --git a/src/textconf.c b/src/textconf.c index 43b57dc40..0d1047b3d 100644 --- a/src/textconf.c +++ b/src/textconf.c @@ -31,6 +31,14 @@ #include "lib/global.h" #include "src/textconf.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + #ifdef ENABLE_VFS static const char *const vfs_supported[] = { #ifdef ENABLE_VFS_CPIO @@ -59,8 +67,7 @@ static const char *const vfs_supported[] = { #endif /* ENABLE_VFS_SMB */ NULL }; -#endif /* ENABLE_VFS */ - +#endif /* ENABLE_VFS */ static const char *const features[] = { #ifdef USE_INTERNAL_EDIT @@ -81,18 +88,18 @@ static const char *const features[] = { N_("Using the ncursesw library"), #else #error "Cannot compile mc without S-Lang or ncurses" -#endif /* !HAVE_SLANG && !USE_NCURSES */ +#endif /* !HAVE_SLANG && !USE_NCURSES */ "\n", #ifdef HAVE_SUBSHELL_SUPPORT -# ifdef SUBSHELL_OPTIONAL +#ifdef SUBSHELL_OPTIONAL N_("With optional subshell support"), -# else +#else N_("With subshell support as default"), -# endif +#endif "\n", -#endif /* !HAVE_SUBSHELL_SUPPORT */ +#endif /* !HAVE_SUBSHELL_SUPPORT */ #ifdef WITH_BACKGROUND N_("With support for background operations\n"), @@ -119,6 +126,13 @@ static const char *const features[] = { NULL }; +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + void show_version (void) { @@ -129,23 +143,25 @@ show_version (void) #ifdef ENABLE_VFS printf (_("Virtual File Systems:")); for (i = 0; vfs_supported[i] != NULL; i++) - printf ("%s %s", i == 0 ? "" : ",", _(vfs_supported[i])); + printf ("%s %s", i == 0 ? "" : ",", _(vfs_supported[i])); printf ("\n"); -#endif /* ENABLE_VFS */ +#endif /* ENABLE_VFS */ for (i = 0; features[i] != NULL; i++) - printf ("%s", _(features[i])); + printf ("%s", _(features[i])); - (void)printf(_("Data types:")); + (void) printf (_("Data types:")); #define TYPE_INFO(T) \ (void)printf(" %s: %d;", #T, (int) (CHAR_BIT * sizeof(T))) - TYPE_INFO(char); - TYPE_INFO(int); - TYPE_INFO(long); - TYPE_INFO(void *); - TYPE_INFO(size_t); - TYPE_INFO(off_t); + TYPE_INFO (char); + TYPE_INFO (int); + TYPE_INFO (long); + TYPE_INFO (void *); + TYPE_INFO (size_t); + TYPE_INFO (off_t); #undef TYPE_INFO - (void)printf("\n"); + (void) printf ("\n"); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/textconf.h b/src/textconf.h index 6c33af6bb..0ea1fcfe8 100644 --- a/src/textconf.h +++ b/src/textconf.h @@ -1,11 +1,21 @@ - /** \file textconf.h * \brief Header: prints features specific for this build */ -#ifndef MC_TEXTCONF_H -#define MC_TEXTCONF_H +#ifndef MC__TEXTCONF_H +#define MC__TEXTCONF_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ extern void show_version (void); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__TEXTCONF_H */ diff --git a/src/tree.c b/src/tree.c index 5dcdfac17..b5f32aeb7 100644 --- a/src/tree.c +++ b/src/tree.c @@ -68,21 +68,24 @@ #include "tree.h" #include "filegui.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines) /* Use the color of the parent widget for the unselected entries */ #define TREE_NORMALC(h) (h->color[DLG_COLOR_NORMAL]) #define TREE_CURRENTC(h) (h->color[DLG_COLOR_FOCUS]) -/* Specifies the display mode: 1d or 2d */ -static gboolean tree_navigation_flag = FALSE; +/*** file scope type declarations ****************************************************************/ struct WTree { Widget widget; struct TreeStore *store; tree_entry *selected_ptr; /* The selected directory */ - char search_buffer[MC_MAXFILENAMELEN]; /* Current search string */ + char search_buffer[MC_MAXFILENAMELEN]; /* Current search string */ tree_entry **tree_shown; /* Entries currently on screen */ int is_panel; /* panel or plain widget flag */ int active; /* if it's currently selected */ @@ -91,9 +94,18 @@ struct WTree shown and the selected */ }; -/* Forwards */ +/*** file scope variables ************************************************************************/ + +/* Specifies the display mode: 1d or 2d */ +static gboolean tree_navigation_flag = FALSE; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static void tree_rescan (void *data); +/* --------------------------------------------------------------------------------------------- */ + static tree_entry * back_ptr (tree_entry * ptr, int *count) { @@ -108,6 +120,8 @@ back_ptr (tree_entry * ptr, int *count) return ptr; } +/* --------------------------------------------------------------------------------------------- */ + static tree_entry * forw_ptr (tree_entry * ptr, int *count) { @@ -122,6 +136,8 @@ forw_ptr (tree_entry * ptr, int *count) return ptr; } +/* --------------------------------------------------------------------------------------------- */ + static void remove_callback (tree_entry * entry, void *data) { @@ -136,7 +152,9 @@ remove_callback (tree_entry * entry, void *data) } } -/* Save the ~/.mc/Tree file */ +/* --------------------------------------------------------------------------------------------- */ +/** Save the ~/.mc/Tree file */ + static void save_tree (WTree * tree) { @@ -156,6 +174,8 @@ save_tree (WTree * tree) } } +/* --------------------------------------------------------------------------------------------- */ + static void tree_remove_entry (WTree * tree, char *name) { @@ -163,6 +183,8 @@ tree_remove_entry (WTree * tree, char *name) tree_store_remove_entry (name); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_destroy (WTree * tree) { @@ -174,7 +196,9 @@ tree_destroy (WTree * tree) tree->selected_ptr = NULL; } -/* Loads the .mc.tree file */ +/* --------------------------------------------------------------------------------------------- */ +/** Loads the .mc.tree file */ + static void load_tree (WTree * tree) { @@ -184,6 +208,8 @@ load_tree (WTree * tree) tree_chdir (tree, home_dir); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_show_mini_info (WTree * tree, int tree_lines, int tree_cols) { @@ -220,6 +246,8 @@ tree_show_mini_info (WTree * tree, int tree_lines, int tree_cols) } } +/* --------------------------------------------------------------------------------------------- */ + static void show_tree (WTree * tree) { @@ -298,7 +326,7 @@ show_tree (WTree * tree) if (tree->is_panel) tty_setcolor (tree->active && current == tree->selected_ptr - ? SELECTED_COLOR : NORMAL_COLOR); + ? SELECTED_COLOR : NORMAL_COLOR); else tty_setcolor (current == tree->selected_ptr ? TREE_CURRENTC (h) : TREE_NORMALC (h)); @@ -306,7 +334,8 @@ show_tree (WTree * tree) if (current->sublevel == topsublevel) { /* Show full name */ - tty_print_string (str_fit_to_term (current->name, tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT)); + tty_print_string (str_fit_to_term + (current->name, tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT)); } else { @@ -336,7 +365,8 @@ show_tree (WTree * tree) /* Show sub-name */ tty_print_char (' '); - tty_print_string (str_fit_to_term (current->subname, tree_cols - x - 3 * j, J_LEFT_FIT)); + tty_print_string (str_fit_to_term + (current->subname, tree_cols - x - 3 * j, J_LEFT_FIT)); } /* Calculate the next value for current */ @@ -373,6 +403,8 @@ show_tree (WTree * tree) tree_show_mini_info (tree, tree_lines, tree_cols); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_check_focus (WTree * tree) { @@ -382,6 +414,8 @@ tree_check_focus (WTree * tree) tree->topdiff = tlines (tree) - 3 - 1; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_backward (WTree * tree, int i) { @@ -409,6 +443,8 @@ tree_move_backward (WTree * tree, int i) tree_check_focus (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_forward (WTree * tree, int i) { @@ -436,6 +472,8 @@ tree_move_forward (WTree * tree, int i) tree_check_focus (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_to_child (WTree * tree) { @@ -468,6 +506,8 @@ tree_move_to_child (WTree * tree) } } +/* --------------------------------------------------------------------------------------------- */ + static gboolean tree_move_to_parent (WTree * tree) { @@ -491,6 +531,8 @@ tree_move_to_parent (WTree * tree) return tree->selected_ptr != old; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_to_top (WTree * tree) { @@ -498,6 +540,8 @@ tree_move_to_top (WTree * tree) tree->topdiff = 0; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_to_bottom (WTree * tree) { @@ -505,7 +549,9 @@ tree_move_to_bottom (WTree * tree) tree->topdiff = tlines (tree) - 3 - 1; } -/* Handle mouse click */ +/* --------------------------------------------------------------------------------------------- */ +/** Handle mouse click */ + static void tree_event (WTree * tree, int y) { @@ -517,6 +563,8 @@ tree_event (WTree * tree, int y) show_tree (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_chdir_sel (WTree * tree) { @@ -535,6 +583,8 @@ tree_chdir_sel (WTree * tree) show_tree (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void maybe_chdir (WTree * tree) { @@ -542,7 +592,9 @@ maybe_chdir (WTree * tree) tree_chdir_sel (tree); } -/* Mouse callback */ +/* --------------------------------------------------------------------------------------------- */ +/** Mouse callback */ + static int event_callback (Gpm_Event * event, void *data) { @@ -587,7 +639,9 @@ event_callback (Gpm_Event * event, void *data) return MOU_NORMAL; } -/* Search tree for text */ +/* --------------------------------------------------------------------------------------------- */ +/** Search tree for text */ + static int search_tree (WTree * tree, char *text) { @@ -619,6 +673,8 @@ search_tree (WTree * tree, char *text) return found; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_do_search (WTree * tree, int key) { @@ -640,6 +696,8 @@ tree_do_search (WTree * tree, int key) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_rescan (void *data) { @@ -655,6 +713,8 @@ tree_rescan (void *data) ret = mc_chdir (old_dir); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_forget (void *data) { @@ -663,6 +723,8 @@ tree_forget (void *data) tree_remove_entry (tree, tree->selected_ptr->name); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_copy (WTree * tree, const char *default_dest) { @@ -695,6 +757,8 @@ tree_copy (WTree * tree, const char *default_dest) g_free (dest); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move (WTree * tree, const char *default_dest) { @@ -743,6 +807,8 @@ tree_move (WTree * tree, const char *default_dest) g_free (dest); } +/* --------------------------------------------------------------------------------------------- */ + #if 0 static void tree_mkdir (WTree * tree) @@ -763,6 +829,8 @@ tree_mkdir (WTree * tree) } #endif +/* --------------------------------------------------------------------------------------------- */ + static void tree_rmdir (void *data) { @@ -795,6 +863,8 @@ tree_rmdir (void *data) file_op_context_destroy (ctx); } +/* --------------------------------------------------------------------------------------------- */ + static inline void tree_move_up (WTree * tree) { @@ -803,6 +873,8 @@ tree_move_up (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static inline void tree_move_down (WTree * tree) { @@ -811,6 +883,8 @@ tree_move_down (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static inline void tree_move_home (WTree * tree) { @@ -819,6 +893,8 @@ tree_move_home (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static inline void tree_move_end (WTree * tree) { @@ -827,6 +903,8 @@ tree_move_end (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_pgup (WTree * tree) { @@ -835,6 +913,8 @@ tree_move_pgup (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static void tree_move_pgdn (WTree * tree) { @@ -843,6 +923,8 @@ tree_move_pgdn (WTree * tree) maybe_chdir (tree); } +/* --------------------------------------------------------------------------------------------- */ + static gboolean tree_move_left (WTree * tree) { @@ -858,6 +940,8 @@ tree_move_left (WTree * tree) return v; } +/* --------------------------------------------------------------------------------------------- */ + static gboolean tree_move_right (WTree * tree) { @@ -874,6 +958,8 @@ tree_move_right (WTree * tree) return v; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_start_search (WTree * tree) { @@ -904,6 +990,8 @@ tree_start_search (WTree * tree) } } +/* --------------------------------------------------------------------------------------------- */ + static void tree_toggle_navig (WTree * tree) { @@ -913,6 +1001,8 @@ tree_toggle_navig (WTree * tree) : Q_ ("ButtonBar|Dynamc"), tree_map, (Widget *) tree); } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t tree_execute_cmd (WTree * tree, unsigned long command) { @@ -977,6 +1067,8 @@ tree_execute_cmd (WTree * tree, unsigned long command) return res; } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t tree_key (WTree * tree, int key) { @@ -1030,6 +1122,8 @@ tree_key (WTree * tree, int key) return MSG_NOT_HANDLED; } +/* --------------------------------------------------------------------------------------------- */ + static void tree_frame (Dlg_head * h, WTree * tree) { @@ -1042,19 +1136,21 @@ tree_frame (Dlg_head * h, WTree * tree) draw_box (h, tree->widget.y, tree->widget.x, tree->widget.lines, tree->widget.cols, FALSE); - widget_move (&tree->widget, 0, (tree->widget.cols - len - 2)/2); + widget_move (&tree->widget, 0, (tree->widget.cols - len - 2) / 2); tty_printf (" %s ", title); if (show_mini_info) widget_move (&tree->widget, tlines (tree) + 1, 0); - tty_print_alt_char (ACS_LTEE, FALSE); - widget_move (&tree->widget, tlines (tree) + 1, tree->widget.cols - 1); - tty_print_alt_char (ACS_RTEE, FALSE); - tty_draw_hline (tree->widget.y + tlines (tree) + 1, - tree->widget.x + 1, ACS_HLINE, tree->widget.cols - 2); + tty_print_alt_char (ACS_LTEE, FALSE); + widget_move (&tree->widget, tlines (tree) + 1, tree->widget.cols - 1); + tty_print_alt_char (ACS_RTEE, FALSE); + tty_draw_hline (tree->widget.y + tlines (tree) + 1, + tree->widget.x + 1, ACS_HLINE, tree->widget.cols - 2); } } +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t tree_callback (Widget * w, widget_msg_t msg, int parm) { @@ -1117,6 +1213,10 @@ tree_callback (Widget * w, widget_msg_t msg, int parm) } } +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + WTree * tree_new (int y, int x, int lines, int cols, gboolean is_panel) { @@ -1140,6 +1240,8 @@ tree_new (int y, int x, int lines, int cols, gboolean is_panel) return tree; } +/* --------------------------------------------------------------------------------------------- */ + void tree_chdir (WTree * tree, const char *dir) { @@ -1154,21 +1256,29 @@ tree_chdir (WTree * tree, const char *dir) } } -/* Return name of the currently selected entry */ +/* --------------------------------------------------------------------------------------------- */ +/** Return name of the currently selected entry */ + char * tree_selected_name (const WTree * tree) { return tree->selected_ptr->name; } +/* --------------------------------------------------------------------------------------------- */ + void sync_tree (const char *path) { tree_chdir (the_tree, path); } +/* --------------------------------------------------------------------------------------------- */ + WTree * find_tree (struct Dlg_head *h) { return (WTree *) find_widget_type (h, tree_callback); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/tree.h b/src/tree.h index 58a20a3d2..93c50d883 100644 --- a/src/tree.h +++ b/src/tree.h @@ -1,27 +1,37 @@ - /** \file tree.h * \brief Header: directory tree browser */ -#ifndef MC_TREE_H -#define MC_TREE_H +#ifndef MC__TREE_H +#define MC__TREE_H #include "lib/global.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + typedef struct WTree WTree; +/*** global variables defined in .c file *********************************************************/ + extern WTree *the_tree; extern int xtree_mode; +struct Dlg_head; + +/*** declarations of public functions ************************************************************/ + WTree *tree_new (int y, int x, int lines, int cols, gboolean is_panel); -void tree_chdir (WTree *tree, const char *dir); -char *tree_selected_name (const WTree *tree); +void tree_chdir (WTree * tree, const char *dir); +char *tree_selected_name (const WTree * tree); void sync_tree (const char *pathname); -struct Dlg_head; - WTree *find_tree (struct Dlg_head *h); -#endif /* MC_TREE_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__TREE_H */ diff --git a/src/treestore.c b/src/treestore.c index bc477c8fb..b79bbf91b 100644 --- a/src/treestore.c +++ b/src/treestore.c @@ -56,13 +56,26 @@ #include "treestore.h" #include "setup.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define TREE_SIGNATURE "Midnight Commander TreeStore v 2.0" +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + static struct TreeStore ts; +static hook_t *remove_entry_hooks; + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + static tree_entry *tree_store_add_entry (const char *name); -static hook_t *remove_entry_hooks; +/* --------------------------------------------------------------------------------------------- */ static void tree_store_dirty (int state) @@ -70,7 +83,9 @@ tree_store_dirty (int state) ts.dirty = state; } -/* Returns the number of common bytes in the strings. */ +/* --------------------------------------------------------------------------------------------- */ +/** Returns the number of common bytes in the strings. */ + static size_t str_common (const char *s1, const char *s2) { @@ -81,6 +96,7 @@ str_common (const char *s1, const char *s2) return result; } +/* --------------------------------------------------------------------------------------------- */ /* The directory names are arranged in a single linked list in the same order as they are displayed. When the tree is displayed the expected order is like this: @@ -102,6 +118,7 @@ str_common (const char *s1, const char *s2) greater than zero if p1 is found to be less than, to match, or be greater than p2. */ + static int pathcmp (const char *p1, const char *p2) { @@ -120,27 +137,7 @@ pathcmp (const char *p1, const char *p2) return (*p1 - *p2); } -/* Searches for specified directory */ -tree_entry * -tree_store_whereis (const char *name) -{ - tree_entry *current = ts.tree_first; - int flag = -1; - - while (current && (flag = pathcmp (current->name, name)) < 0) - current = current->next; - - if (flag == 0) - return current; - else - return NULL; -} - -struct TreeStore * -tree_store_get (void) -{ - return &ts; -} +/* --------------------------------------------------------------------------------------------- */ static char * decode (char *buffer) @@ -179,7 +176,9 @@ decode (char *buffer) return res; } -/* Loads the tree store from the specified filename */ +/* --------------------------------------------------------------------------------------------- */ +/** Loads the tree store from the specified filename */ + static int tree_store_load_from (char *name) { @@ -283,23 +282,7 @@ tree_store_load_from (char *name) return TRUE; } -/** - * \fn int tree_store_load(void) - * \brief Loads the tree from the default location - * \return 1 if success (true), 0 otherwise (false) - */ -int -tree_store_load (void) -{ - char *name; - int retval; - - name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); - retval = tree_store_load_from (name); - g_free (name); - - return retval; -} +/* --------------------------------------------------------------------------------------------- */ static char * encode (const char *string) @@ -341,7 +324,9 @@ encode (const char *string) return res; } -/* Saves the tree to the specified filename */ +/* --------------------------------------------------------------------------------------------- */ +/** Saves the tree to the specified filename */ + static int tree_store_save_to (char *name) { @@ -392,32 +377,7 @@ tree_store_save_to (char *name) return 0; } -/** - * \fn int tree_store_save(void) - * \brief Saves the tree to the default file in an atomic fashion - * \return 0 if success, errno on error - */ -int -tree_store_save (void) -{ - char *name; - int retval; - - name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); - mc_util_make_backup_if_possible (name, ".tmp"); - - retval = tree_store_save_to (name); - if (retval != 0) - { - mc_util_restore_from_backup_if_possible (name, ".tmp"); - g_free (name); - return retval; - } - - mc_util_unlink_backup_if_possible (name, ".tmp"); - g_free (name); - return 0; -} +/* --------------------------------------------------------------------------------------------- */ static tree_entry * tree_store_add_entry (const char *name) @@ -530,17 +490,7 @@ tree_store_add_entry (const char *name) return new; } -void -tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data) -{ - add_hook (&remove_entry_hooks, (void (*)(void *)) callback, data); -} - -void -tree_store_remove_entry_remove_hook (tree_store_remove_fn callback) -{ - delete_hook (&remove_entry_hooks, (void (*)(void *)) callback); -} +/* --------------------------------------------------------------------------------------------- */ static void tree_store_notify_remove (tree_entry * entry) @@ -556,6 +506,8 @@ tree_store_notify_remove (tree_entry * entry) } } +/* --------------------------------------------------------------------------------------------- */ + static tree_entry * remove_entry (tree_entry * entry) { @@ -594,6 +546,153 @@ remove_entry (tree_entry * entry) return ret; } +/* --------------------------------------------------------------------------------------------- */ + +static void +process_special_dirs (GList ** special_dirs, char *file) +{ + gchar **buffers, **start_buff; + mc_config_t *cfg; + gsize buffers_len; + + cfg = mc_config_init (file); + if (cfg == NULL) + return; + + start_buff = buffers = mc_config_get_string_list (cfg, "Special dirs", "list", &buffers_len); + if (buffers != NULL) + { + while (*buffers != NULL) + { + *special_dirs = g_list_prepend (*special_dirs, *buffers); + *buffers = NULL; + buffers++; + } + g_strfreev (start_buff); + } + mc_config_deinit (cfg); +} + +/* --------------------------------------------------------------------------------------------- */ + +static gboolean +should_skip_directory (const char *dir) +{ + static GList *special_dirs = NULL; + GList *l; + static gboolean loaded = FALSE; + + if (!loaded) + { + loaded = TRUE; + setup_init (); + process_special_dirs (&special_dirs, profile_name); + process_special_dirs (&special_dirs, global_profile_name); + } + + for (l = special_dirs; l != NULL; l = g_list_next (l)) + if (strncmp (dir, l->data, strlen (l->data)) == 0) + return TRUE; + + return FALSE; +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* Searches for specified directory */ +tree_entry * +tree_store_whereis (const char *name) +{ + tree_entry *current = ts.tree_first; + int flag = -1; + + while (current && (flag = pathcmp (current->name, name)) < 0) + current = current->next; + + if (flag == 0) + return current; + else + return NULL; +} + +/* --------------------------------------------------------------------------------------------- */ + +struct TreeStore * +tree_store_get (void) +{ + return &ts; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * \fn int tree_store_load(void) + * \brief Loads the tree from the default location + * \return 1 if success (true), 0 otherwise (false) + */ + +int +tree_store_load (void) +{ + char *name; + int retval; + + name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); + retval = tree_store_load_from (name); + g_free (name); + + return retval; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * \fn int tree_store_save(void) + * \brief Saves the tree to the default file in an atomic fashion + * \return 0 if success, errno on error + */ + +int +tree_store_save (void) +{ + char *name; + int retval; + + name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); + mc_util_make_backup_if_possible (name, ".tmp"); + + retval = tree_store_save_to (name); + if (retval != 0) + { + mc_util_restore_from_backup_if_possible (name, ".tmp"); + g_free (name); + return retval; + } + + mc_util_unlink_backup_if_possible (name, ".tmp"); + g_free (name); + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data) +{ + add_hook (&remove_entry_hooks, (void (*)(void *)) callback, data); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +tree_store_remove_entry_remove_hook (tree_store_remove_fn callback) +{ + delete_hook (&remove_entry_hooks, (void (*)(void *)) callback); +} + + +/* --------------------------------------------------------------------------------------------- */ + void tree_store_remove_entry (const char *name) { @@ -627,7 +726,9 @@ tree_store_remove_entry (const char *name) return; } -/* This subdirectory exists -> clear deletion mark */ +/* --------------------------------------------------------------------------------------------- */ +/** This subdirectory exists -> clear deletion mark */ + void tree_store_mark_checked (const char *subname) { @@ -678,7 +779,9 @@ tree_store_mark_checked (const char *subname) } } -/* Mark the subdirectories of the current directory for delete */ +/* --------------------------------------------------------------------------------------------- */ +/** Mark the subdirectories of the current directory for delete */ + tree_entry * tree_store_start_check (const char *path) { @@ -729,7 +832,9 @@ tree_store_start_check (const char *path) return retval; } -/* Delete subdirectories which still have the deletion mark */ +/* --------------------------------------------------------------------------------------------- */ +/** Delete subdirectories which still have the deletion mark */ + void tree_store_end_check (void) { @@ -767,52 +872,7 @@ tree_store_end_check (void) g_list_free (the_queue); } -static void -process_special_dirs (GList ** special_dirs, char *file) -{ - gchar **buffers, **start_buff; - mc_config_t *cfg; - gsize buffers_len; - - cfg = mc_config_init (file); - if (cfg == NULL) - return; - - start_buff = buffers = mc_config_get_string_list (cfg, "Special dirs", "list", &buffers_len); - if (buffers != NULL) - { - while (*buffers != NULL) - { - *special_dirs = g_list_prepend (*special_dirs, *buffers); - *buffers = NULL; - buffers++; - } - g_strfreev (start_buff); - } - mc_config_deinit (cfg); -} - -static gboolean -should_skip_directory (const char *dir) -{ - static GList *special_dirs = NULL; - GList *l; - static gboolean loaded = FALSE; - - if (!loaded) - { - loaded = TRUE; - setup_init (); - process_special_dirs (&special_dirs, profile_name); - process_special_dirs (&special_dirs, global_profile_name); - } - - for (l = special_dirs; l != NULL; l = g_list_next (l)) - if (strncmp (dir, l->data, strlen (l->data)) == 0) - return TRUE; - - return FALSE; -} +/* --------------------------------------------------------------------------------------------- */ tree_entry * tree_store_rescan (const char *dir) @@ -863,3 +923,5 @@ tree_store_rescan (const char *dir) return entry; } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/treestore.h b/src/treestore.h index bc9a677bb..9cdf16038 100644 --- a/src/treestore.h +++ b/src/treestore.h @@ -1,34 +1,51 @@ - /** \file treestore.h * \brief Header: tree store * * Contains a storage of the file system tree representation. */ -#ifndef MC_TREE_STORE_H -#define MC_TREE_STORE_H +#ifndef MC__TREE_STORE_H +#define MC__TREE_STORE_H -typedef struct tree_entry { - char *name; /* The full path of directory */ - int sublevel; /* Number of parent directories (slashes) */ - long submask; /* Bitmask of existing sublevels after this entry */ - const char *subname; /* The last part of name (the actual name) */ - unsigned int mark:1; /* Flag: Is this entry marked (e. g. for delete)? */ - unsigned int scanned:1; /* Flag: childs scanned or not */ - struct tree_entry *next; /* Next item in the list */ - struct tree_entry *prev; /* Previous item in the list */ +/*** typedefs(not structures) and defined constants **********************************************/ + +/* + * Register/unregister notification functions for "entry_remove" + */ +struct tree_entry; +typedef void (*tree_store_remove_fn) (struct tree_entry * tree, void *data); + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef struct tree_entry +{ + char *name; /* The full path of directory */ + int sublevel; /* Number of parent directories (slashes) */ + long submask; /* Bitmask of existing sublevels after this entry */ + const char *subname; /* The last part of name (the actual name) */ + unsigned int mark:1; /* Flag: Is this entry marked (e. g. for delete)? */ + unsigned int scanned:1; /* Flag: childs scanned or not */ + struct tree_entry *next; /* Next item in the list */ + struct tree_entry *prev; /* Previous item in the list */ } tree_entry; -struct TreeStore { - tree_entry *tree_first; /* First entry in the list */ - tree_entry *tree_last; /* Last entry in the list */ - tree_entry *check_start; /* Start of checked subdirectories */ +struct TreeStore +{ + tree_entry *tree_first; /* First entry in the list */ + tree_entry *tree_last; /* Last entry in the list */ + tree_entry *check_start; /* Start of checked subdirectories */ char *check_name; - GList *add_queue; /* List of strings of added directories */ + GList *add_queue; /* List of strings of added directories */ unsigned int loaded:1; unsigned int dirty:1; }; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + struct TreeStore *tree_store_get (void); int tree_store_load (void); int tree_store_save (void); @@ -39,12 +56,8 @@ void tree_store_end_check (void); tree_entry *tree_store_whereis (const char *name); tree_entry *tree_store_rescan (const char *dir); -/* - * Register/unregister notification functions for "entry_remove" - */ -typedef void (*tree_store_remove_fn) (tree_entry *tree, void *data); -void tree_store_add_entry_remove_hook (tree_store_remove_fn callback, - void *data); +void tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data); void tree_store_remove_entry_remove_hook (tree_store_remove_fn callback); -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__TREE_STORE_H */ diff --git a/src/user.c b/src/user.c index 6374f218e..a82ebe6ec 100644 --- a/src/user.c +++ b/src/user.c @@ -52,13 +52,536 @@ #include "widget.h" #include "wtools.h" +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + #define MAX_ENTRIES 16 #define MAX_ENTRY_LEN 60 +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + static int debug_flag = 0; static int debug_error = 0; static char *menu = NULL; +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** strip file's extension */ +static char * +strip_ext (char *ss) +{ + register char *s = ss; + char *e = NULL; + while (*s) + { + if (*s == '.') + e = s; + if (*s == PATH_SEP && e) + e = NULL; /* '.' in *directory* name */ + s++; + } + if (e) + *e = 0; + return ss; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * 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. + */ + +static char * +check_patterns (char *p) +{ + static const char def_name[] = "shell_patterns="; + char *p0 = p; + + if (strncmp (p, def_name, sizeof (def_name) - 1) != 0) + return p0; + + p += sizeof (def_name) - 1; + if (*p == '1') + easy_patterns = 1; + else if (*p == '0') + easy_patterns = 0; + else + return p0; + + /* Skip spaces */ + p++; + while (*p == '\n' || *p == '\t' || *p == ' ') + p++; + return p; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Copies a whitespace separated argument from p to arg. Returns the + point after argument. */ + +static char * +extract_arg (char *p, char *arg, int size) +{ + char *np; + + while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) + p++; + /* support quote space .mnu */ + while (*p && (*p != ' ' || *(p - 1) == '\\') && *p != '\t' && *p != '\n') + { + np = str_get_next_char (p); + if (np - p >= size) + break; + memcpy (arg, p, np - p); + arg += np - p; + size -= np - p; + p = np; + } + *arg = 0; + if (!*p || *p == '\n') + str_prev_char (&p); + return p; +} + +/* --------------------------------------------------------------------------------------------- */ +/* Tests whether the selected file in the panel is of any of the types + specified in argument. */ + +static int +test_type (WPanel * panel, char *arg) +{ + int result = 0; /* False by default */ + int st_mode = panel->dir.list[panel->selected].st.st_mode; + + for (; *arg != 0; arg++) + { + switch (*arg) + { + 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 */ + result |= (st_mode & 0111) ? 1 : 0; + break; + case 't': + result |= panel->marked ? 1 : 0; + break; + default: + debug_error = 1; + break; + } + } + return result; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Calculates the truth value of the next condition starting from + p. Returns the point after condition. */ + +static char * +test_condition (WEdit * edit_widget, char *p, int *condition) +{ + WPanel *panel; + char arg[256]; + mc_search_type_t search_type; + + if (easy_patterns) + { + search_type = MC_SEARCH_T_GLOB; + } + else + { + search_type = MC_SEARCH_T_REGEX; + } + + /* Handle one condition */ + for (; *p != '\n' && *p != '&' && *p != '|'; p++) + { + /* support quote space .mnu */ + if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') + continue; + if (*p >= 'a') + panel = current_panel; + else + { + if (get_other_type () == view_listing) + panel = other_panel; + else + panel = NULL; + } + *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)); + *condition = panel + && mc_search (arg, panel->dir.list[panel->selected].fname, search_type); + break; + case 'y': /* syntax pattern */ +#ifdef USE_INTERNAL_EDIT + if (edit_widget) + { + const char *syntax_type = edit_get_syntax_type (edit_widget); + if (syntax_type != NULL) + { + p = extract_arg (p, arg, sizeof (arg)); + *condition = panel && mc_search (arg, syntax_type, MC_SEARCH_T_NORMAL); + } + } +#endif + break; + case 'd': + p = extract_arg (p, arg, sizeof (arg)); + *condition = panel && mc_search (arg, panel->cwd, search_type); + break; + case 't': + p = extract_arg (p, arg, sizeof (arg)); + *condition = panel && test_type (panel, arg); + break; + case 'x': /* executable */ + { + struct stat status; + + p = extract_arg (p, arg, sizeof (arg)); + if (stat (arg, &status) == 0) + *condition = is_exe (status.st_mode); + else + *condition = 0; + break; + } + default: + debug_error = 1; + break; + } /* switch */ + + } /* while */ + return p; +} + +/* --------------------------------------------------------------------------------------------- */ +/** General purpose condition debug output handler */ + +static void +debug_out (char *start, char *end, int cond) +{ + static char *msg; + int len; + + if (start == NULL && end == NULL) + { + /* Show output */ + if (debug_flag && msg) + { + len = strlen (msg); + if (len) + msg[len - 1] = 0; + message (D_NORMAL, _("Debug"), "%s", msg); + + } + debug_flag = 0; + g_free (msg); + msg = NULL; + } + 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:"); + debug_error = 0; + } + else if (cond) + 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; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/** Calculates the truth value of one lineful of conditions. Returns + the point just before the end of line. */ + +static char * +test_line (WEdit * edit_widget, char *p, int *result) +{ + int condition; + char operator; + char *debug_start, *debug_end; + + /* Repeat till end of line */ + while (*p && *p != '\n') + { + /* support quote space .mnu */ + while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') + p++; + if (!*p || *p == '\n') + break; + operator = *p++; + if (*p == '?') + { + debug_flag = 1; + p++; + } + /* support quote space .mnu */ + while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') + p++; + if (!*p || *p == '\n') + break; + condition = 1; /* True by default */ + + 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 */ + *result &= condition; + break; + case '|': /* Logical or */ + *result |= condition; + break; + default: + debug_error = 1; + break; + } /* switch */ + /* Add one debug statement */ + debug_out (&operator, NULL, *result); + + } /* while (*p != '\n') */ + /* Report debug message */ + debug_out (NULL, NULL, 1); + + if (!*p || *p == '\n') + str_prev_char (&p); + return p; +} + +/* --------------------------------------------------------------------------------------------- */ +/** FIXME: recode this routine on version 3.0, it could be cleaner */ + +static void +execute_menu_command (WEdit * edit_widget, const char *commands) +{ + FILE *cmd_file; + int cmd_file_fd; + int expand_prefix_found = 0; + char *parameter = 0; + gboolean do_quote = FALSE; + char lc_prompt[80]; + int col; + char *file_name; + int run_view = 0; + + /* Skip menu entry title line */ + commands = strchr (commands, '\n'); + if (!commands) + { + return; + } + + cmd_file_fd = mc_mkstemps (&file_name, "mcusr", SCRIPT_SUFFIX); + + if (cmd_file_fd == -1) + { + message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"), + unix_error_string (errno)); + return; + } + cmd_file = fdopen (cmd_file_fd, "w"); + fputs ("#! /bin/sh\n", cmd_file); + commands++; + + for (col = 0; *commands; commands++) + { + if (col == 0) + { + if (*commands != ' ' && *commands != '\t') + break; + while (*commands == ' ' || *commands == '\t') + commands++; + if (*commands == 0) + break; + } + col++; + if (*commands == '\n') + col = 0; + if (parameter) + { + if (*commands == '}') + { + char *tmp; + *parameter = 0; + parameter = + input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, ""); + if (!parameter || !*parameter) + { + /* User canceled */ + fclose (cmd_file); + unlink (file_name); + g_free (file_name); + return; + } + if (do_quote) + { + tmp = name_quote (parameter, 0); + fputs (tmp, cmd_file); + g_free (tmp); + } + else + fputs (parameter, cmd_file); + g_free (parameter); + parameter = 0; + } + else + { + if (parameter < &lc_prompt[sizeof (lc_prompt) - 1]) + { + *parameter++ = *commands; + } + } + } + else if (expand_prefix_found) + { + expand_prefix_found = 0; + if (g_ascii_isdigit ((gchar) * commands)) + { + do_quote = (atoi (commands) != 0); + while (g_ascii_isdigit ((gchar) * commands)) + commands++; + } + if (*commands == '{') + parameter = lc_prompt; + else + { + char *text = expand_format (edit_widget, *commands, do_quote); + fputs (text, cmd_file); + g_free (text); + } + } + else + { + if (*commands == '%') + { + int i = check_format_view (commands + 1); + if (i) + { + commands += i; + run_view = 1; + } + else + { + do_quote = TRUE; /* Default: Quote expanded macro */ + expand_prefix_found = 1; + } + } + else + fputc (*commands, cmd_file); + } + } + fclose (cmd_file); + chmod (file_name, S_IRWXU); + if (run_view) + { + mcview_viewer (file_name, NULL, 0); + dialog_switch_process_pending (); + } + else + { + /* execute the command indirectly to allow execution even + * on no-exec filesystems. */ + char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); + shell_execute (cmd, EXECUTE_HIDE); + g_free (cmd); + } + unlink (file_name); + g_free (file_name); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + ** 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)? + */ + +static int +menu_file_own (char *path) +{ + struct stat st; + + if (stat (path, &st) == 0 + && (!st.st_uid || (st.st_uid == geteuid ())) && ((st.st_mode & (S_IWGRP | S_IWOTH)) == 0)) + { + return 1; + } + 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); + } + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /* Formats defined: %% The % character %f The current file (if non-local vfs, file will be copied locally and @@ -124,15 +647,19 @@ check_format_view (const char *p) return 0; } +/* --------------------------------------------------------------------------------------------- */ + int check_format_cd (const char *p) { return (strncmp (p, "cd", 2)) ? 0 : 3; } +/* --------------------------------------------------------------------------------------------- */ /* 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) { @@ -178,24 +705,7 @@ check_format_var (const char *p, char **v) return 0; } -/* strip file's extension */ -static char * -strip_ext (char *ss) -{ - register char *s = ss; - char *e = NULL; - while (*s) - { - if (*s == '.') - e = s; - if (*s == PATH_SEP && e) - e = NULL; /* '.' in *directory* name */ - s++; - } - if (e) - *e = 0; - return ss; -} +/* --------------------------------------------------------------------------------------------- */ char * expand_format (struct WEdit *edit_widget, char c, gboolean do_quote) @@ -343,483 +853,12 @@ expand_format (struct WEdit *edit_widget, char c, gboolean do_quote) return result; } -/* - * 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. - */ -static char * -check_patterns (char *p) -{ - static const char def_name[] = "shell_patterns="; - char *p0 = p; - - if (strncmp (p, def_name, sizeof (def_name) - 1) != 0) - return p0; - - p += sizeof (def_name) - 1; - if (*p == '1') - easy_patterns = 1; - else if (*p == '0') - easy_patterns = 0; - else - return p0; - - /* Skip spaces */ - p++; - while (*p == '\n' || *p == '\t' || *p == ' ') - p++; - return p; -} - -/* Copies a whitespace separated argument from p to arg. Returns the - point after argument. */ -static char * -extract_arg (char *p, char *arg, int size) -{ - char *np; - - while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) - p++; - /* support quote space .mnu */ - while (*p && (*p != ' ' || *(p - 1) == '\\') && *p != '\t' && *p != '\n') - { - np = str_get_next_char (p); - if (np - p >= size) - break; - memcpy (arg, p, np - p); - arg += np - p; - size -= np - p; - p = np; - } - *arg = 0; - if (!*p || *p == '\n') - str_prev_char (&p); - return p; -} - -/* Tests whether the selected file in the panel is of any of the types - specified in argument. */ -static int -test_type (WPanel * panel, char *arg) -{ - int result = 0; /* False by default */ - int st_mode = panel->dir.list[panel->selected].st.st_mode; - - for (; *arg != 0; arg++) - { - switch (*arg) - { - 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 */ - result |= (st_mode & 0111) ? 1 : 0; - break; - case 't': - result |= panel->marked ? 1 : 0; - break; - default: - debug_error = 1; - break; - } - } - return result; -} - -/* Calculates the truth value of the next condition starting from - p. Returns the point after condition. */ -static char * -test_condition (WEdit * edit_widget, char *p, int *condition) -{ - WPanel *panel; - char arg[256]; - mc_search_type_t search_type; - - if (easy_patterns) - { - search_type = MC_SEARCH_T_GLOB; - } - else - { - search_type = MC_SEARCH_T_REGEX; - } - - /* Handle one condition */ - for (; *p != '\n' && *p != '&' && *p != '|'; p++) - { - /* support quote space .mnu */ - if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') - continue; - if (*p >= 'a') - panel = current_panel; - else - { - if (get_other_type () == view_listing) - panel = other_panel; - else - panel = NULL; - } - *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)); - *condition = panel - && mc_search (arg, panel->dir.list[panel->selected].fname, search_type); - break; - case 'y': /* syntax pattern */ -#ifdef USE_INTERNAL_EDIT - if (edit_widget) - { - const char *syntax_type = edit_get_syntax_type (edit_widget); - if (syntax_type != NULL) - { - p = extract_arg (p, arg, sizeof (arg)); - *condition = panel && mc_search (arg, syntax_type, MC_SEARCH_T_NORMAL); - } - } -#endif - break; - case 'd': - p = extract_arg (p, arg, sizeof (arg)); - *condition = panel && mc_search (arg, panel->cwd, search_type); - break; - case 't': - p = extract_arg (p, arg, sizeof (arg)); - *condition = panel && test_type (panel, arg); - break; - case 'x': /* executable */ - { - struct stat status; - - p = extract_arg (p, arg, sizeof (arg)); - if (stat (arg, &status) == 0) - *condition = is_exe (status.st_mode); - else - *condition = 0; - break; - } - default: - debug_error = 1; - break; - } /* switch */ - - } /* while */ - return p; -} - -/* General purpose condition debug output handler */ -static void -debug_out (char *start, char *end, int cond) -{ - static char *msg; - int len; - - if (start == NULL && end == NULL) - { - /* Show output */ - if (debug_flag && msg) - { - len = strlen (msg); - if (len) - msg[len - 1] = 0; - message (D_NORMAL, _("Debug"), "%s", msg); - - } - debug_flag = 0; - g_free (msg); - msg = NULL; - } - 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:"); - debug_error = 0; - } - else if (cond) - 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; - } -} - -/* Calculates the truth value of one lineful of conditions. Returns - the point just before the end of line. */ -static char * -test_line (WEdit * edit_widget, char *p, int *result) -{ - int condition; - char operator; - char *debug_start, *debug_end; - - /* Repeat till end of line */ - while (*p && *p != '\n') - { - /* support quote space .mnu */ - while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') - p++; - if (!*p || *p == '\n') - break; - operator = *p++; - if (*p == '?') - { - debug_flag = 1; - p++; - } - /* support quote space .mnu */ - while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') - p++; - if (!*p || *p == '\n') - break; - condition = 1; /* True by default */ - - 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 */ - *result &= condition; - break; - case '|': /* Logical or */ - *result |= condition; - break; - default: - debug_error = 1; - break; - } /* switch */ - /* Add one debug statement */ - debug_out (&operator, NULL, *result); - - } /* while (*p != '\n') */ - /* Report debug message */ - debug_out (NULL, NULL, 1); - - if (!*p || *p == '\n') - str_prev_char (&p); - return p; -} - -/* FIXME: recode this routine on version 3.0, it could be cleaner */ -static void -execute_menu_command (WEdit * edit_widget, const char *commands) -{ - FILE *cmd_file; - int cmd_file_fd; - int expand_prefix_found = 0; - char *parameter = 0; - gboolean do_quote = FALSE; - char lc_prompt[80]; - int col; - char *file_name; - int run_view = 0; - - /* Skip menu entry title line */ - commands = strchr (commands, '\n'); - if (!commands) - { - return; - } - - cmd_file_fd = mc_mkstemps (&file_name, "mcusr", SCRIPT_SUFFIX); - - if (cmd_file_fd == -1) - { - message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"), - unix_error_string (errno)); - return; - } - cmd_file = fdopen (cmd_file_fd, "w"); - fputs ("#! /bin/sh\n", cmd_file); - commands++; - - for (col = 0; *commands; commands++) - { - if (col == 0) - { - if (*commands != ' ' && *commands != '\t') - break; - while (*commands == ' ' || *commands == '\t') - commands++; - if (*commands == 0) - break; - } - col++; - if (*commands == '\n') - col = 0; - if (parameter) - { - if (*commands == '}') - { - char *tmp; - *parameter = 0; - parameter = - input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, ""); - if (!parameter || !*parameter) - { - /* User canceled */ - fclose (cmd_file); - unlink (file_name); - g_free (file_name); - return; - } - if (do_quote) - { - tmp = name_quote (parameter, 0); - fputs (tmp, cmd_file); - g_free (tmp); - } - else - fputs (parameter, cmd_file); - g_free (parameter); - parameter = 0; - } - else - { - if (parameter < &lc_prompt[sizeof (lc_prompt) - 1]) - { - *parameter++ = *commands; - } - } - } - else if (expand_prefix_found) - { - expand_prefix_found = 0; - if (g_ascii_isdigit ((gchar) * commands)) - { - do_quote = (atoi (commands) != 0); - while (g_ascii_isdigit ((gchar) * commands)) - commands++; - } - if (*commands == '{') - parameter = lc_prompt; - else - { - char *text = expand_format (edit_widget, *commands, do_quote); - fputs (text, cmd_file); - g_free (text); - } - } - else - { - if (*commands == '%') - { - int i = check_format_view (commands + 1); - if (i) - { - commands += i; - run_view = 1; - } - else - { - do_quote = TRUE; /* Default: Quote expanded macro */ - expand_prefix_found = 1; - } - } - else - fputc (*commands, cmd_file); - } - } - fclose (cmd_file); - chmod (file_name, S_IRWXU); - if (run_view) - { - mcview_viewer (file_name, NULL, 0); - dialog_switch_process_pending (); - } - else - { - /* execute the command indirectly to allow execution even - * on no-exec filesystems. */ - char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); - shell_execute (cmd, EXECUTE_HIDE); - g_free (cmd); - } - unlink (file_name); - g_free (file_name); -} - -/* - ** 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)? - */ -static int -menu_file_own (char *path) -{ - struct stat st; - - if (stat (path, &st) == 0 - && (!st.st_uid || (st.st_uid == geteuid ())) && ((st.st_mode & (S_IWGRP | S_IWOTH)) == 0)) - { - return 1; - } - 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); - } - return 0; -} - -/* +/* --------------------------------------------------------------------------------------------- */ +/** * If edit_widget is NULL then we are called from the mc menu, * otherwise we are called from the mcedit menu. */ + void user_menu_cmd (struct WEdit *edit_widget) { @@ -992,3 +1031,5 @@ user_menu_cmd (struct WEdit *edit_widget) g_free (entries); g_free (data); } + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/user.h b/src/user.h index 8a7c09083..283700fa4 100644 --- a/src/user.h +++ b/src/user.h @@ -1,19 +1,29 @@ - /** \file user.h * \brief Header: user menu implementation */ -#ifndef MC_USER_H -#define MC_USER_H +#ifndef MC__USER_H +#define MC__USER_H #include "lib/global.h" +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + struct WEdit; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + void user_menu_cmd (struct WEdit *edit_widget); char *expand_format (struct WEdit *edit_widget, char c, gboolean do_quote); int check_format_view (const char *); int check_format_var (const char *, char **); int check_format_cd (const char *); -#endif /* MC_USER_H */ +/*** inline functions ****************************************************************************/ +#endif /* MC__USER_H */ diff --git a/src/wtools.c b/src/wtools.c index a0219c475..31d82a7a3 100644 --- a/src/wtools.c +++ b/src/wtools.c @@ -44,92 +44,23 @@ #include "wtools.h" #include "background.h" /* parent_call */ +/*** global variables ****************************************************************************/ -Listbox * -create_listbox_window_centered (int center_y, int center_x, int lines, int cols, - const char *title, const char *help) -{ - const dlg_colors_t listbox_colors = { - MENU_ENTRY_COLOR, - MENU_SELECTED_COLOR, - MENU_HOT_COLOR, - MENU_HOTSEL_COLOR, - COLOR_TITLE - }; +/*** file scope macro definitions ****************************************************************/ - const int space = 4; +/*** file scope type declarations ****************************************************************/ - int xpos, ypos, len; - Listbox *listbox; +/*** file scope variables ************************************************************************/ - /* Adjust sizes */ - lines = min (lines, LINES - 6); +static Dlg_head *last_query_dlg; - if (title != NULL) - { - len = str_term_width1 (title) + 4; - cols = max (cols, len); - } +static int sel_pos = 0; - cols = min (cols, COLS - 6); +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ - /* adjust position */ - if ((center_y < 0) || (center_x < 0)) - { - ypos = LINES / 2; - xpos = COLS / 2; - } - else - { - ypos = center_y; - xpos = center_x; - } +/** default query callback, used to reposition query */ - ypos -= lines / 2; - xpos -= cols / 2; - - if (ypos + lines >= LINES) - ypos = LINES - lines - space; - if (ypos < 0) - ypos = 0; - - if (xpos + cols >= COLS) - xpos = COLS - cols - space; - if (xpos < 0) - xpos = 0; - - listbox = g_new (Listbox, 1); - - listbox->dlg = - create_dlg (TRUE, ypos, xpos, lines + space, cols + space, - listbox_colors, NULL, help, title, DLG_REVERSE | DLG_TRYUP); - - listbox->list = listbox_new (2, 2, lines, cols, FALSE, NULL); - add_widget (listbox->dlg, listbox->list); - - return listbox; -} - -Listbox * -create_listbox_window (int lines, int cols, const char *title, const char *help) -{ - return create_listbox_window_centered (-1, -1, lines, cols, title, help); -} - -/* Returns the number of the item selected */ -int -run_listbox (Listbox * l) -{ - int val = -1; - - if (run_dlg (l->dlg) != B_CANCEL) - val = l->list->pos; - destroy_dlg (l->dlg); - g_free (l); - return val; -} - -/* default query callback, used to reposition query */ static cb_ret_t default_query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { @@ -150,110 +81,9 @@ default_query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, } } -static Dlg_head *last_query_dlg; +/* --------------------------------------------------------------------------------------------- */ +/** Create message dialog */ -static int sel_pos = 0; - -/* Used to ask questions to the user */ -int -query_dialog (const char *header, const char *text, int flags, int count, ...) -{ - va_list ap; - Dlg_head *query_dlg; - WButton *button; - WButton *defbutton = NULL; - int win_len = 0; - int i; - int result = -1; - int cols, lines; - char *cur_name; - const int *query_colors = (flags & D_ERROR) ? alarm_colors : dialog_colors; - - if (header == MSG_ERROR) - header = _("Error"); - - if (count > 0) - { - va_start (ap, count); - for (i = 0; i < count; i++) - { - char *cp = va_arg (ap, char *); - win_len += str_term_width1 (cp) + 6; - if (strchr (cp, '&') != NULL) - win_len--; - } - va_end (ap); - } - - /* count coordinates */ - str_msg_term_size (text, &lines, &cols); - cols = 6 + max (win_len, max (str_term_width1 (header), cols)); - lines += 4 + (count > 0 ? 2 : 0); - - /* prepare dialog */ - query_dlg = - create_dlg (TRUE, 0, 0, lines, cols, query_colors, default_query_callback, - "[QueryBox]", header, DLG_NONE); - - if (count > 0) - { - cols = (cols - win_len - 2) / 2 + 2; - va_start (ap, count); - for (i = 0; i < count; i++) - { - int xpos; - - cur_name = va_arg (ap, char *); - xpos = str_term_width1 (cur_name) + 6; - if (strchr (cur_name, '&') != NULL) - xpos--; - - button = button_new (lines - 3, cols, B_USER + i, NORMAL_BUTTON, cur_name, 0); - add_widget (query_dlg, button); - cols += xpos; - if (i == sel_pos) - defbutton = button; - } - va_end (ap); - - add_widget (query_dlg, label_new (2, 3, text)); - - /* do resize before running and selecting any widget */ - default_query_callback (query_dlg, NULL, DLG_RESIZE, 0, NULL); - - if (defbutton) - dlg_select_widget (defbutton); - - /* run dialog and make result */ - switch (run_dlg (query_dlg)) - { - case B_CANCEL: - break; - default: - result = query_dlg->ret_value - B_USER; - } - - /* free used memory */ - destroy_dlg (query_dlg); - } - else - { - add_widget (query_dlg, label_new (2, 3, text)); - add_widget (query_dlg, button_new (0, 0, 0, HIDDEN_BUTTON, "-", 0)); - last_query_dlg = query_dlg; - } - sel_pos = 0; - return result; -} - -void -query_set_sel (int new_sel) -{ - sel_pos = new_sel; -} - - -/* Create message dialog */ static struct Dlg_head * do_create_message (int flags, const char *title, const char *text) { @@ -274,33 +104,12 @@ do_create_message (int flags, const char *title, const char *text) return d; } - -/* - * Create message dialog. The caller must call dlg_run_done() and - * destroy_dlg() to dismiss it. Not safe to call from background. - */ -struct Dlg_head * -create_message (int flags, const char *title, const char *text, ...) -{ - va_list args; - Dlg_head *d; - char *p; - - va_start (args, text); - p = g_strdup_vprintf (text, args); - va_end (args); - - d = do_create_message (flags, title, p); - g_free (p); - - return d; -} - - -/* +/* --------------------------------------------------------------------------------------------- */ +/** * Show message dialog. Dismiss it when any key is pressed. * Not safe to call from background. */ + static void fg_message (int flags, const char *title, const char *text) { @@ -313,7 +122,9 @@ fg_message (int flags, const char *title, const char *text) } -/* Show message box from background */ +/* --------------------------------------------------------------------------------------------- */ +/** Show message box from background */ + #ifdef WITH_BACKGROUND static void bg_message (int dummy, int *flags, char *title, const char *text) @@ -325,201 +136,11 @@ bg_message (int dummy, int *flags, char *title, const char *text) } #endif /* WITH_BACKGROUND */ - -/* Show message box, background safe */ -void -message (int flags, const char *title, const char *text, ...) -{ - char *p; - va_list ap; - union - { - void *p; - void (*f) (int, int *, char *, const char *); - } func; - - va_start (ap, text); - p = g_strdup_vprintf (text, ap); - va_end (ap); - - if (title == MSG_ERROR) - title = _("Error"); - -#ifdef WITH_BACKGROUND - if (we_are_background) - { - func.f = bg_message; - parent_call (func.p, NULL, 3, sizeof (flags), &flags, strlen (title), title, strlen (p), p); - } - else -#endif /* WITH_BACKGROUND */ - fg_message (flags, title, p); - - g_free (p); -} - - -/* {{{ Quick dialog routines */ - - -int -quick_dialog_skip (QuickDialog * qd, int nskip) -{ -#ifdef ENABLE_NLS -#define I18N(x) (x = !qd->i18n && x && *x ? _(x): x) -#else -#define I18N(x) (x = x) -#endif - Dlg_head *dd; - QuickWidget *qw; - WInput *in; - WRadio *r; - int return_val; - - I18N (qd->title); - - if ((qd->xpos == -1) || (qd->ypos == -1)) - dd = create_dlg (TRUE, 0, 0, qd->ylen, qd->xlen, - dialog_colors, qd->callback, qd->help, qd->title, - DLG_CENTER | DLG_TRYUP | DLG_REVERSE); - else - dd = create_dlg (TRUE, qd->ypos, qd->xpos, qd->ylen, qd->xlen, - dialog_colors, qd->callback, qd->help, qd->title, DLG_REVERSE); - - for (qw = qd->widgets; qw->widget_type != quick_end; qw++) - { - int xpos; - int ypos; - - xpos = (qd->xlen * qw->relative_x) / qw->x_divisions; - ypos = (qd->ylen * qw->relative_y) / qw->y_divisions; - - switch (qw->widget_type) - { - case quick_checkbox: - qw->widget = - (Widget *) check_new (ypos, xpos, *qw->u.checkbox.state, - I18N (qw->u.checkbox.text)); - break; - - case quick_button: - qw->widget = (Widget *) button_new (ypos, xpos, qw->u.button.action, - (qw->u.button.action == - B_ENTER) ? DEFPUSH_BUTTON : NORMAL_BUTTON, - I18N (qw->u.button.text), qw->u.button.callback); - break; - - case quick_input: - in = input_new (ypos, xpos, input_get_default_colors(), - qw->u.input.len, qw->u.input.text, qw->u.input.histname, - INPUT_COMPLETE_DEFAULT); - in->is_password = (qw->u.input.flags == 1); - if ((qw->u.input.flags & 2) != 0) - in->completion_flags |= INPUT_COMPLETE_CD; - qw->widget = (Widget *) in; - *qw->u.input.result = NULL; - break; - - case quick_label: - qw->widget = (Widget *) label_new (ypos, xpos, I18N (qw->u.label.text)); - break; - - case quick_groupbox: - qw->widget = (Widget *) groupbox_new (ypos, xpos, - qw->u.groupbox.height, - qw->u.groupbox.width, - I18N (qw->u.groupbox.title)); - break; - - case quick_radio: - { - int i; - char **items = NULL; - - /* create the copy of radio_items to avoid mwmory leak */ - items = g_new0 (char *, qw->u.radio.count + 1); - - if (!qd->i18n) - for (i = 0; i < qw->u.radio.count; i++) - items[i] = g_strdup (_(qw->u.radio.items[i])); - else - for (i = 0; i < qw->u.radio.count; i++) - items[i] = g_strdup (qw->u.radio.items[i]); - - r = radio_new (ypos, xpos, qw->u.radio.count, (const char **) items); - r->pos = r->sel = *qw->u.radio.value; - qw->widget = (Widget *) r; - g_strfreev (items); - break; - } - - default: - qw->widget = NULL; - fprintf (stderr, "QuickWidget: unknown widget type\n"); - break; - } - - if (qw->widget != NULL) - { - qw->widget->options |= qw->options; /* FIXME: cannot reset flags, setup only */ - add_widget (dd, qw->widget); - } - } - - while (nskip-- != 0) - { - dd->current = g_list_next (dd->current); - if (dd->current == NULL) - dd->current = dd->widgets; - } - - return_val = run_dlg (dd); - - /* Get the data if we found something interesting */ - if (return_val != B_CANCEL) - { - for (qw = qd->widgets; qw->widget_type != quick_end; qw++) - { - switch (qw->widget_type) - { - case quick_checkbox: - *qw->u.checkbox.state = ((WCheck *) qw->widget)->state & C_BOOL; - break; - - case quick_input: - if ((qw->u.input.flags & 2) != 0) - *qw->u.input.result = tilde_expand (((WInput *) qw->widget)->buffer); - else - *qw->u.input.result = g_strdup (((WInput *) qw->widget)->buffer); - break; - - case quick_radio: - *qw->u.radio.value = ((WRadio *) qw->widget)->sel; - break; - - default: - break; - } - } - } - - destroy_dlg (dd); - - return return_val; -#undef I18N -} - -int -quick_dialog (QuickDialog * qd) -{ - return quick_dialog_skip (qd, 0); -} - -/* }}} */ - /* {{{ Input routines */ -/* +/* --------------------------------------------------------------------------------------------- */ + +/** * Show dialog, not background safe. * * If the arguments "header" and "text" should be translated, @@ -618,12 +239,432 @@ fg_input_dialog_help (const char *header, const char *text, const char *help, return (ret != B_CANCEL) ? my_str : NULL; } -/* +/* }}} */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +Listbox * +create_listbox_window_centered (int center_y, int center_x, int lines, int cols, + const char *title, const char *help) +{ + const dlg_colors_t listbox_colors = { + MENU_ENTRY_COLOR, + MENU_SELECTED_COLOR, + MENU_HOT_COLOR, + MENU_HOTSEL_COLOR, + COLOR_TITLE + }; + + const int space = 4; + + int xpos, ypos, len; + Listbox *listbox; + + /* Adjust sizes */ + lines = min (lines, LINES - 6); + + if (title != NULL) + { + len = str_term_width1 (title) + 4; + cols = max (cols, len); + } + + cols = min (cols, COLS - 6); + + /* adjust position */ + if ((center_y < 0) || (center_x < 0)) + { + ypos = LINES / 2; + xpos = COLS / 2; + } + else + { + ypos = center_y; + xpos = center_x; + } + + ypos -= lines / 2; + xpos -= cols / 2; + + if (ypos + lines >= LINES) + ypos = LINES - lines - space; + if (ypos < 0) + ypos = 0; + + if (xpos + cols >= COLS) + xpos = COLS - cols - space; + if (xpos < 0) + xpos = 0; + + listbox = g_new (Listbox, 1); + + listbox->dlg = + create_dlg (TRUE, ypos, xpos, lines + space, cols + space, + listbox_colors, NULL, help, title, DLG_REVERSE | DLG_TRYUP); + + listbox->list = listbox_new (2, 2, lines, cols, FALSE, NULL); + add_widget (listbox->dlg, listbox->list); + + return listbox; +} + +/* --------------------------------------------------------------------------------------------- */ + +Listbox * +create_listbox_window (int lines, int cols, const char *title, const char *help) +{ + return create_listbox_window_centered (-1, -1, lines, cols, title, help); +} + +/* --------------------------------------------------------------------------------------------- */ +/** Returns the number of the item selected */ + +int +run_listbox (Listbox * l) +{ + int val = -1; + + if (run_dlg (l->dlg) != B_CANCEL) + val = l->list->pos; + destroy_dlg (l->dlg); + g_free (l); + return val; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Used to ask questions to the user */ + +int +query_dialog (const char *header, const char *text, int flags, int count, ...) +{ + va_list ap; + Dlg_head *query_dlg; + WButton *button; + WButton *defbutton = NULL; + int win_len = 0; + int i; + int result = -1; + int cols, lines; + char *cur_name; + const int *query_colors = (flags & D_ERROR) ? alarm_colors : dialog_colors; + + if (header == MSG_ERROR) + header = _("Error"); + + if (count > 0) + { + va_start (ap, count); + for (i = 0; i < count; i++) + { + char *cp = va_arg (ap, char *); + win_len += str_term_width1 (cp) + 6; + if (strchr (cp, '&') != NULL) + win_len--; + } + va_end (ap); + } + + /* count coordinates */ + str_msg_term_size (text, &lines, &cols); + cols = 6 + max (win_len, max (str_term_width1 (header), cols)); + lines += 4 + (count > 0 ? 2 : 0); + + /* prepare dialog */ + query_dlg = + create_dlg (TRUE, 0, 0, lines, cols, query_colors, default_query_callback, + "[QueryBox]", header, DLG_NONE); + + if (count > 0) + { + cols = (cols - win_len - 2) / 2 + 2; + va_start (ap, count); + for (i = 0; i < count; i++) + { + int xpos; + + cur_name = va_arg (ap, char *); + xpos = str_term_width1 (cur_name) + 6; + if (strchr (cur_name, '&') != NULL) + xpos--; + + button = button_new (lines - 3, cols, B_USER + i, NORMAL_BUTTON, cur_name, 0); + add_widget (query_dlg, button); + cols += xpos; + if (i == sel_pos) + defbutton = button; + } + va_end (ap); + + add_widget (query_dlg, label_new (2, 3, text)); + + /* do resize before running and selecting any widget */ + default_query_callback (query_dlg, NULL, DLG_RESIZE, 0, NULL); + + if (defbutton) + dlg_select_widget (defbutton); + + /* run dialog and make result */ + switch (run_dlg (query_dlg)) + { + case B_CANCEL: + break; + default: + result = query_dlg->ret_value - B_USER; + } + + /* free used memory */ + destroy_dlg (query_dlg); + } + else + { + add_widget (query_dlg, label_new (2, 3, text)); + add_widget (query_dlg, button_new (0, 0, 0, HIDDEN_BUTTON, "-", 0)); + last_query_dlg = query_dlg; + } + sel_pos = 0; + return result; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +query_set_sel (int new_sel) +{ + sel_pos = new_sel; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Create message dialog. The caller must call dlg_run_done() and + * destroy_dlg() to dismiss it. Not safe to call from background. + */ + +struct Dlg_head * +create_message (int flags, const char *title, const char *text, ...) +{ + va_list args; + Dlg_head *d; + char *p; + + va_start (args, text); + p = g_strdup_vprintf (text, args); + va_end (args); + + d = do_create_message (flags, title, p); + g_free (p); + + return d; +} + +/* --------------------------------------------------------------------------------------------- */ +/** Show message box, background safe */ + +void +message (int flags, const char *title, const char *text, ...) +{ + char *p; + va_list ap; + union + { + void *p; + void (*f) (int, int *, char *, const char *); + } func; + + va_start (ap, text); + p = g_strdup_vprintf (text, ap); + va_end (ap); + + if (title == MSG_ERROR) + title = _("Error"); + +#ifdef WITH_BACKGROUND + if (we_are_background) + { + func.f = bg_message; + parent_call (func.p, NULL, 3, sizeof (flags), &flags, strlen (title), title, strlen (p), p); + } + else +#endif /* WITH_BACKGROUND */ + fg_message (flags, title, p); + + g_free (p); +} + + +/* {{{ Quick dialog routines */ + + +/* --------------------------------------------------------------------------------------------- */ + +int +quick_dialog_skip (QuickDialog * qd, int nskip) +{ +#ifdef ENABLE_NLS +#define I18N(x) (x = !qd->i18n && x && *x ? _(x): x) +#else +#define I18N(x) (x = x) +#endif + Dlg_head *dd; + QuickWidget *qw; + WInput *in; + WRadio *r; + int return_val; + + I18N (qd->title); + + if ((qd->xpos == -1) || (qd->ypos == -1)) + dd = create_dlg (TRUE, 0, 0, qd->ylen, qd->xlen, + dialog_colors, qd->callback, qd->help, qd->title, + DLG_CENTER | DLG_TRYUP | DLG_REVERSE); + else + dd = create_dlg (TRUE, qd->ypos, qd->xpos, qd->ylen, qd->xlen, + dialog_colors, qd->callback, qd->help, qd->title, DLG_REVERSE); + + for (qw = qd->widgets; qw->widget_type != quick_end; qw++) + { + int xpos; + int ypos; + + xpos = (qd->xlen * qw->relative_x) / qw->x_divisions; + ypos = (qd->ylen * qw->relative_y) / qw->y_divisions; + + switch (qw->widget_type) + { + case quick_checkbox: + qw->widget = + (Widget *) check_new (ypos, xpos, *qw->u.checkbox.state, + I18N (qw->u.checkbox.text)); + break; + + case quick_button: + qw->widget = (Widget *) button_new (ypos, xpos, qw->u.button.action, + (qw->u.button.action == + B_ENTER) ? DEFPUSH_BUTTON : NORMAL_BUTTON, + I18N (qw->u.button.text), qw->u.button.callback); + break; + + case quick_input: + in = input_new (ypos, xpos, input_get_default_colors (), + qw->u.input.len, qw->u.input.text, qw->u.input.histname, + INPUT_COMPLETE_DEFAULT); + in->is_password = (qw->u.input.flags == 1); + if ((qw->u.input.flags & 2) != 0) + in->completion_flags |= INPUT_COMPLETE_CD; + qw->widget = (Widget *) in; + *qw->u.input.result = NULL; + break; + + case quick_label: + qw->widget = (Widget *) label_new (ypos, xpos, I18N (qw->u.label.text)); + break; + + case quick_groupbox: + qw->widget = (Widget *) groupbox_new (ypos, xpos, + qw->u.groupbox.height, + qw->u.groupbox.width, + I18N (qw->u.groupbox.title)); + break; + + case quick_radio: + { + int i; + char **items = NULL; + + /* create the copy of radio_items to avoid mwmory leak */ + items = g_new0 (char *, qw->u.radio.count + 1); + + if (!qd->i18n) + for (i = 0; i < qw->u.radio.count; i++) + items[i] = g_strdup (_(qw->u.radio.items[i])); + else + for (i = 0; i < qw->u.radio.count; i++) + items[i] = g_strdup (qw->u.radio.items[i]); + + r = radio_new (ypos, xpos, qw->u.radio.count, (const char **) items); + r->pos = r->sel = *qw->u.radio.value; + qw->widget = (Widget *) r; + g_strfreev (items); + break; + } + + default: + qw->widget = NULL; + fprintf (stderr, "QuickWidget: unknown widget type\n"); + break; + } + + if (qw->widget != NULL) + { + qw->widget->options |= qw->options; /* FIXME: cannot reset flags, setup only */ + add_widget (dd, qw->widget); + } + } + + while (nskip-- != 0) + { + dd->current = g_list_next (dd->current); + if (dd->current == NULL) + dd->current = dd->widgets; + } + + return_val = run_dlg (dd); + + /* Get the data if we found something interesting */ + if (return_val != B_CANCEL) + { + for (qw = qd->widgets; qw->widget_type != quick_end; qw++) + { + switch (qw->widget_type) + { + case quick_checkbox: + *qw->u.checkbox.state = ((WCheck *) qw->widget)->state & C_BOOL; + break; + + case quick_input: + if ((qw->u.input.flags & 2) != 0) + *qw->u.input.result = tilde_expand (((WInput *) qw->widget)->buffer); + else + *qw->u.input.result = g_strdup (((WInput *) qw->widget)->buffer); + break; + + case quick_radio: + *qw->u.radio.value = ((WRadio *) qw->widget)->sel; + break; + + default: + break; + } + } + } + + destroy_dlg (dd); + + return return_val; +#undef I18N +} + +/* --------------------------------------------------------------------------------------------- */ + +int +quick_dialog (QuickDialog * qd) +{ + return quick_dialog_skip (qd, 0); +} + +/* }}} */ + +/* {{{ Input routines */ + +/* --------------------------------------------------------------------------------------------- */ +/** * Show input dialog, background safe. * * If the arguments "header" and "text" should be translated, * that MUST be done by the caller of these wrappers. */ + char * input_dialog_help (const char *header, const char *text, const char *help, const char *history_name, const char *def_text) @@ -648,13 +689,17 @@ input_dialog_help (const char *header, const char *text, const char *help, return fg_input_dialog_help (header, text, help, history_name, def_text); } -/* Show input dialog with default help, background safe */ +/* --------------------------------------------------------------------------------------------- */ +/** Show input dialog with default help, background safe */ + char * input_dialog (const char *header, const char *text, const char *history_name, const char *def_text) { return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text); } +/* --------------------------------------------------------------------------------------------- */ + char * input_expand_dialog (const char *header, const char *text, const char *history_name, const char *def_text) @@ -672,6 +717,8 @@ input_expand_dialog (const char *header, const char *text, return result; } +/* --------------------------------------------------------------------------------------------- */ + /* }}} */ /* }}} */ diff --git a/src/wtools.h b/src/wtools.h index 047532f95..247d82f1d 100644 --- a/src/wtools.h +++ b/src/wtools.h @@ -1,101 +1,19 @@ - /** \file wtools.h * \brief Header: widget based utility functions */ -#ifndef MC_WTOOLS_H -#define MC_WTOOLS_H +#ifndef MC__WTOOLS_H +#define MC__WTOOLS_H #include "lib/global.h" #include "dialog.h" #include "widget.h" -typedef struct -{ - struct Dlg_head *dlg; - struct WListbox *list; -} Listbox; +/*** typedefs(not structures) and defined constants **********************************************/ -/* Listbox utility functions */ -Listbox *create_listbox_window_centered (int center_y, int center_x, int lines, int cols, - const char *title, const char *help); -Listbox *create_listbox_window (int lines, int cols, const char *title, const char *help); #define LISTBOX_APPEND_TEXT(l,h,t,d) \ listbox_add_item (l->list, LISTBOX_APPEND_AT_END, h, t, d) -int run_listbox (Listbox * l); - -/* Quick Widgets */ -typedef enum -{ - quick_end = 0, - quick_checkbox = 1, - quick_button = 2, - quick_input = 3, - quick_label = 4, - quick_radio = 5, - quick_groupbox = 6 -} quick_t; - -/* The widget is placed on relative_?/divisions_? of the parent widget */ -typedef struct -{ - quick_t widget_type; - - int relative_x; - int x_divisions; - int relative_y; - int y_divisions; - - Widget *widget; - widget_options_t options; - - /* widget parameters */ - union - { - struct - { - const char *text; - int *state; /* in/out */ - } checkbox; - - struct - { - const char *text; - int action; - bcback callback; - } button; - - struct - { - const char *text; - int len; - int flags; /* 1 -- is_password, 2 -- INPUT_COMPLETE_CD */ - const char *histname; - char **result; - } input; - - struct - { - const char *text; - } label; - - struct - { - int count; - const char **items; - int *value; /* in/out */ - } radio; - - struct - { - int width; - int height; - const char *title; - } groupbox; - } u; -} QuickWidget; - #define QUICK_CHECKBOX(x, xdiv, y, ydiv, txt, st) \ { \ .widget_type = quick_checkbox, \ @@ -223,6 +141,100 @@ typedef struct } \ } +/* Pass this as def_text to request a password */ +#define INPUT_PASSWORD ((char *) -1) + +/* Use this as header for message() - it expands to "Error" */ +#define MSG_ERROR ((char *) -1) + +/*** enums ***************************************************************************************/ + +/* Quick Widgets */ +typedef enum +{ + quick_end = 0, + quick_checkbox = 1, + quick_button = 2, + quick_input = 3, + quick_label = 4, + quick_radio = 5, + quick_groupbox = 6 +} quick_t; + +/* flags for message() and query_dialog() */ +enum +{ + D_NORMAL = 0, + D_ERROR = 1 +} /* dialog options */ ; + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef struct +{ + struct Dlg_head *dlg; + struct WListbox *list; +} Listbox; + +/* The widget is placed on relative_?/divisions_? of the parent widget */ +typedef struct +{ + quick_t widget_type; + + int relative_x; + int x_divisions; + int relative_y; + int y_divisions; + + Widget *widget; + widget_options_t options; + + /* widget parameters */ + union + { + struct + { + const char *text; + int *state; /* in/out */ + } checkbox; + + struct + { + const char *text; + int action; + bcback callback; + } button; + + struct + { + const char *text; + int len; + int flags; /* 1 -- is_password, 2 -- INPUT_COMPLETE_CD */ + const char *histname; + char **result; + } input; + + struct + { + const char *text; + } label; + + struct + { + int count; + const char **items; + int *value; /* in/out */ + } radio; + + struct + { + int width; + int height; + const char *title; + } groupbox; + } u; +} QuickWidget; + typedef struct { int xlen, ylen; @@ -234,14 +246,22 @@ typedef struct gboolean i18n; /* If true, internationalization has happened */ } QuickDialog; +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +/* Listbox utility functions */ +Listbox *create_listbox_window_centered (int center_y, int center_x, int lines, int cols, + const char *title, const char *help); +Listbox *create_listbox_window (int lines, int cols, const char *title, const char *help); + +int run_listbox (Listbox * l); + int quick_dialog (QuickDialog * qd); int quick_dialog_skip (QuickDialog * qd, int nskip); /* The input dialogs */ -/* Pass this as def_text to request a password */ -#define INPUT_PASSWORD ((char *) -1) - char *input_dialog (const char *header, const char *text, const char *history_name, const char *def_text); char *input_dialog_help (const char *header, const char *text, const char *help, @@ -259,17 +279,7 @@ struct Dlg_head *create_message (int flags, const char *title, void message (int flags, const char *title, const char *text, ...) __attribute__ ((format (__printf__, 3, 4))); - -/* Use this as header for message() - it expands to "Error" */ -#define MSG_ERROR ((char *) -1) - int query_dialog (const char *header, const char *text, int flags, int count, ...); -/* flags for message() and query_dialog() */ -enum -{ - D_NORMAL = 0, - D_ERROR = 1 -} /* dialog options */ ; - -#endif +/*** inline functions ****************************************************************************/ +#endif /* MC__WTOOLS_H */