Merge branch '1705_copy_dialog'

* 1705_copy_dialog:
  Adjust width of Copy/Move dialog depending on initial screen width.
  Fixed calculation of Copy/Move dialog width.
  Use local buffers instead of global cmd_buf one.
  Ticket #1705: fix show of Copy/Move dialog.
This commit is contained in:
Andrew Borodin 2009-10-16 13:09:22 +04:00
commit b48b53729f
7 changed files with 159 additions and 120 deletions

View File

@ -1,7 +1,7 @@
/* File management. /* File management.
Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Written by: 1994, 1995 Janne Kukonlehto Written by: 1994, 1995 Janne Kukonlehto
1994, 1995 Fred Leeflang 1994, 1995 Fred Leeflang
1994, 1995, 1996 Miguel de Icaza 1994, 1995, 1996 Miguel de Icaza
@ -22,7 +22,7 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -66,7 +66,7 @@
#include "setup.h" #include "setup.h"
#include "dialog.h" #include "dialog.h"
#include "widget.h" #include "widget.h"
#include "main.h" /* cmd_buf */ #include "main.h"
#include "layout.h" #include "layout.h"
#include "widget.h" #include "widget.h"
#include "wtools.h" #include "wtools.h"
@ -1632,10 +1632,11 @@ panel_compute_totals (WPanel *panel, const void *ui,
* (I don't use spaces around the words, because someday they could be * (I don't use spaces around the words, because someday they could be
* dropped, when widgets get smarter) * dropped, when widgets get smarter)
*/ */
static const char *op_names1[] = { N_("1Copy"), N_("1Move"), N_("1Delete") }; static const char *op_names1[] = {
#define FMD_XLEN 64 N_("1Copy"),
N_("1Move"),
int fmd_xlen = FMD_XLEN; N_("1Delete")
};
/* /*
* These are formats for building a prompt. Parts encoded as follows: * These are formats for building a prompt. Parts encoded as follows:
@ -1645,14 +1646,20 @@ int fmd_xlen = FMD_XLEN;
* %s - source name (truncated) * %s - source name (truncated)
* %d - number of marked files * %d - number of marked files
* %e - "to:" or question mark for delete * %e - "to:" or question mark for delete
* *
* xgettext:no-c-format */ * xgettext:no-c-format */
static const char *one_format = N_("%o %f \"%s\"%m"); static const char *one_format = N_("%o %f \"%s\"%m");
/* xgettext:no-c-format */ /* xgettext:no-c-format */
static const char *many_format = N_("%o %d %f%m"); static const char *many_format = N_("%o %d %f%m");
static const char *prompt_parts[] = { static const char *prompt_parts[] = {
N_("file"), N_("files"), N_("directory"), N_("directories"), N_("file"),
N_("files/directories"), N_(" with source mask:"), N_(" to:") N_("files"),
N_("directory"),
N_("directories"),
N_("files/directories"),
N_(" with source mask:"),
N_(" to:")
}; };
/* /*
@ -1661,13 +1668,13 @@ static const char *prompt_parts[] = {
* entries. * entries.
* src_stat is only used when single_source is not NULL. * src_stat is only used when single_source is not NULL.
*/ */
static void static char *
panel_operate_generate_prompt (const WPanel *panel, const int operation, panel_operate_generate_prompt (const WPanel *panel, const int operation,
const char *single_source, gboolean single_source,
const struct stat *src_stat) const struct stat *src_stat)
{ {
register const char *sp, *cp; const char *sp, *cp;
register int i; int i;
char format_string[BUF_MEDIUM]; char format_string[BUF_MEDIUM];
char *dp = format_string; char *dp = format_string;
@ -1705,13 +1712,11 @@ panel_operate_generate_prompt (const WPanel *panel, const int operation,
case 'f': case 'f':
if (single_source) { if (single_source) {
cp = S_ISDIR (src_stat-> cp = S_ISDIR (src_stat->
st_mode) ? prompt_parts[2] : st_mode) ? prompt_parts[2] : prompt_parts[0];
prompt_parts[0];
} else { } else {
cp = (panel->marked == panel->dirs_marked) cp = (panel->marked == panel->dirs_marked)
? prompt_parts[3] ? prompt_parts[3]
: (panel->dirs_marked ? prompt_parts[4] : (panel->dirs_marked ? prompt_parts[4] : prompt_parts[1]);
: prompt_parts[1]);
} }
break; break;
default: default:
@ -1729,25 +1734,14 @@ panel_operate_generate_prompt (const WPanel *panel, const int operation,
} }
*dp = '\0'; *dp = '\0';
if (single_source) { return g_strdup (format_string);
i = fmd_xlen - str_term_width1 (format_string) - 4;
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
str_trunc (single_source, i));
} else {
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
panel->marked);
i = str_term_width1 (cmd_buf) + 6 - fmd_xlen;
if (i > 0) {
fmd_xlen += i;
}
}
} }
/** /**
* panel_operate: * panel_operate:
* *
* Performs one of the operations on the selection on the source_panel * Performs one of the operations on the selection on the source_panel
* (copy, delete, move). * (copy, delete, move).
* *
* Returns 1 if did change the directory * Returns 1 if did change the directory
* structure, Returns 0 if user aborted * structure, Returns 0 if user aborted
@ -1760,12 +1754,12 @@ panel_operate (void *source_panel, FileOperation operation,
int force_single) int force_single)
{ {
WPanel *panel = source_panel; WPanel *panel = source_panel;
char *source = NULL;
#ifdef WITH_FULL_PATHS #ifdef WITH_FULL_PATHS
char *source_with_path = NULL; char *source_with_path = NULL;
#else #else
# define source_with_path source # define source_with_path source
#endif /* !WITH_FULL_PATHS */ #endif /* !WITH_FULL_PATHS */
char *source = NULL;
char *dest = NULL; char *dest = NULL;
char *temp = NULL; char *temp = NULL;
char *save_cwd = NULL, *save_dest = NULL; char *save_cwd = NULL, *save_dest = NULL;
@ -1805,26 +1799,13 @@ panel_operate (void *source_panel, FileOperation operation,
} }
} }
/* Generate confirmation prompt */
panel_operate_generate_prompt (panel, operation, source, &src_stat);
ctx = file_op_context_new (operation); ctx = file_op_context_new (operation);
/* Show confirmation dialog */ /* Show confirmation dialog */
if (operation == OP_DELETE && confirm_delete) { if (operation != OP_DELETE) {
if (safe_delete)
query_set_sel (1);
i = query_dialog (_(op_names[operation]), cmd_buf, D_ERROR, 2,
_("&Yes"), _("&No"));
if (i != 0) {
file_op_context_destroy (ctx);
return 0;
}
} else if (operation != OP_DELETE) {
char *dest_dir; char *dest_dir;
char *dest_dir_; char *dest_dir_;
char *format;
/* Forced single operations default to the original name */ /* Forced single operations default to the original name */
if (force_single) if (force_single)
@ -1839,30 +1820,66 @@ panel_operate (void *source_panel, FileOperation operation,
* dir is deleted) * dir is deleted)
*/ */
if (!force_single if (!force_single
&& dest_dir[0] && dest_dir[0] != '\0'
&& dest_dir[strlen(dest_dir)-1] != PATH_SEP) { && dest_dir[strlen (dest_dir) - 1] != PATH_SEP) {
/* add trailing separator */ /* add trailing separator */
dest_dir_ = g_strconcat (dest_dir, PATH_SEP_STR, (char*)0); dest_dir_ = g_strconcat (dest_dir, PATH_SEP_STR, (char *) NULL);
} else { } else {
/* just copy */ /* just copy */
dest_dir_ = g_strdup (dest_dir); dest_dir_ = g_strdup (dest_dir);
} }
if (!dest_dir_) { if (dest_dir_ == NULL) {
file_op_context_destroy (ctx); file_op_context_destroy (ctx);
return 0; return 0;
} }
dest = /* Generate confirmation prompt */
file_mask_dialog (ctx, operation, cmd_buf, dest_dir_, format = panel_operate_generate_prompt (panel, operation,
single_entry, &do_bg); source != NULL, &src_stat);
g_free(dest_dir_);
if (!dest || !dest[0]) { dest = file_mask_dialog (ctx, operation, source != NULL,
format, source != NULL ? source : &panel->marked,
dest_dir_, &do_bg);
g_free (format);
g_free (dest_dir_);
if (dest == NULL || dest[0] == '\0') {
file_op_context_destroy (ctx); file_op_context_destroy (ctx);
g_free (dest); g_free (dest);
return 0; return 0;
} }
} else if (confirm_delete) {
char *format;
char fmd_buf [BUF_MEDIUM];
/* Generate confirmation prompt */
format = panel_operate_generate_prompt (panel, OP_DELETE,
source != NULL, &src_stat);
if (source == NULL)
g_snprintf (fmd_buf, sizeof (fmd_buf), format, panel->marked);
else {
const int fmd_xlen = 64;
i = fmd_xlen - str_term_width1 (format) - 4;
g_snprintf (fmd_buf, sizeof (fmd_buf),
format, str_trunc (source, i));
}
g_free (format);
if (safe_delete)
query_set_sel (1);
i = query_dialog (_(op_names[operation]), fmd_buf, D_ERROR, 2,
_("&Yes"), _("&No"));
if (i != 0) {
file_op_context_destroy (ctx);
return 0;
}
} }
#ifdef WITH_BACKGROUND #ifdef WITH_BACKGROUND
/* Did the user select to do a background operation? */ /* Did the user select to do a background operation? */
if (do_bg) { if (do_bg) {
@ -2176,26 +2193,29 @@ real_do_file_error (enum OperationMode mode, const char *error)
FileProgressStatus FileProgressStatus
file_error (const char *format, const char *file) file_error (const char *format, const char *file)
{ {
g_snprintf (cmd_buf, sizeof (cmd_buf), format, char buf [BUF_MEDIUM];
g_snprintf (buf, sizeof (buf), format,
path_trunc (file, 30), unix_error_string (errno)); path_trunc (file, 30), unix_error_string (errno));
return do_file_error (cmd_buf); return do_file_error (buf);
} }
/* Report error with two files */ /* Report error with two files */
static FileProgressStatus static FileProgressStatus
files_error (const char *format, const char *file1, const char *file2) files_error (const char *format, const char *file1, const char *file2)
{ {
char buf [BUF_MEDIUM];
char *nfile1 = g_strdup (path_trunc (file1, 15)); char *nfile1 = g_strdup (path_trunc (file1, 15));
char *nfile2 = g_strdup (path_trunc (file2, 15)); char *nfile2 = g_strdup (path_trunc (file2, 15));
g_snprintf (cmd_buf, sizeof (cmd_buf), format, nfile1, nfile2, g_snprintf (buf, sizeof (buf), format, nfile1, nfile2,
unix_error_string (errno)); unix_error_string (errno));
g_free (nfile1); g_free (nfile1);
g_free (nfile2); g_free (nfile2);
return do_file_error (cmd_buf); return do_file_error (buf);
} }
static FileProgressStatus static FileProgressStatus

View File

@ -6,11 +6,12 @@
#ifndef MC_FILE_H #ifndef MC_FILE_H
#define MC_FILE_H #define MC_FILE_H
#include "global.h"
#include <sys/types.h> /* off_t */ #include <sys/types.h> /* off_t */
#include "fileopctx.h"
#include "global.h"
#include "dialog.h" /* Dlg_head */ #include "dialog.h" /* Dlg_head */
#include "widget.h" /* WLabel */ #include "widget.h" /* WLabel */
#include "fileopctx.h"
struct link; struct link;
@ -53,5 +54,4 @@ ComputeDirSizeUI *compute_dir_size_create_ui (void);
void compute_dir_size_destroy_ui (ComputeDirSizeUI *ui); void compute_dir_size_destroy_ui (ComputeDirSizeUI *ui);
FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname); FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname);
#endif /* MC_FILE_H */ #endif /* MC_FILE_H */

