示例#1
0
文件: filegui.c 项目: artzub/mc
char *
file_mask_dialog (FileOpContext * ctx, FileOperation operation,
                  gboolean only_one,
                  const char *format, const void *text,
                  const char *def_text, gboolean * do_bg)
{
    const size_t FMDY = 13;
    const size_t FMDX = 68;
    size_t fmd_xlen;

    /* buttons */
    const size_t gap = 1;
    size_t b0_len, b2_len;
    size_t b1_len = 0;

    int source_easy_patterns = easy_patterns;
    size_t i, len;
    char fmd_buf[BUF_MEDIUM];
    char *source_mask, *orig_mask, *dest_dir, *tmp;
    char *def_text_secure;
    int val;

    QuickWidget fmd_widgets[] = {
        /* 0 */ QUICK_BUTTON (42, 64, 10, FMDY, N_("&Cancel"), B_CANCEL, NULL),
#ifdef WITH_BACKGROUND
        /* 1 */ QUICK_BUTTON (25, 64, 10, FMDY, N_("&Background"), B_USER, NULL),
#define OFFSET 0
#else
#define OFFSET 1
#endif /* WITH_BACKGROUND */
        /*  2 - OFFSET */
        QUICK_BUTTON (14, FMDX, 10, FMDY, N_("&OK"), B_ENTER, NULL),
        /*  3 - OFFSET */
        QUICK_CHECKBOX (42, FMDX, 8, FMDY, N_("&Stable Symlinks"), &ctx->stable_symlinks),
        /*  4 - OFFSET */
        QUICK_CHECKBOX (31, FMDX, 7, FMDY, N_("Di&ve into subdir if exists"),
                        &ctx->dive_into_subdirs),
        /*  5 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 8, FMDY, N_("Preserve &attributes"), &ctx->op_preserve),
        /*  6 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 7, FMDY, N_("Follow &links"), &ctx->follow_links),
        /*  7 - OFFSET */
        QUICK_INPUT (3, FMDX, 6, FMDY, "", 58, 0, "input2", &dest_dir),
        /*  8 - OFFSET */
        QUICK_LABEL (3, FMDX, 5, FMDY, N_("to:")),
        /*  9 - OFFSET */
        QUICK_CHECKBOX (37, FMDX, 4, FMDY, N_("&Using shell patterns"), &source_easy_patterns),
        /* 10 - OFFSET */
        QUICK_INPUT (3, FMDX, 3, FMDY, easy_patterns ? "*" : "^(.*)$", 58, 0, "input-def",
                     &source_mask),
        /* 11 - OFFSET */
        QUICK_LABEL (3, FMDX, 2, FMDY, fmd_buf),
        QUICK_END
    };

    g_return_val_if_fail (ctx != NULL, NULL);

#ifdef ENABLE_NLS
    /* buttons */
    for (i = 0; i <= 2 - OFFSET; i++)
        fmd_widgets[i].u.button.text = _(fmd_widgets[i].u.button.text);

    /* checkboxes */
    for (i = 3 - OFFSET; i <= 9 - OFFSET; i++)
        if (i != 7 - OFFSET)
            fmd_widgets[i].u.checkbox.text = _(fmd_widgets[i].u.checkbox.text);
#endif /* !ENABLE_NLS */

    fmd_xlen = max (FMDX, (size_t) COLS * 2 / 3);

    len = str_term_width1 (fmd_widgets[6 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[4 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    len = str_term_width1 (fmd_widgets[5 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[3 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    /* buttons */
    b2_len = str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) + 6 + gap; /* OK */
#ifdef WITH_BACKGROUND
    b1_len = str_term_width1 (fmd_widgets[1].u.button.text) + 4 + gap;  /* Background */
#endif
    b0_len = str_term_width1 (fmd_widgets[0].u.button.text) + 4;        /* Cancel */
    len = b0_len + b1_len + b2_len;
    fmd_xlen = min (max (fmd_xlen, len + 6), (size_t) COLS);

    if (only_one)
    {
        int flen;

        flen = str_term_width1 (format);
        i = fmd_xlen - flen - 4;        /* FIXME */
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, str_trunc ((const char *) text, i));
    }
    else
    {
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, *(const int *) text);
        fmd_xlen = max (fmd_xlen, (size_t) str_term_width1 (fmd_buf) + 6);
    }

    for (i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]); i > 0;)
        fmd_widgets[--i].x_divisions = fmd_xlen;

    i = (fmd_xlen - len) / 2;
    /* OK button */
    fmd_widgets[2 - OFFSET].relative_x = i;
    i += b2_len;
#ifdef WITH_BACKGROUND
    /* Background button */
    fmd_widgets[1].relative_x = i;
    i += b1_len;
#endif
    /* Cancel button */
    fmd_widgets[0].relative_x = i;

#define chkbox_xpos(i) \
    fmd_widgets [i].relative_x = fmd_xlen - str_term_width1 (fmd_widgets [i].u.checkbox.text) - 6
    chkbox_xpos (3 - OFFSET);
    chkbox_xpos (4 - OFFSET);
    chkbox_xpos (9 - OFFSET);
#undef chkbox_xpos

    /* inputs */
    fmd_widgets[7 - OFFSET].u.input.len = fmd_widgets[10 - OFFSET].u.input.len = fmd_xlen - 6;

    /* unselect checkbox if target filesystem don't support attributes */
    ctx->op_preserve = filegui__check_attrs_on_fs (def_text);

    /* filter out a possible password from def_text */
    tmp = strip_password (g_strdup (def_text), 1);
    if (source_easy_patterns)
        def_text_secure = strutils_glob_escape (tmp);
    else
        def_text_secure = strutils_regex_escape (tmp);
    g_free (tmp);

    /* destination */
    fmd_widgets[7 - OFFSET].u.input.text = def_text_secure;

    ctx->stable_symlinks = FALSE;
    *do_bg = FALSE;

    {
        struct stat buf;

        QuickDialog Quick_input = {
            fmd_xlen, FMDY, -1, -1, op_names[operation],
            "[Mask Copy/Rename]", fmd_widgets, NULL, TRUE
        };

      ask_file_mask:
        val = quick_dialog_skip (&Quick_input, 4);

        if (val == B_CANCEL)
        {
            g_free (def_text_secure);
            return NULL;
        }

        if (ctx->follow_links)
            ctx->stat_func = mc_stat;
        else
            ctx->stat_func = mc_lstat;

        if (ctx->op_preserve)
        {
            ctx->preserve = TRUE;
            ctx->umask_kill = 0777777;
            ctx->preserve_uidgid = (geteuid () == 0);
        }
        else
        {
            int i2;
            ctx->preserve = ctx->preserve_uidgid = FALSE;
            i2 = umask (0);
            umask (i2);
            ctx->umask_kill = i2 ^ 0777777;
        }

        if ((dest_dir == NULL) || (*dest_dir == '\0'))
        {
            g_free (def_text_secure);
            g_free (source_mask);
            return dest_dir;
        }

        ctx->search_handle = mc_search_new (source_mask, -1);

        if (ctx->search_handle == NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Invalid source pattern `%s'"), source_mask);
            g_free (dest_dir);
            g_free (source_mask);
            goto ask_file_mask;
        }

        g_free (def_text_secure);
        g_free (source_mask);

        ctx->search_handle->is_case_sensitive = TRUE;
        if (source_easy_patterns)
            ctx->search_handle->search_type = MC_SEARCH_T_GLOB;
        else
            ctx->search_handle->search_type = MC_SEARCH_T_REGEX;

        tmp = dest_dir;
        dest_dir = tilde_expand (tmp);
        g_free (tmp);

        ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
        if (ctx->dest_mask == NULL)
            ctx->dest_mask = dest_dir;
        else
            ctx->dest_mask++;
        orig_mask = ctx->dest_mask;
        if (!*ctx->dest_mask
            || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask)
                && (!only_one
                    || (!mc_stat (dest_dir, &buf) && S_ISDIR (buf.st_mode))))
            || (ctx->dive_into_subdirs
                && ((!only_one && !is_wildcarded (ctx->dest_mask))
                    || (only_one && !mc_stat (dest_dir, &buf) && S_ISDIR (buf.st_mode)))))
            ctx->dest_mask = g_strdup ("\\0");
        else
        {
            ctx->dest_mask = g_strdup (ctx->dest_mask);
            *orig_mask = '\0';
        }
        if (!*dest_dir)
        {
            g_free (dest_dir);
            dest_dir = g_strdup ("./");
        }
        if (val == B_USER)
            *do_bg = TRUE;
    }

    return dest_dir;
}
void
fmd_init_i18n()
{
#ifdef ENABLE_NLS

	register int i;
	int len;

	for (i = sizeof (op_names) / sizeof (op_names[0]); i--;)
		op_names [i] = _(op_names [i]);

	i = sizeof (fmd_widgets) / sizeof (fmd_widgets [0]) - 1;
	while (i--)
		if (fmd_widgets [i].text[0] != '\0')
			fmd_widgets [i].text = _(fmd_widgets [i].text);

	len = strlen (fmd_widgets [FMCB11].text)
		+ strlen (fmd_widgets [FMCB21].text) + 15;
	fmd_xlen = max (fmd_xlen, len);

	len = strlen (fmd_widgets [FMCB12].text)
		+ strlen (fmd_widgets [FMCB22].text) + 15;
	fmd_xlen = max (fmd_xlen, len);
		
	len = strlen (fmd_widgets [FMBRGT].text)
		+ strlen (fmd_widgets [FMBLFT].text) + 11;

#ifdef FMBMID
	len += strlen (fmd_widgets [FMBMID].text) + 6;
#endif

	fmd_xlen = max (fmd_xlen, len + 4);

	len = (fmd_xlen - (len + 6)) / 2;
	i = fmd_widgets [FMBLFT].relative_x = len + 3;
	i += strlen (fmd_widgets [FMBLFT].text) + 8;

#ifdef FMBMID
	fmd_widgets [FMBMID].relative_x = i;
	i += strlen (fmd_widgets [FMBMID].text) + 6;
#endif

	fmd_widgets [FMBRGT].relative_x = i;

#define	chkbox_xpos(i) \
	fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6

	chkbox_xpos(FMCB0);
	chkbox_xpos(FMCB21);
	chkbox_xpos(FMCB22);

	if (fmd_xlen != FMD_XLEN)
	{
		i = sizeof (fmd_widgets) / sizeof (fmd_widgets [0]) - 1;
		while (i--)
			fmd_widgets [i].x_divisions = fmd_xlen;

		fmd_widgets [FMDI1].hotkey_pos =
			fmd_widgets [FMDI2].hotkey_pos = fmd_xlen - 6;
	}
#undef chkbox_xpos
#endif /* ENABLE_NLS */

	fmd_i18n_flag = 1;
}