--- src/file.c +++ src/file.c @@ -176,15 +176,20 @@ static unsigned char * do_transform_source (FileOpContext *ctx, unsigned char *source) { int j, k, l, len; - unsigned char *fnsource = x_basename (source); + unsigned char *fnsource = g_strdup(x_basename (source)); int next_reg; enum CaseConvs case_conv = NO_CONV; static unsigned char fntarget[MC_MAXPATHLEN]; +#ifdef UTF8 + fix_utf8(fnsource); +#endif + len = strlen (fnsource); j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); if (j != len) { transform_error = FILE_SKIP; + g_free(fnsource); return NULL; } for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { @@ -228,6 +233,7 @@ do_transform_source (FileOpContext *ctx, || ctx->regs.start[next_reg] < 0) { message_1s (1, MSG_ERROR, _(" Invalid target mask ")); transform_error = FILE_ABORT; + g_free(fnsource); return NULL; } for (l = ctx->regs.start[next_reg]; @@ -242,6 +248,7 @@ do_transform_source (FileOpContext *ctx, } } fntarget[k] = 0; + g_free(fnsource); return fntarget; } --- src/filegui.c +++ src/filegui.c @@ -85,6 +85,7 @@ #include "fileopctx.h" /* FILE_CONT */ #include "filegui.h" #include "key.h" /* get_event */ +#include "tty.h" /* }}} */ @@ -869,7 +870,7 @@ fmd_init_i18n (int force) char * file_mask_dialog (FileOpContext *ctx, FileOperation operation, char *text, - char *def_text, int only_one, int *do_background) + char *def_text_orig, int only_one, int *do_background) { int source_easy_patterns = easy_patterns; char *source_mask, *orig_mask, *dest_dir; @@ -877,12 +878,20 @@ file_mask_dialog (FileOpContext *ctx, Fi struct stat buf; int val; QuickDialog Quick_input; - + char *def_text; g_return_val_if_fail (ctx != NULL, NULL); + + def_text = g_strdup(def_text_orig); + #if 0 message_3s (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, def_text); #endif + +#ifdef UTF8 + fix_utf8(def_text); +#endif + fmd_init_i18n (FALSE); /* Set up the result pointers */ @@ -912,8 +921,10 @@ file_mask_dialog (FileOpContext *ctx, Fi *do_background = 0; ask_file_mask: - if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) + if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) { + g_free(def_text); return 0; + } if (ctx->follow_links) ctx->stat_func = (mc_stat_fn) mc_stat; @@ -936,6 +947,7 @@ file_mask_dialog (FileOpContext *ctx, Fi if (!dest_dir || !*dest_dir) { if (source_mask) g_free (source_mask); + g_free(def_text); return dest_dir; } if (source_easy_patterns) { @@ -986,5 +998,6 @@ file_mask_dialog (FileOpContext *ctx, Fi } if (val == B_USER) *do_background = 1; + g_free(def_text); return dest_dir; } --- src/info.c +++ src/info.c @@ -74,10 +74,7 @@ info_show_info (WInfo *info) printw (_("Midnight Commander %s"), VERSION); attrset (NORMAL_COLOR); widget_move (&info->widget, 2, 1); - /* .ado: info->widget.x has wrong value (==0) on Win32, why? */ -#ifndef NATIVE_WIN32 - hline (ACS_HLINE|NORMAL_COLOR, info->widget.x-2); -#endif + hline (ACS_HLINE|NORMAL_COLOR, info->widget.cols-2); if (get_current_type () != view_listing) return; --- src/main.c +++ src/main.c @@ -868,7 +868,7 @@ load_prompt (int fd, void *unused) int prompt_len; prompt = strip_ctrl_codes (subshell_prompt); - prompt_len = strlen (prompt); + prompt_len = mbstrlen (prompt); /* Check for prompts too big */ if (COLS > 8 && prompt_len > COLS - 8) { @@ -1844,7 +1844,7 @@ update_xterm_title_path (void) if (xterm_flag && xterm_title) { p = s = g_strdup (strip_home_and_password (cpanel->cwd)); do { - if (!is_printable (*s)) + if (*s < ' ') *s = '?'; } while (*++s); fprintf (stdout, "\33]0;mc - %s\7", p); --- src/menu.c +++ src/menu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "global.h" #include "tty.h" #include "menu.h" --- src/screen.c +++ src/screen.c @@ -523,6 +523,7 @@ format_file (WPanel *panel, int file_ind #else char buffer[BUF_MEDIUM]; #endif + int txtwidth; length = 0; empty_line = (file_index >= panel->count); @@ -575,13 +576,18 @@ format_file (WPanel *panel, int file_ind if (txtlen < 0) { txt = " "; txtlen = 1; - } else + } else { wide = 1; + txtwidth = wcswidth(buffer, txtlen); + } } else #endif + { txtlen = strlen (txt); + txtwidth = txtlen; + } - over = txtlen > len; + over = txtwidth > len; still = over ? txtlen - len : len - txtlen; switch (HIDE_FIT(format->just_mode)) { @@ -602,19 +608,46 @@ format_file (WPanel *panel, int file_ind #ifdef UTF8 if (over) { if (IS_FIT (format->just_mode)) { - int len2 = len / 2 - 1 + (len % 2); + int n1 = 0; + int width1 = 0; + int n2 = 0; + int width2 = 0; + int len1 = len / 2; + int len2; + + while (1) { + int w = wcwidth(((wchar_t *) buffer)[n1]); + if (width1 + w <= len1) { + width1 += w; + n1++; + } + else + break; + } + len2 = len - width1 - 1; + + while (1) { + int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); + if (width2 + w <= len2) { + width2 += w; + n2++; + } + else + break; + } + - SLsmg_write_nwchars ((wchar_t *) buffer, - len / 2); + SLsmg_write_nwchars ((wchar_t *) buffer, n1); SLsmg_write_nwchars (L"~", 1); + printw ("%*s", len - width1 - width2 - 1, ""); SLsmg_write_nwchars (((wchar_t *) buffer) - + txtlen - len2, len2); + + txtlen - n2, n2); } else SLsmg_write_nwchars ((wchar_t *) buffer, len); } else { printw ("%*s", still, ""); SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); - printw ("%*s", len - txtlen - still, ""); + printw ("%*s", len - txtwidth - still, ""); } #endif } else { @@ -826,8 +859,21 @@ show_dir (WPanel *panel) widget_move (&panel->widget, 0, 3); +#ifndef UTF8 trim (strip_home_and_password (panel->cwd), tmp, - max (panel->widget.cols - 7, 0)); + min(max (panel->widget.cols - 7, 0), 200)); +#else /* UTF8 */ + { + char *tmp2 = g_strdup(panel->cwd); + fix_utf8(tmp2); + trim (strip_home_and_password (tmp2), tmp, + min(max (panel->widget.cols - 7, 0), 200)); + g_free(tmp2); + + } +#endif + + addstr (tmp); widget_move (&panel->widget, 0, 1); addstr ("<"); --- src/util.c +++ src/util.c @@ -84,11 +84,13 @@ mbstrlen (const char *str) if (SLsmg_Is_Unicode) { static mbstate_t s; int len; + const char *str0 = str; len = mbsrtowcs (NULL, &str, -1, &s); if (len < 0) { - memset (&s, 0, sizeof (s)); - return -1; + memset (&s, 0, sizeof (s)); + /* invalid multibyte character, probably not UTF-8 string */ + return strlen (str0); } return len; } else @@ -96,6 +98,33 @@ mbstrlen (const char *str) return strlen (str); } +#ifdef UTF8 + +void +fix_utf8(char *str) +{ + mbstate_t mbs; + + char *p = str; + + while (*p) { + int len; + memset (&mbs, 0, sizeof (mbs)); + len = mbrlen(p, MB_CUR_MAX, &mbs); + if (len == -1) { + *p = '?'; + p++; + } else if (len > 0) { + p += len; + } else { + p++; + } + } +} +#endif + + + int is_printable (int c) { @@ -224,7 +253,23 @@ name_quote (const char *s, int quote_per *d++ = '\\'; break; } +#ifndef UTF8 *d = *s; +#else /* UTF8 */ + { + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + int len = mbrlen(s, MB_CUR_MAX, &mbs); + if (len > 0) { + while (len-- > 1) + *d++ = *s++; + *d = *s; + } else { + *d = '?'; + } + + } +#endif /* UTF8 */ } *d = '\0'; return ret; @@ -916,10 +961,26 @@ char *strip_ctrl_codes (char *s) r++; continue; } - +#ifndef UTF8 if (is_printable(*r)) *w++ = *r; ++r; +#else /* UTF8 */ + { + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + int len = mbrlen(r, MB_CUR_MAX, &mbs); + + if (len > 0 && (unsigned char)*r >= ' ') + while (len--) + *w++ = *r++; + else { + if (len == -1) + *w++ = '?'; + r++; + } + } +#endif /* UTF8 */ } *w = 0; return s; --- src/util.h +++ src/util.h @@ -47,6 +47,7 @@ void init_uid_gid_cache (void); char *get_group (int); char *get_owner (int); +void fix_utf8(char *str); int mbstrlen (const char *); #define MAX_I18NTIMELENGTH 14 --- src/widget.c +++ src/widget.c @@ -134,10 +134,11 @@ button_callback (WButton *b, int Msg, in attrset ((b->selected) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&b->widget, 0, b->hotpos+off); #ifdef UTF8 - SLsmg_write_nwchars (&b->hotwc, 1); -#else - addch ((unsigned char)b->text [b->hotpos]); + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&b->hotwc, 1); + else #endif + addch ((unsigned char)b->text [b->hotpos]); } if (Msg == WIDGET_FOCUS) break; @@ -220,7 +221,7 @@ scan_hotkey(char *text, int *hotposp, in } else #endif { - *hotkeyp = tolower (*cp); + *hotkeyp = tolower (*(cp+1)); *hotposp = cp - text; } strcpy (cp, cp+1); @@ -464,10 +465,11 @@ check_callback (WCheck *c, int Msg, int attrset ((Msg == WIDGET_FOCUS) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&c->widget, 0, + c->hotpos+4); #ifdef UTF8 - SLsmg_write_nwchars (&c->hotwc, 1); -#else - addch ((unsigned char)c->text [c->hotpos]); + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&c->hotwc, 1); + else #endif + addch ((unsigned char)c->text [c->hotpos]); } return 1; }