View File

@ -816,15 +816,23 @@ is_wildcarded (char *p)
} }
char * char *
file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, file_mask_dialog (FileOpContext *ctx, FileOperation operation,
const char *def_text, int only_one, int *do_background) gboolean only_one,
const char *format, const void *text,
const char *def_text, gboolean *do_background)
{ {
const size_t FMDY = 13; const size_t FMDY = 13;
const size_t FMDX = 64; const size_t FMDX = 68;
size_t fmd_xlen = 0; 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; int source_easy_patterns = easy_patterns;
size_t i, len; size_t i, len;
char fmd_buf [BUF_MEDIUM];
char *source_mask, *orig_mask, *dest_dir, *tmp; char *source_mask, *orig_mask, *dest_dir, *tmp;
char *def_text_secure; char *def_text_secure;
int val; int val;
@ -861,7 +869,7 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
/* 10 - OFFSET */ /* 10 - OFFSET */
QUICK_INPUT (3, FMDX, 3, FMDY, easy_patterns ? "*" : "^\\(.*\\)$", 58, 0, "input-def", &source_mask), QUICK_INPUT (3, FMDX, 3, FMDY, easy_patterns ? "*" : "^\\(.*\\)$", 58, 0, "input-def", &source_mask),
/* 11 - OFFSET */ /* 11 - OFFSET */
QUICK_LABEL (3, FMDX, 2, FMDY, text), QUICK_LABEL (3, FMDX, 2, FMDY, fmd_buf),
QUICK_END QUICK_END
}; };
@ -875,6 +883,8 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
i18n = TRUE; i18n = TRUE;
} }
fmd_xlen = max (FMDX, COLS * 2/3);
/* buttons */ /* buttons */
for (i = 0; i <= 2 - OFFSET; i++) for (i = 0; i <= 2 - OFFSET; i++)
fmd_widgets[i].u.button.text = _(fmd_widgets[i].u.button.text); fmd_widgets[i].u.button.text = _(fmd_widgets[i].u.button.text);
@ -894,23 +904,39 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
fmd_xlen = max (fmd_xlen, len); fmd_xlen = max (fmd_xlen, len);
/* buttons */ /* buttons */
len = str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) b2_len = str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) + 6 + gap; /* OK */
+ str_term_width1 (fmd_widgets[0].u.button.text) + 11;
#ifdef WITH_BACKGROUND #ifdef WITH_BACKGROUND
len += str_term_width1 (fmd_widgets[1].u.button.text) + 6; b1_len = str_term_width1 (fmd_widgets[1].u.button.text) + 4 + gap; /* Background */
#endif #endif
fmd_xlen = max (fmd_xlen, len + 4); 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), COLS);
len = (fmd_xlen - (len + 6)) / 2; if (only_one) {
i = len + 3; 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, 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; fmd_widgets[2 - OFFSET].relative_x = i;
i += str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) + 8; i += b2_len;
#ifdef WITH_BACKGROUND #ifdef WITH_BACKGROUND
/* Background button */
fmd_widgets[1].relative_x = i; fmd_widgets[1].relative_x = i;
i += str_term_width1 (fmd_widgets[1].u.button.text) + 6; i += b1_len;
#endif #endif
/* Cancel button */
fmd_widgets[0].relative_x = i; fmd_widgets[0].relative_x = i;
#define chkbox_xpos(i) \ #define chkbox_xpos(i) \
@ -920,15 +946,9 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
chkbox_xpos (9 - OFFSET); chkbox_xpos (9 - OFFSET);
#undef chkbox_xpos #undef chkbox_xpos
if (fmd_xlen != FMDX) { /* inputs */
i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]) - 1; fmd_widgets[ 7 - OFFSET].u.input.len =
while (i--) fmd_widgets[10 - OFFSET].u.input.len = fmd_xlen - 6;
fmd_widgets[i].x_divisions = fmd_xlen;
/* 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 */ /* unselect checkbox if target filesystem don't support attributes */
ctx->op_preserve = filegui__check_attrs_on_fs (def_text); ctx->op_preserve = filegui__check_attrs_on_fs (def_text);
@ -945,7 +965,7 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
fmd_widgets[7 - OFFSET].u.input.text = def_text_secure; fmd_widgets[7 - OFFSET].u.input.text = def_text_secure;
ctx->stable_symlinks = 0; ctx->stable_symlinks = 0;
*do_background = 0; *do_background = FALSE;
{ {
struct stat buf; struct stat buf;
@ -1034,7 +1054,7 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
dest_dir = g_strdup ("./"); dest_dir = g_strdup ("./");
} }
if (val == B_USER) if (val == B_USER)
*do_background = 1; *do_background = TRUE;
} }
return dest_dir; return dest_dir;

