コード例 #1
0
ファイル: layout.c プロジェクト: m32/mc
void
layout_box (void)
{
    WDialog *layout_dlg;

    old_layout = panels_layout;
    old_output_lines = output_lines;
    layout_dlg = init_layout ();

    if (dlg_run (layout_dlg) == B_ENTER)
    {
        size_t i;

        for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
            if (check_options[i].widget != NULL)
                *check_options[i].variable = check_options[i].widget->state & C_BOOL;
    }
    else
    {
        /* restore layout */
        panels_layout = old_layout;
        output_lines = old_output_lines;
        update_split (layout_dlg);
    }

    dlg_destroy (layout_dlg);
    layout_change ();
    do_refresh ();
}
コード例 #2
0
ファイル: layout.c プロジェクト: GalaxyTab4/workbench
void
layout_box (void)
{
    WDialog *layout_dlg;
    gboolean layout_do_change = FALSE;

    layout_dlg = init_layout ();

    if (dlg_run (layout_dlg) == B_ENTER)
    {
        size_t i;

        for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
            if (check_options[i].widget != NULL)
                *check_options[i].variable = check_options[i].widget->state & C_BOOL;

        panels_layout.horizontal_split = radio_widget->sel;
        if (panels_layout.horizontal_split)
        {
            panels_layout.horizontal_equal = *check_options[0].variable;
            panels_layout.top_panel_size = _panels_layout.top_panel_size;
        }
        else
        {
            panels_layout.vertical_equal = *check_options[0].variable;
            panels_layout.left_panel_size = _panels_layout.left_panel_size;
        }
        output_lines = _output_lines;
        layout_do_change = TRUE;
    }

    dlg_destroy (layout_dlg);
    if (layout_do_change)
        layout_change ();
}
コード例 #3
0
ファイル: editwidget.c プロジェクト: BpArCuCTeMbI/mc
gboolean
edit_files (const GList * files)
{
    static gboolean made_directory = FALSE;
    WDialog *edit_dlg;
    WMenuBar *menubar;
    const GList *file;
    gboolean ok = FALSE;

    if (!made_directory)
    {
        char *dir;

        dir = mc_build_filename (mc_config_get_cache_path (), EDIT_DIR, NULL);
        made_directory = (mkdir (dir, 0700) != -1 || errno == EEXIST);
        g_free (dir);

        dir = mc_build_filename (mc_config_get_path (), EDIT_DIR, NULL);
        made_directory = (mkdir (dir, 0700) != -1 || errno == EEXIST);
        g_free (dir);

        dir = mc_build_filename (mc_config_get_data_path (), EDIT_DIR, NULL);
        made_directory = (mkdir (dir, 0700) != -1 || errno == EEXIST);
        g_free (dir);
    }

    /* Create a new dialog and add it widgets to it */
    edit_dlg =
        dlg_create (FALSE, 0, 0, LINES, COLS, NULL, edit_dialog_callback, edit_dialog_event,
                    "[Internal File Editor]", NULL, DLG_WANT_TAB);

    edit_dlg->get_shortcut = edit_get_shortcut;
    edit_dlg->get_title = edit_get_title;

    menubar = menubar_new (0, 0, COLS, NULL, TRUE);
    add_widget (edit_dlg, menubar);
    edit_init_menu (menubar);

    add_widget (edit_dlg, buttonbar_new (TRUE));

    for (file = files; file != NULL; file = g_list_next (file))
    {
        Widget *w = WIDGET (edit_dlg);
        mcedit_arg_t *f = (mcedit_arg_t *) file->data;
        gboolean f_ok;

        f_ok = edit_add_window (edit_dlg, w->y + 1, w->x, w->lines - 2, w->cols, f->file_vpath,
                                f->line_number);
        /* at least one file has been opened succefully */
        ok = ok || f_ok;
    }

    if (ok)
        dlg_run (edit_dlg);

    if (!ok || edit_dlg->state == DLG_CLOSED)
        dlg_destroy (edit_dlg);

    return ok;
}
コード例 #4
0
ファイル: boxes.c プロジェクト: andi5/mc
static int
sel_skin_button (WButton * button, int action)
{
    int result;
    WListbox *skin_list;
    WDialog *skin_dlg;
    const gchar *skin_name;
    int lxx, lyy;
    unsigned int i;
    unsigned int pos = 1;

    (void) action;

    lxx = COLS / 2;
    lyy = (LINES - 13) / 2;
    skin_dlg =
        dlg_create (TRUE, lyy, lxx, 13, 24, dialog_colors, NULL, NULL, "[Appearance]", _("Skins"),
                    DLG_COMPACT);

    skin_list = listbox_new (1, 1, 11, 22, FALSE, NULL);
    skin_name = "default";
    listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
                      (void *) skin_name);

    if (strcmp (skin_name, current_skin_name) == 0)
        listbox_select_entry (skin_list, 0);

    for (i = 0; i < skin_names->len; i++)
    {
        skin_name = g_ptr_array_index (skin_names, i);
        if (strcmp (skin_name, "default") != 0)
        {
            listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
                              (void *) skin_name);
            if (strcmp (skin_name, current_skin_name) == 0)
                listbox_select_entry (skin_list, pos);
            pos++;
        }
    }

    add_widget (skin_dlg, skin_list);

    result = dlg_run (skin_dlg);
    if (result == B_ENTER)
    {
        Widget *w;
        gchar *skin_label;

        listbox_get_current (skin_list, &skin_label, (void **) &skin_name);
        g_free (current_skin_name);
        current_skin_name = g_strdup (skin_name);
        skin_apply (skin_name);

        w = dlg_find_by_id (WIDGET (button)->owner, skin_name_id);
        button_set_text (BUTTON (w), str_fit_to_term (skin_label, 20, J_LEFT_FIT));
    }
    dlg_destroy (skin_dlg);

    return 0;
}
コード例 #5
0
ファイル: boxes.c プロジェクト: ActionLuzifer/mc
char *
tree_box (const char *current_dir)
{
    WTree *mytree;
    WDialog *dlg;
    Widget *wd;
    char *val = NULL;
    WButtonBar *bar;

    (void) current_dir;

    /* Create the components */
    dlg = dlg_create (TRUE, 0, 0, LINES - 9, COLS - 20, dialog_colors, tree_callback, NULL,
                      "[Directory Tree]", _("Directory tree"), DLG_CENTER);
    wd = WIDGET (dlg);

    mytree = tree_new (2, 2, wd->lines - 6, wd->cols - 5, FALSE);
    add_widget_autopos (dlg, mytree, WPOS_KEEP_ALL, NULL);
    add_widget_autopos (dlg, hline_new (wd->lines - 4, 1, -1), WPOS_KEEP_BOTTOM, NULL);
    bar = buttonbar_new (TRUE);
    add_widget (dlg, bar);
    /* restore ButtonBar coordinates after add_widget() */
    WIDGET (bar)->x = 0;
    WIDGET (bar)->y = LINES - 1;

    if (dlg_run (dlg) == B_ENTER)
    {
        const vfs_path_t *selected_name;
        selected_name = tree_selected_name (mytree);
        val = g_strdup (vfs_path_as_str (selected_name));
    }

    dlg_destroy (dlg);
    return val;
}
コード例 #6
0
ファイル: mcviewer.c プロジェクト: CTU-OSP/mc
gboolean
mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line)
{
    gboolean succeeded;
    mcview_t *lc_mcview;
    WDialog *view_dlg;

    /* Create dialog and widgets, put them on the dialog */
    view_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, NULL, mcview_dialog_callback, NULL,
                           "[Internal File Viewer]", NULL, DLG_WANT_TAB);

    lc_mcview = mcview_new (0, 0, LINES - 1, COLS, FALSE);
    add_widget (view_dlg, lc_mcview);

    add_widget (view_dlg, buttonbar_new (TRUE));

    view_dlg->get_title = mcview_get_title;

    succeeded = mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line);

    if (succeeded)
        dlg_run (view_dlg);
    else
        view_dlg->state = DLG_CLOSED;

    if (view_dlg->state == DLG_CLOSED)
        dlg_destroy (view_dlg);

    return succeeded;
}
コード例 #7
0
ファイル: mcviewer.c プロジェクト: Kafkamorph/mc
gboolean
mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line,
               off_t search_start, off_t search_end)
{
    gboolean succeeded;
    WView *lc_mcview;
    WDialog *view_dlg;

    /* Create dialog and widgets, put them on the dialog */
    view_dlg = dlg_create (FALSE, 0, 0, 1, 1, WPOS_FULLSCREEN, FALSE, NULL, mcview_dialog_callback,
                           NULL, "[Internal File Viewer]", NULL);
    widget_want_tab (WIDGET (view_dlg), TRUE);

    lc_mcview = mcview_new (0, 0, LINES - 1, COLS, FALSE);
    add_widget (view_dlg, lc_mcview);

    add_widget (view_dlg, buttonbar_new (TRUE));

    view_dlg->get_title = mcview_get_title;

    succeeded =
        mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line, search_start,
                     search_end);

    if (succeeded)
        dlg_run (view_dlg);
    else
        dlg_stop (view_dlg);

    if (widget_get_state (WIDGET (view_dlg), WST_CLOSED))
        dlg_destroy (view_dlg);

    return succeeded;
}
コード例 #8
0
ファイル: editcmd_dialogs.c プロジェクト: Acidburn0zzz/mc
int
editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean cancel)
{
    int w, wq;
    int y = 2;
    WDialog *raw_dlg;

    w = str_term_width1 (heading) + 6;
    wq = str_term_width1 (query);
    w = MAX (w, wq + 3 * 2 + 1 + 2);

    raw_dlg =
        dlg_create (TRUE, 0, 0, cancel ? 7 : 5, w, WPOS_CENTER | WPOS_TRYUP, FALSE, dialog_colors,
                    editcmd_dialog_raw_key_query_cb, NULL, NULL, heading);
    widget_want_tab (WIDGET (raw_dlg), TRUE);

    add_widget (raw_dlg, label_new (y, 3, query));
    add_widget (raw_dlg, input_new (y++, 3 + wq + 1, input_colors,
                                    w - (6 + wq + 1), "", 0, INPUT_COMPLETE_NONE));
    if (cancel)
    {
        add_widget (raw_dlg, hline_new (y++, -1, -1));
        /* Button w/o hotkey to allow use any key as raw or macro one */
        add_widget_autopos (raw_dlg, button_new (y, 1, B_CANCEL, NORMAL_BUTTON, _("Cancel"), NULL),
                            WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
    }

    w = dlg_run (raw_dlg);
    dlg_destroy (raw_dlg);

    return (cancel && (w == ESC_CHAR || w == B_CANCEL)) ? 0 : w;
}
コード例 #9
0
ファイル: learn.c プロジェクト: MidnightCommander/mc
void
learn_keys (void)
{
    gboolean save_old_esc_mode = old_esc_mode;
    gboolean save_alternate_plus_minus = mc_global.tty.alternate_plus_minus;
    int result;

    /* old_esc_mode cannot work in learn keys dialog */
    old_esc_mode = 0;

    /* don't translate KP_ADD, KP_SUBTRACT and
       KP_MULTIPLY to '+', '-' and '*' in
       correct_key_code */
    mc_global.tty.alternate_plus_minus = TRUE;
    application_keypad_mode ();

    init_learn ();
    result = dlg_run (learn_dlg);

    old_esc_mode = save_old_esc_mode;
    mc_global.tty.alternate_plus_minus = save_alternate_plus_minus;

    if (!mc_global.tty.alternate_plus_minus)
        numeric_keypad_mode ();

    if (result == B_ENTER)
        learn_save ();

    learn_done ();
}
コード例 #10
0
ファイル: listmode.c プロジェクト: Distrotech/mc
/** Return new format or NULL if the user cancelled the dialog */
char *
listmode_edit (char *oldlistformat)
{
    char *newformat = NULL;
    char *s;
    WDialog *listmode_dlg;

    s = g_strdup (oldlistformat);
    listmode_dlg = init_listmode (s);
    g_free (s);

    if (dlg_run (listmode_dlg) == B_ENTER)
    {
        newformat = collect_new_format ();
    }

    listmode_done (listmode_dlg);
    return newformat;
}
コード例 #11
0
ファイル: editcmd_dialogs.c プロジェクト: Acidburn0zzz/mc
void
editcmd_dialog_select_definition_show (WEdit * edit, char *match_expr, int max_len, int word_len,
                                       etags_hash_t * def_hash, int num_lines)
{

    int start_x, start_y, offset, i;
    char *curr = NULL;
    etags_hash_t *curr_def = NULL;
    WDialog *def_dlg;
    WListbox *def_list;
    int def_dlg_h;              /* dialog height */
    int def_dlg_w;              /* dialog width */

    (void) word_len;
    /* calculate the dialog metrics */
    def_dlg_h = num_lines + 2;
    def_dlg_w = max_len + 4;
    start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2) +
        EDIT_TEXT_HORIZONTAL_OFFSET + (edit->fullscreen ? 0 : 1) + option_line_state_width;
    start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + (edit->fullscreen ? 0 : 1) + 1;

    if (start_x < 0)
        start_x = 0;
    if (def_dlg_w > COLS)
        def_dlg_w = COLS;
    if (def_dlg_h > LINES - 2)
        def_dlg_h = LINES - 2;

    offset = start_x + def_dlg_w - COLS;
    if (offset > 0)
        start_x -= offset;
    offset = start_y + def_dlg_h - LINES;
    if (offset > 0)
        start_y -= (offset + 1);

    /* create the dialog */
    def_dlg = dlg_create (TRUE, start_y, start_x, def_dlg_h, def_dlg_w, WPOS_KEEP_DEFAULT, TRUE,
                          dialog_colors, NULL, NULL, "[Definitions]", match_expr);

    /* create the listbox */
    def_list = listbox_new (1, 1, def_dlg_h - 2, def_dlg_w - 2, FALSE, NULL);

    /* add the dialog */
    add_widget (def_dlg, def_list);

    /* fill the listbox with the completions */
    for (i = 0; i < num_lines; i++)
    {
        char *label_def;

        label_def =
            g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename,
                             def_hash[i].line);
        listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i], FALSE);
        g_free (label_def);
    }

    /* pop up the dialog and apply the chosen completion */
    if (dlg_run (def_dlg) == B_ENTER)
    {
        char *tmp_curr_def = (char *) curr_def;
        int do_moveto = 0;

        listbox_get_current (def_list, &curr, (void **) &tmp_curr_def);
        curr_def = (etags_hash_t *) tmp_curr_def;
        if (edit->modified)
        {
            if (!edit_query_dialog2
                (_("Warning"),
                 _("Current text was modified without a file save.\n"
                   "Continue discards these changes."), _("C&ontinue"), _("&Cancel")))
            {
                edit->force |= REDRAW_COMPLETELY;
                do_moveto = 1;
            }
        }
        else
        {
            do_moveto = 1;
        }

        if (curr && do_moveto)
        {
            if (edit_stack_iterator + 1 < MAX_HISTORY_MOVETO)
            {
                vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath);
                if (edit->dir_vpath != NULL)
                {
                    edit_history_moveto[edit_stack_iterator].filename_vpath =
                        vfs_path_append_vpath_new (edit->dir_vpath, edit->filename_vpath, NULL);
                }
                else
                {
                    edit_history_moveto[edit_stack_iterator].filename_vpath =
                        vfs_path_clone (edit->filename_vpath);
                }
                edit_history_moveto[edit_stack_iterator].line = edit->start_line +
                    edit->curs_row + 1;
                edit_stack_iterator++;
                vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath);
                edit_history_moveto[edit_stack_iterator].filename_vpath =
                    vfs_path_from_str ((char *) curr_def->fullpath);
                edit_history_moveto[edit_stack_iterator].line = curr_def->line;
                edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath,
                                  edit_history_moveto[edit_stack_iterator].line);
            }
        }
    }

    /* clear definition hash */
    for (i = 0; i < MAX_DEFINITIONS; i++)
    {
        g_free (def_hash[i].filename);
    }

    /* destroy dialog before return */
    dlg_destroy (def_dlg);
}
コード例 #12
0
ファイル: editcmd_dialogs.c プロジェクト: Acidburn0zzz/mc
char *
editcmd_dialog_completion_show (const WEdit * edit, int max_len, GString ** compl, int num_compl)
{
    const Widget *we = CONST_WIDGET (edit);
    int start_x, start_y, offset, i;
    char *curr = NULL;
    WDialog *compl_dlg;
    WListbox *compl_list;
    int compl_dlg_h;            /* completion dialog height */
    int compl_dlg_w;            /* completion dialog width */

    /* calculate the dialog metrics */
    compl_dlg_h = num_compl + 2;
    compl_dlg_w = max_len + 4;
    start_x = we->x + edit->curs_col + edit->start_col + EDIT_TEXT_HORIZONTAL_OFFSET +
        (edit->fullscreen ? 0 : 1) + option_line_state_width;
    start_y = we->y + edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + (edit->fullscreen ? 0 : 1) + 1;

    if (start_x < 0)
        start_x = 0;
    if (start_x < we->x + 1)
        start_x = we->x + 1 + option_line_state_width;
    if (compl_dlg_w > COLS)
        compl_dlg_w = COLS;
    if (compl_dlg_h > LINES - 2)
        compl_dlg_h = LINES - 2;

    offset = start_x + compl_dlg_w - COLS;
    if (offset > 0)
        start_x -= offset;
    offset = start_y + compl_dlg_h - LINES;
    if (offset > 0)
        start_y -= offset;

    /* create the dialog */
    compl_dlg =
        dlg_create (TRUE, start_y, start_x, compl_dlg_h, compl_dlg_w, WPOS_KEEP_DEFAULT, TRUE,
                    dialog_colors, NULL, NULL, "[Completion]", NULL);

    /* create the listbox */
    compl_list = listbox_new (1, 1, compl_dlg_h - 2, compl_dlg_w - 2, FALSE, NULL);

    /* add the dialog */
    add_widget (compl_dlg, compl_list);

    /* fill the listbox with the completions */
    for (i = num_compl - 1; i >= 0; i--)        /* reverse order */
        listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, (char *) compl[i]->str, NULL,
                          FALSE);

    /* pop up the dialog and apply the chosen completion */
    if (dlg_run (compl_dlg) == B_ENTER)
    {
        listbox_get_current (compl_list, &curr, NULL);
        curr = g_strdup (curr);
    }

    /* destroy dialog before return */
    dlg_destroy (compl_dlg);

    return curr;
}
コード例 #13
0
ファイル: achown.c プロジェクト: jskDr/mc
void
chown_advanced_cmd (void)
{
    /* Number of files at startup */
    int files_on_begin;

    files_on_begin = MAX (1, current_panel->marked);

    do
    {                           /* do while any files remaining */
        int file_idx;
        char buffer[BUF_MEDIUM];
        vfs_path_t *vpath;
        int result;

        init_chown_advanced ();

        if (current_panel->marked)
            fname = next_file ();       /* next marked file */
        else
            fname = selection (current_panel)->fname;   /* single file */
        vpath = vfs_path_from_str (fname);

        if (mc_stat (vpath, sf_stat) != 0)
        {                       /* get status of file */
            dlg_destroy (ch_dlg);
            vfs_path_free (vpath);
            break;
        }

        ch_cmode = sf_stat->st_mode;

        file_idx = files_on_begin == 1 ? 1 : (files_on_begin - current_panel->marked + 1);
        g_snprintf (buffer, sizeof (buffer), "%s (%d/%d)",
                    str_fit_to_term (fname, WIDGET (ch_dlg)->cols - 20, J_LEFT_FIT),
                    file_idx, files_on_begin);
        label_set_text (l_filename, buffer);
        chown_refresh ();
        update_ownership ();

        result = dlg_run (ch_dlg);

        switch (result)
        {
        case B_CANCEL:
            end_chown = TRUE;
            break;

        case B_ENTER:
            need_update = TRUE;
            if (mc_chmod (vpath, get_mode ()) == -1)
                message (D_ERROR, MSG_ERROR, _("Cannot chmod \"%s\"\n%s"),
                         fname, unix_error_string (errno));
            /* call mc_chown only, if mc_chmod didn't fail */
            else if (mc_chown
                     (vpath, (ch_flags[9] == '+') ? sf_stat->st_uid : (uid_t) (-1),
                      (ch_flags[10] == '+') ? sf_stat->st_gid : (gid_t) (-1)) == -1)
                message (D_ERROR, MSG_ERROR, _("Cannot chown \"%s\"\n%s"), fname,
                         unix_error_string (errno));
            break;

        case B_SETALL:
            apply_advanced_chowns (sf_stat);
            break;

        case B_SKIP:
        default:
            break;
        }

        if (current_panel->marked && result != B_CANCEL)
        {
            do_file_mark (current_panel, current_file, 0);
            need_update = TRUE;
        }
        dlg_destroy (ch_dlg);
        vfs_path_free (vpath);
    }
    while (current_panel->marked && !end_chown);

    chown_advanced_done ();
}
コード例 #14
0
ファイル: achown.c プロジェクト: jskDr/mc
static void
do_enter_key (WDialog * h, int f_pos)
{
    WListbox *chl_list;
    struct passwd *chl_pass;
    struct group *chl_grp;
    int fe;
    gboolean chl_end, is_owner;

    do
    {
        int result;
        WDialog *chl_dlg;
        const char *title;
        int lxx, lyy, b_pos;

        is_owner = (f_pos == 3);
        title = is_owner ? _("owner") : _("group");

        lxx = (COLS - 74) / 2 + (is_owner ? 35 : 53);
        lyy = (LINES - 13) / 2;
        chl_end = FALSE;

        chl_dlg =
            dlg_create (TRUE, lyy, lxx, 13, 17, WPOS_KEEP_DEFAULT, TRUE, dialog_colors,
                        chl_callback, NULL, "[Advanced Chown]", title);

        /* get new listboxes */
        chl_list = listbox_new (1, 1, 11, 15, FALSE, NULL);
        listbox_add_item (chl_list, LISTBOX_APPEND_AT_END, 0, "<Unknown>", NULL, FALSE);
        if (is_owner)
        {
            /* get and put user names in the listbox */
            setpwent ();
            while ((chl_pass = getpwent ()) != NULL)
                listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_pass->pw_name, NULL,
                                  FALSE);
            endpwent ();
            fe = listbox_search_text (chl_list, get_owner (sf_stat->st_uid));
        }
        else
        {
            /* get and put group names in the listbox */
            setgrent ();
            while ((chl_grp = getgrent ()) != NULL)
                listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_grp->gr_name, NULL,
                                  FALSE);
            endgrent ();
            fe = listbox_search_text (chl_list, get_group (sf_stat->st_gid));
        }

        listbox_select_entry (chl_list, fe);

        b_pos = chl_list->pos;
        add_widget (chl_dlg, chl_list);

        result = dlg_run (chl_dlg);

        if (result != B_CANCEL)
        {
            if (b_pos != chl_list->pos)
            {
                gboolean ok = FALSE;
                char *text;

                listbox_get_current (chl_list, &text, NULL);
                if (is_owner)
                {
                    chl_pass = getpwnam (text);
                    if (chl_pass != NULL)
                    {
                        ok = TRUE;
                        sf_stat->st_uid = chl_pass->pw_uid;
                    }
                }
                else
                {
                    chl_grp = getgrnam (text);
                    if (chl_grp != NULL)
                    {
                        sf_stat->st_gid = chl_grp->gr_gid;
                        ok = TRUE;
                    }
                }
                if (ok)
                {
                    ch_flags[f_pos + 6] = '+';
                    update_ownership ();
                }
                dlg_focus (h);
                if (ok)
                    print_flags ();
            }
            if (result == KEY_LEFT)
            {
                if (!is_owner)
                    chl_end = TRUE;
                dlg_one_up (ch_dlg);
                f_pos--;
            }
            else if (result == KEY_RIGHT)
            {
                if (is_owner)
                    chl_end = TRUE;
                dlg_one_down (ch_dlg);
                f_pos++;
            }
        }

        /* Here we used to redraw the window */
        dlg_destroy (chl_dlg);
    }
    while (chl_end);
}
コード例 #15
0
ファイル: quick.c プロジェクト: idispatch/mc
int
quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
{
    int len;
    int blen = 0;
    int x, y;                   /* current positions */
    int y1 = 0;                 /* bottom of 1st column in case of two columns */
    int y2 = -1;                /* start of two columns */
    int width1 = 0;             /* width of single column */
    int width2 = 0;             /* width of each of two columns */
    gboolean have_groupbox = FALSE;
    gboolean two_columns = FALSE;
    gboolean put_buttons = FALSE;

    /* x position of 1st column is 3 */
    const int x1 = 3;
    /* x position of 2nd column is 4 and it will be fixed later, after creation of all widgets */
    int x2 = 4;

    GArray *widgets;
    size_t i;
    quick_widget_t *quick_widget;
    WGroupbox *g = NULL;
    WDialog *dd;
    GList *input_labels = NULL; /* Widgets not directly requested by the user. */
    int return_val;

    len = str_term_width1 (I18N (quick_dlg->title)) + 6;
    quick_dlg->cols = MAX (quick_dlg->cols, len);

    y = 1;
    x = x1;

    /* create widgets */
    widgets = g_array_sized_new (FALSE, FALSE, sizeof (quick_widget_item_t), 8);

    for (quick_widget = quick_dlg->widgets; quick_widget->widget_type != quick_end; quick_widget++)
    {
        quick_widget_item_t item = { NULL, quick_widget };
        int width = 0;

        switch (quick_widget->widget_type)
        {
        case quick_checkbox:
            item.widget =
                WIDGET (check_new
                        (++y, x, *quick_widget->u.checkbox.state,
                         I18N (quick_widget->u.checkbox.text)));
            g_array_append_val (widgets, item);
            width = item.widget->cols;
            if (g != NULL)
                width += 2;
            if (two_columns)
                width2 = MAX (width2, width);
            else
                width1 = MAX (width1, width);
            break;

        case quick_button:
            /* single button */
            item.widget = WIDGET (button_new (++y, x, quick_widget->u.button.action,
                                              quick_widget->u.button.action == B_ENTER ?
                                              DEFPUSH_BUTTON : NORMAL_BUTTON,
                                              I18N (quick_widget->u.button.text),
                                              quick_widget->u.button.callback));
            g_array_append_val (widgets, item);
            width = item.widget->cols;
            if (g != NULL)
                width += 2;
            if (two_columns)
                width2 = MAX (width2, width);
            else
                width1 = MAX (width1, width);
            break;

        case quick_input:
            *quick_widget->u.input.result = NULL;
            y++;
            if (quick_widget->u.input.label_location != input_label_none)
            {
                quick_create_labeled_input (widgets, &y, x, quick_widget, &width);
                input_labels = g_list_prepend (input_labels, quick_widget->u.input.label);
            }
            else
            {
                item.widget = WIDGET (quick_create_input (y, x, quick_widget));
                g_array_append_val (widgets, item);
                width = item.widget->cols;
            }
            if (g != NULL)
                width += 2;
            if (two_columns)
                width2 = MAX (width2, width);
            else
                width1 = MAX (width1, width);
            break;

        case quick_label:
            item.widget = WIDGET (label_new (++y, x, I18N (quick_widget->u.label.text)));
            g_array_append_val (widgets, item);
            y += item.widget->lines - 1;
            width = item.widget->cols;
            if (g != NULL)
                width += 2;
            if (two_columns)
                width2 = MAX (width2, width);
            else
                width1 = MAX (width1, width);
            break;

        case quick_radio:
            {
                WRadio *r;
                char **items = NULL;

                /* create the copy of radio_items to avoid mwmory leak */
                items = g_new (char *, quick_widget->u.radio.count + 1);
                for (i = 0; i < (size_t) quick_widget->u.radio.count; i++)
                    items[i] = g_strdup (_(quick_widget->u.radio.items[i]));
                items[i] = NULL;

                r = radio_new (++y, x, quick_widget->u.radio.count, (const char **) items);
                r->pos = r->sel = *quick_widget->u.radio.value;
                g_strfreev (items);
                item.widget = WIDGET (r);
                g_array_append_val (widgets, item);
                y += item.widget->lines - 1;
                width = item.widget->cols;
                if (g != NULL)
                    width += 2;
                if (two_columns)
                    width2 = MAX (width2, width);
                else
                    width1 = MAX (width1, width);
            }
            break;

        case quick_start_groupbox:
            I18N (quick_widget->u.groupbox.title);
            len = str_term_width1 (quick_widget->u.groupbox.title);
            g = groupbox_new (++y, x, 1, len + 4, quick_widget->u.groupbox.title);
            item.widget = WIDGET (g);
            g_array_append_val (widgets, item);
            have_groupbox = TRUE;
            break;

        case quick_stop_groupbox:
            if (g != NULL)
            {
                Widget *w = WIDGET (g);

                y++;
                w->lines = y + 1 - w->y;
                g = NULL;

                g_array_append_val (widgets, item);
            }
            break;

        case quick_separator:
            y++;
            if (quick_widget->u.separator.line)
            {
                item.widget = WIDGET (hline_new (y, x, 1));
                g_array_append_val (widgets, item);
            }
            break;

        case quick_start_columns:
            y2 = y;
            g_array_append_val (widgets, item);
            two_columns = TRUE;
            break;

        case quick_next_column:
            x = x2;
            y1 = y;
            y = y2;
            break;

        case quick_stop_columns:
            x = x1;
            y = MAX (y1, y);
            g_array_append_val (widgets, item);
            two_columns = FALSE;
            break;

        case quick_buttons:
            /* start put several buttons in bottom line */
            if (quick_widget->u.separator.space)
            {
                y++;

                if (quick_widget->u.separator.line)
                    item.widget = WIDGET (hline_new (y, 1, -1));
            }

            g_array_append_val (widgets, item);

            /* several buttons in bottom line */
            y++;
            quick_widget++;
            for (; quick_widget->widget_type == quick_button; quick_widget++)
            {
                item.widget = WIDGET (button_new (y, x++, quick_widget->u.button.action,
                                                  quick_widget->u.button.action == B_ENTER ?
                                                  DEFPUSH_BUTTON : NORMAL_BUTTON,
                                                  I18N (quick_widget->u.button.text),
                                                  quick_widget->u.button.callback));
                item.quick_widget = quick_widget;
                g_array_append_val (widgets, item);
                blen += item.widget->cols + 1;
            }

            /* stop dialog build here */
            blen--;
            quick_widget->widget_type = quick_end;
            quick_widget--;
            break;

        default:
            break;
        }
    }

    /* adjust dialog width */
    quick_dlg->cols = MAX (quick_dlg->cols, blen + 6);
    if (have_groupbox)
    {
        if (width1 != 0)
            width1 += 2;
        if (width2 != 0)
            width2 += 2;
    }
    if (width2 == 0)
        len = width1 + 6;
    else
    {
        len = width2 * 2 + 7;
        if (width1 != 0)
            len = MAX (len, width1 + 6);
    }

    quick_dlg->cols = MAX (quick_dlg->cols, len);
    width1 = quick_dlg->cols - 6;
    width2 = (quick_dlg->cols - 7) / 2;

    if (quick_dlg->x == -1 || quick_dlg->y == -1)
        dd = dlg_create (TRUE, 0, 0, y + 3, quick_dlg->cols, WPOS_CENTER | WPOS_TRYUP, FALSE,
                         dialog_colors, quick_dlg->callback, quick_dlg->mouse_callback,
                         quick_dlg->help, quick_dlg->title);
    else
        dd = dlg_create (TRUE, quick_dlg->y, quick_dlg->x, y + 3, quick_dlg->cols,
                         WPOS_KEEP_DEFAULT, FALSE, dialog_colors, quick_dlg->callback,
                         quick_dlg->mouse_callback, quick_dlg->help, quick_dlg->title);

    /* add widgets into the dialog */
    x2 = x1 + width2 + 1;
    g = NULL;
    two_columns = FALSE;
    x = (WIDGET (dd)->cols - blen) / 2;

    for (i = 0; i < widgets->len; i++)
    {
        quick_widget_item_t *item;
        int column_width;

        item = &g_array_index (widgets, quick_widget_item_t, i);
        column_width = two_columns ? width2 : width1;

        /* adjust widget width and x position */
        switch (item->quick_widget->widget_type)
        {
        case quick_label:
            {
                quick_widget_t *input = item->quick_widget->u.label.input;

                if (input != NULL && input->u.input.label_location == input_label_right)
                {
                    /* location of this label will be adjusted later */
                    break;
                }
            }
            /* fall through */
        case quick_checkbox:
        case quick_radio:
            if (item->widget->x != x1)
                item->widget->x = x2;
            if (g != NULL)
                item->widget->x += 2;
            break;

        case quick_button:
            if (!put_buttons)
            {
                if (item->widget->x != x1)
                    item->widget->x = x2;
                if (g != NULL)
                    item->widget->x += 2;
            }
            else
            {
                item->widget->x = x;
                x += item->widget->cols + 1;
            }
            break;

        case quick_input:
            {
                Widget *label = WIDGET (INPUT (item->widget)->label);
                int width = column_width;

                if (g != NULL)
                    width -= 4;

                switch (item->quick_widget->u.input.label_location)
                {
                case input_label_left:
                    /* label was adjusted before; adjust input line */
                    item->widget->x = label->x + label->cols + 1 - WIDGET (label->owner)->x;
                    item->widget->cols = width - label->cols - 1;
                    break;

                case input_label_right:
                    if (item->widget->x != x1)
                        item->widget->x = x2;
                    if (g != NULL)
                        item->widget->x += 2;
                    item->widget->cols = width - label->cols - 1;
                    label->x = item->widget->x + item->widget->cols + 1;
                    break;

                default:
                    if (item->widget->x != x1)
                        item->widget->x = x2;
                    if (g != NULL)
                        item->widget->x += 2;
                    item->widget->cols = width;
                    break;
                }

                /* forced update internal variables of inpuit line */
                widget_set_size (item->widget, item->widget->y, item->widget->x, 1,
                                 item->widget->cols);
            }
            break;

        case quick_start_groupbox:
            g = GROUPBOX (item->widget);
            if (item->widget->x != x1)
                item->widget->x = x2;
            item->widget->cols = column_width;
            break;

        case quick_stop_groupbox:
            g = NULL;
            break;

        case quick_separator:
            if (item->widget != NULL)
            {
                if (g != NULL)
                {
                    Widget *wg = WIDGET (g);

                    HLINE (item->widget)->auto_adjust_cols = FALSE;
                    item->widget->x = wg->x + 1 - WIDGET (wg->owner)->x;
                    item->widget->cols = wg->cols;
                }
                else if (two_columns)
                {
                    HLINE (item->widget)->auto_adjust_cols = FALSE;
                    if (item->widget->x != x1)
                        item->widget->x = x2;
                    item->widget->x--;
                    item->widget->cols = column_width + 2;
                }
                else
                    HLINE (item->widget)->auto_adjust_cols = TRUE;
            }
            break;

        case quick_start_columns:
            two_columns = TRUE;
            break;

        case quick_stop_columns:
            two_columns = FALSE;
            break;

        case quick_buttons:
            /* several buttons in bottom line */
            put_buttons = TRUE;
            break;

        default:
            break;
        }

        if (item->widget != NULL)
        {
            unsigned long id;

            /* add widget into dialog */
            item->widget->options |= item->quick_widget->options;       /* FIXME: cannot reset flags, setup only */
            item->widget->state |= item->quick_widget->state;   /* FIXME: cannot reset flags, setup only */
            id = add_widget_autopos (dd, item->widget, item->quick_widget->pos_flags, NULL);
            if (item->quick_widget->id != NULL)
                *item->quick_widget->id = id;
        }
    }

    while (nskip-- != 0)
        dlg_set_current_widget_next (dd);

    return_val = dlg_run (dd);

    /* Get the data if we found something interesting */
    if (return_val != B_CANCEL)
        for (i = 0; i < widgets->len; i++)
        {
            quick_widget_item_t *item;

            item = &g_array_index (widgets, quick_widget_item_t, i);

            switch (item->quick_widget->widget_type)
            {
            case quick_checkbox:
                *item->quick_widget->u.checkbox.state = CHECK (item->widget)->state;
                break;

            case quick_input:
                if ((quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0)
                    *item->quick_widget->u.input.result =
                        tilde_expand (INPUT (item->widget)->buffer);
                else
                    *item->quick_widget->u.input.result = g_strdup (INPUT (item->widget)->buffer);
                break;

            case quick_radio:
                *item->quick_widget->u.radio.value = RADIO (item->widget)->sel;
                break;

            default:
                break;
            }
        }

    dlg_destroy (dd);

    g_list_free_full (input_labels, g_free);    /* destroy input labels created before */
    g_array_free (widgets, TRUE);

    return return_val;
}
コード例 #16
0
ファイル: help.c プロジェクト: GarothLongint/mc
/* event callback */
gboolean
help_interactive_display (const gchar * event_group_name, const gchar * event_name,
                          gpointer init_data, gpointer data)
{
    const dlg_colors_t help_colors = {
        HELP_NORMAL_COLOR,      /* common text color */
        0,                      /* unused in help */
        HELP_BOLD_COLOR,        /* bold text color */
        0,                      /* unused in help */
        HELP_TITLE_COLOR        /* title color */
    };

    WButtonBar *help_bar;
    Widget *md;
    char *hlpfile = NULL;
    char *filedata;
    ev_help_t *event_data = (ev_help_t *) data;

    (void) event_group_name;
    (void) event_name;
    (void) init_data;

    if (event_data->filename != NULL)
        g_file_get_contents (event_data->filename, &filedata, NULL, NULL);
    else
        filedata = load_mc_home_file (mc_global.share_data_dir, MC_HELP, &hlpfile);

    if (filedata == NULL)
        message (D_ERROR, MSG_ERROR, _("Cannot open file %s\n%s"),
                 event_data->filename ? event_data->filename : hlpfile, unix_error_string (errno));

    g_free (hlpfile);

    if (filedata == NULL)
        return TRUE;

    translate_file (filedata);

    g_free (filedata);

    if (fdata == NULL)
        return TRUE;

    if ((event_data->node == NULL) || (*event_data->node == '\0'))
        event_data->node = "[main]";

    main_node = search_string (fdata, event_data->node);

    if (main_node == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot find node %s in help file"), event_data->node);

        /* Fallback to [main], return if it also cannot be found */
        main_node = search_string (fdata, "[main]");
        if (main_node == NULL)
        {
            interactive_display_finish ();
            return TRUE;
        }
    }

    help_lines = min (LINES - 4, max (2 * LINES / 3, 18));

    whelp =
        dlg_create (TRUE, 0, 0, help_lines + 4, HELP_WINDOW_WIDTH + 4,
                    help_colors, help_callback, NULL, "[Help]", _("Help"),
                    DLG_TRYUP | DLG_CENTER | DLG_WANT_TAB);

    selected_item = search_string_node (main_node, STRING_LINK_START) - 1;
    currentpoint = main_node + 1;       /* Skip the newline following the start of the node */

    for (history_ptr = HISTORY_SIZE; history_ptr;)
    {
        history_ptr--;
        history[history_ptr].page = currentpoint;
        history[history_ptr].link = selected_item;
    }

    help_bar = buttonbar_new (TRUE);
    WIDGET (help_bar)->y -= WIDGET (whelp)->y;
    WIDGET (help_bar)->x -= WIDGET (whelp)->x;

    md = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH - 2);

    add_widget (whelp, md);
    add_widget (whelp, help_bar);

    buttonbar_set_label (help_bar, 1, Q_ ("ButtonBar|Help"), help_map, NULL);
    buttonbar_set_label (help_bar, 2, Q_ ("ButtonBar|Index"), help_map, NULL);
    buttonbar_set_label (help_bar, 3, Q_ ("ButtonBar|Prev"), help_map, NULL);
    buttonbar_set_label (help_bar, 4, "", help_map, NULL);
    buttonbar_set_label (help_bar, 5, "", help_map, NULL);
    buttonbar_set_label (help_bar, 6, "", help_map, NULL);
    buttonbar_set_label (help_bar, 7, "", help_map, NULL);
    buttonbar_set_label (help_bar, 8, "", help_map, NULL);
    buttonbar_set_label (help_bar, 9, "", help_map, NULL);
    buttonbar_set_label (help_bar, 10, Q_ ("ButtonBar|Quit"), help_map, NULL);

    dlg_run (whelp);
    interactive_display_finish ();
    dlg_destroy (whelp);
    return TRUE;
}
コード例 #17
0
ファイル: boxes.c プロジェクト: ActionLuzifer/mc
void
jobs_cmd (void)
{
    struct
    {
        const char *name;
        int flags;
        int value;
        int len;
        bcback_fn callback;
    }
    job_but[] =
    {
        /* *INDENT-OFF* */
        { N_("&Stop"), NORMAL_BUTTON, B_STOP, 0, task_cb },
        { N_("&Resume"), NORMAL_BUTTON, B_RESUME, 0, task_cb },
        { N_("&Kill"), NORMAL_BUTTON, B_KILL, 0, task_cb },
        { N_("&OK"), DEFPUSH_BUTTON, B_CANCEL, 0, NULL }
        /* *INDENT-ON* */
    };

    size_t i;
    const size_t n_but = G_N_ELEMENTS (job_but);

    WDialog *jobs_dlg;
    int cols = 60;
    int lines = 15;
    int x = 0;

    for (i = 0; i < n_but; i++)
    {
#ifdef ENABLE_NLS
        job_but[i].name = _(job_but[i].name);
#endif /* ENABLE_NLS */

        job_but[i].len = str_term_width1 (job_but[i].name) + 3;
        if (job_but[i].flags == DEFPUSH_BUTTON)
            job_but[i].len += 2;
        x += job_but[i].len;
    }

    x += (int) n_but - 1;
    cols = max (cols, x + 6);

    jobs_dlg = dlg_create (TRUE, 0, 0, lines, cols, dialog_colors, NULL, NULL,
                           "[Background jobs]", _("Background jobs"), DLG_CENTER);

    bg_list = listbox_new (2, 2, lines - 6, cols - 6, FALSE, NULL);
    jobs_fill_listbox (bg_list);
    add_widget (jobs_dlg, bg_list);

    add_widget (jobs_dlg, hline_new (lines - 4, -1, -1));

    x = (cols - x) / 2;
    for (i = 0; i < n_but; i++)
    {
        add_widget (jobs_dlg,
                    button_new (lines - 3, x, job_but[i].value, job_but[i].flags, job_but[i].name,
                                job_but[i].callback));
        x += job_but[i].len + 1;
    }

    (void) dlg_run (jobs_dlg);
    dlg_destroy (jobs_dlg);
}
コード例 #18
0
ファイル: chown.c プロジェクト: LubkaB/mc
void
chown_cmd (void)
{
    char *fname;
    struct stat sf_stat;
    uid_t new_user;
    gid_t new_group;
    char buffer[BUF_TINY];

    chown_i18n ();

    do
    {                           /* do while any files remaining */
        vfs_path_t *vpath;
        WDialog *ch_dlg;

        ch_dlg = init_chown ();
        new_user = new_group = -1;

        if (current_panel->marked)
            fname = next_file ();       /* next marked file */
        else
            fname = selection (current_panel)->fname;   /* single file */

        vpath = vfs_path_from_str (fname);
        if (mc_stat (vpath, &sf_stat) != 0)
        {                       /* get status of file */
            dlg_destroy (ch_dlg);
            vfs_path_free (vpath);
            break;
        }
        vfs_path_free (vpath);

        /* select in listboxes */
        listbox_select_entry (l_user, listbox_search_text (l_user, get_owner (sf_stat.st_uid)));
        listbox_select_entry (l_group, listbox_search_text (l_group, get_group (sf_stat.st_gid)));

        chown_label (0, str_trunc (fname, GW - 4));
        chown_label (1, str_trunc (get_owner (sf_stat.st_uid), GW - 4));
        chown_label (2, str_trunc (get_group (sf_stat.st_gid), GW - 4));
        size_trunc_len (buffer, GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si);
        chown_label (3, buffer);
        chown_label (4, string_perm (sf_stat.st_mode));

        switch (dlg_run (ch_dlg))
        {
        case B_CANCEL:
            end_chown = 1;
            break;

        case B_SETUSR:
            {
                struct passwd *user;
                char *text;

                listbox_get_current (l_user, &text, NULL);
                user = getpwnam (text);
                if (user)
                {
                    new_user = user->pw_uid;
                    apply_chowns (new_user, new_group);
                }
                break;
            }

        case B_SETGRP:
            {
                struct group *grp;
                char *text;

                listbox_get_current (l_group, &text, NULL);
                grp = getgrnam (text);
                if (grp)
                {
                    new_group = grp->gr_gid;
                    apply_chowns (new_user, new_group);
                }
                break;
            }

        case B_SETALL:
        case B_ENTER:
            {
                struct group *grp;
                struct passwd *user;
                char *text;

                listbox_get_current (l_group, &text, NULL);
                grp = getgrnam (text);
                if (grp)
                    new_group = grp->gr_gid;
                listbox_get_current (l_user, &text, NULL);
                user = getpwnam (text);
                if (user)
                    new_user = user->pw_uid;
                if (ch_dlg->ret_value == B_ENTER)
                {
                    vfs_path_t *fname_vpath;

                    fname_vpath = vfs_path_from_str (fname);
                    need_update = 1;
                    if (mc_chown (fname_vpath, new_user, new_group) == -1)
                        message (D_ERROR, MSG_ERROR, _("Cannot chown \"%s\"\n%s"),
                                 fname, unix_error_string (errno));
                    vfs_path_free (fname_vpath);
                }
                else
                    apply_chowns (new_user, new_group);
                break;
            }
        }                       /* switch */

        if (current_panel->marked && ch_dlg->ret_value != B_CANCEL)
        {
            do_file_mark (current_panel, current_file, 0);
            need_update = 1;
        }

        dlg_destroy (ch_dlg);
    }
    while (current_panel->marked && !end_chown);

    chown_done ();
}
コード例 #19
0
ファイル: filegui.c プロジェクト: CTU-OSP/mc
/*
 * 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 :(
 *   alex
 */
