7018 lines
193 KiB
Diff
7018 lines
193 KiB
Diff
|
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, ", ¯o[n].command, ¯o[n].ch))
|
|||
|
+#else /* UTF8 */
|
|||
|
+ while (fscanf (f, "%hd %lu, ", ¯o[n].command, ¯o[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, ", ¯o[*n].command, ¯o[*n].ch))
|
|||
|
+#else /* UTF8 */
|
|||
|
+ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", ¯o[*n].command, ¯o[*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;
|