View File

@ -6,10 +6,12 @@
#ifndef MC_FILEGUI_H #ifndef MC_FILEGUI_H
#define MC_FILEGUI_H #define MC_FILEGUI_H
#include "global.h"
#include "fileopctx.h" #include "fileopctx.h"
char *file_mask_dialog (FileOpContext *ctx, FileOperation operation, char *file_mask_dialog (FileOpContext *ctx, FileOperation operation,
const char *text, const char *def_text, int only_one, gboolean only_one,
int *do_background); const char *format, const void *text,
const char *def_text, gboolean *do_background);
#endif #endif /* MC_FILEGUI_H */

View File

@ -298,8 +298,6 @@ char *mc_home = NULL;
/* mc_home_alt: Alternative home of MC - deprecated /usr/share/mc */ /* mc_home_alt: Alternative home of MC - deprecated /usr/share/mc */
char *mc_home_alt = NULL; char *mc_home_alt = NULL;
char cmd_buf[512];
/* Define this function for glib-style error handling */ /* Define this function for glib-style error handling */
GQuark GQuark
mc_main_error_quark (void) mc_main_error_quark (void)

View File

@ -66,7 +66,6 @@ extern int vfs_use_limit;
extern int only_leading_plus_minus; extern int only_leading_plus_minus;
extern int output_starts_shell; extern int output_starts_shell;
extern int midnight_shutdown; extern int midnight_shutdown;
extern char cmd_buf [512];
extern char *shell; extern char *shell;
extern int auto_fill_mkdir_name; extern int auto_fill_mkdir_name;
extern int skip_check_codeset; extern int skip_check_codeset;

