mc/mc-4.6.2-utf8.patch
Jindrich Novy 63def9a2fa - update to mc-4.6.2 release
- drop .8bit-hex, .preserveattrs, .cloexec, .7zip and part of
    .utf8-look-and-feel patch, applied upstream
- sync the rest of patches, adopt upstream version of UTF8 patch
- update URL and source links
- add required BR
2009-05-27 05:49:13 +00:00

7018 lines
193 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/acinclude.m4 b/acinclude.m4
index f4c0e3b..f7f4fd4 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [
fi
dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks
- if test x$with_screen = xslang; then
- :
- m4_if([$1], strict, ,
- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
-it's not fully supported yet])
- with_screen=mcslang])])
- fi
+dnl if test x$with_screen = xslang; then
+dnl :
+dnl m4_if([$1], strict, ,
+dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
+dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
+dnl it's not fully supported yet])
+dnl with_screen=mcslang])])
+dnl fi
if test x$with_screen = xslang; then
AC_DEFINE(HAVE_SYSTEM_SLANG, 1,
diff --git a/edit/edit-widget.h b/edit/edit-widget.h
index ab55764..fd51aaa 100644
--- a/edit/edit-widget.h
+++ b/edit/edit-widget.h
@@ -30,6 +30,11 @@ typedef struct edit_key_map_type {
long command;
} edit_key_map_type;
+struct action {
+ mc_wchar_t ch;
+ long flags;
+};
+
struct WEdit {
Widget widget;
@@ -42,8 +47,17 @@ struct WEdit {
/* dynamic buffers and cursor position for editor: */
long curs1; /* position of the cursor from the beginning of the file. */
long curs2; /* position from the end of the file */
+#ifndef UTF8
unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+#else /* UTF8 */
+ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
+ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+
+ unsigned char charbuf[MB_LEN_MAX];
+ int charpoint;
+#endif /* UTF8 */
+
/* search variables */
long search_start; /* First character to start searching from */
@@ -87,7 +101,7 @@ struct WEdit {
/* undo stack and pointers */
unsigned long stack_pointer;
- long *undo_stack;
+ struct action *undo_stack;
unsigned long stack_size;
unsigned long stack_size_mask;
unsigned long stack_bottom;
diff --git a/edit/edit.c b/edit/edit.c
index bec84d7..8df473b 100644
--- a/edit/edit.c
+++ b/edit/edit.c
@@ -105,7 +105,11 @@ char *option_backup_ext = NULL;
static void user_menu (WEdit *edit);
+#ifndef UTF8
int edit_get_byte (WEdit * edit, long byte_index)
+#else
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index)
+#endif
{
unsigned long p;
if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0)
@@ -134,7 +138,7 @@ edit_init_buffers (WEdit *edit)
edit->curs1 = 0;
edit->curs2 = 0;
- edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
}
/*
@@ -159,7 +163,7 @@ edit_load_file_fast (WEdit *edit, const char *filename)
}
if (!edit->buffers2[buf2])
- edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
mc_read (file,
(char *) edit->buffers2[buf2] + EDIT_BUF_SIZE -
@@ -169,7 +173,7 @@ edit_load_file_fast (WEdit *edit, const char *filename)
for (buf = buf2 - 1; buf >= 0; buf--) {
/* edit->buffers2[0] is already allocated */
if (!edit->buffers2[buf])
- edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE);
}
@@ -242,9 +246,44 @@ edit_insert_stream (WEdit * edit, FILE * f)
{
int c;
long i = 0;
- while ((c = fgetc (f)) >= 0) {
+#ifndef UTF8
+ while ((c = fgetc (f)) != EOF) {
edit_insert (edit, c);
i++;
+#else /* UTF8 */
+ unsigned char buf[MB_LEN_MAX];
+ int charpos = 0;
+ mbstate_t mbs;
+
+ while ((c = fgetc (f)) != EOF) {
+ mc_wchar_t wc;
+ int size;
+ int j;
+
+ buf[charpos++] = c;
+
+ memset (&mbs, 0, sizeof (mbs));
+ size = mbrtowc(&wc, (char *)buf, charpos, &mbs);
+
+ if (size == -2)
+ continue; /* incomplete */
+
+ else if (size >= 0) {
+ edit_insert (edit, wc);
+ i++;
+ charpos = 0;
+ continue;
+ }
+ else {
+
+ /* invalid */
+#ifdef __STDC_ISO_10646__
+ for (j=0; j<charpos; j++)
+ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[j]);
+#endif
+ charpos = 0;
+ }
+#endif /* UTF8 */
}
return i;
}
@@ -252,9 +291,32 @@ edit_insert_stream (WEdit * edit, FILE * f)
long edit_write_stream (WEdit * edit, FILE * f)
{
long i;
+#ifndef UTF8
for (i = 0; i < edit->last_byte; i++)
if (fputc (edit_get_byte (edit, i), f) < 0)
break;
+#else /* UTF8 */
+ for (i = 0; i < edit->last_byte; i++) {
+ mc_wchar_t wc = edit_get_byte (edit, i);
+ int res;
+ char tmpbuf[MB_LEN_MAX];
+ mbstate_t mbs;
+
+ memset (&mbs, 0, sizeof (mbs));
+
+#ifdef __STDC_ISO_10646__
+ if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) {
+ res = 1;
+ tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET);
+ } else
+#endif
+ res = wcrtomb(tmpbuf, wc, &mbs);
+ if (res > 0) {
+ if (fwrite(tmpbuf, res, 1, f) != 1)
+ break;
+ }
+ }
+#endif /* UTF8 */
return i;
}
@@ -293,12 +355,46 @@ edit_insert_file (WEdit *edit, const char *filename)
int i, file, blocklen;
long current = edit->curs1;
unsigned char *buf;
+#ifdef UTF8
+ mbstate_t mbs;
+ int bufstart = 0;
+
+ memset (&mbs, 0, sizeof (mbs));
+#endif /* UTF8 */
if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1)
return 0;
buf = g_malloc (TEMP_BUF_LEN);
+#ifndef UTF8
while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) {
for (i = 0; i < blocklen; i++)
edit_insert (edit, buf[i]);
+#else /* UTF8 */
+ while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) {
+ blocklen += bufstart;
+ bufstart = 0;
+ for (i = 0; i < blocklen; ) {
+ mc_wchar_t wc;
+ int j;
+ int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs);
+ if (size == -2) { /*incomplete char*/
+ bufstart = blocklen - i;
+ memcpy(buf, buf+i, bufstart);
+ i = blocklen;
+ memset (&mbs, 0, sizeof (mbs));
+ }
+ else if (size <= 0) {
+#ifdef __STDC_ISO_10646__
+ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]);
+#endif
+ memset (&mbs, 0, sizeof (mbs));
+ i++; /* skip broken char */
+ }
+ else {
+ edit_insert (edit, wc);
+ i+=size;
+ }
+ }
+#endif /* UTF8 */
}
edit_cursor_move (edit, current - edit->curs1);
g_free (buf);
@@ -388,7 +484,11 @@ cleanup:
static int
edit_load_file (WEdit *edit)
{
+#ifndef UTF8
int fast_load = 1;
+#else /* UTF8 */
+ int fast_load = 0; /* can't be used with multibyte characters */
+#endif /* UTF8 */
/* Cannot do fast load if a filter is used */
if (edit_find_filter (edit->filename) >= 0)
@@ -454,6 +554,7 @@ edit_load_position (WEdit *edit)
edit->prev_col = column;
edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1));
edit_move_display (edit, line - (edit->num_widget_lines / 2));
+ edit->charpoint = 0;
}
/* Save cursor position in the file */
@@ -537,7 +638,7 @@ edit_init (WEdit *edit, int lines, int columns, const char *filename,
edit_set_filename (edit, filename);
edit->stack_size = START_STACK_SIZE;
edit->stack_size_mask = START_STACK_SIZE - 1;
- edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long));
+ edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action));
if (edit_load_file (edit)) {
/* edit_load_file already gives an error message */
if (to_free)
@@ -692,14 +793,23 @@ void edit_push_action (WEdit * edit, long c,...)
{
unsigned long sp = edit->stack_pointer;
unsigned long spm1;
- long *t;
+
+ struct action *t;
+ mc_wchar_t ch = 0;
+
+ if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) {
+ va_list ap;
+ va_start (ap, c);
+ ch = va_arg (ap, mc_wint_t);
+ va_end (ap);
+ }
/* first enlarge the stack if necessary */
if (sp > edit->stack_size - 10) { /* say */
if (option_max_undo < 256)
option_max_undo = 256;
if (edit->stack_size < (unsigned long) option_max_undo) {
- t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long));
+ t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action));
if (t) {
edit->undo_stack = t;
edit->stack_size <<= 1;
@@ -714,7 +824,7 @@ void edit_push_action (WEdit * edit, long c,...)
#ifdef FAST_MOVE_CURSOR
if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) {
va_list ap;
- edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT;
+ edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT;
edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;
va_start (ap, c);
c = -(va_arg (ap, int));
@@ -725,12 +835,14 @@ void edit_push_action (WEdit * edit, long c,...)
&& spm1 != edit->stack_bottom
&& ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) {
int d;
- if (edit->undo_stack[spm1] < 0) {
- d = edit->undo_stack[(sp - 2) & edit->stack_size_mask];
- if (d == c) {
- if (edit->undo_stack[spm1] > -1000000000) {
+ mc_wchar_t d_ch;
+ if (edit->undo_stack[spm1].flags < 0) {
+ d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags;
+ d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch;
+ if (d == c && d_ch == ch) {
+ if (edit->undo_stack[spm1].flags > -1000000000) {
if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */
- edit->undo_stack[spm1]--;
+ edit->undo_stack[spm1].flags--;
return;
}
}
@@ -738,19 +850,20 @@ void edit_push_action (WEdit * edit, long c,...)
#ifndef NO_STACK_CURSMOVE_ANIHILATION
else if ((c == CURS_LEFT && d == CURS_RIGHT)
|| (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */
- if (edit->undo_stack[spm1] == -2)
+ if (edit->undo_stack[spm1].flags == -2)
edit->stack_pointer = spm1;
else
- edit->undo_stack[spm1]++;
+ edit->undo_stack[spm1].flags++;
return;
}
#endif
} else {
- d = edit->undo_stack[spm1];
- if (d == c) {
+ d = edit->undo_stack[spm1].flags;
+ d_ch = edit->undo_stack[spm1].ch;
+ if (d == c && d_ch == ch) {
if (c >= KEY_PRESS)
return; /* --> no need to push multiple do-nothings */
- edit->undo_stack[sp] = -2;
+ edit->undo_stack[sp].flags = -2;
goto check_bottom;
}
#ifndef NO_STACK_CURSMOVE_ANIHILATION
@@ -762,7 +875,9 @@ void edit_push_action (WEdit * edit, long c,...)
#endif
}
}
- edit->undo_stack[sp] = c;
+ edit->undo_stack[sp].flags = c;
+ edit->undo_stack[sp].ch = ch;
+
check_bottom:
edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;
@@ -775,10 +890,10 @@ void edit_push_action (WEdit * edit, long c,...)
(((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom)
do {
edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask;
- } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer);
+ } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer);
/*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */
- if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS)
+ if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS)
edit->stack_bottom = edit->stack_pointer = 0;
}
@@ -787,30 +902,30 @@ void edit_push_action (WEdit * edit, long c,...)
then the file should be as it was when he loaded up. Then set edit->modified to 0.
*/
static long
-pop_action (WEdit * edit)
+pop_action (WEdit * edit, struct action *c)
{
- long c;
unsigned long sp = edit->stack_pointer;
if (sp == edit->stack_bottom) {
- return STACK_BOTTOM;
+ c->flags = STACK_BOTTOM;
+ return c->flags;
}
sp = (sp - 1) & edit->stack_size_mask;
- if ((c = edit->undo_stack[sp]) >= 0) {
-/* edit->undo_stack[sp] = '@'; */
+ *c = edit->undo_stack[sp];
+ if (edit->undo_stack[sp].flags >= 0) {
edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask;
- return c;
+ return c->flags;
}
if (sp == edit->stack_bottom) {
return STACK_BOTTOM;
}
- c = edit->undo_stack[(sp - 1) & edit->stack_size_mask];
- if (edit->undo_stack[sp] == -2) {
-/* edit->undo_stack[sp] = '@'; */
+ *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask];
+
+ if (edit->undo_stack[sp].flags == -2) {
edit->stack_pointer = sp;
} else
- edit->undo_stack[sp]++;
+ edit->undo_stack[sp].flags++;
- return c;
+ return c->flags;
}
/* is called whenever a modification is made by one of the four routines below */
@@ -831,7 +946,7 @@ static inline void edit_modification (WEdit * edit)
*/
void
-edit_insert (WEdit *edit, int c)
+edit_insert (WEdit *edit, mc_wchar_t c)
{
/* check if file has grown to large */
if (edit->last_byte >= SIZE_LIMIT)
@@ -869,12 +984,11 @@ edit_insert (WEdit *edit, int c)
/* add a new buffer if we've reached the end of the last one */
if (!(edit->curs1 & M_EDIT_BUF_SIZE))
edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] =
- g_malloc (EDIT_BUF_SIZE);
+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
/* perform the insertion */
- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->
- curs1 & M_EDIT_BUF_SIZE]
- = (unsigned char) c;
+ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]
+ [edit->curs1 & M_EDIT_BUF_SIZE] = c;
/* update file length */
edit->last_byte++;
@@ -885,7 +999,7 @@ edit_insert (WEdit *edit, int c)
/* same as edit_insert and move left */
-void edit_insert_ahead (WEdit * edit, int c)
+void edit_insert_ahead (WEdit * edit, mc_wchar_t c)
{
if (edit->last_byte >= SIZE_LIMIT)
return;
@@ -908,7 +1022,7 @@ void edit_insert_ahead (WEdit * edit, int c)
edit->last_get_rule += (edit->last_get_rule >= edit->curs1);
if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE))
- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c;
edit->last_byte++;
@@ -918,7 +1032,7 @@ void edit_insert_ahead (WEdit * edit, int c)
int edit_delete (WEdit * edit)
{
- int p;
+ mc_wint_t p;
if (!edit->curs2)
return 0;
@@ -942,7 +1056,7 @@ int edit_delete (WEdit * edit)
edit->total_lines--;
edit->force |= REDRAW_AFTER_CURSOR;
}
- edit_push_action (edit, p + 256);
+ edit_push_action (edit, CHAR_INSERT_AHEAD, p);
if (edit->curs1 < edit->start_display) {
edit->start_display--;
if (p == '\n')
@@ -956,7 +1070,7 @@ int edit_delete (WEdit * edit)
static int
edit_backspace (WEdit * edit)
{
- int p;
+ mc_wint_t p;
if (!edit->curs1)
return 0;
@@ -980,7 +1094,7 @@ edit_backspace (WEdit * edit)
edit->total_lines--;
edit->force |= REDRAW_AFTER_CURSOR;
}
- edit_push_action (edit, p);
+ edit_push_action (edit, CHAR_INSERT, p);
if (edit->curs1 < edit->start_display) {
edit->start_display--;
@@ -993,10 +1107,18 @@ edit_backspace (WEdit * edit)
#ifdef FAST_MOVE_CURSOR
-static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n)
+static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n)
{
unsigned long next;
+#ifndef UTF8
while ((next = (unsigned long) memccpy (dest, src, '\n', n))) {
+#else /* UTF8 */
+ while (n) {
+ next = 0;
+ while (next < n && src[next]!='\n') next++;
+ if (next < n) next++;
+ wmemcpy (dest, src, next)
+#endif /* UTF8 */
edit->curs_line--;
next -= (unsigned long) dest;
n -= next;
@@ -1009,7 +1131,7 @@ int
edit_move_backward_lots (WEdit *edit, long increment)
{
int r, s, t;
- unsigned char *p;
+ mc_wchar_t *p;
if (increment > edit->curs1)
increment = edit->curs1;
@@ -1049,7 +1171,7 @@ edit_move_backward_lots (WEdit *edit, long increment)
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p;
else
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
- g_malloc (EDIT_BUF_SIZE);
+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
} else {
g_free (p);
}
@@ -1087,7 +1209,7 @@ edit_move_backward_lots (WEdit *edit, long increment)
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p;
else
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
- g_malloc (EDIT_BUF_SIZE);
+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
} else {
g_free (p);
}
@@ -1120,7 +1242,7 @@ void edit_cursor_move (WEdit * edit, long increment)
c = edit_get_byte (edit, edit->curs1 - 1);
if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE))
- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c;
edit->curs2++;
c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE];
@@ -1144,7 +1266,7 @@ void edit_cursor_move (WEdit * edit, long increment)
c = edit_get_byte (edit, edit->curs1);
if (!(edit->curs1 & M_EDIT_BUF_SIZE))
- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
+ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c;
edit->curs1++;
c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1];
@@ -1249,7 +1371,7 @@ long edit_move_forward3 (WEdit * edit, long current, int cols, long upto)
q = edit->last_byte + 2;
for (col = 0, p = current; p < q; p++) {
- int c;
+ mc_wchar_t c;
if (cols != -10) {
if (col == cols)
return p;
@@ -1267,7 +1389,7 @@ long edit_move_forward3 (WEdit * edit, long current, int cols, long upto)
} else if (c < 32 || c == 127)
col += 2; /* Caret notation for control characters */
else
- col++;
+ col += wcwidth(c);
}
return col;
}
@@ -1400,12 +1522,16 @@ static int
is_blank (WEdit *edit, long offset)
{
long s, f;
- int c;
+ mc_wchar_t c;
s = edit_bol (edit, offset);
f = edit_eol (edit, offset) - 1;
while (s <= f) {
c = edit_get_byte (edit, s++);
+#ifndef UTF8
if (!isspace (c))
+#else
+ if (!iswspace (c))
+#endif /* UTF8 */
return 0;
}
return 1;
@@ -1660,6 +1786,7 @@ my_type_of (int c)
return 2;
return 0x80000000UL;
}
+#ifndef UTF8
if (isupper (c))
c = 'A';
else if (islower (c))
@@ -1670,6 +1797,18 @@ my_type_of (int c)
c = '0';
else if (isspace (c))
c = ' ';
+#else
+ if (iswupper (c))
+ c = 'A';
+ else if (iswlower (c))
+ c = 'a';
+ else if (iswalpha (c))
+ c = 'a';
+ else if (iswdigit (c))
+ c = '0';
+ else if (iswspace (c))
+ c = ' ';
+#endif /* UTF8 */
q = strchr (option_chars_move_whole_word, c);
if (!q)
return 0xFFFFFFFFUL;
@@ -1694,10 +1833,18 @@ edit_left_word_move (WEdit *edit, int s)
c2 = edit_get_byte (edit, edit->curs1);
if (!(my_type_of (c1) & my_type_of (c2)))
break;
+#ifndef UTF8
if (isspace (c1) && !isspace (c2))
+#else
+ if (iswspace (c1) && !iswspace (c2))
+#endif /* UTF8 */
break;
if (s)
+#ifndef UTF8
if (!isspace (c1) && isspace (c2))
+#else
+ if (!iswspace (c1) && iswspace (c2))
+#endif /* UTF8 */
break;
}
}
@@ -1720,10 +1867,18 @@ edit_right_word_move (WEdit *edit, int s)
c2 = edit_get_byte (edit, edit->curs1);
if (!(my_type_of (c1) & my_type_of (c2)))
break;
+#ifndef UTF8
if (isspace (c1) && !isspace (c2))
+#else
+ if (iswspace (c1) && !iswspace (c2))
+#endif /* UTF8 */
break;
if (s)
+#ifndef UTF8
if (!isspace (c1) && isspace (c2))
+#else
+ if (!iswspace (c1) && iswspace (c2))
+#endif /* UTF8 */
break;
}
}
@@ -1743,7 +1898,11 @@ static void edit_right_delete_word (WEdit * edit)
break;
c1 = edit_delete (edit);
c2 = edit_get_byte (edit, edit->curs1);
+#ifndef UTF8
if ((isspace (c1) == 0) != (isspace (c2) == 0))
+#else
+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0))
+#endif /* UTF8 */
break;
if (!(my_type_of (c1) & my_type_of (c2)))
break;
@@ -1758,7 +1917,11 @@ static void edit_left_delete_word (WEdit * edit)
break;
c1 = edit_backspace (edit);
c2 = edit_get_byte (edit, edit->curs1 - 1);
+#ifndef UTF8
if ((isspace (c1) == 0) != (isspace (c2) == 0))
+#else
+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0))
+#endif /* UTF8 */
break;
if (!(my_type_of (c1) & my_type_of (c2)))
break;
@@ -1772,13 +1935,13 @@ static void edit_left_delete_word (WEdit * edit)
static void
edit_do_undo (WEdit * edit)
{
- long ac;
+ struct action ac;
long count = 0;
edit->stack_disable = 1; /* don't record undo's onto undo stack! */
- while ((ac = pop_action (edit)) < KEY_PRESS) {
- switch ((int) ac) {
+ while (pop_action (edit, &ac) < KEY_PRESS) {
+ switch ((int) ac.flags) {
case STACK_BOTTOM:
goto done_undo;
case CURS_RIGHT:
@@ -1799,31 +1962,33 @@ edit_do_undo (WEdit * edit)
case COLUMN_OFF:
column_highlighting = 0;
break;
+ case CHAR_INSERT:
+ edit_insert (edit, ac.ch);
+ break;
+ case CHAR_INSERT_AHEAD:
+ edit_insert_ahead (edit, ac.ch);
+ break;
}
- if (ac >= 256 && ac < 512)
- edit_insert_ahead (edit, ac - 256);
- if (ac >= 0 && ac < 256)
- edit_insert (edit, ac);
- if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) {
- edit->mark1 = ac - MARK_1;
+ if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) {
+ edit->mark1 = ac.flags - MARK_1;
edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1);
- } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) {
- edit->mark2 = ac - MARK_2;
+ } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) {
+ edit->mark2 = ac.flags - MARK_2;
edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2);
}
if (count++)
edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */
}
- if (edit->start_display > ac - KEY_PRESS) {
- edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display);
+ if (edit->start_display > ac.flags - KEY_PRESS) {
+ edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display);
edit->force |= REDRAW_PAGE;
- } else if (edit->start_display < ac - KEY_PRESS) {
- edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS);
+ } else if (edit->start_display < ac.flags - KEY_PRESS) {
+ edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS);
edit->force |= REDRAW_PAGE;
}
- edit->start_display = ac - KEY_PRESS; /* see push and pop above */
+ edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */
edit_update_curs_row (edit);
done_undo:;
@@ -2103,7 +2268,7 @@ static void edit_goto_matching_bracket (WEdit *edit)
* passed as -1. Commands are executed, and char_for_insertion is
* inserted at the cursor.
*/
-void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion)
+void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion)
{
if (command == CK_Begin_Record_Macro) {
edit->macro_i = 0;
@@ -2138,7 +2303,7 @@ static const char * const shell_cmd[] = SHELL_COMMANDS_i;
all of them. It also does not check for the Undo command.
*/
void
-edit_execute_cmd (WEdit *edit, int command, int char_for_insertion)
+edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion)
{
edit->force |= REDRAW_LINE;
@@ -2171,7 +2336,7 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion)
}
/* An ordinary key press */
- if (char_for_insertion >= 0) {
+ if (char_for_insertion != (mc_wint_t) -1) {
if (edit->overwrite) {
if (edit_get_byte (edit, edit->curs1) != '\n')
edit_delete (edit);
diff --git a/edit/edit.h b/edit/edit.h
index 4a1c39b..672bf3d 100644
--- a/edit/edit.h
+++ b/edit/edit.h
@@ -25,6 +25,27 @@
#include <stdio.h>
+#include "src/tty.h"
+
+#ifdef UTF8
+#include <wchar.h>
+#include <wctype.h>
+
+#define mc_wchar_t wchar_t
+#define mc_wint_t wint_t
+
+#else
+
+#define mc_wchar_t unsigned char
+#define mc_wint_t int
+
+#endif
+
+
+/* unicode private use area */
+#define BINARY_CHAR_OFFSET 0xFFE00
+
+
#define N_menus 5
#define SEARCH_DIALOG_OPTION_NO_SCANF (1 << 0)
@@ -86,6 +107,8 @@
#define START_STACK_SIZE 32
/* Some codes that may be pushed onto or returned from the undo stack */
+#define CHAR_INSERT 65
+#define CHAR_INSERT_AHEAD 66
#define CURS_LEFT 601
#define CURS_RIGHT 602
#define DELCHAR 603
@@ -105,7 +128,7 @@
struct macro {
short command;
- short ch;
+ mc_wchar_t ch;
};
struct WEdit;
@@ -120,8 +143,12 @@ void edit_reload_menu (void);
void menu_save_mode_cmd (void);
int edit_raw_key_query (const char *heading, const char *query, int cancel);
int edit_file (const char *_file, int line);
-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch);
+int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch);
+#ifndef UTF8
int edit_get_byte (WEdit * edit, long byte_index);
+#else /* UTF8 */
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index);
+#endif /* UTF8 */
int edit_count_lines (WEdit * edit, long current, int upto);
long edit_move_forward (WEdit * edit, long current, int lines, long upto);
long edit_move_forward3 (WEdit * edit, long current, int cols, long upto);
@@ -148,11 +175,11 @@ int edit_block_delete_cmd (WEdit * edit);
void edit_delete_line (WEdit * edit);
int edit_delete (WEdit * edit);
-void edit_insert (WEdit * edit, int c);
+void edit_insert (WEdit * edit, mc_wchar_t c);
void edit_cursor_move (WEdit * edit, long increment);
void edit_push_action (WEdit * edit, long c, ...);
void edit_push_key_press (WEdit * edit);
-void edit_insert_ahead (WEdit * edit, int c);
+void edit_insert_ahead (WEdit * edit, mc_wchar_t c);
long edit_write_stream (WEdit * edit, FILE * f);
char *edit_get_write_filter (const char *writename, const char *filename);
int edit_save_confirm_cmd (WEdit * edit);
@@ -183,7 +210,7 @@ void edit_goto_cmd (WEdit * edit);
int eval_marks (WEdit * edit, long *start_mark, long *end_mark);
void edit_status (WEdit * edit);
void edit_execute_key_command (WEdit *edit, int command,
- int char_for_insertion);
+ mc_wint_t char_for_insertion);
void edit_update_screen (WEdit * edit);
int edit_print_string (WEdit * e, const char *s);
void edit_move_to_line (WEdit * e, long line);
@@ -233,7 +260,7 @@ void edit_mail_dialog (WEdit *edit);
void format_paragraph (WEdit *edit, int force);
/* either command or char_for_insertion must be passed as -1 */
-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion);
+void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion);
#define get_sys_error(s) (s)
diff --git a/edit/editcmd.c b/edit/editcmd.c
index d223c35..b85d9cd 100644
--- a/edit/editcmd.c
+++ b/edit/editcmd.c
@@ -60,7 +60,7 @@
#include "../src/selcodepage.h"
struct selection {
- unsigned char * text;
+ mc_wchar_t *text;
int len;
};
@@ -83,21 +83,16 @@ int edit_confirm_save = 1;
#define MAX_REPL_LEN 1024
static int edit_save_cmd (WEdit *edit);
-static unsigned char *edit_get_block (WEdit *edit, long start,
+static mc_wchar_t *edit_get_block (WEdit *edit, long start,
long finish, int *l);
-static inline int my_lower_case (int c)
+static inline mc_wchar_t my_lower_case (mc_wchar_t c)
{
+#ifndef UTF8
return tolower(c & 0xFF);
-}
-
-static const char *
-strcasechr (const char *s, int c)
-{
- for (c = my_lower_case (c); my_lower_case ((int) *s) != c; ++s)
- if (*s == '\0')
- return 0;
- return s;
+#else
+ return towlower(c);
+#endif
}
#ifndef HAVE_MEMMOVE
@@ -123,11 +118,11 @@ static void *memmove (void *dest, const void *src, size_t n)
#endif /* !HAVE_MEMMOVE */
/* #define itoa MY_itoa <---- this line is now in edit.h */
-static char *
+static mc_wchar_t *
MY_itoa (int i)
{
- static char t[14];
- char *s = t + 13;
+ static mc_wchar_t t[14];
+ mc_wchar_t *s = t + 13;
int j = i;
*s-- = 0;
do {
@@ -212,6 +207,48 @@ void edit_refresh_cmd (WEdit * edit)
doupdate();
}
+#ifdef UTF8
+
+static size_t
+wchar_write(int fd, mc_wchar_t *buf, size_t len)
+{
+ char *tmpbuf = g_malloc(len + MB_LEN_MAX);
+ mbstate_t mbs;
+ size_t i;
+ size_t outlen = 0;
+ size_t res;
+
+ for (i = 0; i < len; i++) {
+ if (outlen >= len) {
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ outlen = 0;
+ }
+ memset (&mbs, 0, sizeof (mbs));
+#ifdef __STDC_ISO_10646__
+ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) {
+ res = 1;
+ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET);
+
+ } else
+#endif
+ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs);
+ if (res > 0) {
+ outlen += res;
+ }
+ }
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ g_free(tmpbuf);
+ return len;
+}
+
+#endif /* UTF8 */
+
/* If 0 (quick save) then a) create/truncate <filename> file,
b) save to <filename>;
if 1 (safe save) then a) save to <tempnam>,
@@ -359,32 +396,48 @@ edit_save_file (WEdit *edit, const char *filename)
buf = 0;
filelen = edit->last_byte;
while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) {
+#ifndef UTF8
if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE)
+#else /* UTF8 */
+ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE)
+#endif /* UTF8 */
!= EDIT_BUF_SIZE) {
mc_close (fd);
goto error_save;
}
buf++;
}
+#ifndef UTF8
if (mc_write
(fd, (char *) edit->buffers1[buf],
+#else /* UTF8 */
+ if (wchar_write
+ (fd, edit->buffers1[buf],
+#endif /* UTF8 */
edit->curs1 & M_EDIT_BUF_SIZE) !=
(edit->curs1 & M_EDIT_BUF_SIZE)) {
filelen = -1;
} else if (edit->curs2) {
edit->curs2--;
buf = (edit->curs2 >> S_EDIT_BUF_SIZE);
- if (mc_write
- (fd,
- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
+#ifndef UTF8
+ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
+#else /* UTF8 */
+ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE -
+#endif /* UTF8 */
(edit->curs2 & M_EDIT_BUF_SIZE) - 1,
1 + (edit->curs2 & M_EDIT_BUF_SIZE)) !=
1 + (edit->curs2 & M_EDIT_BUF_SIZE)) {
filelen = -1;
} else {
while (--buf >= 0) {
+#ifndef UTF8
if (mc_write
(fd, (char *) edit->buffers2[buf],
+#else /* UTF8 */
+ if (wchar_write
+ (fd, edit->buffers2[buf],
+#endif /* UTF8 */
EDIT_BUF_SIZE) != EDIT_BUF_SIZE) {
filelen = -1;
break;
@@ -705,13 +758,21 @@ edit_delete_macro (WEdit * edit, int k)
if (!n || n == EOF)
break;
n = 0;
+#ifndef UTF8
while (fscanf (f, "%hd %hd, ", &macro[n].command, &macro[n].ch))
+#else /* UTF8 */
+ while (fscanf (f, "%hd %lu, ", &macro[n].command, &macro[n].ch))
+#endif /* UTF8 */
n++;
fscanf (f, ";\n");
if (s != k) {
fprintf (g, ("key '%d 0': "), s);
for (i = 0; i < n; i++)
+#ifndef UTF8
fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch);
+#else /* UTF8 */
+ fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch);
+#endif /* UTF8 */
fprintf (g, ";\n");
}
}
@@ -744,7 +805,11 @@ int edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n)
if (f) {
fprintf (f, ("key '%d 0': "), s);
for (i = 0; i < n; i++)
+#ifndef UTF8
fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch);
+#else /* UTF8 */
+ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch);
+#endif /* UTF8 */
fprintf (f, ";\n");
fclose (f);
if (saved_macros_loaded) {
@@ -794,10 +859,18 @@ int edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k)
saved_macro[i++] = s;
if (!found) {
*n = 0;
+#ifndef UTF8
while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", &macro[*n].command, &macro[*n].ch))
+#else /* UTF8 */
+ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", &macro[*n].command, &macro[*n].ch))
+#endif /* UTF8 */
(*n)++;
} else {
+#ifndef UTF8
while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch));
+#else /* UTF8 */
+ while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch));
+#endif /* UTF8 */
}
fscanf (f, ";\n");
if (s == k)
@@ -945,7 +1018,7 @@ int eval_marks (WEdit * edit, long *start_mark, long *end_mark)
#define space_width 1
static void
-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width)
+edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width)
{
long cursor;
int i, col;
@@ -993,7 +1066,7 @@ edit_block_copy_cmd (WEdit *edit)
{
long start_mark, end_mark, current = edit->curs1;
int size;
- unsigned char *copy_buf;
+ mc_wchar_t *copy_buf;
edit_update_curs_col (edit);
if (eval_marks (edit, &start_mark, &end_mark))
@@ -1033,7 +1106,7 @@ edit_block_move_cmd (WEdit *edit)
{
long count;
long current;
- unsigned char *copy_buf;
+ mc_wchar_t *copy_buf;
long start_mark, end_mark;
int deleted = 0;
int x = 0;
@@ -1094,7 +1167,7 @@ edit_block_move_cmd (WEdit *edit)
edit_push_action (edit, COLUMN_ON);
column_highlighting = 0;
} else {
- copy_buf = g_malloc (end_mark - start_mark);
+ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t));
edit_cursor_move (edit, start_mark - edit->curs1);
edit_scroll_screen_over_cursor (edit);
count = start_mark;
@@ -1433,7 +1506,11 @@ static long sargs[NUM_REPL_ARGS][256 / sizeof (long)];
/* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */
/* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */
static int
+#ifndef UTF8
string_regexp_search (char *pattern, char *string, int match_type,
+#else /* UTF8 */
+string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type,
+#endif /* UTF8 */
int match_bol, int icase, int *found_len, void *d)
{
static regex_t r;
@@ -1442,6 +1519,11 @@ string_regexp_search (char *pattern, char *string, int match_type,
regmatch_t *pmatch;
static regmatch_t s[1];
+#ifdef UTF8
+ char *string;
+ int i;
+#endif /* UTF8 */
+
pmatch = (regmatch_t *) d;
if (!pmatch)
pmatch = s;
@@ -1462,13 +1544,51 @@ string_regexp_search (char *pattern, char *string, int match_type,
old_type = match_type;
old_icase = icase;
}
+
+#ifdef UTF8
+ string = wchar_to_mbstr(wstring);
+ if (string == NULL)
+ return -1;
+#endif /* UTF8 */
+
if (regexec
(&r, string, d ? NUM_REPL_ARGS : 1, pmatch,
((match_bol
|| match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) {
*found_len = 0;
+
+#ifdef UTF8
+ g_free(string);
+#endif /* UTF8 */
+
return -1;
}
+
+#ifdef UTF8
+ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) {
+ char tmp;
+ int new_o;
+
+ if (pmatch[i].rm_so < 0)
+ continue;
+ tmp = string[pmatch[i].rm_so];
+ string[pmatch[i].rm_so] = 0;
+ new_o = mbstrlen(string);
+ string[pmatch[i].rm_so] = tmp;
+ pmatch[i].rm_so = new_o;
+
+ if (pmatch[i].rm_eo < 0)
+ continue;
+ tmp = string[pmatch[i].rm_eo];
+ string[pmatch[i].rm_eo] = 0;
+ new_o = mbstrlen(string);
+ string[pmatch[i].rm_eo] = tmp;
+ pmatch[i].rm_eo = new_o;
+ }
+
+ g_free(string);
+#endif /* UTF8 */
+
*found_len = pmatch[0].rm_eo - pmatch[0].rm_so;
return (pmatch[0].rm_so);
}
@@ -1476,13 +1596,29 @@ string_regexp_search (char *pattern, char *string, int match_type,
/* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
(and the above) routines to work properly - paul */
+#ifndef UTF8
typedef int (*edit_getbyte_fn) (WEdit *, long);
+#else /* UTF8 */
+typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long);
+#endif /* UTF8 */
static long
+#ifndef UTF8
edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d)
+#else /* UTF8 */
+edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d)
+#endif /* UTF8 */
{
long p, q = 0;
- long l = strlen ((char *) exp), f = 0;
+ long f = 0;
+
+#ifndef UTF8
+ long l = strlen ((char *) exp);
+#else /* UTF8 */
+ mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb);
+ mc_wchar_t *exp_backup = exp;
+ long l = wcslen(exp);
+#endif /* UTF8 */
int n = 0;
for (p = 0; p < l; p++) /* count conversions... */
@@ -1491,19 +1627,22 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
n++;
if (replace_scanf || replace_regexp) {
- int c;
- unsigned char *buf;
- unsigned char mbuf[MAX_REPL_LEN * 2 + 3];
+ mc_wint_t c;
+ mc_wchar_t *buf;
+ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3];
replace_scanf = (!replace_regexp); /* can't have both */
buf = mbuf;
if (replace_scanf) {
- unsigned char e[MAX_REPL_LEN];
- if (n >= NUM_REPL_ARGS)
- return -3;
-
+ mc_wchar_t e[MAX_REPL_LEN];
+ if (n >= NUM_REPL_ARGS) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
+ return -3;
+ }
if (replace_case) {
for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++)
buf[p - start] = (*get_byte) (data, p);
@@ -1517,20 +1656,36 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
}
buf[(q = p - start)] = 0;
+#ifndef UTF8
strcpy ((char *) e, (char *) exp);
strcat ((char *) e, "%n");
+#else /* UTF8 */
+ wcscpy (e, exp);
+ wcscat (e, L"%n");
+#endif /* UTF8 */
exp = e;
while (q) {
*((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */
+#ifndef UTF8
if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) {
+#else /* UTF8 */
+ if (n == swscanf (buf, exp, SCANF_ARGS)) {
+#endif /* UTF8 */
if (*((int *) sargs[n])) {
*len = *((int *) sargs[n]);
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return start;
}
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
if (q + start < last_byte) {
if (replace_case) {
buf[q] = (*get_byte) (data, q + start);
@@ -1544,7 +1699,11 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
start++;
buf++; /* move the window along */
if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */
+#ifndef UTF8
memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */
+#else /* UTF8 */
+ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */
+#endif /* UTF8 */
buf = mbuf;
}
q--;
@@ -1571,10 +1730,16 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
buf = mbuf;
while (q) {
+#ifndef UTF8
found_start = string_regexp_search ((char *) exp, (char *) buf, match_normal, match_bol, !replace_case, len, d);
-
+#else /* UTF8 */
+ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d);
+#endif /* UTF8 */
if (found_start <= -2) { /* regcomp/regexec error */
*len = 0;
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -3;
}
else if (found_start == -1) /* not found: try next line */
@@ -1585,15 +1750,27 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
match_bol = 0;
continue;
}
- else /* found */
+ else { /* found */
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return (start + offset - q + found_start);
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
if (buf[q - 1] != '\n') { /* incomplete line: try to recover */
buf = mbuf + MAX_REPL_LEN / 2;
+#ifndef UTF8
q = strlen ((const char *) buf);
+#else /* UTF8 */
+ q = wcslen (buf);
+#endif /* UTF8 */
memmove (mbuf, buf, q);
p = start + q;
move_win = 1;
@@ -1603,36 +1780,59 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit
}
}
} else {
+#ifndef UTF8
*len = strlen ((const char *) exp);
+#else /* UTF8 */
+ *len = wcslen (exp);
+#endif /* UTF8 */
if (replace_case) {
for (p = start; p <= last_byte - l; p++) {
- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */
+ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */
for (f = 0, q = 0; q < l && f < 1; q++)
- if ((*get_byte) (data, q + p) != (unsigned char)exp[q])
+ if ((*get_byte) (data, q + p) != exp[q])
f = 1;
- if (f == 0)
+ if (f == 0) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return p;
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
}
} else {
for (p = 0; exp[p] != 0; p++)
exp[p] = my_lower_case (exp[p]);
for (p = start; p <= last_byte - l; p++) {
- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) {
+ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) {
for (f = 0, q = 0; q < l && f < 1; q++)
- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q])
+ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q])
f = 1;
- if (f == 0)
+ if (f == 0) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return p;
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -2;
+ }
}
}
}
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -2;
}
@@ -1646,9 +1846,14 @@ edit_find_forwards (long search_start, unsigned char *exp, int *len, long last_b
while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) {
if (replace_whole) {
+#ifndef UTF8
/*If the bordering chars are not in option_whole_chars_search then word is whole */
if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1))
&& !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len)))
+#else /* UTF8 */
+ if (!iswalnum((*get_byte) (data, p - 1))
+ && !iswalnum((*get_byte) (data, p + *len)))
+#endif /* UTF8 */
return p;
if (once_only)
return -2;
@@ -1680,6 +1885,7 @@ edit_find (long search_start, unsigned char *exp, int *len, long last_byte, edit
#define is_digit(x) ((x) >= '0' && (x) <= '9')
+#ifndef UTF8
#define snprint(v) { \
*p1++ = *p++; \
*p1 = '\0'; \
@@ -1687,33 +1893,48 @@ edit_find (long search_start, unsigned char *exp, int *len, long last_byte, edit
if (n >= (size_t) (e - s)) goto nospc; \
s += n; \
}
+#else /* UTF8 */
+#define snprint(v) { \
+ *p1++ = *p++; \
+ *p1 = '\0'; \
+ n = swprintf(s, e-s, q1,v); \
+ if (n >= (size_t) (e - s)) goto nospc; \
+ s += n; \
+ }
+#endif /* UTF8 */
/* this function uses the sprintf command to do a vprintf */
/* it takes pointers to arguments instead of the arguments themselves */
/* The return value is the number of bytes written excluding '\0'
if successfull, -1 if the resulting string would be too long and
-2 if the format string is errorneous. */
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
- __attribute__ ((format (printf, 3, 4)));
-
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
+static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...)
{
va_list ap;
size_t n;
- const char *q, *p;
- char *s = str, *e = str + size;
- char q1[40];
- char *p1;
+ const mc_wchar_t *q, *p;
+ mc_wchar_t *s = str, *e = str + size;
+ mc_wchar_t q1[40];
+
+ mc_wchar_t *p1;
int nargs = 0;
va_start (ap, fmt);
p = q = fmt;
+#ifndef UTF8
while ((p = strchr (p, '%'))) {
+#else /* UTF8 */
+ while ((p = wcschr (p, L'%'))) {
+#endif /* UTF8 */
n = p - q;
if (n >= (size_t) (e - s))
goto nospc;
+#ifndef UTF8
memcpy (s, q, n); /* copy stuff between format specifiers */
+#else /* UTF8 */
+ wmemcpy (s, q, n); /* copy stuff between format specifiers */
+#endif /* UTF8 */
s += n;
q = p;
p1 = q1;
@@ -1741,45 +1962,78 @@ static int snprintf_p (char *str, size_t size, const char *fmt,...)
*p1++ = *p++;
if (*p == '*') {
p++;
+#ifndef UTF8
strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */
p1 += strlen (p1);
+#else /* UTF8 */
+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */
+ p1 += wcslen (p1);
+#endif /* UTF8 */
} else {
- while (is_digit (*p) && p1 < q1 + 20)
+#ifndef UTF8
+ while (is_digit (*p)
+#else /* UTF8 */
+ while (iswdigit (*p)
+#endif /* UTF8 */
+ && p1 < q1 + 20)
*p1++ = *p++;
+#ifndef UTF8
if (is_digit (*p))
+#else /* UTF8 */
+ if (iswdigit (*p))
+#endif /* UTF8 */
goto err;
}
if (*p == '.')
*p1++ = *p++;
if (*p == '*') {
p++;
+#ifndef UTF8
strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */
p1 += strlen (p1);
+#else /* UTF8 */
+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */
+ p1 += wcslen (p1);
+#endif /* UTF8 */
} else {
- while (is_digit (*p) && p1 < q1 + 32)
+#ifndef UTF8
+ while (is_digit (*p)
+#else /* UTF8 */
+ while (iswdigit (*p)
+#endif /* UTF8 */
+ && p1 < q1 + 32)
*p1++ = *p++;
+#ifndef UTF8
if (is_digit (*p))
+#else /* UTF8 */
+ if (iswdigit (*p))
+#endif /* UTF8 */
goto err;
}
/* flags done, now get argument */
if (*p == 's') {
+#ifndef UTF8
snprint (va_arg (ap, char *));
+#else /* UTF8 */
+ *p1++ = 'l';
+ snprint (va_arg (ap, mc_wchar_t *));
+#endif /* UTF8 */
} else if (*p == 'h') {
- if (strchr ("diouxX", *p))
+ if (*p < 128 && strchr ("diouxX", *p))
snprint (*va_arg (ap, short *));
} else if (*p == 'l') {
*p1++ = *p++;
- if (strchr ("diouxX", *p))
+ if (*p < 128 && strchr ("diouxX", *p))
snprint (*va_arg (ap, long *));
- } else if (strchr ("cdiouxX", *p)) {
+ } else if (*p < 128 && strchr ("cdiouxX", *p)) {
snprint (*va_arg (ap, int *));
} else if (*p == 'L') {
*p1++ = *p++;
- if (strchr ("EefgG", *p))
+ if (*p < 128 && strchr ("EefgG", *p))
snprint (*va_arg (ap, double *)); /* should be long double */
- } else if (strchr ("EefgG", *p)) {
+ } else if (*p < 128 && strchr ("EefgG", *p)) {
snprint (*va_arg (ap, double *));
- } else if (strchr ("DOU", *p)) {
+ } else if (*p < 128 && strchr ("DOU", *p)) {
snprint (*va_arg (ap, long *));
} else if (*p == 'p') {
snprint (*va_arg (ap, void **));
@@ -1788,10 +2042,17 @@ static int snprintf_p (char *str, size_t size, const char *fmt,...)
q = p;
}
va_end (ap);
+#ifndef UTF8
n = strlen (q);
if (n >= (size_t) (e - s))
return -1;
memcpy (s, q, n + 1);
+#else /* UTF8 */
+ n = wcslen (q);
+ if (n >= (size_t) (e - s))
+ return -1;
+ wmemcpy (s, q, n + 1);
+#endif /* UTF8 */
return s + n - str;
nospc:
va_end (ap);
@@ -1970,8 +2231,11 @@ edit_replace_cmd (WEdit *edit, int again)
}
}
if (replace_yes) { /* delete then insert new */
+#ifdef UTF8
+ mc_wchar_t *winput2 = mbstr_to_wchar(input2);
+#endif /* UTF8 */
if (replace_scanf) {
- char repl_str[MAX_REPL_LEN + 2];
+ mc_wchar_t repl_str[MAX_REPL_LEN + 2];
int ret = 0;
/* we need to fill in sargs just like with scanf */
@@ -1980,17 +2244,25 @@ edit_replace_cmd (WEdit *edit, int again)
for (k = 1;
k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0;
k++) {
+#ifndef UTF8
unsigned char *t;
+#else /* UTF8 */
+ mc_wchar_t *t;
+#endif
if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) {
ret = -1;
break;
}
+#ifndef UTF8
t = (unsigned char *) &sargs[k - 1][0];
+#else /* UTF8 */
+ t = (mc_wchar_t *) &sargs[k - 1][0];
+#endif /* UTF8 */
for (j = 0;
j < pmatch[k].rm_eo - pmatch[k].rm_so
&& j < 255; j++, t++)
- *t = (unsigned char) edit_get_byte (edit,
+ *t = edit_get_byte (edit,
edit->
search_start
-
@@ -2008,14 +2280,23 @@ edit_replace_cmd (WEdit *edit, int again)
}
if (!ret)
ret =
+#ifndef UTF8
snprintf_p (repl_str, MAX_REPL_LEN + 2, input2,
+#else /* UTF8 */
+ snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2,
+#endif /* UTF8 */
PRINTF_ARGS);
if (ret >= 0) {
times_replaced++;
while (i--)
edit_delete (edit);
+#ifndef UTF8
while (repl_str[++i])
edit_insert (edit, repl_str[i]);
+#else /* UTF8 */
+ while (winput2[++i])
+ edit_insert (edit, winput2[i]);
+#endif /* UTF8 */
} else {
edit_error_dialog (_(" Replace "),
ret ==
@@ -2029,10 +2310,18 @@ edit_replace_cmd (WEdit *edit, int again)
times_replaced++;
while (i--)
edit_delete (edit);
+#ifndef UTF8
while (input2[++i])
edit_insert (edit, input2[i]);
+#else /* UTF8 */
+ while (winput2[++i])
+ edit_insert (edit, winput2[i]);
+#endif /* UTF8 */
}
edit->found_len = i;
+#ifdef UTF8
+ g_free (winput2);
+#endif /* UTF8 */
}
/* so that we don't find the same string again */
if (replace_backwards) {
@@ -2205,16 +2494,17 @@ edit_ok_to_exit (WEdit *edit)
#define TEMP_BUF_LEN 1024
/* Return a null terminated length of text. Result must be g_free'd */
-static unsigned char *
+static mc_wchar_t *
edit_get_block (WEdit *edit, long start, long finish, int *l)
{
- unsigned char *s, *r;
- r = s = g_malloc (finish - start + 1);
+ mc_wchar_t *s, *r;
+ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t));
if (column_highlighting) {
*l = 0;
/* copy from buffer, excluding chars that are out of the column 'margins' */
while (start < finish) {
- int c, x;
+ mc_wchar_t c;
+ int x;
x = edit_move_forward3 (edit, edit_bol (edit, start), 0,
start);
c = edit_get_byte (edit, start);
@@ -2247,11 +2537,15 @@ edit_save_block (WEdit * edit, const char *filename, long start,
return 0;
if (column_highlighting) {
- unsigned char *block, *p;
+ mc_wchar_t *block, *p;
int r;
p = block = edit_get_block (edit, start, finish, &len);
while (len) {
+#ifndef UTF8
r = mc_write (file, p, len);
+#else /* UTF8 */
+ r = wchar_write (file, p, len);
+#endif /* UTF8 */
if (r < 0)
break;
p += r;
@@ -2259,15 +2553,19 @@ edit_save_block (WEdit * edit, const char *filename, long start,
}
g_free (block);
} else {
- unsigned char *buf;
+ mc_wchar_t *buf;
int i = start, end;
len = finish - start;
- buf = g_malloc (TEMP_BUF_LEN);
+ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t));
while (start != finish) {
end = min (finish, start + TEMP_BUF_LEN);
for (; i < end; i++)
buf[i - start] = edit_get_byte (edit, i);
+#ifndef UTF8
len -= mc_write (file, (char *) buf, end - start);
+#else /* UTF8 */
+ len -= wchar_write (file, buf, end - start);
+#endif /* UTF8 */
start = end;
}
g_free (buf);
@@ -2609,17 +2907,20 @@ edit_block_process_cmd (WEdit *edit, const char *shell_cmd, int block)
/* prints at the cursor */
/* returns the number of chars printed */
+#ifndef UTF8
int edit_print_string (WEdit * e, const char *s)
+#else /* UTF8 */
+int edit_print_wstring (WEdit * e, mc_wchar_t *s)
+#endif /* UTF8 */
{
int i = 0;
while (s[i])
- edit_execute_cmd (e, -1, (unsigned char) s[i++]);
+ edit_execute_cmd (e, -1, s[i++]);
e->force |= REDRAW_COMPLETELY;
edit_update_screen (e);
return i;
}
-
static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc)
{
FILE *p = 0;
@@ -2713,15 +3014,20 @@ void edit_mail_dialog (WEdit * edit)
/* find first character of current word */
static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len)
{
- int i, c, last;
+ int i;
+ mc_wint_t c, last;
/* return if at begin of file */
if (edit->curs1 <= 0)
return 0;
- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1);
+ c = edit_get_byte (edit, edit->curs1 - 1);
/* return if not at end or in word */
+#ifndef UTF8
if (isspace (c) || !(isalnum (c) || c == '_'))
+#else /* UTF8 */
+ if (iswspace (c) || !(iswalnum (c) || c == '_'))
+#endif /* UTF8 */
return 0;
/* search start of word to be completed */
@@ -2731,11 +3037,19 @@ static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len)
return 0;
last = c;
- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i);
+ c = edit_get_byte (edit, edit->curs1 - i);
+#ifndef UTF8
if (!(isalnum (c) || c == '_')) {
+#else /* UTF8 */
+ if (!(iswalnum (c) || c == '_')) {
+#endif /* UTF8 */
/* return if word starts with digit */
+#ifndef UTF8
if (isdigit (last))
+#else /* UTF8 */
+ if (iswdigit (last))
+#endif /* UTF8 */
return 0;
*word_start = edit->curs1 - (i - 1); /* start found */
@@ -2768,7 +3082,7 @@ edit_collect_completions (WEdit *edit, long start, int word_len,
int *num)
{
int len, max_len = 0, i, skip;
- unsigned char *bufpos;
+ mc_wchar_t *bufpos;
/* collect max MAX_WORD_COMPLETIONS completions */
while (*num < MAX_WORD_COMPLETIONS) {
@@ -2787,11 +3101,16 @@ edit_collect_completions (WEdit *edit, long start, int word_len,
buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE];
skip = 0;
for (i = 0; i < *num; i++) {
+#ifndef UTF8
if (strncmp
((char *) &compl[i].text[word_len],
- (char *) &bufpos[word_len], max (len,
- compl[i].len) -
- word_len) == 0) {
+ (char *) &bufpos[word_len],
+#else /* UTF8 */
+ if (wcsncmp
+ ((wchar_t *) &compl[i].text[word_len],
+ (wchar_t *) &bufpos[word_len],
+#endif /* UTF8 */
+ max (len, compl[i].len) - word_len) == 0) {
skip = 1;
break; /* skip it, already added */
}
@@ -2799,7 +3118,7 @@ edit_collect_completions (WEdit *edit, long start, int word_len,
if (skip)
continue;
- compl[*num].text = g_malloc (len + 1);
+ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t));
compl[*num].len = len;
for (i = 0; i < len; i++)
compl[*num].text[i] = *(bufpos + i);
@@ -2813,6 +3132,18 @@ edit_collect_completions (WEdit *edit, long start, int word_len,
return max_len;
}
+#ifdef UTF8
+int edit_print_string (WEdit * e, const char *s)
+{
+ int i;
+ mc_wchar_t *ws = mbstr_to_wchar(s);
+ i = edit_print_wstring (e, ws);
+ g_free(ws);
+ return i;
+}
+
+#endif /* UTF8 */
+
/* let the user select its preferred completion */
static void
@@ -2825,6 +3156,9 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len,
WListbox *compl_list;
int compl_dlg_h; /* completion dialog height */
int compl_dlg_w; /* completion dialog width */
+#ifdef UTF8
+ char *mbtext;
+#endif /* UTF8 */
/* calculate the dialog metrics */
compl_dlg_h = num_compl + 2;
@@ -2860,9 +3194,18 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len,
add_widget (compl_dlg, compl_list);
/* fill the listbox with the completions */
+#ifndef UTF8
for (i = 0; i < num_compl; i++)
listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0,
(char *) compl[i].text, NULL);
+#else /* UTF8 */
+ for (i = 0; i < num_compl; i++) {
+ mbtext = wchar_to_mbstr(compl[i].text);
+ listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0,
+ mbtext, NULL);
+ g_free(mbtext);
+ }
+#endif /* UTF8 */
/* pop up the dialog */
run_dlg (compl_dlg);
@@ -2870,9 +3213,17 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len,
/* apply the choosen completion */
if (compl_dlg->ret_value == B_ENTER) {
listbox_get_current (compl_list, &curr, NULL);
- if (curr)
+ if (curr){
+#ifndef UTF8
for (curr += word_len; *curr; curr++)
edit_insert (edit, *curr);
+#else /* UTF8 */
+ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr);
+ for (wc = wccurr + word_len; *wc; wc++)
+ edit_insert (edit, *wc);
+ g_free(wccurr);
+#endif /* UTF8 */
+ }
}
/* destroy dialog before return */
@@ -2889,8 +3240,9 @@ edit_complete_word_cmd (WEdit *edit)
{
int word_len = 0, i, num_compl = 0, max_len;
long word_start = 0;
- unsigned char *bufpos;
- char *match_expr;
+ mc_wchar_t *bufpos;
+ mc_wchar_t *match_expr;
+ char *mbmatch_expr;
struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */
/* don't want to disturb another search */
@@ -2907,16 +3259,32 @@ edit_complete_word_cmd (WEdit *edit)
/* prepare match expression */
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
[word_start & M_EDIT_BUF_SIZE];
+
+ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t));
+#ifndef UTF8
match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
+#else /* UTF8 */
+ wcsncpy (match_expr, bufpos, word_len);
+ match_expr[word_len] = '\0';
+ wcscat (match_expr, L"[a-zA-Z_0-9]+");
+#endif /* UTF8 */
/* init search: backward, regexp, whole word, case sensitive */
edit_set_search_parameters (0, 1, 1, 1, 1);
/* collect the possible completions */
/* start search from curs1 down to begin of file */
+#ifndef UTF8
max_len =
edit_collect_completions (edit, word_start, word_len, match_expr,
(struct selection *) &compl, &num_compl);
+#else /* UTF8 */
+ mbmatch_expr = wchar_to_mbstr(match_expr);
+ max_len =
+ edit_collect_completions (edit, word_start, word_len, mbmatch_expr,
+ (struct selection *) &compl, &num_compl);
+ g_free(mbmatch_expr);
+#endif /* UTF8 */
if (num_compl > 0) {
/* insert completed word if there is only one match */
@@ -2951,7 +3319,7 @@ void
edit_select_codepage_cmd (WEdit *edit)
{
#ifdef HAVE_CHARSET
- do_select_codepage ();
+ do_select_codepage (_(" Choose codepage "));
edit->force = REDRAW_COMPLETELY;
edit_refresh_cmd (edit);
#endif
diff --git a/edit/editdraw.c b/edit/editdraw.c
index 86ea3f9..654f0b3 100644
--- a/edit/editdraw.c
+++ b/edit/editdraw.c
@@ -71,11 +71,26 @@ static void status_string (WEdit * edit, char *s, int w)
* as decimal and as hex.
*/
if (edit->curs1 < edit->last_byte) {
- unsigned char cur_byte = edit_get_byte (edit, edit->curs1);
+ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1);
+ mc_wchar_t cur_byte2 = cur_byte;
+#ifndef UTF8
g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
is_printable (cur_byte) ? cur_byte : '.',
- (int) cur_byte,
- (unsigned) cur_byte);
+#else /* UTF8 */
+ /* In 8-bit locales show the byte itself instead of its Unicode value */
+ if (MB_CUR_MAX == 1) {
+ unsigned char cur_8bit_byte;
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+ if (wcrtomb(&cur_8bit_byte, cur_byte, &mbs) == 1) {
+ cur_byte = cur_8bit_byte;
+ }
+ }
+ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X",
+ iswprint(cur_byte2) ? cur_byte2 : '.',
+#endif /* UTF8 */
+ (int) cur_byte,
+ (unsigned) cur_byte);
} else {
strcpy (byte_str, "<EOF>");
}
@@ -207,11 +222,16 @@ void edit_scroll_screen_over_cursor (WEdit * edit)
#define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color))
#endif
+struct line_s {
+ mc_wchar_t ch;
+ unsigned int style;
+};
+
static void
print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
- long end_col, unsigned int line[])
+ long end_col, struct line_s line[])
{
- unsigned int *p;
+ struct line_s *p;
int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET;
int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET;
@@ -225,9 +245,9 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y);
p = line;
- while (*p) {
+ while (p->ch) {
int style;
- int textchar;
+ mc_wchar_t textchar;
int color;
if (cols_to_skip) {
@@ -236,9 +256,9 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
continue;
}
- style = *p & 0xFF00;
- textchar = *p & 0xFF;
- color = *p >> 16;
+ style = p->style & 0xFF00;
+ textchar = p->ch;
+ color = p->style >> 16;
if (style & MOD_ABNORMAL) {
/* Non-printable - use black background */
@@ -267,8 +287,11 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
lowlevel_set_color (color);
}
}
-
+#ifdef UTF8
+ SLsmg_write_nwchars(&textchar, 1);
+#else
addch (textchar);
+#endif
p++;
}
}
@@ -280,11 +303,11 @@ static void
edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
long end_col)
{
- static unsigned int line[MAX_LINE_LEN];
- unsigned int *p = line;
+ struct line_s line[MAX_LINE_LEN];
+ struct line_s *p = line;
long m1 = 0, m2 = 0, q, c1, c2;
int col, start_col_real;
- unsigned int c;
+ mc_wint_t c;
int color;
int i;
@@ -309,62 +332,88 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
}
while (col <= end_col - edit->start_col) {
- *p = 0;
+ p->ch = 0;
+ p->style = 0;
if (q == edit->curs1)
- *p |= MOD_CURSOR;
+ p->style |= MOD_CURSOR;
if (q >= m1 && q < m2) {
if (column_highlighting) {
int x;
x = edit_move_forward3 (edit, b, 0, q);
if (x >= c1 && x < c2)
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
} else
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
}
if (q == edit->bracket)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
if (q >= edit->found_start
&& q < edit->found_start + edit->found_len)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
c = edit_get_byte (edit, q);
/* we don't use bg for mc - fg contains both */
edit_get_syntax_color (edit, q, &color);
- *p |= color << 16;
+ p->style |= color << 16;
switch (c) {
case '\n':
col = end_col - edit->start_col + 1; /* quit */
- *(p++) |= ' ';
+ p->ch = ' ';
+ p++;
break;
case '\t':
i = TAB_SIZE - ((int) col % TAB_SIZE);
col += i;
if (use_colors && visible_tabs) {
- c = (*p & ~MOD_CURSOR) | MOD_WHITESPACE;
+ c = (p->style & ~MOD_CURSOR) | MOD_WHITESPACE;
if (i > 2) {
- *(p++) |= '<' | MOD_WHITESPACE;
- while (--i > 1)
- *(p++) = c | '-';
- *(p++) = c | '>';
+ p->ch = '<';
+ p->style |= MOD_WHITESPACE;
+ p++;
+ while (--i > 1) {
+ p->ch = '-';
+ p->style = c;
+ p++;
+ }
+ p->ch = '>';
+ p->style = c;
+ p++;
} else if (i > 1) {
- *(p++) |= '<' | MOD_WHITESPACE;
- *(p++) = c | '>';
- } else
- *(p++) |= '>' | MOD_WHITESPACE;
+ p->ch = '<';
+ p->style |= MOD_WHITESPACE;
+ p++;
+ p->ch = '>';
+ p->style = c;
+ p++;
+ } else {
+ p->ch = '>';
+ p->style |= MOD_WHITESPACE;
+ p++;
+ }
} else if (use_colors && visible_tws && q >= tws) {
- *p |= '.' | MOD_WHITESPACE;
- c = *(p++) & ~MOD_CURSOR;
- while (--i)
- *(p++) = c;
+ p->ch = '.';
+ p->style |= MOD_WHITESPACE;
+ c = p->style & ~MOD_CURSOR;
+ p++;
+ while (--i) {
+ p->ch = '.';
+ p->style = c;
+ p++;
+ }
} else {
- *p |= ' ';
- c = *(p++) & ~MOD_CURSOR;
- while (--i)
- *(p++) = c;
+ p->ch = ' ';
+ c = p->style & ~MOD_CURSOR;
+ p++;
+ while (--i) {
+ p->ch = ' '; p->style = c;
+ p++;
+ }
}
break;
case ' ':
if (use_colors && visible_tws && q >= tws) {
- *(p++) |= '.' | MOD_WHITESPACE;
+ p->ch = '.';
+ p->style |= MOD_WHITESPACE;
+ p++;
col++;
break;
}
@@ -374,22 +423,47 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
/* Caret notation for control characters */
if (c < 32) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = (c + 0x40) | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = c + 0x40;
+ p->style = MOD_ABNORMAL;
col += 2;
break;
}
if (c == 127) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = '?' | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = '?';
+ p->style = MOD_ABNORMAL;
+ p++;
col += 2;
break;
}
- if (is_printable (c)) {
- *(p++) |= c;
+#ifndef UTF8
+ if (is_printable (c)
+#else /* UTF8 */
+ if (iswprint (c)
+#ifdef __STDC_ISO_10646__
+ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256))
+#endif
+#endif /* UTF8 */
+ ) {
+ p->ch = c;
+ p++;
+
+#ifdef UTF8
+ i = wcwidth(c);
+ if (i > 1) {
+ col += i - 1;
+ }
+#endif /* UTF8 */
} else {
- *(p++) = '.' | MOD_ABNORMAL;
+ p->ch = '.';
+ p->style = MOD_ABNORMAL;
+ p++;
}
col++;
break;
@@ -400,7 +474,7 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
} else {
start_col_real = start_col = 0;
}
- *p = 0;
+ p->ch = 0;
print_to_widget (edit, row, start_col, start_col_real, end_col, line);
}
diff --git a/edit/editkeys.c b/edit/editkeys.c
index 2cc6add..111d377 100644
--- a/edit/editkeys.c
+++ b/edit/editkeys.c
@@ -183,10 +183,10 @@ static const edit_key_map_type common_key_map[] = {
* 'command' is one of the editor commands from editcmddef.h.
*/
int
-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
+edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch)
{
int command = CK_Insert_Char;
- int char_for_insertion = -1;
+ mc_wint_t char_for_insertion = -1;
int i = 0;
int extmod = 0;
const edit_key_map_type *key_map = NULL;
@@ -243,9 +243,30 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
/* an ordinary insertable character */
if (x_key < 256 && !extmod) {
int c = convert_from_input_c (x_key);
+#ifdef UTF8
+ mbstate_t mbs;
+ int res;
+ mc_wchar_t wc;
+ memset (&mbs, 0, sizeof (mbs));
+
+ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0;
+
+ edit->charbuf[edit->charpoint++] = c;
+
+ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs);
+ if (res < 0) {
+ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */
+ return 0;
+ }
+ edit->charpoint = 0;
+
+ if (iswprint (wc)) {
+ char_for_insertion = wc;
+#else
if (is_printable (c)) {
char_for_insertion = c;
+#endif /* UTF8 */
goto fin;
}
}
@@ -284,7 +305,7 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
*cmd = command;
*ch = char_for_insertion;
- if (command == CK_Insert_Char && char_for_insertion == -1) {
+ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) {
/* unchanged, key has no function here */
return 0;
}
diff --git a/edit/editwidget.c b/edit/editwidget.c
index 8ae8cf0..286a844 100644
--- a/edit/editwidget.c
+++ b/edit/editwidget.c
@@ -333,7 +333,8 @@ edit_callback (Widget *w, widget_msg_t msg, int parm)
case WIDGET_KEY:
{
- int cmd, ch;
+ int cmd;
+ mc_wint_t ch;
/* The user may override the access-keys for the menu bar. */
if (edit_translate_key (e, parm, &cmd, &ch)) {
diff --git a/edit/wordproc.c b/edit/wordproc.c
index fc16136..25a534e 100644
--- a/edit/wordproc.c
+++ b/edit/wordproc.c
@@ -40,7 +40,12 @@
#define tab_width option_tab_spacing
+#ifndef UTF8
#define NO_FORMAT_CHARS_START "-+*\\,.;:&>"
+#else /* UTF8 */
+#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>"
+#endif /* UTF8 */
+
#define FONT_MEAN_WIDTH 1
static long
@@ -57,14 +62,21 @@ line_start (WEdit *edit, long line)
p = edit_move_forward (edit, p, line - l, 0);
p = edit_bol (edit, p);
+
+#ifndef UTF8
while (strchr ("\t ", edit_get_byte (edit, p)))
+#else /* UTF8 */
+ while (wcschr (L"\t ", edit_get_byte (edit, p)))
+#endif /* UTF8 */
+
p++;
return p;
}
static int bad_line_start (WEdit * edit, long p)
{
- int c;
+ mc_wint_t c;
+
c = edit_get_byte (edit, p);
if (c == '.') { /* `...' is acceptable */
if (edit_get_byte (edit, p + 1) == '.')
@@ -78,7 +90,13 @@ static int bad_line_start (WEdit * edit, long p)
return 0; /* `---' is acceptable */
return 1;
}
+
+#ifndef UTF8
if (strchr (NO_FORMAT_CHARS_START, c))
+#else /* UTF8 */
+ if (wcschr (NO_FORMAT_CHARS_START, c))
+#endif /* UTF8 */
+
return 1;
return 0;
}
@@ -131,33 +149,37 @@ end_paragraph (WEdit *edit, int force)
i - edit->curs_line, 0));
}
-static unsigned char *
+static mc_wchar_t *
get_paragraph (WEdit *edit, long p, long q, int indent, int *size)
{
- unsigned char *s, *t;
+ mc_wchar_t *s, *t;
#if 0
- t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length +
- 10);
+ t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length +
+ 10) * sizeof(mc_wchar_t));
#else
- t = g_malloc (2 * (q - p) + 100);
+ t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t));
#endif
if (!t)
return 0;
for (s = t; p < q; p++, s++) {
if (indent)
if (edit_get_byte (edit, p - 1) == '\n')
+#ifndef UTF8
while (strchr ("\t ", edit_get_byte (edit, p)))
+#else /* UTF8 */
+ while (wcschr (L"\t ", edit_get_byte (edit, p)))
+#endif /* UTF8 */
p++;
*s = edit_get_byte (edit, p);
}
- *size = (unsigned long) s - (unsigned long) t;
+ *size = s - t;
t[*size] = '\n';
return t;
}
-static void strip_newlines (unsigned char *t, int size)
+static void strip_newlines (mc_wchar_t *t, int size)
{
- unsigned char *p = t;
+ mc_wchar_t *p = t;
while (size--) {
*p = *p == '\n' ? ' ' : *p;
p++;
@@ -174,7 +196,7 @@ static inline int next_tab_pos (int x)
{
return x += tab_width - x % tab_width;
}
-static int line_pixel_length (unsigned char *t, long b, int l)
+static int line_pixel_length (mc_wchar_t *t, long b, int l)
{
int x = 0, c, xn = 0;
for (;;) {
@@ -198,7 +220,7 @@ static int line_pixel_length (unsigned char *t, long b, int l)
}
static int
-next_word_start (unsigned char *t, int q, int size)
+next_word_start (mc_wchar_t *t, int q, int size)
{
int i;
int saw_ws = 0;
@@ -222,7 +244,7 @@ next_word_start (unsigned char *t, int q, int size)
/* find the start of a word */
static int
-word_start (unsigned char *t, int q, int size)
+word_start (mc_wchar_t *t, int q, int size)
{
int i = q;
if (t[q] == ' ' || t[q] == '\t')
@@ -241,7 +263,7 @@ word_start (unsigned char *t, int q, int size)
}
/* replaces ' ' with '\n' to properly format a paragraph */
-static void format_this (unsigned char *t, int size, int indent)
+static void format_this (mc_wchar_t *t, int size, int indent)
{
int q = 0, ww;
strip_newlines (t, size);
@@ -269,7 +291,7 @@ static void format_this (unsigned char *t, int size, int indent)
}
}
-static void replace_at (WEdit * edit, long q, int c)
+static void replace_at (WEdit * edit, long q, mc_wint_t c)
{
edit_cursor_move (edit, q - edit->curs1);
edit_delete (edit);
@@ -278,18 +300,27 @@ static void replace_at (WEdit * edit, long q, int c)
/* replaces a block of text */
static void
-put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size)
+put_paragraph (WEdit * edit, mc_wchar_t *t, long p, int indent, int size)
{
long cursor;
- int i, c = 0;
+ int i;
+ mc_wchar_t c = 0;
cursor = edit->curs1;
if (indent)
+#ifndef UTF8
while (strchr ("\t ", edit_get_byte (edit, p)))
+#else /* UTF8 */
+ while (wcschr (L"\t ", edit_get_byte (edit, p)))
+#endif /* UTF8 */
p++;
for (i = 0; i < size; i++, p++) {
if (i && indent) {
if (t[i - 1] == '\n' && c == '\n') {
+#ifndef UTF8
while (strchr ("\t ", edit_get_byte (edit, p)))
+#else /* UTF8 */
+ while (wcschr (L"\t ", edit_get_byte (edit, p)))
+#endif /* UTF8 */
p++;
} else if (t[i - 1] == '\n') {
long curs;
@@ -301,7 +332,11 @@ put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size)
p = edit->curs1;
} else if (c == '\n') {
edit_cursor_move (edit, p - edit->curs1);
+#ifndef UTF8
while (strchr ("\t ", edit_get_byte (edit, p))) {
+#else /* UTF8 */
+ while (wcschr (L"\t ", edit_get_byte (edit, p))) {
+#endif /* UTF8 */
edit_delete (edit);
if (cursor > edit->curs1)
cursor--;
@@ -334,7 +369,7 @@ format_paragraph (WEdit *edit, int force)
{
long p, q;
int size;
- unsigned char *t;
+ mc_wchar_t *t;
int indent = 0;
if (option_word_wrap_line_length < 2)
return;
@@ -348,13 +383,21 @@ format_paragraph (WEdit *edit, int force)
return;
if (!force) {
int i;
+#ifndef UTF8
if (strchr (NO_FORMAT_CHARS_START, *t)) {
+#else /* UTF8 */
+ if (wcschr (NO_FORMAT_CHARS_START, *t)) {
+#endif /* UTF8 */
g_free (t);
return;
}
for (i = 0; i < size - 1; i++) {
if (t[i] == '\n') {
+#ifndef UTF8
if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) {
+#else /* UTF8 */
+ if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) {
+#endif /* UTF8 */
g_free (t);
return;
}
diff --git a/po/ru.po b/po/ru.po
index 5ee11d0..76c3a6b 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -3650,5 +3650,30 @@ msgstr "
#~ " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ~/.mc, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \n"
#~ " <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n"
-#~ msgid "%s bytes in %d files"
-#~ msgstr "%s <20><><EFBFBD><EFBFBD> <20> %d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+#: messages for recode patch
+msgid "Panel &codepage"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose panel codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid " Choose default FTP codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FTP <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid "FTP default codepage:"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FTP <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"
+
+msgid "Recode file names:"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>:"
+
+msgid "Recoding works only with COPY/MOVE operation"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose \"FROM\" codepage for COPY/MOVE operaion "
+msgstr" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid " Choose \"TO\" codepage for COPY/MOVE operaion "
+msgstr" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
diff --git a/src/Makefile.am b/src/Makefile.am
index d43b198..90bd1b1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,7 +41,8 @@ endif
mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \
$(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV)
-CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h
+CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \
+ recode.c recode.h
SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \
chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \
@@ -58,7 +59,7 @@ SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \
menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \
option.c option.h panel.h panelize.c panelize.h poptalloca.h \
popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \
- profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \
+ profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c setup.h \
slint.c subshell.c subshell.h textconf.c textconf.h \
tree.c tree.h treestore.c treestore.h timefmt.h tty.c tty.h user.c \
user.h util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \
diff --git a/src/achown.c b/src/achown.c
index 72ddcad..f1f3024 100644
--- a/src/achown.c
+++ b/src/achown.c
@@ -585,6 +585,12 @@ init_chown_advanced (void)
b_att[2] = button_new (XTRACT (6));
b_user = button_new (XTRACT (5));
b_group = button_new (XTRACT (4));
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1);
+ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1);
+ }
+#endif
add_widget (ch_dlg, b_group);
add_widget (ch_dlg, b_user);
diff --git a/src/boxes.c b/src/boxes.c
index 0ff72d4..82a0e1b 100644
--- a/src/boxes.c
+++ b/src/boxes.c
@@ -53,6 +53,7 @@
#ifdef HAVE_CHARSET
#include "charsets.h"
#include "selcodepage.h"
+#include "recode.h"
#endif
#ifdef USE_NETCODE
@@ -154,23 +155,23 @@ display_init (int radio_sel, char *init_text, int _check_status,
display_title = _(display_title);
for (i = 0; i < LIST_TYPES; i++) {
displays[i] = _(displays[i]);
- if ((l = strlen (displays[i])) > maxlen)
+ if ((l = mbstrlen (displays[i])) > maxlen)
maxlen = l;
}
- i = strlen (ok_button) + 5;
- l = strlen (cancel_button) + 3;
+ i = mbstrlen (ok_button) + 5;
+ l = mbstrlen (cancel_button) + 3;
l = max (i, l);
i = maxlen + l + 16;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (user_mini_status) + 13;
+ i = mbstrlen (user_mini_status) + 13;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (display_title) + 10;
+ i = mbstrlen (display_title) + 10;
if (i > DISPLAY_X)
DISPLAY_X = i;
@@ -290,20 +291,20 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first)
int maxlen = 0;
for (i = SORT_TYPES - 1; i >= 0; i--) {
sort_orders_names[i] = _(sort_orders[i].sort_name);
- r = strlen (sort_orders_names[i]);
+ r = mbstrlen (sort_orders_names[i]);
if (r > maxlen)
maxlen = r;
}
check_pos = maxlen + 9;
- r = strlen (reverse_label) + 4;
- i = strlen (case_label) + 4;
+ r = mbstrlen (reverse_label) + 4;
+ i = mbstrlen (case_label) + 4;
if (i > r)
r = i;
- l = strlen (ok_button) + 6;
- i = strlen (cancel_button) + 4;
+ l = mbstrlen (ok_button) + 6;
+ i = mbstrlen (cancel_button) + 4;
if (i > l)
l = i;
@@ -312,7 +313,7 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first)
if (i > SORT_X)
SORT_X = i;
- i = strlen (sort_title) + 6;
+ i = mbstrlen (sort_title) + 6;
if (i > SORT_X)
SORT_X = i;
@@ -413,7 +414,7 @@ confirm_box (void)
while (i--)
{
conf_widgets [i].text = _(conf_widgets [i].text);
- l1 = strlen (conf_widgets [i].text) + 3;
+ l1 = mbstrlen (conf_widgets [i].text) + 3;
if (l1 > maxlen)
maxlen = l1;
}
@@ -428,8 +429,8 @@ confirm_box (void)
* And this for the case when buttons with some space to the right
* do not fit within 2/6
*/
- l1 = strlen (conf_widgets [0].text) + 3;
- i = strlen (conf_widgets [1].text) + 5;
+ l1 = mbstrlen (conf_widgets [0].text) + 3;
+ i = mbstrlen (conf_widgets [1].text) + 5;
if (i > l1)
l1 = i;
@@ -459,8 +460,8 @@ confirm_box (void)
}
}
-#define DISPY 11
-#define DISPX 46
+#define DISPY 13
+#define DISPX 35
#ifndef HAVE_CHARSET
@@ -502,11 +503,11 @@ display_bits_box (void)
{
display_widgets [i].text = _(display_widgets[i].text);
display_bits_str [i] = _(display_bits_str [i]);
- l1 = strlen (display_bits_str [i]);
+ l1 = mbstrlen (display_bits_str [i]);
if (l1 > maxlen)
maxlen = l1;
}
- l1 = strlen (display_widgets [2].text);
+ l1 = mbstrlen (display_widgets [2].text);
if (l1 > maxlen)
maxlen = l1;
@@ -514,8 +515,8 @@ display_bits_box (void)
display_bits.xlen = (maxlen + 5) * 6 / 4;
/* See above confirm_box */
- l1 = strlen (display_widgets [0].text) + 3;
- i = strlen (display_widgets [1].text) + 5;
+ l1 = mbstrlen (display_widgets [0].text) + 3;
+ i = mbstrlen (display_widgets [1].text) + 5;
if (i > l1)
l1 = i;
@@ -556,23 +557,58 @@ display_bits_box (void)
static int new_display_codepage;
+static int new_ftp_codepage;
-static WLabel *cplabel;
static WCheck *inpcheck;
+static WButton *cpbutton;
+static WButton *cpbutton_ftp;
+
static int
sel_charset_button (int action)
{
const char *cpname;
char buf[64];
- new_display_codepage = select_charset (new_display_codepage, 1);
+ new_display_codepage = select_charset (new_display_codepage, 1, _(" Choose input codepage "));
cpname = (new_display_codepage < 0)
? _("Other 8 bit")
: codepages[new_display_codepage].name;
/* avoid strange bug with label repainting */
- g_snprintf (buf, sizeof (buf), "%-27s", cpname);
- label_set_text (cplabel, buf);
+ sprintf( buf, "%s", cpname );
+ button_set_text (cpbutton, buf);
+
+ if(new_display_codepage<0) new_ftp_codepage=-1;
+ cpname = (new_ftp_codepage < 0)
+ ? _("Other 8 bit")
+ : codepages[ new_ftp_codepage ].name;
+ sprintf( buf, "%s", cpname );
+ button_set_text (cpbutton_ftp, buf);
+
+ return 0;
+}
+
+static int sel_charset_button_ftp(int action) {
+ char *cpname, buf[64];
+ if(new_display_codepage>0) {
+ new_ftp_codepage = select_charset(new_ftp_codepage, 0, _(" Choose default FTP codepage "));
+ cpname = (new_display_codepage < 0)
+ ? _("Other 8 bit")
+ : codepages[ new_display_codepage ].name;
+ sprintf( buf, "%s", cpname );
+ button_set_text( cpbutton, buf );
+ cpname = (new_ftp_codepage < 0)
+ ? _("Other 8 bit")
+ : codepages[ new_ftp_codepage ].name;
+ sprintf( buf, "%s", cpname );
+ button_set_text( cpbutton_ftp, buf );
+ }
+ else {
+ message( 1, _(" Warning "),
+ _("To use this feature select your codepage in\n"
+ "Setup / Display Bits dialog!\n"
+ "Do not forget to save options." ));
+ }
return 0;
}
@@ -594,9 +630,6 @@ init_disp_bits_box (void)
cpname = (new_display_codepage < 0)
? _("Other 8 bit")
: codepages[new_display_codepage].name;
- cplabel = label_new (4, 4, cpname);
- add_widget (dbits_dlg, cplabel);
-
add_widget (dbits_dlg,
button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL,
NORMAL_BUTTON, _("&Cancel"), 0));
@@ -605,13 +638,30 @@ init_disp_bits_box (void)
0));
inpcheck =
- check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input"));
+ check_new (8, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input"));
add_widget (dbits_dlg, inpcheck);
- cpname = _("&Select");
- add_widget (dbits_dlg,
- button_new (4, DISPX - 8 - strlen (cpname), B_USER,
- NORMAL_BUTTON, cpname, sel_charset_button));
+
+ add_widget( dbits_dlg, label_new( 5, 4, _("FTP default codepage:")));
+ if(n_codepages>0) {
+ cpname = (new_display_codepage < 0)
+ ? _("Other 8 bit")
+ : codepages[ new_display_codepage ].name;
+ }
+ else cpname= _("Other 8 bit");
+ cpbutton=button_new(4, 5, B_USER,
+ NORMAL_BUTTON, cpname, sel_charset_button);
+
+ if(n_codepages>0) {
+ cpname = (new_ftp_codepage < 0)
+ ? _("Other 8 bit")
+ : codepages[ new_ftp_codepage ].name;
+ }
+ else cpname= _("Other 8 bit");
+ cpbutton_ftp=button_new(6, 5, B_USER,
+ NORMAL_BUTTON, cpname, sel_charset_button_ftp);
+ add_widget( dbits_dlg, cpbutton_ftp);
+ add_widget (dbits_dlg, cpbutton);
return dbits_dlg;
}
@@ -621,6 +671,7 @@ display_bits_box (void)
{
Dlg_head *dbits_dlg;
new_display_codepage = display_codepage;
+ new_ftp_codepage = ftp_codepage;
application_keypad_mode ();
dbits_dlg = init_disp_bits_box ();
@@ -641,6 +692,17 @@ display_bits_box (void)
&& display_codepage != 1) ? 128 : 160;
#endif
use_8th_bit_as_meta = !(inpcheck->state & C_BOOL);
+
+ ftp_codepage=new_ftp_codepage;
+ if(display_codepage<=0) {
+ panel_reset_codepage(left_panel);
+ paint_dir(left_panel);
+ display_mini_info(left_panel);
+ panel_reset_codepage(right_panel);
+ paint_dir(right_panel);
+ display_mini_info(right_panel);
+ }
+
}
destroy_dlg (dbits_dlg);
repaint_screen ();
@@ -821,7 +883,7 @@ cd_dialog (void)
quick_widgets [1].y_divisions =
quick_widgets [0].y_divisions = Quick_input.ylen = 5;
- len = strlen (quick_widgets [1].text);
+ len = mbstrlen (quick_widgets [1].text);
quick_widgets [0].relative_x =
quick_widgets [1].relative_x + len + 1;
@@ -980,7 +1042,7 @@ jobs_cmd (void)
{
job_buttons [i].name = _(job_buttons [i].name);
- len = strlen (job_buttons [i].name) + 4;
+ len = mbstrlen (job_buttons [i].name) + 4;
JOBS_X = max (JOBS_X, startx + len + 3);
job_buttons [i].xpos = startx;
@@ -989,7 +1051,7 @@ jobs_cmd (void)
/* Last button - Ok a.k.a. Cancel :) */
job_buttons [n_buttons - 1].xpos =
- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7;
+ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7;
i18n_flag = 1;
}
@@ -1047,7 +1109,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain,
while (i--)
{
- l1 = strlen (labs [i] = _(labs [i]));
+ l1 = mbstrlen (labs [i] = _(labs [i]));
if (l1 > maxlen)
maxlen = l1;
}
@@ -1057,7 +1119,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain,
for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; )
{
- l1 += strlen (buts [i] = _(buts [i]));
+ l1 += mbstrlen (buts [i] = _(buts [i]));
}
l1 += 15;
if (l1 > dialog_x)
@@ -1066,7 +1128,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain,
ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
istart = dialog_x - 3 - ilen;
- b2 = dialog_x - (strlen(buts[1]) + 6);
+ b2 = dialog_x - (mbstrlen(buts[1]) + 6);
i18n_flag = 1;
}
diff --git a/src/charsets.c b/src/charsets.c
index f2e69e0..bac7b3b 100644
--- a/src/charsets.c
+++ b/src/charsets.c
@@ -123,8 +123,6 @@ free_codepages_list (void)
}
}
-#define OTHER_8BIT "Other_8_bit"
-
const char *
get_codepage_id (int n)
{
@@ -143,7 +141,7 @@ get_codepage_index (const char *id)
return -1;
}
-static char
+char
translate_character (iconv_t cd, char c)
{
char outbuf[4], *obuf;
diff --git a/src/charsets.h b/src/charsets.h
index b701d5a..0698dc2 100644
--- a/src/charsets.h
+++ b/src/charsets.h
@@ -6,6 +6,7 @@
#define UNKNCHAR '\001'
#define CHARSETS_INDEX "mc.charsets"
+#define OTHER_8BIT "Other_8_bit"
extern int n_codepages;
@@ -19,6 +20,10 @@ struct codepage_desc {
extern struct codepage_desc *codepages;
+#include <iconv.h>
+extern char translate_character(iconv_t cd, char c);
+extern char errbuf[255];
+
const char *get_codepage_id (int n);
int get_codepage_index (const char *id);
int load_codepages_list (void);
diff --git a/src/cmd.c b/src/cmd.c
index f82165c..e24d563 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -73,6 +73,10 @@
# include "../edit/edit.h"
#endif
+#ifdef HAVE_CHARSET
+#include "recode.h"
+#endif
+
/* If set and you don't have subshell support,then C-o will give you a shell */
int output_starts_shell = 0;
@@ -353,6 +357,9 @@ void
mkdir_cmd (void)
{
char *dir, *absdir;
+#ifdef HAVE_CHARSET
+ char *recoded_dir;
+#endif
dir =
input_expand_dialog (_("Create a new Directory"),
@@ -363,8 +370,16 @@ mkdir_cmd (void)
if (dir[0] == '/' || dir[0] == '~')
absdir = g_strdup (dir);
- else
+ else {
+#ifdef HAVE_CHARSET
+ recoded_dir=g_strdup(dir);
+ my_translate_string(dir,strlen(dir), recoded_dir,current_panel->tr_table_input);
+ absdir = mhl_str_dir_plus_file (current_panel->cwd, recoded_dir);
+ g_free(recoded_dir);
+#else
absdir = mhl_str_dir_plus_file (current_panel->cwd, dir);
+#endif
+ }
save_cwds_stat ();
if (my_mkdir (absdir, 0777) == 0) {
diff --git a/src/dialog.c b/src/dialog.c
index f8467b9..43d117f 100644
--- a/src/dialog.c
+++ b/src/dialog.c
@@ -167,7 +167,7 @@ common_dialog_repaint (struct Dlg_head *h)
if (h->title) {
attrset (DLG_HOT_NORMALC (h));
- dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
+ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2);
addstr (h->title);
}
}
diff --git a/src/file.c b/src/file.c
index 6400e3e..056aa11 100644
--- a/src/file.c
+++ b/src/file.c
@@ -79,6 +79,9 @@
#include "../vfs/vfs-impl.h"
/* }}} */
+#ifdef HAVE_CHARSET
+#include "recode.h"
+#endif
/* Hack: the vfs code should not rely on this */
#define WITH_FULL_PATHS 1
@@ -167,15 +170,20 @@ static const char *
do_transform_source (FileOpContext *ctx, const char *source)
{
size_t j, k, l, len;
- const char *fnsource = x_basename (source);
+ char *fnsource = g_strdup (x_basename (source));
int next_reg;
enum CaseConvs case_conv = NO_CONV;
static 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++) {
@@ -225,6 +233,7 @@ do_transform_source (FileOpContext *ctx, const char *source)
|| ctx->regs.start[next_reg] < 0) {
message (1, MSG_ERROR, _(" Invalid target mask "));
transform_error = FILE_ABORT;
+ g_free(fnsource);
return NULL;
}
for (l = (size_t) ctx->regs.start[next_reg];
@@ -239,6 +248,7 @@ do_transform_source (FileOpContext *ctx, const char *source)
}
}
fntarget[k] = 0;
+ g_free(fnsource);
return fntarget;
}
@@ -922,7 +932,12 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel,
}
/* Dive into subdir if exists */
if (toplevel && ctx->dive_into_subdirs) {
+#ifdef HAVE_CHARSET
+ /*FIXME: Use here somehow mhl_str_dir_plus_file */
+ dest_dir = concat_dir_and_recoded_fname(d, x_basename (s), ctx);
+#else
dest_dir = mhl_str_dir_plus_file (d, x_basename (s));
+#endif
} else {
dest_dir = g_strdup (d);
goto dont_mkdir;
@@ -972,7 +987,11 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel,
(*ctx->stat_func) (path, &buf);
if (S_ISDIR (buf.st_mode)) {
+#ifdef HAVE_CHARSET
+ mdpath = concat_dir_and_recoded_fname(dest_dir, next->d_name, ctx);
+#else
mdpath = mhl_str_dir_plus_file (dest_dir, next->d_name);
+#endif
/*
* From here, we just intend to recursively copy subdirs, not
* the double functionality of copying different when the target
@@ -983,7 +1002,11 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel,
parent_dirs, progress_count, progress_bytes);
g_free (mdpath);
} else {
+#ifdef HAVE_CHARSET
+ dest_file=concat_dir_and_recoded_fname(dest_dir, x_basename(path),ctx);
+#else
dest_file = mhl_str_dir_plus_file (dest_dir, x_basename (path));
+#endif
return_status = copy_file_file (ctx, path, dest_file, 1,
progress_count, progress_bytes, 0);
g_free (dest_file);
@@ -1173,7 +1196,12 @@ move_dir_dir (FileOpContext *ctx, const char *s, const char *d,
destdir = g_strdup (d);
move_over = 1;
} else
+#ifdef HAVE_CHARSET
+ destdir = concat_dir_and_recoded_fname(d, x_basename (s), ctx);
+#else
destdir = mhl_str_dir_plus_file (d, x_basename (s));
+#endif
+
if (sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) {
int msize = COLS - 36;
@@ -1700,13 +1728,13 @@ panel_operate_generate_prompt (const WPanel *panel, const int operation,
*dp = '\0';
if (single_source) {
- i = fmd_xlen - strlen (format_string) - 4;
+ i = fmd_xlen - mbstrlen (format_string) - 4;
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
name_trunc (single_source, i));
} else {
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
panel->marked);
- i = strlen (cmd_buf) + 6 - fmd_xlen;
+ i = mbstrlen (cmd_buf) + 6 - fmd_xlen;
if (i > 0) {
fmd_xlen += i;
fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */
@@ -1901,7 +1929,12 @@ panel_operate (void *source_panel, FileOperation operation,
if (temp == NULL) {
value = transform_error;
} else {
+#ifdef HAVE_CHARSET
+ char *temp2 = concat_dir_and_recoded_fname (dest, temp, ctx);
+#else
char *temp2 = mhl_str_dir_plus_file (dest, temp);
+#endif
+
g_free (dest);
dest = temp2;
temp = NULL;
@@ -1995,7 +2028,12 @@ panel_operate (void *source_panel, FileOperation operation,
if (temp == NULL)
value = transform_error;
else {
+#ifdef HAVE_CHARSET
+ char *temp2 = concat_dir_and_recoded_fname(dest, temp, ctx);
+#else
char *temp2 = mhl_str_dir_plus_file (dest, temp);
+#endif
+
source_with_path = mhl_shell_unescape_buf(source_with_path);
temp2 = mhl_shell_unescape_buf(temp2);
diff --git a/src/filegui.c b/src/filegui.c
index 441adb7..e9920d0 100644
--- a/src/filegui.c
+++ b/src/filegui.c
@@ -66,6 +66,11 @@
#include "filegui.h"
#include "key.h" /* get_event */
#include "util.h" /* strip_password() */
+#include "tty.h"
+
+#ifdef HAVE_CHARSET
+#include "recode.h"
+#endif
/* }}} */
@@ -564,8 +569,8 @@ init_replace (FileOpContext *ctx, enum OperationMode mode)
* longest of "Overwrite..." labels
* (assume "Target date..." are short enough)
*/
- l1 = max (strlen (rd_widgets[6].text),
- strlen (rd_widgets[11].text));
+ l1 = max (mbstrlen (rd_widgets[6].text),
+ mbstrlen (rd_widgets[11].text));
/* longest of button rows */
i = sizeof (rd_widgets) / sizeof (rd_widgets[0]);
@@ -576,7 +581,7 @@ init_replace (FileOpContext *ctx, enum OperationMode mode)
l2 = max (l2, l);
l = 0;
}
- l += strlen (rd_widgets[i].text) + 4;
+ l += mbstrlen (rd_widgets[i].text) + 4;
}
}
l2 = max (l2, l); /* last row */
@@ -594,12 +599,12 @@ init_replace (FileOpContext *ctx, enum OperationMode mode)
l = l1;
}
rd_widgets[i].xpos = l;
- l += strlen (rd_widgets[i].text) + 4;
+ l += mbstrlen (rd_widgets[i].text) + 4;
}
}
/* Abort button is centered */
rd_widgets[1].xpos =
- (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2;
+ (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2;
}
#endif /* ENABLE_NLS */
@@ -618,7 +623,7 @@ init_replace (FileOpContext *ctx, enum OperationMode mode)
ADD_RD_LABEL (ui, 0,
name_trunc (ui->replace_filename,
- rd_trunc - strlen (rd_widgets[0].text)), 0);
+ rd_trunc - mbstrlen (rd_widgets[0].text)), 0);
ADD_RD_BUTTON (1);
ADD_RD_BUTTON (2);
@@ -721,57 +726,79 @@ file_progress_real_query_replace (FileOpContext *ctx,
}
}
+#ifdef HAVE_CHARSET
+#define FMDY 15
+#else
#define FMDY 13
+#endif
+
#define FMD_XLEN 64
extern int fmd_xlen;
static QuickWidget fmd_widgets[] = {
-#define FMCB0 FMDC
-#define FMCB12 0
-#define FMCB11 1
- /* follow symlinks and preserve Attributes must be the first */
- {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"), 9, 0,
- 0 /* &op_preserve */ , 0, NULL},
- {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"), 7, 0,
- 0 /* &file_mask_op_follow_links */ , 0, NULL},
- {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, NULL},
- {quick_checkbox, 37, 64, 4, FMDY, N_("&Using shell patterns"), 0, 0,
- 0 /* &source_easy_patterns */ , 0, NULL},
- {quick_input, 3, 64, 3, FMDY, "", 58,
- 0, 0, 0, "input-def"},
-#define FMDI1 4
-#define FMDI2 5
-#define FMDC 3
- {quick_input, 3, 64, 6, FMDY, "", 58, 0,
- 0, 0, "input2"},
-#define FMDI0 6
- {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, NULL},
-#define FMBRGT 7
- {quick_button, 42, 64, 9, FMDY, N_("&Cancel"), 0, B_CANCEL, 0, 0,
- NULL},
-#undef SKIP
+#ifdef HAVE_CHARSET
+ #define Y_OK 12
+#else
+ #define Y_OK 9
+#endif
+
#ifdef WITH_BACKGROUND
-# define SKIP 5
-# define FMCB21 11
-# define FMCB22 10
-# define FMBLFT 9
-# define FMBMID 8
- {quick_button, 25, 64, 9, FMDY, N_("&Background"), 0, B_USER, 0, 0,
- NULL},
-#else /* WITH_BACKGROUND */
-# define SKIP 4
-# define FMCB21 10
-# define FMCB22 9
-# define FMBLFT 8
-# undef FMBMID
+ #define ADD 0
+#else
+ #define ADD -1
#endif
- {quick_button, 14, 64, 9, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, NULL},
- {quick_checkbox, 42, 64, 8, FMDY, N_("&Stable Symlinks"), 0, 0,
- 0 /* &file_mask_stable_symlinks */ , 0, NULL},
- {quick_checkbox, 31, 64, 7, FMDY, N_("&Dive into subdir if exists"), 0,
- 0,
- 0 /* &dive_into_subdirs */ , 0, NULL},
- NULL_QuickWidget
+
+ #define FM_STAB_SYM 0
+ #define FM_DIVE_INTO_SUBDIR 1
+ #define FM_PRES_ATTR 2
+ #define FM_FOLLOW_LINKS 3
+ #define FM_DST_INPUT 4
+ #define FM_DST_TITLE 5
+ #define FM_USING_SHELL_PATT 6
+ #define FM_SRC_INPUT 7
+ #define FM_SRC_TITLE 8
+ #define FM_CANCEL 9
+#ifdef WITH_BACKGROUND
+ #define FM_BKGND 10
+#endif
+ #define FM_OK 11+ADD
+#ifdef HAVE_CHARSET
+ #define FM_TO_CODEPAGE 12+ADD
+ #define FM_FROM_CODEPAGE 13+ADD
+ #define FM_RECODE_TITLE 14+ADD
+ #define FM_RECODE_ARROW 15+ADD
+#endif // HAVE_CHARSET
+
+
+#ifdef HAVE_CHARSET
+ #define SKIP 10
+ #define B_FROM B_USER+1
+ #define B_TO B_USER+2
+#else
+ #define SKIP 10
+#endif
+
+ {quick_checkbox, 42,64, 8, FMDY, N_("&Stable Symlinks"),0,0,0,0,"stab-sym"},
+ {quick_checkbox, 31,64, 7, FMDY, N_("&Dive into subdir if exists"),0,0,0,0,"dive"},
+ {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"),9,0,0,0,"preserve"},
+ {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"),7,0,0,0,"follow"},
+ {quick_input, 3, 64, 6, FMDY, "", 58, 0, 0, 0, "input2"},
+ {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"},
+ {quick_checkbox, 37,64, 4, FMDY, N_("&Using shell patterns"),0,0, 0,0,"us-sh"},
+ {quick_input, 3, 64, 3, FMDY, "", 58, 0, 0, 0, "input-def"},
+ {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"},
+ {quick_button, 42,64, Y_OK, FMDY, N_("&Cancel"), 0, B_CANCEL, 0,0, "cancel"},
+#ifdef WITH_BACKGROUND
+ {quick_button, 25,64, Y_OK, FMDY, N_("&Background"), 0, B_USER, 0,0, "back"},
+#endif
+ {quick_button, 14,64, Y_OK, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"},
+#ifdef HAVE_CHARSET
+ {quick_button, 46,64, 10, FMDY,"to codepage", 0, B_TO, 0, 0, "ql"},
+ {quick_button, 25,64, 10, FMDY, "from codepage", 0, B_FROM, 0, 0, "ql"},
+ {quick_label, 3, 64, 10, FMDY, N_("Recode file names:"), 0, 0, 0, 0, "ql"},
+ {quick_label, 42,64, 10, FMDY, "->", 0, 0, 0, 0, "ql"},
+#endif
+ {0}
};
static int
@@ -805,48 +832,48 @@ fmd_init_i18n (int force)
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;
+ len = mbstrlen (fmd_widgets[FM_FOLLOW_LINKS].text)
+ + mbstrlen (fmd_widgets[FM_DIVE_INTO_SUBDIR].text) + 15;
fmd_xlen = max (fmd_xlen, len);
- len = strlen (fmd_widgets[FMCB12].text)
- + strlen (fmd_widgets[FMCB22].text) + 15;
+ len = mbstrlen (fmd_widgets[FM_PRES_ATTR].text)
+ + mbstrlen (fmd_widgets[FM_STAB_SYM].text) + 15;
fmd_xlen = max (fmd_xlen, len);
- len = strlen (fmd_widgets[FMBRGT].text)
- + strlen (fmd_widgets[FMBLFT].text) + 11;
+ len = mbstrlen (fmd_widgets[FM_CANCEL].text)
+ + mbstrlen (fmd_widgets[FM_OK].text) + 11;
-#ifdef FMBMID
- len += strlen (fmd_widgets[FMBMID].text) + 6;
+#ifdef FM_BKGND
+ len += mbstrlen (fmd_widgets[FM_BKGND].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;
+ i = fmd_widgets[FM_OK].relative_x = len + 3;
+ i += mbstrlen (fmd_widgets[FM_OK].text) + 8;
-#ifdef FMBMID
- fmd_widgets[FMBMID].relative_x = i;
- i += strlen (fmd_widgets[FMBMID].text) + 6;
+#ifdef FM_BKGND
+ fmd_widgets[FM_BKGND].relative_x = i;
+ i += mbstrlen (fmd_widgets[FM_BKGND].text) + 6;
#endif
- fmd_widgets[FMBRGT].relative_x = i;
+ fmd_widgets[FM_CANCEL].relative_x = i;
#define chkbox_xpos(i) \
- fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6
+ fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6
- chkbox_xpos (FMCB0);
- chkbox_xpos (FMCB21);
- chkbox_xpos (FMCB22);
+ chkbox_xpos (FM_USING_SHELL_PATT);
+ chkbox_xpos (FM_DIVE_INTO_SUBDIR);
+ chkbox_xpos (FM_STAB_SYM);
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;
+ fmd_widgets[FM_SRC_INPUT].hotkey_pos =
+ fmd_widgets[FM_DST_INPUT].hotkey_pos = fmd_xlen - 6;
}
#undef chkbox_xpos
@@ -856,7 +883,7 @@ fmd_init_i18n (int force)
char *
file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
- const char *def_text, int only_one, int *do_background)
+ const char *def_text_orig, int only_one, int *do_background)
{
int source_easy_patterns = easy_patterns;
char *source_mask, *orig_mask, *dest_dir, *tmpdest;
@@ -865,20 +892,32 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
struct stat buf;
int val;
QuickDialog Quick_input;
-
+ char *def_text;
+#ifdef HAVE_CHARSET
+ char *errmsg;
+#endif
g_return_val_if_fail (ctx != NULL, NULL);
+
+ def_text = g_strdup(def_text_orig);
+
#if 0
message (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 */
- fmd_widgets[FMCB12].result = &ctx->op_preserve;
- fmd_widgets[FMCB11].result = &ctx->follow_links;
- fmd_widgets[FMCB22].result = &ctx->stable_symlinks;
- fmd_widgets[FMCB21].result = &ctx->dive_into_subdirs;
+ fmd_widgets[FM_PRES_ATTR].result = &ctx->op_preserve;
+ fmd_widgets[FM_FOLLOW_LINKS].result = &ctx->follow_links;
+ fmd_widgets[FM_STAB_SYM].result = &ctx->stable_symlinks;
+ fmd_widgets[FM_DIVE_INTO_SUBDIR].result = &ctx->dive_into_subdirs;
+
/* filter out a possible password from def_text */
def_text_secure = strip_password (g_strdup (def_text), 1);
@@ -886,8 +925,9 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
/* Create the dialog */
ctx->stable_symlinks = 0;
- fmd_widgets[FMDC].result = &source_easy_patterns;
- fmd_widgets[FMDI1].text = easy_patterns ? "*" : "^\\(.*\\)$";
+ fmd_widgets[FM_USING_SHELL_PATT].result = &source_easy_patterns;
+ fmd_widgets[FM_SRC_INPUT].text = easy_patterns ? "*" : "^\\(.*\\)$";
+
Quick_input.xlen = fmd_xlen;
Quick_input.xpos = -1;
Quick_input.title = op_names[operation];
@@ -895,19 +935,37 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
Quick_input.ylen = FMDY;
Quick_input.i18n = 1;
Quick_input.widgets = fmd_widgets;
- fmd_widgets[FMDI0].text = text;
- fmd_widgets[FMDI2].text = def_text_secure;
- fmd_widgets[FMDI2].str_result = &dest_dir;
- fmd_widgets[FMDI1].str_result = &source_mask;
+ fmd_widgets[FM_SRC_TITLE].text = text;
+ fmd_widgets[FM_DST_INPUT].text = def_text_secure;
+ fmd_widgets[FM_DST_INPUT].str_result = &dest_dir;
+ fmd_widgets[FM_SRC_INPUT].str_result = &source_mask;
*do_background = 0;
+
+#ifdef HAVE_CHARSET
+ ctx->from_codepage=current_panel->src_codepage;
+ ctx->to_codepage=left_panel->src_codepage;
+ if (left_panel) {
+ ctx->to_codepage=left_panel->src_codepage;
+ if( (current_panel==left_panel) && right_panel ) ctx->to_codepage=right_panel->src_codepage;
+ }
+#endif
+
ask_file_mask:
+#ifdef HAVE_CHARSET
+ if(operation!=OP_COPY && operation!=OP_MOVE) {
+ ctx->from_codepage=-1;
+ ctx->to_codepage=-1;
+ }
+ fmd_widgets[FM_FROM_CODEPAGE].text=get_codepage_id(ctx->from_codepage);
+ fmd_widgets[FM_TO_CODEPAGE].text=get_codepage_id(ctx->to_codepage);
+#endif
+
if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) {
g_free (def_text_secure);
return 0;
}
- g_free (def_text_secure);
if (ctx->follow_links)
ctx->stat_func = mc_stat;
@@ -929,6 +987,8 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
orig_mask = source_mask;
if (!dest_dir || !*dest_dir) {
g_free (source_mask);
+ g_free (def_text_secure);
+ g_free(def_text);
return dest_dir;
}
if (source_easy_patterns) {
@@ -982,5 +1042,48 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
}
if (val == B_USER)
*do_background = 1;
+#ifdef HAVE_CHARSET
+ if(val == B_FROM) {
+ if(operation==OP_COPY || operation==OP_MOVE) {
+ if(display_codepage<=0) {
+ message( 1, _(" Warning "),
+ _("To use this feature select your codepage in\n"
+ "Setup / Display Bits dialog!\n"
+ "Do not forget to save options." ));
+ goto ask_file_mask;
+ }
+ ctx->from_codepage=select_charset(ctx->from_codepage,0,
+ _(" Choose \"FROM\" codepage for COPY/MOVE operaion "));
+ }
+ else
+ message(1,"Warning",_("Recoding works only with COPY or MOVE operation"));
+ goto ask_file_mask;
+ }
+ if(val == B_TO) {
+ if(operation==OP_COPY || operation==OP_MOVE) {
+ if(display_codepage<=0) {
+ message( 1, _(" Warning "),
+ _("To use this feature select your codepage in\n"
+ "Setup / Display Bits dialog!\n"
+ "Do not forget to save options." ));
+ goto ask_file_mask;
+ }
+ ctx->to_codepage=select_charset(ctx->to_codepage,0,
+ _(" Choose \"TO\" codepage for COPY/MOVE operaion "));
+ }
+ else
+ message(1,"Warning",_("Recoding works only with COPY or MOVE operation"));
+ goto ask_file_mask;
+ }
+
+ errmsg=my_init_tt(ctx->to_codepage,ctx->from_codepage,ctx->tr_table);
+ if(errmsg) {
+ my_reset_tt(ctx->tr_table,256);
+ message( 1, MSG_ERROR, "%s", errmsg);
+ }
+#endif
+
+ g_free(def_text_secure);
+ g_free(def_text);
return dest_dir;
}
diff --git a/src/fileopctx.c b/src/fileopctx.c
index ad02cf4..904b7f8 100644
--- a/src/fileopctx.c
+++ b/src/fileopctx.c
@@ -26,8 +26,12 @@
#include <unistd.h>
#include "global.h"
-#include "fileopctx.h"
+#ifdef HAVE_CHARSET
+#include "recode.h"
+#endif
+
+#include "fileopctx.h"
/**
* file_op_context_new:
@@ -54,6 +58,12 @@ file_op_context_new (FileOperation op)
ctx->umask_kill = 0777777;
ctx->erase_at_end = TRUE;
+#ifdef HAVE_CHARSET
+ ctx->from_codepage=-1;
+ ctx->to_codepage=-1;
+ my_reset_tt(ctx->tr_table,256);
+#endif
+
return ctx;
}
diff --git a/src/fileopctx.h b/src/fileopctx.h
index d2de6a9..339ab42 100644
--- a/src/fileopctx.h
+++ b/src/fileopctx.h
@@ -108,6 +108,14 @@ typedef struct FileOpContext {
/* User interface data goes here */
void *ui;
+
+#ifdef HAVE_CHARSET
+ /* Recode data */
+ int from_codepage, to_codepage;
+ unsigned char tr_table[256];
+ unsigned char recode_buf[MC_MAXPATHLEN];
+#endif
+
} FileOpContext;
diff --git a/src/find.c b/src/find.c
index 9ff1ef7..daa1d5b 100644
--- a/src/find.c
+++ b/src/find.c
@@ -219,7 +219,7 @@ find_parameters (char **start_dir, char **pattern, char **content)
int l1, maxlen = 0;
while (i--) {
- l1 = strlen (labs[i] = _(labs[i]));
+ l1 = mbstrlen (labs[i] = _(labs[i]));
if (l1 > maxlen)
maxlen = l1;
}
@@ -228,7 +228,7 @@ find_parameters (char **start_dir, char **pattern, char **content)
FIND_X = i;
for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) {
- l1 += strlen (buts[i] = _(buts[i]));
+ l1 += mbstrlen (buts[i] = _(buts[i]));
}
l1 += 21;
if (l1 > FIND_X)
@@ -237,8 +237,8 @@ find_parameters (char **start_dir, char **pattern, char **content)
ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */
istart = FIND_X - 3 - ilen;
- b1 = b0 + strlen (buts[0]) + 7;
- b2 = FIND_X - (strlen (buts[2]) + 6);
+ b1 = b0 + mbstrlen (buts[0]) + 7;
+ b2 = FIND_X - (mbstrlen (buts[2]) + 6);
i18n_flag = 1;
case_label = _(case_label);
@@ -865,7 +865,7 @@ setup_gui (void)
if (!i18n_flag) {
register int i = sizeof (fbuts) / sizeof (fbuts[0]);
while (i--)
- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3;
+ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3;
fbuts[2].len += 2; /* DEFPUSH_BUTTON */
i18n_flag = 1;
}
@@ -1030,7 +1030,7 @@ find_file (char *start_dir, char *pattern, char *content, char **dirname,
if (!next_free) /* first turn i.e clean old list */
panel_clean_dir (current_panel);
- list->list[next_free].fnamelen = strlen (name);
+ list->list[next_free].fnamelen = mbstrlen (name);
list->list[next_free].fname = name;
list->list[next_free].f.marked = 0;
list->list[next_free].f.link_to_dir = link_to_dir;
diff --git a/src/help.c b/src/help.c
index 3261cbb..2f5bdac 100644
--- a/src/help.c
+++ b/src/help.c
@@ -416,10 +416,28 @@ static void help_show (Dlg_head *h, const char *paint_start)
#ifndef HAVE_SLANG
addch (acs_map [c]);
#else
+#if defined(UTF8) && SLANG_VERSION < 20000
+ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]);
+#else
SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
+#endif /* UTF8 */
#endif
+ } else {
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ int len;
+ mbstate_t mbs;
+ wchar_t wc;
+ memset (&mbs, 0, sizeof (mbs));
+ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs);
+ if (len <= 0) len = 1; /* skip broken multibyte chars */
+
+ SLsmg_write_nwchars(&wc, 1);
+ p += len - 1;
} else
+#endif
addch (c);
+ }
col++;
break;
}
@@ -772,6 +790,12 @@ interactive_display (const char *filename, const char *node)
message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile,
unix_error_string (errno));
}
+ else
+ {
+ char *conv = utf8_to_local(data);
+ g_free(data);
+ data = conv;
+ }
if (!filename)
g_free (hlpfile);
diff --git a/src/hotlist.c b/src/hotlist.c
index 737c9c1..74f9568 100644
--- a/src/hotlist.c
+++ b/src/hotlist.c
@@ -566,7 +566,7 @@ init_i18n_stuff(int list_type, int cols)
row = hotlist_but [i].y;
++count [row];
- len [row] += strlen (hotlist_but [i].text) + 5;
+ len [row] += mbstrlen (hotlist_but [i].text) + 5;
if (hotlist_but [i].flags == DEFPUSH_BUTTON)
len [row] += 2;
}
@@ -591,12 +591,12 @@ init_i18n_stuff(int list_type, int cols)
/* not first int the row */
if (!strcmp (hotlist_but [i].text, cancel_but))
hotlist_but [i].x =
- cols - strlen (hotlist_but [i].text) - 13;
+ cols - mbstrlen (hotlist_but [i].text) - 13;
else
hotlist_but [i].x = cur_x [row];
}
- cur_x [row] += strlen (hotlist_but [i].text) + 2
+ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2
+ (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3);
}
}
@@ -837,7 +837,7 @@ static void add_widgets_i18n(QuickWidget* qw, int len)
for (i = 0; i < 3; i++)
{
qw [i].text = _(qw [i].text);
- l[i] = strlen (qw [i].text) + 3;
+ l[i] = mbstrlen (qw [i].text) + 3;
}
space = (len - 4 - l[0] - l[1] - l[2]) / 4;
@@ -886,7 +886,7 @@ add_new_entry_input (const char *header, const char *text1, const char *text2,
msglen(text1, &lines1, &cols1);
msglen(text2, &lines2, &cols2);
- len = max ((int) strlen (header), cols1);
+ len = max ((int) mbstrlen (header), cols1);
len = max (len, cols2) + 4;
len = max (len, 64);
@@ -982,7 +982,7 @@ add_new_group_input (const char *header, const char *label, char **result)
#endif /* ENABLE_NLS */
msglen (label, &lines, &cols);
- len = max ((int) strlen (header), cols) + 4;
+ len = max ((int) mbstrlen (header), cols) + 4;
len = max (len, 64);
#ifdef ENABLE_NLS
@@ -1038,7 +1038,7 @@ void add2hotlist_cmd (void)
{
char *prompt, *label;
const char *cp = _("Label for \"%s\":");
- int l = strlen (cp);
+ int l = mbstrlen (cp);
char *label_string = g_strdup (current_panel->cwd);
strip_password (label_string, 1);
diff --git a/src/layout.c b/src/layout.c
index 9f3616f..c759348 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -367,36 +367,36 @@ init_layout (void)
while (i--) {
s_split_direction[i] = _(s_split_direction[i]);
- l1 = strlen (s_split_direction[i]) + 7;
+ l1 = mbstrlen (s_split_direction[i]) + 7;
if (l1 > first_width)
first_width = l1;
}
for (i = 0; i <= 8; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (l1 > first_width)
first_width = l1;
}
- l1 = strlen (title1) + 1;
+ l1 = mbstrlen (title1) + 1;
if (l1 > first_width)
first_width = l1;
- l1 = strlen (title2) + 1;
+ l1 = mbstrlen (title2) + 1;
if (l1 > first_width)
first_width = l1;
- second_width = strlen (title3) + 1;
+ second_width = mbstrlen (title3) + 1;
for (i = 0; i < 6; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (l1 > second_width)
second_width = l1;
}
if (console_flag) {
- l1 = strlen (output_lines_label) + 13;
+ l1 = mbstrlen (output_lines_label) + 13;
if (l1 > second_width)
second_width = l1;
}
@@ -410,14 +410,14 @@ init_layout (void)
*
* Now the last thing to do - properly space buttons...
*/
- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */
- +strlen (save_button) /* notice: it is 3 char less because */
- +strlen (cancel_button); /* of '&' char in button text */
+ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */
+ +mbstrlen (save_button) /* notice: it is 3 char less because */
+ +mbstrlen (cancel_button); /* of '&' char in button text */
i = (first_width + second_width - l1) / 4;
b1 = 5 + i;
- b2 = b1 + strlen (ok_button) + i + 6;
- b3 = b2 + strlen (save_button) + i + 4;
+ b2 = b1 + mbstrlen (ok_button) + i + 6;
+ b3 = b2 + mbstrlen (save_button) + i + 4;
i18n_layt_flag = 1;
}
@@ -681,7 +681,7 @@ setup_panels (void)
panel_do_cols (0);
panel_do_cols (1);
- promptl = strlen (prompt);
+ promptl = mbstrlen (prompt);
widget_set_size (&the_menubar->widget, 0, 0, 1, COLS);
diff --git a/src/learn.c b/src/learn.c
index dff560c..cc6ec93 100644
--- a/src/learn.c
+++ b/src/learn.c
@@ -238,7 +238,7 @@ init_learn (void)
learn_but[0].x = 78 / 2 + 4;
learn_but[1].text = _(learn_but[1].text);
- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9);
+ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9);
learn_title = _(learn_title);
i18n_flag = 1;
diff --git a/src/main.c b/src/main.c
index db26945..edf6a03 100644
--- a/src/main.c
+++ b/src/main.c
@@ -82,6 +82,7 @@
#ifdef HAVE_CHARSET
#include "charsets.h"
+#include "recode.h"
#endif /* HAVE_CHARSET */
#ifdef USE_VFS
@@ -98,6 +99,7 @@
/* The structures for the panels */
WPanel *left_panel = NULL;
WPanel *right_panel = NULL;
+WPanel* ret_panel=NULL;
/* The pointer to the tree */
WTree *the_tree = NULL;
@@ -276,6 +278,9 @@ int midnight_shutdown = 0;
/* The user's shell */
const char *shell = NULL;
+/* Is the LANG UTF-8 ? */
+gboolean is_utf8 = FALSE;
+
/* mc_home: The home of MC */
char *mc_home = NULL;
@@ -587,6 +592,7 @@ _do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type)
}
directory = *new_dir ? new_dir : home_dir;
+ ret_panel=panel;
if (mc_chdir (directory) == -1) {
strcpy (panel->cwd, olddir);
g_free (olddir);
@@ -706,7 +712,7 @@ load_prompt (int fd, void *unused)
int prompt_len;
tmp_prompt = strip_ctrl_codes (subshell_prompt);
- prompt_len = strlen (tmp_prompt);
+ prompt_len = mbstrlen (tmp_prompt);
/* Check for prompts too big */
if (COLS > 8 && prompt_len > COLS - 8) {
@@ -808,6 +814,10 @@ static menu_entry LeftMenu[] = {
{' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd},
{' ', N_("&Info C-x i"), 'I', info_cmd},
{' ', N_("&Tree"), 'T', tree_cmd},
+#ifdef HAVE_CHARSET
+ {' ', "", ' ', 0},
+ {' ', N_("Panel &codepage"), 'C', fnc_l_cmd},
+#endif
{' ', "", ' ', 0},
{' ', N_("&Sort order..."), 'S', sort_cmd},
{' ', "", ' ', 0},
@@ -832,6 +842,10 @@ static menu_entry RightMenu[] = {
{' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd},
{' ', N_("&Info C-x i"), 'I', info_cmd},
{' ', N_("&Tree"), 'T', tree_cmd},
+#ifdef HAVE_CHARSET
+ {' ', "", ' ', 0},
+ {' ', N_("Panel &codepage"), 'C', fnc_r_cmd},
+#endif
{' ', "", ' ', 0},
{' ', N_("&Sort order..."), 'S', sort_cmd},
{' ', "", ' ', 0},
@@ -1614,7 +1628,11 @@ update_xterm_title_path (void)
if (xterm_flag && xterm_title) {
p = s = g_strdup (strip_home_and_password (current_panel->cwd));
do {
+#ifndef UTF8
if (!is_printable ((unsigned char) *s))
+#else /* UTF8 */
+ if (*(unsigned char *)s < ' ')
+#endif /* UTF8 */
*s = '?';
} while (*++s);
if (!alternate_plus_minus)
@@ -2122,6 +2140,16 @@ handle_args (int argc, char *argv[])
int
main (int argc, char *argv[])
{
+ /* Check whether we have UTF-8 locale */
+ char *lang = getenv("LANG");
+ size_t len = 0;
+
+ if ( lang )
+ len = strlen(lang);
+
+ if ( len >= 5 && !strcasecmp(&lang[len-5],"UTF-8") )
+ is_utf8 = TRUE;
+
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
setlocale (LC_ALL, "");
bindtextdomain ("mc", LOCALEDIR);
diff --git a/src/main.h b/src/main.h
index 3f3c695..fca81e7 100644
--- a/src/main.h
+++ b/src/main.h
@@ -69,6 +69,7 @@ extern int alternate_plus_minus;
extern int only_leading_plus_minus;
extern int output_starts_shell;
extern int midnight_shutdown;
+extern gboolean is_utf8;
extern char cmd_buf [512];
extern const char *shell;
diff --git a/src/menu.c b/src/menu.c
index f291071..862eea8 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <sys/types.h>
+#include <wchar.h>
#include "global.h"
#include "tty.h"
@@ -54,35 +55,95 @@ create_menu (const char *name, menu_entry *entries, int count, const char *help_
{
Menu *menu;
const char *cp;
+ int wlen = 0;
+ mbstate_t s;
menu = (Menu *) g_malloc (sizeof (*menu));
menu->count = count;
menu->max_entry_len = 20;
menu->entries = entries;
+ menu->name = g_strdup (name);
+ menu_scan_hotkey (menu);
+#ifdef UTF8
+ menu->wentries = NULL;
+ menu->wname = NULL;
+ if (SLsmg_Is_Unicode) {
+ const char *str = menu->name;
+ memset (&s, 0, sizeof (s));
+ wlen = mbsrtowcs (NULL, &str, -1, &s);
+ if (wlen > 0)
+ ++wlen;
+ else {
+ wlen = 0;
+ memset (&s, 0, sizeof (s));
+ }
+ }
+#endif
if (entries != (menu_entry*) NULL) {
register menu_entry* mp;
for (mp = entries; count--; mp++) {
if (mp->text[0] != '\0') {
+ int len;
#ifdef ENABLE_NLS
mp->text = _(mp->text);
#endif /* ENABLE_NLS */
cp = strchr (mp->text,'&');
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ len = mbstrlen(mp->text) + 1;
+ wlen += len;
+ menu->max_entry_len = max (len - 1, menu->max_entry_len);
+ } else
+#endif
+ len = strlen (mp->text);
if (cp != NULL && *(cp+1) != '\0') {
mp->hot_key = tolower ((unsigned char) *(cp+1));
- menu->max_entry_len = max ((int) (strlen (mp->text) - 1),
- menu->max_entry_len);
+ menu->max_entry_len = max (len - 1, menu->max_entry_len);
} else {
- menu->max_entry_len = max ((int) strlen (mp->text),
- menu->max_entry_len);
+ menu->max_entry_len = max (len, menu->max_entry_len);
}
}
}
}
- menu->name = g_strdup (name);
- menu_scan_hotkey(menu);
+#ifdef UTF8
+ if (wlen) {
+ wchar_t *wp;
+ const char *str;
+ int len;
+
+ menu->wentries = (wchar_t **)
+ g_malloc (sizeof (wchar_t *) * menu->count
+ + wlen * sizeof (wchar_t));
+ wp = (wchar_t *) (menu->wentries + menu->count);
+ str = menu->name;
+ len = mbsrtowcs (wp, &str, wlen, &s);
+ if (len > 0) {
+ menu->wname = wp;
+ wlen -= len + 1;
+ wp += len + 1;
+ } else
+ memset (&s, 0, sizeof (s));
+ if (menu->entries != NULL)
+ for (count = 0; count < menu->count; ++count)
+ if (menu->entries[count].text[0] != '\0') {
+ str = menu->entries[count].text;
+ menu->wentries[count] = wp;
+ len = mbsrtowcs (wp, &str, wlen, &s);
+ if (len > 0) {
+ wlen -= len + 1;
+ wp += len + 1;
+ } else {
+ memset (&s, 0, sizeof (s));
+ *wp++ = L'\0';
+ --wlen;
+ }
+ }
+ }
+#endif
+
menu->start_x = 0;
menu->help_node = g_strdup (help_node);
return menu;
@@ -113,8 +174,26 @@ static void menubar_paint_idx (WMenu *menubar, int idx, int color)
const char *text;
addch((unsigned char)menu->entries [idx].first_letter);
- for (text = menu->entries [idx].text; *text; text++)
- {
+#ifdef UTF8
+ if (menu->wentries) {
+ wchar_t *wtext, *wp;
+
+ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) {
+ if (*wtext == L'&') {
+ if (wtext > wp)
+ SLsmg_write_nwchars (wp, wtext - wp);
+ attrset (color == MENU_SELECTED_COLOR ?
+ MENU_HOTSEL_COLOR : MENU_HOT_COLOR);
+ SLsmg_write_nwchars (++wtext, 1);
+ attrset (color);
+ wp = wtext + 1;
+ }
+ }
+ if (wtext > wp)
+ SLsmg_write_nwchars (wp, wtext - wp);
+ } else
+#endif
+ for (text = menu->entries [idx].text; *text; text++) {
if (*text != '&')
addch(*text);
else {
@@ -123,7 +202,7 @@ static void menubar_paint_idx (WMenu *menubar, int idx, int color)
addch(*(++text));
attrset(color);
}
- }
+ }
}
widget_move (&menubar->widget, y, x + 1);
}
@@ -169,6 +248,12 @@ static void menubar_draw (WMenu *menubar)
if (menubar->active)
attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR);
widget_move (&menubar->widget, 0, menubar->menu [i]->start_x);
+#ifdef UTF8
+ if (menubar->menu [i]->wname)
+ SLsmg_write_nwchars (menubar->menu [i]->wname,
+ wcslen (menubar->menu [i]->wname));
+ else
+#endif
tty_printf ("%s", menubar->menu [i]->name);
}
@@ -494,7 +579,13 @@ menubar_arrange(WMenu* menubar)
for (i = 0; i < items; i++)
{
- int len = strlen(menubar->menu[i]->name);
+ int len;
+#ifdef UTF8
+ if (menubar->menu[i]->wname)
+ len = wcslen (menubar->menu[i]->wname);
+ else
+#endif
+ len = strlen(menubar->menu[i]->name);
menubar->menu[i]->start_x = start_x;
start_x += len + gap;
}
@@ -507,7 +598,13 @@ menubar_arrange(WMenu* menubar)
for (i = 0; i < items; i++)
{
/* preserve length here, to be used below */
- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name));
+#ifdef UTF8
+ if (menubar->menu[i]->wname)
+ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname);
+ else
+#endif
+ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name);
+ gap -= menubar->menu[i]->start_x;
}
gap /= (items - 1);
@@ -531,6 +628,9 @@ menubar_arrange(WMenu* menubar)
void
destroy_menu (Menu *menu)
{
+#ifdef UTF8
+ g_free (menu->wentries);
+#endif
g_free (menu->name);
g_free (menu->help_node);
g_free (menu);
diff --git a/src/menu.h b/src/menu.h
index e3e043e..8f52351 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -21,6 +21,8 @@ typedef struct Menu {
menu_entry *entries;
int start_x; /* position relative to menubar start */
char *help_node;
+ wchar_t **wentries;
+ wchar_t *wname;
} Menu;
extern int menubar_visible;
diff --git a/src/myslang.h b/src/myslang.h
index 17057e7..774b310 100644
--- a/src/myslang.h
+++ b/src/myslang.h
@@ -11,6 +11,16 @@
#endif /* HAVE_SLANG_SLANG_H */
#endif
+#if SLANG_VERSION >= 20000
+#define UTF8 1
+#define SLsmg_Is_Unicode SLsmg_is_utf8_mode()
+void SLsmg_write_nwchars(wchar_t *s, size_t n);
+#endif
+
+#ifdef UTF8
+# include <wchar.h>
+#endif
+
enum {
KEY_BACKSPACE = 400,
KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
diff --git a/src/option.c b/src/option.c
index 2898266..b22c5f2 100644
--- a/src/option.c
+++ b/src/option.c
@@ -124,12 +124,12 @@ init_configure (void)
title2 = _(" Pause after run... ");
title3 = _(" Other options ");
- first_width = strlen (title1) + 1;
- second_width = strlen (title3) + 1;
+ first_width = mbstrlen (title1) + 1;
+ second_width = mbstrlen (title3) + 1;
for (i = 0; check_options[i].text; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (i >= OTHER_OPTIONS) {
if (l1 > first_width)
first_width = l1;
@@ -142,23 +142,23 @@ init_configure (void)
i = PAUSE_OPTIONS;
while (i--) {
pause_options[i] = _(pause_options[i]);
- l1 = strlen (pause_options[i]) + 7;
+ l1 = mbstrlen (pause_options[i]) + 7;
if (l1 > first_width)
first_width = l1;
}
- l1 = strlen (title2) + 1;
+ l1 = mbstrlen (title2) + 1;
if (l1 > first_width)
first_width = l1;
- l1 = 11 + strlen (ok_button)
- + strlen (save_button)
- + strlen (cancel_button);
+ l1 = 11 + mbstrlen (ok_button)
+ + mbstrlen (save_button)
+ + mbstrlen (cancel_button);
i = (first_width + second_width - l1) / 4;
b1 = 5 + i;
- b2 = b1 + strlen (ok_button) + i + 6;
- b3 = b2 + strlen (save_button) + i + 4;
+ b2 = b1 + mbstrlen (ok_button) + i + 6;
+ b3 = b2 + mbstrlen (save_button) + i + 4;
i18n_config_flag = 1;
}
diff --git a/src/panel.h b/src/panel.h
index 844f359..05ec163 100644
--- a/src/panel.h
+++ b/src/panel.h
@@ -72,6 +72,19 @@ typedef struct WPanel {
int searching;
char search_buffer [256];
+
+#ifdef HAVE_CHARSET
+ int src_codepage;
+ unsigned char tr_table[256], tr_table_input[256];
+#endif
+
+#ifdef USE_VFS
+ #ifdef HAVE_CHARSET
+ int ret_codepage;
+ #endif
+ int is_return;
+ char retdir[MC_MAXPATHLEN];
+#endif
} WPanel;
WPanel *panel_new (const char *panel_name);
@@ -97,6 +110,7 @@ int set_panel_formats (WPanel *p);
extern WPanel *left_panel;
extern WPanel *right_panel;
extern WPanel *current_panel;
+extern WPanel* ret_panel;
void try_to_select (WPanel *panel, const char *name);
diff --git a/src/panelize.c b/src/panelize.c
index ef80619..d932241 100644
--- a/src/panelize.c
+++ b/src/panelize.c
@@ -129,7 +129,7 @@ init_panelize (void)
i = sizeof (panelize_but) / sizeof (panelize_but[0]);
while (i--) {
panelize_but[i].text = _(panelize_but[i].text);
- maxlen += strlen (panelize_but[i].text) + 5;
+ maxlen += mbstrlen (panelize_but[i].text) + 5;
}
maxlen += 10;
@@ -138,11 +138,11 @@ init_panelize (void)
panelize_cols = max (panelize_cols, maxlen);
panelize_but[2].x =
- panelize_but[3].x + strlen (panelize_but[3].text) + 7;
+ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7;
panelize_but[1].x =
- panelize_but[2].x + strlen (panelize_but[2].text) + 5;
+ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5;
panelize_but[0].x =
- panelize_cols - strlen (panelize_but[0].text) - 8 - BX;
+ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX;
#endif /* ENABLE_NLS */
diff --git a/src/recode.c b/src/recode.c
new file mode 100644
index 0000000..b485dfc
--- /dev/null
+++ b/src/recode.c
@@ -0,0 +1,153 @@
+#include "recode.h"
+#ifdef HAVE_CHARSET
+
+char *lang;
+char lang_codepage_name[256];
+int lang_codepage;
+
+int ftp_codepage=-1;
+
+// recode buffer for displaying file names
+unsigned char recode_buf[MC_MAXPATHLEN];
+
+WPanel* recode_panel;
+
+//--- get codepage from $LANG
+void get_locale_codepage() {
+ char* a;
+ char* b;
+ int len;
+
+ lang=getenv("LANG");
+ if(!lang) {
+ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT));
+ lang_codepage=-1;
+ return;
+ }
+
+ a=strchr(lang,'.');
+ if(!a) {
+ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT));
+ lang_codepage=-1;
+ return;
+ }
+ ++a;
+
+ b=strchr(lang,'@');
+ if(!b) b=lang+strlen(lang);
+
+ len=b-a;
+ if(len>=sizeof(lang_codepage_name)) len=sizeof(lang_codepage_name)-1;
+
+ memcpy(lang_codepage_name,a, len);
+ lang_codepage_name[len]='\0';
+ lang_codepage=get_codepage_index(lang_codepage_name);
+ if(lang_codepage<0) strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT));
+}
+
+//--- reset translation table
+void my_reset_tt(unsigned char *table,int n) {
+ int i;
+ for(i=0;i<n;i++) table[i]=i;
+}
+
+//--- reset panel codepage
+void panel_reset_codepage(WPanel *p) {
+ p->src_codepage=-1;
+ my_reset_tt(p->tr_table,256);
+ my_reset_tt(p->tr_table_input,256);
+}
+
+//--- Initialize translation table
+// i need this function because init_translation_table from
+// charsets.c fills only fixed translation tables conv_displ and conv_input
+//---
+char* my_init_tt( int from, int to, unsigned char *table) {
+ int i;
+ iconv_t cd;
+ char *cpfrom, *cpto;
+
+ if(from < 0 || to < 0 || from == to) {
+ my_reset_tt(table,256);
+ return NULL;
+ }
+ my_reset_tt(table,128);
+ cpfrom=codepages[from ].id;
+ cpto=codepages[to].id;
+ cd=iconv_open(cpfrom, cpto);
+ if(cd==(iconv_t)-1) {
+ snprintf(errbuf, 255, _("Cannot translate from %s to %s"), cpfrom, cpto);
+ return errbuf;
+ }
+ for(i=128; i<=255; ++i) table[i] = translate_character(cd, i);
+ iconv_close(cd);
+ return NULL;
+}
+
+//--- Translate string from one codepage to another
+void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table) {
+ int i=0;
+ if(!s1) return;
+ while(i<l1) {
+ s2[i]=table[s1[i]];
+ i++;
+ }
+ s2[i]=0;
+}
+
+//--- Recode filename and concat in to dir
+char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx) {
+ int i = strlen (dir);
+
+ my_translate_string((unsigned char*)fname,strlen(fname),ctx->recode_buf,ctx->tr_table);
+ if (dir [i-1] == PATH_SEP)
+ return g_strconcat (dir, ctx->recode_buf, NULL);
+ else
+ return g_strconcat (dir, PATH_SEP_STR, ctx->recode_buf, NULL);
+ return 0;
+}
+
+
+//--- Internal handler for "Panel codepage"
+static void fnc_cmd(WPanel *p) {
+ char *errmsg;
+ if(display_codepage > 0) {
+ p->src_codepage=select_charset(p->src_codepage, 0, _(" Choose panel codepage "));
+ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table);
+ if(errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg);
+ }
+ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input);
+ if (errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+ paint_dir(p);
+ show_dir(p);
+ display_mini_info(p);
+ }
+ else {
+ message( 1, _(" Warning "),
+ _("To use this feature select your codepage in\n"
+ "Setup / Display Bits dialog!\n"
+ "Do not forget to save options." ));
+ }
+}
+
+//--- Menu handlers for "Panel codepage" for left and right panel menu
+
+void fnc_l_cmd() {
+ fnc_cmd(left_panel);
+}
+
+void fnc_r_cmd() {
+ fnc_cmd(right_panel);
+}
+
+//--- screen handler for "Panel codepage"
+void fnc_c_cmd(WPanel *panel) {
+ fnc_cmd(current_panel);
+}
+
+#endif //HAVE_CHARSET
diff --git a/src/recode.h b/src/recode.h
new file mode 100644
index 0000000..8e817ea
--- /dev/null
+++ b/src/recode.h
@@ -0,0 +1,48 @@
+#ifndef __RECODE_H__
+#define __RECODE_H__
+#include <config.h>
+#ifdef HAVE_CHARSET
+
+#include <stdio.h>
+#include <locale.h>
+#include <iconv.h>
+
+#include "global.h"
+#include "wtools.h"
+#include "panel.h"
+#include "charsets.h"
+#include "selcodepage.h"
+#include "screen.h"
+#include "main.h"
+#include "fileopctx.h"
+
+extern char *lang;
+extern char lang_codepage_name[256];
+extern int lang_codepage;
+
+extern int ftp_codepage;
+
+// recode buffer for displaying file names
+extern unsigned char recode_buf[MC_MAXPATHLEN];
+extern WPanel* recode_panel;
+
+//--- get codepage from $LANG
+extern void get_locale_codepage();
+
+//--- reset translation table
+extern void my_reset_tt(unsigned char *table,int n);
+//--- reset panel codepage
+extern void panel_reset_codepage(WPanel *p);
+//--- Initialize translation table
+extern char* my_init_tt( int from, int to, unsigned char *table);
+//--- Translate string from one codepage to another
+extern void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table);
+//--- Recode filename and concat in to dir
+extern char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx);
+//--- handlers for "Panel codepage"
+extern void fnc_l_cmd();
+extern void fnc_r_cmd();
+extern void fnc_c_cmd(WPanel *panel);
+
+#endif // HAVE_CHARSET
+#endif //__RECODE_H__
diff --git a/src/screen.c b/src/screen.c
index 6c3821b..1f938bc 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -52,6 +52,10 @@
#include "main.h" /* the_menubar */
#include "unixcompat.h"
+#ifdef HAVE_CHARSET
+#include "recode.h"
+#endif
+
#define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) )
#define J_LEFT 1
@@ -173,21 +177,64 @@ add_permission_string (char *dest, int width, file_entry *fe, int attr, int colo
static const char *
string_file_name (file_entry *fe, int len)
{
- static char buffer [MC_MAXPATHLEN + 1];
size_t i;
+ char* filename;
- for (i = 0; i < sizeof(buffer) - 1; i++) {
- char c;
+#ifdef UTF8
+ static char buffer [BUF_SMALL * 4];
+ mbstate_t s;
+ int mbmax = MB_CUR_MAX;
+ const char *str = fe->fname;
- c = fe->fname[i];
+ memset (&s, 0, sizeof (s));
+#else
+ static char buffer [BUF_SMALL];
+#endif
- if (!c)
- break;
+#ifdef HAVE_CHARSET
+ my_translate_string(fe->fname,fe->fnamelen, recode_buf, recode_panel->tr_table);
+ filename= recode_buf;
+#else
+ filename=fe->fname;
+#endif
- if (!is_printable(c))
- c = '?';
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ for (i = 0; i < sizeof (buffer) - 1; i++) {
+ wchar_t wc;
+ int len;
- buffer[i] = c;
+ len = mbrtowc (&wc, str, mbmax, &s);
+ if (!len)
+ break;
+ if (len < 0) {
+ memset (&s, 0, sizeof (s));
+ buffer[i] = '?';
+ str++;
+ continue;
+ }
+ if (!is_printable (wc)) {
+ buffer[i] = '?';
+ str++;
+ continue;
+ }
+ if (i >= sizeof (buffer) - len)
+ break;
+ memcpy (buffer + i, str, len);
+ i += len - 1;
+ str += len;
+ } else
+#endif
+ for (i = 0; i < sizeof(buffer) - 1; i++) {
+ char c;
+
+ c = filename[i];
+
+ if (!c) break;
+
+ if (!is_printable(c)) c = '?';
+
+ buffer[i] = c;
}
buffer[i] = 0;
@@ -452,42 +499,6 @@ static struct {
{ "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL },
};
-static char *
-to_buffer (char *dest, int just_mode, int len, const char *txt)
-{
- int txtlen = strlen (txt);
- int still, over;
-
- /* Fill buffer with spaces */
- memset (dest, ' ', len);
-
- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen);
-
- switch (HIDE_FIT(just_mode)){
- case J_LEFT:
- still = 0;
- break;
- case J_CENTER:
- still /= 2;
- break;
- case J_RIGHT:
- default:
- break;
- }
-
- if (over){
- if (IS_FIT(just_mode))
- strcpy (dest, name_trunc(txt, len));
- else
- strncpy (dest, txt+still, len);
- } else
- strncpy (dest+still, txt, txtlen);
-
- dest[len] = '\0';
-
- return (dest + len);
-}
-
static int
file_compute_color (int attr, file_entry *fe)
{
@@ -541,14 +552,18 @@ file_compute_color (int attr, file_entry *fe)
/* Formats the file number file_index of panel in the buffer dest */
static void
-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus)
+format_file (WPanel *panel, int file_index, int width, int attr, int isstatus)
{
int color, length, empty_line;
const char *txt;
- char *old_pos;
- char *cdest = dest;
format_e *format, *home;
file_entry *fe;
+#ifdef UTF8
+ char buffer[BUF_MEDIUM * sizeof (wchar_t)];
+#else
+ char buffer[BUF_MEDIUM];
+#endif
+ int txtwidth = 0;
length = 0;
empty_line = (file_index >= panel->count);
@@ -566,34 +581,137 @@ format_file (char *dest, int limit, WPanel *panel, int file_index, int width, in
break;
if (format->string_fn){
- int len;
+ int len, still, over, perm, txtlen, wide;
if (empty_line)
txt = " ";
else
txt = (*format->string_fn)(fe, format->field_len);
- old_pos = cdest;
-
len = format->field_len;
if (len + length > width)
len = width - length;
- if (len + (cdest - dest) > limit)
- len = limit - (cdest - dest);
+ if (len >= BUF_MEDIUM)
+ len = BUF_MEDIUM - 1;
if (len <= 0)
break;
- cdest = to_buffer (cdest, format->just_mode, len, txt);
- length += len;
- attrset (color);
+ perm = 0;
+ if (permission_mode) {
+ if (!strcmp(format->id, "perm"))
+ perm = 1;
+ else if (!strcmp(format->id, "mode"))
+ perm = 2;
+ }
- if (permission_mode && !strcmp(format->id, "perm"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 0);
- else if (permission_mode && !strcmp(format->id, "mode"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 1);
- else
- addstr (old_pos);
+ wide = 0;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode && !empty_line && !perm) {
+ mbstate_t s;
+ const char *str = txt;
+
+ memset (&s, 0, sizeof (s));
+ txtlen = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t), &s);
+ if (txtlen < 0) {
+ txt = " ";
+ txtlen = 1;
+ } else {
+ wide = 1;
+ txtwidth = wcswidth((wchar_t*)buffer, txtlen);
+ }
+ } else
+#endif
+ {
+ txtlen = mbstrlen (txt);
+ txtwidth = txtlen;
+ }
+
+ over = txtwidth > len;
+ still = over ? txtlen - len : len - txtlen;
+
+ switch (HIDE_FIT(format->just_mode)) {
+ case J_LEFT:
+ still = 0;
+ break;
+ case J_CENTER:
+ still /= 2;
+ break;
+ case J_RIGHT:
+ default:
+ break;
+ }
+
+ attrset (color);
+
+ if (wide) {
+#ifdef UTF8
+ if (over) {
+ if (IS_FIT (format->just_mode)) {
+ 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, n1);
+ SLsmg_write_nwchars (L"~", 1);
+ printw ("%*s", len - width1 - width2 - 1, "");
+ SLsmg_write_nwchars (((wchar_t *) buffer)
+ + txtlen - n2, n2);
+ } else
+ SLsmg_write_nwchars ((wchar_t *) buffer + still, len);
+ } else {
+ printw ("%*s", still, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen);
+ printw ("%*s", len - txtwidth - still, "");
+ }
+#endif
+ } else {
+ if (over) {
+ if (IS_FIT (format->just_mode))
+ strcpy (buffer, name_trunc(txt, len));
+ else
+ memcpy (buffer, txt + still, len);
+ } else {
+ memset (buffer, ' ', still);
+ memcpy (buffer + still, txt, txtlen);
+ memset (buffer + still + txtlen, ' ',
+ len - txtlen - still);
+ }
+ buffer[len] = '\0';
+
+ if (perm)
+ add_permission_string (buffer, format->field_len, fe,
+ attr, color, perm - 1);
+ else
+ addstr (buffer);
+ }
+ length += len;
} else {
if (attr == SELECTED || attr == MARKED_SELECTED)
attrset (SELECTED_COLOR);
@@ -616,7 +734,10 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus)
{
int second_column = 0;
int width, offset;
- char buffer [BUF_MEDIUM];
+
+#ifdef HAVE_CHARSET
+ recode_panel=panel;
+#endif
offset = 0;
if (!isstatus && panel->split){
@@ -645,7 +766,7 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus)
widget_move (&panel->widget, file_index - panel->top_file + 2, 1);
}
- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus);
+ format_file (panel, file_index, width, attr, isstatus);
if (!isstatus && panel->split){
if (second_column)
@@ -657,7 +778,7 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus)
}
}
-static void
+void
display_mini_info (WPanel *panel)
{
if (!show_mini_info)
@@ -694,7 +815,7 @@ display_mini_info (WPanel *panel)
ngettext("%s in %d file", "%s in %d files", panel->marked),
b_bytes, panel->marked);
- if ((int) strlen (buffer) > cols-2){
+ if ((int) mbstrlen (buffer) > cols-2){
buffer [cols] = 0;
p += 2;
} else
@@ -727,7 +848,7 @@ display_mini_info (WPanel *panel)
return;
}
-static void
+void
paint_dir (WPanel *panel)
{
int i;
@@ -765,7 +886,7 @@ mini_info_separator (WPanel *panel)
#endif /* !HAVE_SLANG */
}
-static void
+void
show_dir (WPanel *panel)
{
char *tmp;
@@ -785,6 +906,9 @@ show_dir (WPanel *panel)
}
#endif /* HAVE_SLANG */
+ vscrollbar (panel->widget, panel->widget.lines, panel->widget.cols-1, 2, 2,
+ panel->selected, panel->count, TRUE);
+
if (panel->active)
attrset (REVERSE_COLOR);
@@ -794,8 +918,15 @@ show_dir (WPanel *panel)
tmp = g_malloc (panel->widget.cols + 1);
tmp[panel->widget.cols] = '\0';
+#ifdef HAVE_CHARSET
+ my_translate_string(panel->cwd,strlen(panel->cwd),recode_buf, panel->tr_table);
+ trim (strip_home_and_password (recode_buf), tmp,
+ min (max (panel->widget.cols - 7, 0), panel->widget.cols) );
+ #else
trim (strip_home_and_password (panel->cwd), tmp,
max (panel->widget.cols - 9, 0));
+#endif
+
addstr (tmp);
g_free (tmp);
@@ -1008,6 +1139,17 @@ panel_new (const char *panel_name)
mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2);
strcpy (panel->lwd, ".");
+#ifdef HAVE_CHARSET
+ panel_reset_codepage(panel);
+#endif
+
+#ifdef USE_VFS
+ panel->is_return=0;
+ #ifdef HAVE_CHARSET
+ panel->ret_codepage=-1;
+ #endif
+#endif
+
panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL);
panel->dir_history = history_get (panel->hist_name);
directory_history_add (panel, panel->cwd);
@@ -1107,6 +1249,12 @@ paint_frame (WPanel *panel)
int side, width;
const char *txt;
+#ifdef UTF8
+ char buffer[30 * sizeof (wchar_t)];
+ mbstate_t s;
+
+ memset (&s, 0, sizeof (s));
+#endif
if (!panel->split)
adjust_top_file (panel);
@@ -1131,16 +1279,38 @@ paint_frame (WPanel *panel)
if (format->string_fn){
txt = format->title;
- header_len = strlen (txt);
+ attrset (MARKED_COLOR);
+ width -= format->field_len;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ const char *str = txt;
+ header_len = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t),
+ &s);
+ if (header_len < 0) {
+ memset (&s, 0, sizeof (s));
+ printw ("%*s", format->field_len, "");
+ continue;
+ }
+ if (header_len > format->field_len)
+ header_len = format->field_len;
+ spaces = (format->field_len - header_len) / 2;
+ extra = (format->field_len - header_len) % 2;
+ printw ("%*s", spaces, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, header_len);
+ printw ("%*s", spaces + extra, "");
+ continue;
+ }
+#endif
+
+ header_len = mbstrlen (txt);
if (header_len > format->field_len)
header_len = format->field_len;
- attrset (MARKED_COLOR);
spaces = (format->field_len - header_len) / 2;
extra = (format->field_len - header_len) % 2;
tty_printf ("%*s%.*s%*s", spaces, "",
header_len, txt, spaces+extra, "");
- width -= 2 * spaces + extra + header_len;
} else {
attrset (NORMAL_COLOR);
one_vline ();
@@ -1358,7 +1528,7 @@ use_display_format (WPanel *panel, const char *format, char **error, int isstatu
panel->dirty = 1;
/* Status needn't to be split */
- usable_columns = ((panel->widget.cols-2)/((isstatus)
+ usable_columns = ((panel->widget.cols-3)/((isstatus)
? 1
: (panel->split+1))) - (!isstatus && panel->split);
@@ -1897,11 +2067,24 @@ do_search (WPanel *panel, int c_code)
int i;
int wrapped = 0;
int found;
+ int prevpos, pos;
+ int j;
+ mbstate_t mbs;
l = strlen (panel->search_buffer);
if (c_code == KEY_BACKSPACE) {
- if (l)
- panel->search_buffer[--l] = '\0';
+ if (l) {
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
+ --l;
+ panel->search_buffer[prevpos] = 0;
+ }
} else {
if (c_code && l < sizeof (panel->search_buffer)) {
panel->search_buffer[l] = c_code;
@@ -1910,6 +2093,14 @@ do_search (WPanel *panel, int c_code)
}
}
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
found = 0;
for (i = panel->selected; !wrapped || i != panel->selected; i++) {
if (i >= panel->count) {
@@ -1920,9 +2111,9 @@ do_search (WPanel *panel, int c_code)
}
if (panel->
case_sensitive
- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l)
+ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos)
== 0) : (g_strncasecmp (panel->dir.list[i].fname,
- panel->search_buffer, l) == 0)) {
+ panel->search_buffer, pos) == 0)) {
unselect_item (panel);
panel->selected = i;
select_item (panel);
@@ -1931,7 +2122,7 @@ do_search (WPanel *panel, int c_code)
}
}
if (!found)
- panel->search_buffer[--l] = 0;
+ panel->search_buffer[prevpos] = 0;
paint_panel (panel);
}
@@ -2160,7 +2351,12 @@ static const panel_key_map panel_keymap [] = {
{ XCTRL('n'), move_down }, /* C-n like emacs */
{ XCTRL('s'), start_search }, /* C-s like emacs */
{ ALT('s'), start_search }, /* M-s not like emacs */
+#ifndef HAVE_CHARSET
{ XCTRL('t'), mark_file },
+#endif
+#ifdef HAVE_CHARSET
+ { XCTRL('t'), mark_file }, /* was 'fnc_c_cmd' */
+#endif
{ ALT('o'), chdir_other_panel },
{ ALT('i'), sync_other_panel },
{ ALT('l'), chdir_to_readlink },
diff --git a/src/screen.h b/src/screen.h
new file mode 100644
index 0000000..4efb525
--- /dev/null
+++ b/src/screen.h
@@ -0,0 +1,11 @@
+#ifndef __SCREEN_H__
+#define __SCREEN_H__
+#include <config.h>
+
+#include "global.h"
+
+extern void paint_dir (WPanel *panel);
+extern void display_mini_info (WPanel *panel);
+extern void show_dir(WPanel *panel);
+#endif //__SCREEN_H__
+
diff --git a/src/selcodepage.c b/src/selcodepage.c
index 3e9ec63..dabed0e 100644
--- a/src/selcodepage.c
+++ b/src/selcodepage.c
@@ -45,14 +45,16 @@ get_hotkey (int n)
}
int
-select_charset (int current_charset, int seldisplay)
+select_charset (int current_charset, int seldisplay, const char *title)
{
+ int new_charset;
+
int i, menu_lines = n_codepages + 1;
char buffer[255];
/* Create listbox */
Listbox *listbox = create_listbox_window (ENTRY_LEN + 2, menu_lines,
- _(" Choose input codepage "),
+ title,
"[Codepages Translation]");
if (!seldisplay)
@@ -82,20 +84,26 @@ select_charset (int current_charset, int seldisplay)
i = run_listbox (listbox);
- return (seldisplay) ? ((i >= n_codepages) ? -1 : i)
- : (i - 1);
+ if(i==-1)
+ i = (seldisplay)
+ ? ((current_charset < 0) ? n_codepages : current_charset)
+ : (current_charset + 1);
+
+ new_charset =(seldisplay) ? ( (i >= n_codepages) ? -1 : i ) : ( i-1 );
+ new_charset = (new_charset==-2) ? current_charset:new_charset;
+ return new_charset;
}
/* Helper functions for codepages support */
int
-do_select_codepage (void)
+do_select_codepage (const char *title)
{
const char *errmsg;
if (display_codepage > 0) {
- source_codepage = select_charset (source_codepage, 0);
+ source_codepage = select_charset (source_codepage, 0, title);
errmsg =
init_translation_table (source_codepage, display_codepage);
if (errmsg) {
diff --git a/src/selcodepage.h b/src/selcodepage.h
index 06fbd77..f7f16de 100644
--- a/src/selcodepage.h
+++ b/src/selcodepage.h
@@ -2,8 +2,8 @@
#define MC_SELCODEPAGE_H
#ifdef HAVE_CHARSET
-int select_charset (int current_charset, int seldisplay);
-int do_select_codepage (void);
+int select_charset (int current_charset, int seldisplay, const char *title);
+int do_select_codepage (const char *title);
#endif /* HAVE_CHARSET */
#endif
diff --git a/src/setup.c b/src/setup.c
index 67dec4a..4c78e5b 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -50,6 +50,8 @@
#ifdef HAVE_CHARSET
#include "charsets.h"
+#include"recode.h"
+#include "wtools.h"
#endif
#ifdef USE_NETCODE
@@ -273,6 +275,11 @@ panel_save_setup (struct WPanel *panel, const char *section)
g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status);
save_string (section, "user_mini_status", buffer,
profile_name);
+
+#ifdef HAVE_CHARSET
+ // save panel codepage
+ save_string(section, "panel_display_codepage", get_codepage_id(panel->src_codepage), profile_name);
+#endif
}
void
@@ -375,6 +382,7 @@ save_setup (void)
#ifdef HAVE_CHARSET
save_string( "Misc", "display_codepage",
get_codepage_id( display_codepage ), profile_name );
+ save_string( "Misc", "ftp_codepage", get_codepage_id(ftp_codepage), profile_name);
#endif /* HAVE_CHARSET */
g_free (profile);
@@ -425,6 +433,31 @@ panel_load_setup (WPanel *panel, const char *section)
panel->user_mini_status =
load_int (section, "user_mini_status", 0);
+#ifdef HAVE_CHARSET
+//--- Loading panel codepage
+ panel_reset_codepage(panel);
+ if(load_codepages_list()>0) {
+ char cpname[128];
+ char *errmsg;
+
+
+ if(display_codepage>=0) {
+ load_string(section, "panel_display_codepage", "", cpname, sizeof(cpname));
+ if(cpname[0]!='\0') panel->src_codepage = get_codepage_index(cpname);
+ }
+
+ errmsg=my_init_tt(display_codepage,panel->src_codepage,panel->tr_table);
+ if(errmsg) {
+ panel_reset_codepage(panel);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+ errmsg=my_init_tt(panel->src_codepage,display_codepage,panel->tr_table_input);
+ if(errmsg) {
+ panel_reset_codepage(panel);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+ }
+#endif
}
static void
@@ -574,10 +607,16 @@ load_setup (void)
#ifdef HAVE_CHARSET
if ( load_codepages_list() > 0 ) {
char cpname[128];
- load_string( "Misc", "display_codepage", "",
- cpname, sizeof(cpname) );
- if ( cpname[0] != '\0' )
- display_codepage = get_codepage_index( cpname );
+ get_locale_codepage();
+ load_string("Misc", "display_codepage", "", cpname, sizeof(cpname));
+ if(cpname[0] != '\0') display_codepage=get_codepage_index(cpname);
+ else display_codepage=lang_codepage;
+
+ ftp_codepage=-1;
+ if(display_codepage >= 0) {
+ load_string( "Misc", "ftp_codepage", "", cpname, sizeof(cpname));
+ if(cpname[0] != '\0') ftp_codepage=get_codepage_index(cpname);
+ }
}
init_translation_table( source_codepage, display_codepage );
diff --git a/src/slint.c b/src/slint.c
index c30fac1..88557ac 100644
--- a/src/slint.c
+++ b/src/slint.c
@@ -142,7 +142,9 @@ void
slang_init (void)
{
SLtt_get_terminfo ();
-
+#if SLANG_VERSION >= 20000
+ SLutf8_enable (-1);
+#endif
/*
* If the terminal in not in terminfo but begins with a well-known
* string such as "linux" or "xterm" S-Lang will go on, but the
diff --git a/src/timefmt.h b/src/timefmt.h
index 2b8d52f..2cf4a38 100644
--- a/src/timefmt.h
+++ b/src/timefmt.h
@@ -19,7 +19,7 @@
} \
else \
{ \
- strftime(buffer, bufsize, fmt, whentm); \
+ strftime(buffer, bufsize -1, fmt, whentm); \
} \
} \
diff --git a/src/tty.c b/src/tty.c
index a71c6cc..961132b 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -134,10 +134,12 @@ tty_print_char(int c)
* defined or not. Congratulations! At least, they left the API call
* for SLsmg_write_nchars as it has always been.
*/
- char ch;
- ch = c;
- SLsmg_write_nchars(&ch, 1);
+ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty
+ * good for me. So please don't mess with Red Hat people.
+ * Jindrich Novy (jnovy@redhat.com)
+ */
+ SLsmg_write_nwchars(&c, 1);
#else
addch(c);
#endif
diff --git a/src/tty.h b/src/tty.h
index 85d286b..d27e639 100644
--- a/src/tty.h
+++ b/src/tty.h
@@ -8,6 +8,8 @@
of ifdefs in the other files small.
*/
+#include <glib.h> /* gboolean is used here */
+
#ifdef HAVE_SLANG
# include "myslang.h"
#endif
diff --git a/src/util.c b/src/util.c
index 35658b0..5f87b57 100644
--- a/src/util.c
+++ b/src/util.c
@@ -34,10 +34,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <errno.h>
#include <mhl/escape.h>
#include <mhl/string.h>
+#include "tty.h"
#include "global.h"
#include "profile.h"
#include "main.h" /* mc_home */
@@ -50,9 +54,39 @@
#include "charsets.h"
#endif
+#ifdef UTF8
+#include <wctype.h>
+#endif
+
static const char app_text [] = "Midnight-Commander";
int easy_patterns = 1;
+#if SLANG_VERSION >= 20000
+void SLsmg_write_nwchars(wchar_t *s, size_t n)
+{
+ if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */
+ while(n-- && *s)
+ SLsmg_write_char(*s++);
+ }
+ else { /* convert wchars back to 8bit encoding */
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+ while (n-- && *s) {
+ char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */
+ if (*s < 0x80) {
+ SLsmg_write_char(*s++); /* ASCII */
+ }
+ else {
+ if (wcrtomb(buf, *s++, &mbs) == 1)
+ SLsmg_write_char((wchar_t)(buf[0]));
+ else
+ SLsmg_write_char('?'); /* should not happen */
+ }
+ }
+ }
+}
+#endif
+
extern void str_replace(char *s, char from, char to)
{
for (; *s != '\0'; s++) {
@@ -83,9 +117,106 @@ is_8bit_printable (unsigned char c)
return (c > 31 && c != 127 && c != 155);
}
+size_t
+mbstrlen (const char *str)
+{
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ size_t width = 0;
+
+ for (; *str; str++) {
+ wchar_t c;
+ size_t len;
+
+ len = mbrtowc (&c, str, MB_CUR_MAX, NULL);
+
+ if (len == (size_t)(-1) || len == (size_t)(-2)) break;
+
+ if (len > 0) {
+ int wcsize = wcwidth(c);
+ width += wcsize > 0 ? wcsize : 0;
+ str += len-1;
+ }
+ }
+
+ return width;
+ } else
+#endif
+ 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
+
+
+
+#ifdef UTF8
+wchar_t *
+mbstr_to_wchar (const char *str)
+{
+ int len = mbstrlen(str);
+ wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t));
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+ mbsrtowcs (buf, &str, len, &mbs);
+ buf[len] = 0;
+ return buf;
+}
+
+char *
+wchar_to_mbstr (const wchar_t *wstr)
+{
+ mbstate_t mbs;
+ const wchar_t *wstr2;
+ char * string;
+ int len;
+
+ memset (&mbs, 0, sizeof (mbs));
+ wstr2 = wstr;
+ len = wcsrtombs(NULL, &wstr2, 0, &mbs);
+ if (len <= 0)
+ return NULL;
+
+ string = g_malloc(len + 1);
+
+ wstr2 = wstr;
+ wcsrtombs(string, &wstr2, len, &mbs);
+ string[len] = 0;
+ return string;
+}
+#endif
+
+
+
int
is_printable (int c)
{
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ return iswprint (c);
+#endif
c &= 0xff;
#ifdef HAVE_CHARSET
@@ -103,7 +234,7 @@ is_printable (int c)
#endif /* !HAVE_CHARSET */
}
-/* Calculates the message dimensions (lines and columns) */
+/* Calculates the message dimension in columns and lines. */
void
msglen (const char *text, int *lines, int *columns)
{
@@ -116,8 +247,21 @@ msglen (const char *text, int *lines, int *columns)
nlines++;
colindex = 0;
} else {
+#ifndef UTF8
colindex++;
if (colindex > ncolumns)
+#else /* UTF8 */
+ size_t len;
+ wchar_t c;
+
+ len = mbrtowc (&c, text, MB_CUR_MAX, NULL);
+ if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) {
+ int wcsize = wcwidth(c);
+ colindex += wcsize > 0 ? wcsize-1 : -1;
+ text += len-1;
+ }
+ if (++colindex > ncolumns)
+#endif /* UTF8 */
ncolumns = colindex;
}
}
@@ -211,7 +355,24 @@ name_quote (const char *s, int quote_percent)
*d++ = '\\';
break;
}
+#ifndef UTF8
*d = *s;
+#else /* UTF8 */
+ {
+ mbstate_t mbs;
+ int len;
+ memset (&mbs, 0, sizeof (mbs));
+ 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;
@@ -233,25 +394,90 @@ const char *
name_trunc (const char *txt, int trunc_len)
{
static char x[MC_MAXPATHLEN + MC_MAXPATHLEN];
- int txt_len;
+ int txt_len, first, skip;
char *p;
+ const char *str;
if ((size_t) trunc_len > sizeof (x) - 1) {
trunc_len = sizeof (x) - 1;
}
- txt_len = strlen (txt);
- if (txt_len <= trunc_len) {
- strcpy (x, txt);
- } else {
- int y = (trunc_len / 2) + (trunc_len % 2);
- strncpy (x, txt, y);
- strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2);
- x[y] = '~';
+ txt_len = mbstrlen (txt);
+ first = 0;
+ skip = 0;
+ if (txt_len > trunc_len) {
+ first = trunc_len / 2;
+ skip = txt_len - trunc_len + 1;
}
- x[trunc_len] = 0;
- for (p = x; *p; p++)
- if (!is_printable (*p))
- *p = '?';
+
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ mbstate_t s;
+ int mbmax;
+
+ str = txt;
+ memset (&s, 0, sizeof (s));
+ mbmax = MB_CUR_MAX;
+ p = x;
+ while (p < x + sizeof (x) - 1 && trunc_len) {
+ wchar_t wc;
+ int len;
+
+ len = mbrtowc (&wc, str, mbmax, &s);
+ if (!len)
+ break;
+ if (len < 0) {
+ memset (&s, 0, sizeof (s));
+ *p = '?';
+ len = 1;
+ str++;
+ } else if (!is_printable (wc)) {
+ *p = '?';
+ str += len;
+ len = 1;
+ } else if (p >= x + sizeof (x) - len)
+ break;
+ else {
+ memcpy (p, str, len);
+ str += len;
+ }
+ if (first) {
+ --trunc_len;
+ --first;
+ p += len;
+ if (!first && p < x + sizeof (x) - 1 && trunc_len) {
+ *p++ = '~';
+ --trunc_len;
+ }
+ } else if (skip)
+ --skip;
+ else {
+ --trunc_len;
+ p += len;
+ }
+ }
+ } else
+#endif
+ {
+ str = txt;
+ p = x;
+ while (p < x + sizeof (x) - 1) {
+ if (*str == '\0')
+ break;
+ else if (!is_printable (*str))
+ *p++ = '?';
+ else
+ *p++ = *str;
+ ++str;
+ if (first) {
+ --first;
+ if (!first) {
+ *p++ = '~';
+ str += skip;
+ }
+ }
+ }
+ }
+ *p = '\0';
return x;
}
@@ -683,11 +909,66 @@ load_file (const char *filename)
}
char *
+utf8_to_local(char *str)
+{
+ iconv_t cd;
+ size_t buflen;
+ char *output;
+ int retry = 1;
+
+ if (!str)
+ return 0;
+
+ buflen = strlen(str);
+
+ cd = iconv_open (nl_langinfo(CODESET), "UTF-8");
+ if (cd == (iconv_t) -1) {
+ return g_strdup(str);
+ }
+
+ output = g_malloc(buflen + 1);
+
+ while (retry)
+ {
+ char *wrptr = output;
+ char *inptr = str;
+ size_t insize = buflen;
+ size_t avail = buflen;
+ size_t nconv;
+
+ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);
+ if (nconv == (size_t) -1)
+ {
+ if (errno == E2BIG)
+ {
+ buflen *= 2;
+ g_free(output);
+ output = g_malloc(buflen + 1);
+ }
+ else
+ {
+ g_free(output);
+ return g_strdup(str);
+ }
+ }
+ else {
+ retry = 0;
+ *wrptr = 0;
+ }
+ }
+
+ iconv_close (cd);
+
+ return output;
+}
+
+char *
load_mc_home_file (const char *filename, char **allocated_filename)
{
char *hintfile_base, *hintfile;
char *lang;
char *data;
+ char *conv_data;
hintfile_base = mhl_str_dir_plus_file (mc_home, filename);
lang = guess_message_value ();
@@ -720,7 +1001,10 @@ load_mc_home_file (const char *filename, char **allocated_filename)
else
g_free (hintfile);
- return data;
+ conv_data = utf8_to_local(data);
+ g_free(data);
+
+ return conv_data;
}
/* Check strftime() results. Some systems (i.e. Solaris) have different
@@ -736,10 +1020,12 @@ i18n_checktimelength (void)
// huh, localtime() doesnt seem to work ... falling back to "(invalid)"
length = strlen(INVALID_TIME_TEXT);
} else {
- char buf [MAX_I18NTIMELENGTH + 1];
+ char buf [4* MAX_I18NTIMELENGTH + 1];
size_t a, b;
- a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), lt);
- b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), lt);
+ strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), lt);
+ a = mbstrlen(buf);
+ strftime (buf, sizeof(buf)-1, _("%b %e %Y"), lt);
+ b = mbstrlen(buf);
length = max (a, b);
}
@@ -753,15 +1039,12 @@ i18n_checktimelength (void)
const char *
file_date (time_t when)
{
- static char timebuf [MAX_I18NTIMELENGTH + 1];
+ static char timebuf [4 * MAX_I18NTIMELENGTH + 1];
time_t current_time = time ((time_t) 0);
- static size_t i18n_timelength = 0;
static const char *fmtyear, *fmttime;
const char *fmt;
- if (i18n_timelength == 0){
- i18n_timelength = i18n_checktimelength() + 1;
-
+ if ( fmtyear == NULL ) {
/* strftime() format string for old dates */
fmtyear = _("%b %e %Y");
/* strftime() format string for recent dates */
@@ -781,7 +1064,7 @@ file_date (time_t when)
else
fmt = fmttime;
- FMT_LOCALTIME(timebuf, i18n_timelength, fmt, when);
+ FMT_LOCALTIME(timebuf, sizeof(timebuf), fmt, when);
return timebuf;
}
@@ -912,10 +1195,27 @@ strip_ctrl_codes (char *s)
r++;
continue;
}
-
+#ifndef UTF8
if (is_printable(*r))
*w++ = *r;
++r;
+#else /* UTF8 */
+ {
+ mbstate_t mbs;
+ int len;
+ memset (&mbs, 0, sizeof (mbs));
+ 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;
diff --git a/src/util.h b/src/util.h
index 0cf2099..82edcde 100644
--- a/src/util.h
+++ b/src/util.h
@@ -102,6 +102,13 @@ void init_uid_gid_cache (void);
char *get_group (int);
char *get_owner (int);
+void fix_utf8(char *str);
+size_t mbstrlen (const char *);
+wchar_t *mbstr_to_wchar (const char *);
+char *wchar_to_mbstr (const wchar_t *);
+char *utf8_to_local(char *str);
+
+
#define MAX_I18NTIMELENGTH 14
#define MIN_I18NTIMELENGTH 10
#define STD_I18NTIMELENGTH 12
diff --git a/src/view.c b/src/view.c
index 8465301..8bc1792 100644
--- a/src/view.c
+++ b/src/view.c
@@ -44,6 +44,10 @@
#include <sys/stat.h>
#include <unistd.h>
+#ifdef UTF8
+#include <wctype.h>
+#endif /* UTF8 */
+
#include "global.h"
#include "tty.h"
#include "cmd.h" /* For view_other_cmd */
@@ -1643,7 +1647,7 @@ view_display_status (WView *view)
hline (' ', width);
file_label = _("File: %s");
- file_label_width = strlen (file_label) - 2;
+ file_label_width = mbstrlen (file_label) - 2;
file_name = view->filename ? view->filename
: view->command ? view->command
: "";
@@ -1911,6 +1915,12 @@ view_display_text (WView * view)
offset_type from;
int c;
struct hexedit_change_node *curr = view->change_list;
+#ifdef UTF8
+ mbstate_t mbs;
+ char mbbuf[MB_LEN_MAX];
+ int mblen;
+ wchar_t wc;
+#endif /* UTF8 */
view_display_clean (view);
view_display_ruler (view);
@@ -1923,8 +1933,37 @@ view_display_text (WView * view)
tty_setcolor (NORMAL_COLOR);
for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) {
-
+#ifndef UTF8
if (view->text_nroff_mode && c == '\b') {
+#else /* UTF8 */
+ mblen = 1;
+ mbbuf[0] = convert_to_display_c (c);
+
+ while (mblen < MB_LEN_MAX) {
+ int res;
+ memset (&mbs, 0, sizeof (mbs));
+ res = mbrtowc (&wc, mbbuf, mblen, &mbs);
+ if (res <= 0 && res != -2) {
+ wc = '.';
+ mblen = 1;
+ break;
+ }
+ if (res == mblen)
+ break;
+
+ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen));
+ mblen++;
+ }
+
+ if (mblen == MB_LEN_MAX) {
+ wc = '.';
+ mblen = 1;
+ }
+
+ from += mblen - 1;
+
+ if (view->text_nroff_mode && wc == '\b') {
+#endif /* UTF8 */
int c_prev;
int c_next;
@@ -1989,10 +2028,17 @@ view_display_text (WView * view)
if (col >= view->dpy_text_column
&& col - view->dpy_text_column < width) {
widget_move (view, top + row, left + (col - view->dpy_text_column));
+#ifndef UTF8
c = convert_to_display_c (c);
if (!is_printable (c))
c = '.';
tty_print_char (c);
+#else
+ wc = convert_to_display_c (wc);
+ if (!iswprint (wc))
+ wc = '.';
+ tty_print_char (wc);
+#endif
}
col++;
tty_setcolor (NORMAL_COLOR);
@@ -3187,7 +3233,7 @@ view_handle_key (WView *view, int c)
#ifdef HAVE_CHARSET
case XCTRL ('t'):
- do_select_codepage ();
+ do_select_codepage (_(" Choose codepage "));
view->dirty++;
view_update (view);
return MSG_HANDLED;
diff --git a/src/widget.c b/src/widget.c
index f85cc2a..635441d 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -38,6 +38,9 @@
#include "global.h"
#include "tty.h"
+#ifdef UTF8
+#include <wctype.h>
+#endif /* UTF8 */
#include "color.h"
#include "mouse.h"
#include "dialog.h"
@@ -183,6 +186,11 @@ button_callback (Widget *w, widget_msg_t msg, int parm)
if (b->hotpos >= 0) {
widget_selectcolor (w, b->selected, TRUE);
widget_move (w, 0, b->hotpos + off);
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ SLsmg_write_nwchars (&b->hotwc, 1);
+ else
+#endif
addch ((unsigned char) b->text[b->hotpos]);
}
return MSG_HANDLED;
@@ -216,7 +224,7 @@ button_event (Gpm_Event *event, void *data)
static int
button_len (const char *text, unsigned int flags)
{
- int ret = strlen (text);
+ int ret = mbstrlen (text);
switch (flags){
case DEFPUSH_BUTTON:
ret += 6;
@@ -239,14 +247,36 @@ button_len (const char *text, unsigned int flags)
* the button text is g_malloc()ed, we can safely change and shorten it.
*/
static void
-button_scan_hotkey (WButton *b)
+scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp)
{
- char *cp = strchr (b->text, '&');
+ char *cp = strchr (text, '&');
if (cp != NULL && cp[1] != '\0') {
- g_strlcpy (cp, cp + 1, strlen (cp));
- b->hotkey = tolower ((unsigned char) *cp);
- b->hotpos = cp - b->text;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ mbstate_t s;
+ int len;
+
+ *cp = '\0';
+ memset (&s, 0, sizeof (s));
+ len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s);
+ if (len > 0) {
+ *hotposp = mbstrlen (text);
+ if (*hotposp < 0) {
+ *hotposp = -1;
+ } else {
+ /* FIXME */
+ *hotkeyp = tolower (*hotwcp);
+ }
+ }
+ } else
+#endif
+ {
+ *hotkeyp = tolower (cp[1]);
+ *hotposp = cp - text;
+ }
+
+ memmove (cp, cp + 1, strlen (cp + 1) + 1);
}
}
@@ -267,8 +297,9 @@ button_new (int y, int x, int action, int flags, const char *text,
widget_want_hotkey (b->widget, 1);
b->hotkey = 0;
b->hotpos = -1;
+ b->hotwc = L'\0';
- button_scan_hotkey(b);
+ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc);
return b;
}
@@ -281,14 +312,13 @@ button_get_text (WButton *b)
void
button_set_text (WButton *b, const char *text)
{
- g_free (b->text);
+ g_free (b->text);
b->text = g_strdup (text);
b->widget.cols = button_len (text, b->flags);
- button_scan_hotkey(b);
+ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc);
dlg_redraw (b->widget.parent);
}
-
/* Radio button widget */
static int radio_event (Gpm_Event *event, void *);
@@ -363,14 +393,35 @@ radio_callback (Widget *w, widget_msg_t msg, int parm)
widget_move (&r->widget, i, 0);
tty_printf ("(%c) ", (r->sel == i) ? '*' : ' ');
- for (cp = r->texts[i]; *cp; cp++) {
- if (*cp == '&') {
- widget_selectcolor (w, focused, TRUE);
+ cp = strchr (r->texts[i], '&');
+ if (cp != NULL) {
+#ifdef UTF8
+ mbstate_t s;
+ wchar_t wc;
+ int len;
+#endif
+ tty_printf ("%.*s", (int) ((char *) cp - r->texts[i]),
+ r->texts[i]);
+ widget_selectcolor (w, focused, TRUE);
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ memset (&s, 0, sizeof (s));
+ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s);
+ ++cp;
+ if (len > 0) {
+ tty_printf ("%.*s", len, cp);
+ cp += len;
+ }
+ } else
+#endif
+ {
addch (*++cp);
- widget_selectcolor (w, focused, FALSE);
- } else
- addch (*cp);
- }
+ ++cp;
+ }
+ widget_selectcolor (w, focused, FALSE);
+ } else
+ cp = r->texts[i];
+ addstr ((char *) cp);
}
return MSG_HANDLED;
@@ -409,7 +460,7 @@ radio_new (int y, int x, int count, const char **texts)
/* Compute the longest string */
max = 0;
for (i = 0; i < count; i++){
- m = strlen (texts [i]);
+ m = mbstrlen (texts [i]);
if (m > max)
max = m;
}
@@ -469,6 +520,11 @@ check_callback (Widget *w, widget_msg_t msg, int parm)
if (c->hotpos >= 0) {
widget_selectcolor (w, msg == WIDGET_FOCUS, TRUE);
widget_move (&c->widget, 0, +c->hotpos + 4);
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ SLsmg_write_nwchars (&c->hotwc, 1);
+ else
+#endif
addch ((unsigned char) c->text[c->hotpos]);
}
return MSG_HANDLED;
@@ -506,35 +562,20 @@ WCheck *
check_new (int y, int x, int state, const char *text)
{
WCheck *c = g_new (WCheck, 1);
- const char *s;
- char *t;
-
- init_widget (&c->widget, y, x, 1, strlen (text),
+
+ init_widget (&c->widget, y, x, 1, mbstrlen (text),
check_callback, check_event);
c->state = state ? C_BOOL : 0;
c->text = g_strdup (text);
c->hotkey = 0;
c->hotpos = -1;
+ c->hotwc = L'\0';
widget_want_hotkey (c->widget, 1);
- /* Scan for the hotkey */
- for (s = text, t = c->text; *s; s++, t++){
- if (*s != '&'){
- *t = *s;
- continue;
- }
- s++;
- if (*s){
- c->hotkey = tolower ((unsigned char) *s);
- c->hotpos = t - c->text;
- }
- *t = *s;
- }
- *t = 0;
+ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc);
return c;
}
-
/* Label widget */
static cb_ret_t
@@ -573,7 +614,7 @@ label_callback (Widget *w, widget_msg_t msg, int parm)
}
widget_move (&l->widget, y, 0);
tty_printf ("%s", p);
- xlen = l->widget.cols - strlen (p);
+ xlen = l->widget.cols - mbstrlen (p);
if (xlen > 0)
tty_printf ("%*s", xlen, " ");
if (!q)
@@ -607,7 +648,7 @@ label_set_text (WLabel *label, const char *text)
if (text){
label->text = g_strdup (text);
if (label->auto_adjust_cols) {
- newcols = strlen (text);
+ newcols = mbstrlen (text);
if (newcols > label->widget.cols)
label->widget.cols = newcols;
}
@@ -631,7 +672,7 @@ label_new (int y, int x, const char *text)
if (!text || strchr(text, '\n'))
width = 1;
else
- width = strlen (text);
+ width = mbstrlen (text);
l = g_new (WLabel, 1);
init_widget (&l->widget, y, x, 1, width, label_callback, NULL);
@@ -779,13 +820,69 @@ static void draw_history_button (WInput * in)
/* Pointer to killed data */
static char *kill_buffer = 0;
+#ifdef UTF8
+static int
+charpos(WInput *in, int idx)
+{
+ int i, pos, l, len;
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+ i = 0;
+ pos = 0;
+ len = strlen(in->buffer);
+
+ while (in->buffer[pos]) {
+ if (i == idx)
+ return pos;
+ l = mbrlen(in->buffer + pos, len - pos, &mbs);
+ if (l <= 0)
+ return pos;
+ pos+=l;
+ i++;
+ };
+ return pos;
+}
+
+static int
+charcolumn(WInput *in, int idx)
+{
+ int i, pos, l, width, len;
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+ i = 0;
+ pos = 0; width = 0;
+ len = strlen(in->buffer);
+
+ while (in->buffer[pos]) {
+ wchar_t wc;
+ if (i == idx)
+ return width;
+ l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs);
+ if (l <= 0)
+ return width;
+ pos += l; width += wcwidth(wc);
+ i++;
+ };
+ return width;
+}
+#else
+#define charpos(in, idx) (idx)
+#define charcolumn(in, idx) (idx)
+#endif /* UTF8 */
+
void
update_input (WInput *in, int clear_first)
{
int has_history = 0;
int i, j;
- unsigned char c;
- int buf_len = strlen (in->buffer);
+ int buf_len = mbstrlen (in->buffer);
+#ifndef UTF8
+ unsigned char c;
+#else /* UTF8 */
+ wchar_t c;
+ mbstate_t mbs;
+ memset (&mbs, 0, sizeof (mbs));
+#endif /* UTF8 */
if (should_show_history_button (in))
has_history = HISTORY_BUTTON_WIDTH;
@@ -795,7 +892,7 @@ update_input (WInput *in, int clear_first)
/* Make the point visible */
if ((in->point < in->first_shown) ||
- (in->point >= in->first_shown+in->field_len - has_history)){
+ (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){
in->first_shown = in->point - (in->field_len / 3);
if (in->first_shown < 0)
in->first_shown = 0;
@@ -815,14 +912,29 @@ update_input (WInput *in, int clear_first)
addch (' ');
widget_move (&in->widget, 0, 0);
+#ifndef UTF8
for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){
c = in->buffer [j++];
c = is_printable (c) ? c : '.';
+#else /* UTF8 */
+ for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){
+ char * chp = in->buffer + charpos(in,j);
+ size_t res = mbrtowc(&c, chp, strlen(chp), &mbs);
+ c = (res && iswprint (c)) ? 0 : '.';
+#endif /* UTF8 */
if (in->is_password)
c = '*';
+#ifndef UTF8
addch (c);
+#else /* UTF8 */
+ if (c) {
+ addch (c);
+ }
+ else
+ SLsmg_write_nchars (chp, res);
+#endif /* UTF8 */
}
- widget_move (&in->widget, 0, in->point - in->first_shown);
+ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown));
if (clear_first)
in->first = 0;
@@ -975,7 +1087,7 @@ char *
show_hist (GList *history, int widget_x, int widget_y)
{
GList *hi, *z;
- size_t maxlen = strlen (i18n_htitle ()), i, count = 0;
+ size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0;
int x, y, w, h;
char *q, *r = 0;
Dlg_head *query_dlg;
@@ -988,7 +1100,7 @@ show_hist (GList *history, int widget_x, int widget_y)
z = g_list_first (history);
hi = z;
while (hi) {
- if ((i = strlen ((char *) hi->data)) > maxlen)
+ if ((i = mbstrlen ((char *) hi->data)) > maxlen)
maxlen = i;
count++;
hi = g_list_next (hi);
@@ -1158,35 +1270,83 @@ new_input (WInput *in)
in->need_push = 1;
in->buffer [0] = 0;
in->point = 0;
+ in->charpoint = 0;
in->mark = 0;
free_completions (in);
update_input (in, 0);
}
+static void
+move_buffer_backward (WInput *in, int point)
+{
+ int i, pos, len;
+ int str_len = mbstrlen (in->buffer);
+ if (point >= str_len) return;
+
+ pos = charpos(in,point);
+ len = charpos(in,point + 1) - pos;
+
+ for (i = pos; in->buffer [i + len - 1]; i++)
+ in->buffer [i] = in->buffer [i + len];
+}
+
static cb_ret_t
insert_char (WInput *in, int c_code)
{
size_t i;
+#ifdef UTF8
+ mbstate_t mbs;
+ int res;
+
+ memset (&mbs, 0, sizeof (mbs));
+#else
+ in->charpoint = 0;
+#endif /* UTF8 */
if (c_code == -1)
return MSG_NOT_HANDLED;
+#ifdef UTF8
+ if (in->charpoint >= MB_CUR_MAX) return 1;
+
+ in->charbuf[in->charpoint++] = c_code;
+
+ res = mbrlen((char *)in->charbuf, in->charpoint, &mbs);
+ if (res < 0) {
+ if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */
+ return 1;
+ }
+
+#endif /* UTF8 */
in->need_push = 1;
- if (strlen (in->buffer)+1 == (size_t) in->current_max_len){
+ if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){
/* Expand the buffer */
- char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len);
+ char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint);
if (narea){
in->buffer = narea;
- in->current_max_len += in->field_len;
+ in->current_max_len += in->field_len + in->charpoint;
}
}
+#ifndef UTF8
if (strlen (in->buffer)+1 < (size_t) in->current_max_len){
size_t l = strlen (&in->buffer [in->point]);
for (i = l+1; i > 0; i--)
in->buffer [in->point+i] = in->buffer [in->point+i-1];
in->buffer [in->point] = c_code;
+#else /* UTF8 */
+ if (strlen (in->buffer) + in->charpoint < in->current_max_len){
+ size_t ins_point = charpos(in,in->point); /* bytes from begin */
+ /* move chars */
+ size_t rest_bytes = strlen (in->buffer + ins_point);
+
+ for (i = rest_bytes + 1; i > 0; i--)
+ in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1];
+
+ memcpy(in->buffer + ins_point, in->charbuf, in->charpoint);
+#endif /* UTF8 */
in->point++;
}
+ in->charpoint = 0;
return MSG_HANDLED;
}
@@ -1194,12 +1354,14 @@ static void
beginning_of_line (WInput *in)
{
in->point = 0;
+ in->charpoint = 0;
}
static void
end_of_line (WInput *in)
{
- in->point = strlen (in->buffer);
+ in->point = mbstrlen (in->buffer);
+ in->charpoint = 0;
}
static void
@@ -1207,18 +1369,21 @@ backward_char (WInput *in)
{
if (in->point)
in->point--;
+ in->charpoint = 0;
}
static void
forward_char (WInput *in)
{
- if (in->buffer [in->point])
+ if (in->buffer [charpos(in,in->point)])
in->point++;
+ in->charpoint = 0;
}
static void
forward_word (WInput * in)
{
+#ifndef UTF8
char *p = in->buffer + in->point;
while (*p
@@ -1228,11 +1393,39 @@ forward_word (WInput * in)
while (*p && isalnum ((unsigned char) *p))
p++;
in->point = p - in->buffer;
+#else /* UTF8 */
+ mbstate_t mbs;
+ int len = mbstrlen (in->buffer);
+ memset (&mbs, 0, sizeof (mbs));
+
+ while (in->point < len) {
+ wchar_t c;
+ char *p = in->buffer + charpos(in,in->point);
+ size_t res = mbrtowc(&c, p, strlen(p), &mbs);
+ if (res <= 0 || !(iswspace (c) || iswpunct (c)))
+ break;
+ in->point++;
+ }
+
+ memset (&mbs, 0, sizeof (mbs));
+
+ while (in->point < len) {
+ wchar_t c;
+ char *p = in->buffer + charpos(in,in->point);
+ size_t res = mbrtowc(&c, p, strlen(p), &mbs);
+ if (res <= 0 || !iswalnum (c))
+ break;
+ in->point++;
+ }
+
+ in->charpoint = 0;
+#endif /* UTF8 */
}
static void
backward_word (WInput *in)
{
+#ifndef UTF8
char *p = in->buffer + in->point;
while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1))
@@ -1242,6 +1435,32 @@ backward_word (WInput *in)
while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(p - 1)))
p--;
in->point = p - in->buffer;
+#else /* UTF8 */
+ mbstate_t mbs;
+
+ memset (&mbs, 0, sizeof (mbs));
+ while (in->point > 0) {
+ wchar_t c;
+ char *p = in->buffer + charpos(in,in->point);
+ size_t res = mbrtowc(&c, p, strlen(p), &mbs);
+ if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c))))
+ break;
+ in->point--;
+ }
+
+ memset (&mbs, 0, sizeof (mbs));
+
+ while (in->point > 0) {
+ wchar_t c;
+ char *p = in->buffer + charpos(in,in->point);
+ size_t res = mbrtowc(&c, p, strlen(p), &mbs);
+ if (*p && (res <= 0 || !iswalnum (c)))
+ break;
+ in->point--;
+ }
+
+ in->charpoint = 0;
+#endif /* UTF8 */
}
static void
@@ -1270,12 +1489,12 @@ key_ctrl_right (WInput *in)
static void
backward_delete (WInput *in)
{
- int i;
if (!in->point)
return;
- for (i = in->point; in->buffer [i-1]; i++)
- in->buffer [i-1] = in->buffer [i];
+
+ move_buffer_backward(in, in->point - 1);
+ in->charpoint = 0;
in->need_push = 1;
in->point--;
}
@@ -1283,10 +1502,8 @@ backward_delete (WInput *in)
static void
delete_char (WInput *in)
{
- int i;
-
- for (i = in->point; in->buffer [i]; i++)
- in->buffer [i] = in->buffer [i+1];
+ move_buffer_backward(in, in->point);
+ in->charpoint = 0;
in->need_push = 1;
}
@@ -1301,6 +1518,9 @@ copy_region (WInput *in, int x_first, int x_last)
g_free (kill_buffer);
+ first=charpos(in,first);
+ last=charpos(in,last);
+
kill_buffer = g_strndup(in->buffer+first,last-first);
}
@@ -1309,11 +1529,13 @@ delete_region (WInput *in, int x_first, int x_last)
{
int first = min (x_first, x_last);
int last = max (x_first, x_last);
- size_t len = strlen (&in->buffer [last]) + 1;
+ size_t len;
in->point = first;
in->mark = first;
- memmove (&in->buffer [first], &in->buffer [last], len);
+ len = strlen (&in->buffer [charpos(in,last)]) + 1;
+ memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len);
+ in->charpoint = 0;
in->need_push = 1;
}
@@ -1330,6 +1552,8 @@ kill_word (WInput *in)
copy_region (in, old_point, new_point);
delete_region (in, old_point, new_point);
in->need_push = 1;
+ in->charpoint = 0;
+ in->charpoint = 0;
}
static void
@@ -1373,16 +1597,20 @@ yank (WInput *in)
if (!kill_buffer)
return;
+ in->charpoint = 0;
for (p = kill_buffer; *p; p++)
insert_char (in, *p);
+ in->charpoint = 0;
}
static void
kill_line (WInput *in)
{
+ int chp = charpos(in,in->point);
g_free (kill_buffer);
- kill_buffer = g_strdup (&in->buffer [in->point]);
- in->buffer [in->point] = 0;
+ kill_buffer = g_strdup (&in->buffer [chp]);
+ in->buffer [chp] = 0;
+ in->charpoint = 0;
}
void
@@ -1392,9 +1620,10 @@ assign_text (WInput *in, const char *text)
g_free (in->buffer);
in->buffer = g_strdup (text); /* was in->buffer->text */
in->current_max_len = strlen (in->buffer) + 1;
- in->point = strlen (in->buffer);
+ in->point = mbstrlen (in->buffer);
in->mark = 0;
in->need_push = 1;
+ in->charpoint = 0;
}
static void
@@ -1521,6 +1750,7 @@ port_region_marked_for_delete (WInput *in)
*in->buffer = 0;
in->point = 0;
in->first = 0;
+ in->charpoint = 0;
}
cb_ret_t
@@ -1549,7 +1779,11 @@ handle_char (WInput *in, int c_code)
}
}
if (!input_map [i].fn){
+#ifndef UTF8
if (c_code > 255 || !is_printable (c_code))
+#else /* UTF8 */
+ if (c_code > 255)
+#endif /* UTF8 */
return MSG_NOT_HANDLED;
if (in->first){
port_region_marked_for_delete (in);
@@ -1582,6 +1816,9 @@ input_set_point (WInput *in, int pos)
if (pos != in->point)
free_completions (in);
in->point = pos;
+#ifdef UTF8
+ in->charpoint = 0;
+#endif /* UTF8 */
update_input (in, 1);
}
@@ -1622,7 +1859,7 @@ input_callback (Widget *w, widget_msg_t msg, int parm)
return MSG_HANDLED;
case WIDGET_CURSOR:
- widget_move (&in->widget, 0, in->point - in->first_shown);
+ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown));
return MSG_HANDLED;
case WIDGET_DESTROY:
@@ -1646,7 +1883,7 @@ input_event (Gpm_Event * event, void *data)
&& should_show_history_button (in)) {
do_show_hist (in);
} else {
- in->point = strlen (in->buffer);
+ in->point = mbstrlen (in->buffer);
if (event->x - in->first_shown - 1 < in->point)
in->point = event->x - in->first_shown - 1;
if (in->point < 0)
@@ -1701,56 +1938,91 @@ input_new (int y, int x, int color, int len, const char *def_text,
in->is_password = 0;
strcpy (in->buffer, def_text);
- in->point = strlen (in->buffer);
+ in->point = mbstrlen (in->buffer);
+ in->charpoint = 0;
return in;
}
-
-/* Listbox widget */
+/* Vertical scrollbar widget */
-/* Should draw the scrollbar, but currently draws only
- * indications that there is more information
- */
-static int listbox_cdiff (WLEntry *s, WLEntry *e);
-
-static void
-listbox_drawscroll (WListbox *l)
+void
+vscrollbar (Widget widget, int height, int width, int tpad, int bpad,
+ int selected, int count, gboolean color)
{
int line;
- int i, top;
- int max_line = l->height-1;
-
+ int i;
+
/* Are we at the top? */
- widget_move (&l->widget, 0, l->width);
- if (l->list == l->top)
- one_vline ();
+ widget_move (&widget, tpad, width);
+#ifndef UTF8
+ if (!selected)
+ one_vline ();
+ else
+ addch ('^');
+#else
+ if (color) attrset (MARKED_COLOR);
+ if (is_utf8)
+ SLsmg_write_string("▴");
else
- addch ('^');
+ addch ('^');
+ if (color) attrset (NORMAL_COLOR);
+#endif
/* Are we at the bottom? */
- widget_move (&l->widget, max_line, l->width);
- top = listbox_cdiff (l->list, l->top);
- if ((top + l->height == l->count) || l->height >= l->count)
- one_vline ();
+ widget_move (&widget, height-1-bpad, width);
+#ifndef UTF8
+ if (selected == count-1)
+ one_vline ();
+ else
+ addch ('v');
+#else
+ if (color) attrset (MARKED_COLOR);
+ if (is_utf8)
+ SLsmg_write_string("▾");
else
- addch ('v');
+ addch('v');
+ if (color) attrset (NORMAL_COLOR);
+#endif
/* Now draw the nice relative pointer */
- if (l->count)
- line = 1+ ((l->pos * (l->height-2)) / l->count);
+ if (count > 1)
+ line = tpad + 1 + ((selected * (height-3-tpad-bpad)) / (count-1));
else
- line = 0;
-
- for (i = 1; i < max_line; i++){
- widget_move (&l->widget, i, l->width);
- if (i != line)
- one_vline ();
- else
- addch ('*');
+ line = 0;
+
+ for (i = tpad + 1; i < height-1-bpad; i++){
+ widget_move (&widget, i, width);
+ if (i != line)
+#ifndef UTF8
+ one_vline ();
+ else
+ addch ('*');
+#else
+ if (is_utf8)
+ SLsmg_write_string("▒");
+ else
+ one_vline();
+ else {
+ if (color) attrset (MARKED_COLOR);
+ if (is_utf8)
+ SLsmg_write_string("◈");
+ else
+ addch('*');
+ if (color) attrset (NORMAL_COLOR);
+ }
+#endif
}
}
-
-static void
+
+
+/* Listbox widget */
+
+/* Should draw the scrollbar, but currently draws only
+ * indications that there is more information
+ */
+static int listbox_cdiff (WLEntry *s, WLEntry *e);
+
+void
listbox_draw (WListbox *l, int focused)
{
WLEntry *e;
@@ -1791,7 +2063,7 @@ listbox_draw (WListbox *l, int focused)
if (!l->scrollbar)
return;
attrset (normalc);
- listbox_drawscroll (l);
+ vscrollbar (l->widget, l->height, l->width, 0, 0, l->pos, l->count, FALSE);
}
/* Returns the number of items between s and e,
diff --git a/src/widget.h b/src/widget.h
index 8c6f781..d1d91f2 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -39,6 +39,7 @@ typedef struct WButton {
char *text; /* text of button */
int hotkey; /* hot KEY */
int hotpos; /* offset hot KEY char in text */
+ wchar_t hotwc;
bcback callback; /* Callback function */
} WButton;
@@ -59,6 +60,7 @@ typedef struct WCheck {
char *text; /* text of check button */
int hotkey; /* hot KEY */
int hotpos; /* offset hot KEY char in text */
+ wchar_t hotwc;
} WCheck;
typedef struct WGauge {
@@ -74,16 +76,20 @@ char *show_hist (GList *history, int widget_y, int widget_x);
typedef struct {
Widget widget;
- int point; /* cursor position in the input line */
- int mark; /* The mark position */
- int first_shown; /* Index of the first shown character */
- int current_max_len; /* Maximum length of input line */
- int field_len; /* Length of the editing field */
+ int point; /* cursor position in the input line (mb chars) */
+ int mark; /* The mark position (mb chars) */
+ int first_shown; /* Index of the first shown character (mb chars) */
+ int current_max_len; /* Maximum length of input line (bytes) */
+ int field_len; /* Length of the editing field (mb chars) */
int color; /* color used */
int first; /* Is first keystroke? */
int disable_update; /* Do we want to skip updates? */
int is_password; /* Is this a password input line? */
char *buffer; /* pointer to editing buffer */
+#ifdef UTF8
+ char charbuf[MB_LEN_MAX];
+#endif /* UTF8 */
+ int charpoint;
GList *history; /* The history */
int need_push; /* need to push the current Input on hist? */
char **completions; /* Possible completions array */
@@ -181,6 +187,10 @@ void button_set_text (WButton *b, const char *text);
/* Listbox manager */
WLEntry *listbox_get_data (WListbox *l, int pos);
+/* Vertical scrollbar */
+void vscrollbar (Widget widget, int height, int width, int tpad, int bpad,
+ int selected, int count, gboolean color);
+
/* search text int listbox entries */
WLEntry *listbox_search_text (WListbox *l, const char *text);
void listbox_select_entry (WListbox *l, WLEntry *dest);
diff --git a/src/wtools.c b/src/wtools.c
index ba317e9..a6eaffa 100644
--- a/src/wtools.c
+++ b/src/wtools.c
@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lines, const char *title, const char *help)
/* Adjust sizes */
lines = (lines > LINES - 6) ? LINES - 6 : lines;
- if (title && (cols < (len = strlen (title) + 2)))
+ if (title && (cols < (len = mbstrlen (title) + 2)))
cols = len;
/* no &, but 4 spaces around button for brackets and such */
- if (cols < (len = strlen (cancel_string) + 3))
+ if (cols < (len = mbstrlen (cancel_string) + 3))
cols = len;
cols = cols > COLS - 6 ? COLS - 6 : cols;
@@ -124,7 +124,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...)
va_start (ap, count);
for (i = 0; i < count; i++) {
char *cp = va_arg (ap, char *);
- win_len += strlen (cp) + 6;
+ win_len += mbstrlen (cp) + 6;
if (strchr (cp, '&') != NULL)
win_len--;
}
@@ -133,7 +133,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...)
/* count coordinates */
msglen (text, &lines, &cols);
- cols = 6 + max (win_len, max ((int) strlen (header), cols));
+ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols));
lines += 4 + (count > 0 ? 2 : 0);
xpos = COLS / 2 - cols / 2;
ypos = LINES / 3 - (lines - 3) / 2;
@@ -148,7 +148,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...)
va_start (ap, count);
for (i = 0; i < count; i++) {
cur_name = va_arg (ap, char *);
- xpos = strlen (cur_name) + 6;
+ xpos = mbstrlen (cur_name) + 6;
if (strchr (cur_name, '&') != NULL)
xpos--;
@@ -467,7 +467,7 @@ fg_input_dialog_help (const char *header, const char *text, const char *help,
}
msglen (text, &lines, &cols);
- len = max ((int) strlen (header), cols) + 4;
+ len = max ((int) mbstrlen (header), cols) + 4;
len = max (len, 64);
/* The special value of def_text is used to identify password boxes
@@ -489,7 +489,7 @@ fg_input_dialog_help (const char *header, const char *text, const char *help,
quick_widgets[1].text = _(quick_widgets[1].text);
quick_widgets[0].relative_x = len / 2 + 4;
quick_widgets[1].relative_x =
- len / 2 - (strlen (quick_widgets[1].text) + 9);
+ len / 2 - (mbstrlen (quick_widgets[1].text) + 9);
quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len;
#endif /* ENABLE_NLS */
diff --git a/vfs/vfs.c b/vfs/vfs.c
index 39fdc73..1658eaa 100644
--- a/vfs/vfs.c
+++ b/vfs/vfs.c
@@ -56,6 +56,11 @@
#include "smbfs.h"
#include "local.h"
+#include "../src/panel.h"
+#ifdef HAVE_CHARSET
+#include "../src/recode.h"
+#endif
+
/* They keep track of the current directory */
static struct vfs_class *current_vfs;
static char *current_dir;
@@ -688,8 +693,66 @@ mc_chdir (const char *path)
vfsid old_vfsid;
int result;
+#ifdef HAVE_CHARSET
+ char* errmsg;
+#endif
+ WPanel* p=ret_panel;
+
new_dir = vfs_canon (path);
new_vfs = vfs_get_class (new_dir);
+ old_vfsid = vfs_getid (current_vfs, current_dir);
+ old_vfs = current_vfs;
+
+ if(p) {
+
+ // Change from localfs to ftpfs
+ ret_panel=NULL;
+ if( (strcmp(old_vfs->name,"localfs")==0) &&
+ (strcmp(new_vfs->name,"ftpfs")==0)){
+ p->is_return=1;
+ strncpy(p->retdir,current_dir, MC_MAXPATHLEN);
+#ifdef HAVE_CHARSET
+ p->ret_codepage=p->src_codepage;
+ p->src_codepage=ftp_codepage;
+ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table);
+ if(errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input);
+ if(errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+#endif
+ }
+
+ // Change from ftpfs to localfs
+ if( (strcmp(old_vfs->name,"ftpfs")==0) &&
+ (strcmp(new_vfs->name,"localfs")==0) &&
+ p->is_return){
+ p->is_return=0;
+ g_free(new_dir);
+ new_dir = vfs_canon (p->retdir);
+ new_vfs = vfs_get_class (new_dir);
+#ifdef HAVE_CHARSET
+ p->src_codepage=p->ret_codepage;
+ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table);
+ if(errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input);
+ if(errmsg) {
+ panel_reset_codepage(p);
+ message( 1, MSG_ERROR, "%s", errmsg );
+ }
+#endif
+ }
+ }
+
+
+
if (!new_vfs->chdir) {
g_free (new_dir);
return -1;
@@ -703,9 +766,6 @@ mc_chdir (const char *path)
return -1;
}
- old_vfsid = vfs_getid (current_vfs, current_dir);
- old_vfs = current_vfs;
-
/* Actually change directory */
g_free (current_dir);
current_dir = new_dir;