static replace_action_t
overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
{
#define ADD_RD_BUTTON(i, ypos) \
    add_widget_autopos (ui->replace_dlg, \
                        button_new (ypos, rd_widgets [i].xpos, rd_widgets [i].value, \
                                    NORMAL_BUTTON, rd_widgets [i].text, NULL), \
                        rd_widgets [i].pos_flags, ui->replace_dlg->current->data)

#define ADD_RD_LABEL(i, p1, p2, ypos) \
    g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2); \
    label2 = WIDGET (label_new (ypos, rd_widgets [i].xpos, buffer)); \
    add_widget_autopos (ui->replace_dlg, label2, rd_widgets [i].pos_flags, \
                        ui->replace_dlg->current != NULL ? ui->replace_dlg->current->data : NULL)

    /* dialog sizes */
    const int rd_ylen = 1;
    int rd_xlen = 60;
    int y = 2;
    unsigned long yes_id;

    struct
    {
        const char *text;
        int ypos, xpos;
        widget_pos_flags_t pos_flags;
        int value;              /* 0 for labels */
    } rd_widgets[] =
    {
    /* *INDENT-OFF* */
        /*  0 */
        { N_("Target file already exists!"), 3, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  1 */
        { "%s", 4, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  2 */
        { N_("New     : %s, size %s"), 6, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  3 */
        { N_("Existing: %s, size %s"), 7, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  4 */
        { N_("Overwrite this target?"), 9, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  5 */
        { N_("&Yes"), 9, 28, WPOS_KEEP_DEFAULT, REPLACE_YES },
        /*  6 */
        { N_("&No"), 9, 37, WPOS_KEEP_DEFAULT, REPLACE_NO },
        /*  7 */
        { N_("A&ppend"), 9, 45, WPOS_KEEP_DEFAULT, REPLACE_APPEND },
        /*  8 */
        { N_("&Reget"), 10, 28, WPOS_KEEP_DEFAULT, REPLACE_REGET },
        /*  9 */
        { N_("Overwrite all targets?"), 11, 4, WPOS_KEEP_DEFAULT, 0 },
        /* 10 */
        { N_("A&ll"), 11, 28, WPOS_KEEP_DEFAULT, REPLACE_ALWAYS },
        /* 11 */
        { N_("&Update"), 11, 36, WPOS_KEEP_DEFAULT, REPLACE_UPDATE },
        /* 12 */
        { N_("Non&e"), 11, 47, WPOS_KEEP_DEFAULT, REPLACE_NEVER },
        /* 13 */
        { N_("If &size differs"), 12, 28, WPOS_KEEP_DEFAULT, REPLACE_SIZE },
        /* 14 */
        { N_("&Abort"), 14, 25, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, REPLACE_ABORT }
    /* *INDENT-ON* */
    };

    const size_t num = G_N_ELEMENTS (rd_widgets);
    int *widgets_len;

    file_op_context_ui_t *ui = ctx->ui;

    char buffer[BUF_SMALL];
    char fsize_buffer[BUF_SMALL];
    Widget *label1, *label2;
    const char *title;
    vfs_path_t *stripped_vpath;
    const char *stripped_name;
    char *stripped_name_orig;
    int result;

    widgets_len = g_new0 (int, num);

    if (mode == Foreground)
        title = _("File exists");
    else
        title = _("Background process: File exists");

    stripped_vpath = vfs_path_from_str (ui->replace_filename);
    stripped_name = stripped_name_orig =
        vfs_path_to_str_flags (stripped_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
    vfs_path_free (stripped_vpath);

    {
        size_t i;
        int l1, l2, l, row;
        int stripped_name_len;

        for (i = 0; i < num; i++)
        {
#ifdef ENABLE_NLS
            if (i != 1)         /* skip filename */
                rd_widgets[i].text = _(rd_widgets[i].text);
#endif /* ENABLE_NLS */
            widgets_len[i] = str_term_width1 (rd_widgets[i].text);
        }

        /*
         * longest of "Overwrite..." labels
         * (assume "Target date..." are short enough)
         */
        l1 = max (widgets_len[9], widgets_len[4]);

        /* longest of button rows */
        l = l2 = 0;
        row = 0;
        for (i = 1; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l2 = max (l2, l);
                    l = 0;
                }
                l += widgets_len[i] + 4;
            }

        l2 = max (l2, l);       /* last row */
        rd_xlen = max (rd_xlen, l1 + l2 + 8);
        /* rd_xlen = max (rd_xlen, str_term_width1 (title) + 2); */
        stripped_name_len = str_term_width1 (stripped_name);
        rd_xlen = max (rd_xlen, min (COLS, stripped_name_len + 8));

        /* Now place widgets */
        l1 += 5;                /* start of first button in the row */
        l = l1;
        row = 0;
        for (i = 2; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l = l1;
                }
                rd_widgets[i].xpos = l;
                l += widgets_len[i] + 4;
            }
    }

    /* FIXME - missing help node */
    ui->replace_dlg =
        dlg_create (TRUE, 0, 0, rd_ylen, rd_xlen, alarm_colors, NULL, NULL, "[Replace]", title,
                    DLG_CENTER);

    /* prompt */
    ADD_RD_LABEL (0, "", "", y++);
    /* file name */
    ADD_RD_LABEL (1, "", "", y++);
    label1 = label2;

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    /* source date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->s_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);
    /* destination date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->d_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (4, 0, 0, y);  /* Overwrite this target? */
    yes_id = ADD_RD_BUTTON (5, y);      /* Yes */
    ADD_RD_BUTTON (6, y);       /* No */

    /* "this target..." widgets */
    if (!S_ISDIR (ui->d_stat->st_mode))
    {
        ADD_RD_BUTTON (7, y++); /* Append */

        if ((ctx->operation == OP_COPY) && (ui->d_stat->st_size != 0)
            && (ui->s_stat->st_size > ui->d_stat->st_size))
            ADD_RD_BUTTON (8, y++);     /* Reget */
    }

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (9, 0, 0, y);  /* Overwrite all targets? */
    ADD_RD_BUTTON (10, y);      /* All" */
    ADD_RD_BUTTON (11, y);      /* Update */
    ADD_RD_BUTTON (12, y++);    /* None */
    ADD_RD_BUTTON (13, y++);    /* If size differs */

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_BUTTON (14, y);      /* Abort */

    label_set_text (LABEL (label1), str_trunc (stripped_name, rd_xlen - 8));
    dlg_set_size (ui->replace_dlg, y + 3, rd_xlen);
    dlg_select_by_id (ui->replace_dlg, yes_id);
    result = dlg_run (ui->replace_dlg);
    dlg_destroy (ui->replace_dlg);

    g_free (widgets_len);
    g_free (stripped_name_orig);

    return (result == B_CANCEL) ? REPLACE_ABORT : (replace_action_t) result;
#undef ADD_RD_LABEL
#undef ADD_RD_BUTTON
}