View File

@ -608,32 +608,29 @@ tree_forget_cmd (void *data)
tree_remove_entry (tree, tree->selected_ptr->name); tree_remove_entry (tree, tree->selected_ptr->name);
} }
static void tree_copy (WTree *tree, const char *default_dest) static void
tree_copy (WTree *tree, const char *default_dest)
{ {
char msg [BUF_MEDIUM];
char *dest; char *dest;
off_t count = 0; off_t count = 0;
double bytes = 0; double bytes = 0;
FileOpContext *ctx; FileOpContext *ctx;
if (!tree->selected_ptr) if (tree->selected_ptr == NULL)
return;
g_snprintf (cmd_buf, sizeof(cmd_buf), _("Copy \"%s\" directory to:"),
str_trunc (tree->selected_ptr->name, 50));
dest = input_expand_dialog (_(" Copy "), cmd_buf, MC_HISTORY_FM_TREE_COPY, default_dest);
if (!dest)
return; return;
if (!*dest){ g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"),
g_free (dest); str_trunc (tree->selected_ptr->name, 50));
return; dest = input_expand_dialog (_(" Copy "), msg, MC_HISTORY_FM_TREE_COPY, default_dest);
if (dest != NULL && *dest != '\0') {
ctx = file_op_context_new (OP_COPY);
file_op_context_create_ui (ctx, FALSE);
copy_dir_dir (ctx, tree->selected_ptr->name, dest, 1, 0, 0, 0, &count, &bytes);
file_op_context_destroy (ctx);
} }
ctx = file_op_context_new (OP_COPY);
file_op_context_create_ui (ctx, FALSE);
copy_dir_dir (ctx, tree->selected_ptr->name, dest, 1, 0, 0, 0, &count, &bytes);
file_op_context_destroy (ctx);
g_free (dest); g_free (dest);
} }
@ -650,25 +647,28 @@ tree_copy_cmd (void *data)
tree_copy (tree, ""); tree_copy (tree, "");
} }
static void tree_move (WTree *tree, const char *default_dest) static void
tree_move (WTree *tree, const char *default_dest)
{ {
char msg [BUF_MEDIUM];
char *dest; char *dest;
struct stat buf; struct stat buf;
double bytes = 0; double bytes = 0;
off_t count = 0; off_t count = 0;
FileOpContext *ctx; FileOpContext *ctx;
if (!tree->selected_ptr) if (tree->selected_ptr == NULL)
return; return;
g_snprintf (cmd_buf, sizeof (cmd_buf), _("Move \"%s\" directory to:"),
str_trunc (tree->selected_ptr->name, 50)); g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"),
dest = input_expand_dialog (_(" Move "), cmd_buf, MC_HISTORY_FM_TREE_MOVE, default_dest); str_trunc (tree->selected_ptr->name, 50));
if (!dest) dest = input_expand_dialog (_(" Move "), msg, MC_HISTORY_FM_TREE_MOVE, default_dest);
return;
if (!*dest){ if (dest == NULL || *dest == '\0') {
g_free (dest); g_free (dest);
return; return;
} }
if (stat (dest, &buf)){ if (stat (dest, &buf)){
message (D_ERROR, MSG_ERROR, _(" Cannot stat the destination \n %s "), message (D_ERROR, MSG_ERROR, _(" Cannot stat the destination \n %s "),
unix_error_string (errno)); unix_error_string (errno));