Ticket #3006: mc.insert_estring.diff

File mc.insert_estring.diff, 59.7 KB (added by szaszg, 10 years ago)
  • doc/man/mc.1.in

    diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in
    index 74b53a4..044e33b 100644
    a b Sections: 
    29732973.\"LINK2" 
    29742974Options of editor in ini\-file 
    29752975.\"Internal File Editor / options" 
     2976.IP 
     2977.\"LINK2" 
     2978Unescape, reencode and insert string 
     2979.\"NODE "Internal File Editor / estring"/ 
    29762980.PP 
    29772981The editor is very easy to use and requires no tutoring. To see what 
    29782982keys do what, just consult the appropriate pull\-down menu. Other keys 
    symbols (as \fB\\?\fR, \fB\\*\fR, \fB\\&\fR ) 
    31153119in filenames to disallow use them as metasymbols in regular expressions 
    31163120when substitution is performed in the input line. 
    31173121 
     3122.\"NODE "Internal File Editor / estring" 
     3123.SH "Internal File Editor: Unescape, reencode and insert string" 
     3124The options in this dialog are divided into several groups:  
     3125"Select input encoding", "Escaping method", and "Other options". 
     3126.PP 
     3127.B Select input encoding 
     3128.PP 
     3129.I Encoding... 
     3130Show up a list of encodings. User can select one to reencode inserted 
     3131string from 
     3132.B selected encoding 
     3133to 
     3134.B editor encoding 
     3135(user can set this by M\-e or Alt\-e for editor). 
     3136If you select a 8 bit encoding for input (e.g. ISO-8859-1 or CP437) 
     3137you can insert only those unicode characters which exists in the 
     3138input encoding. even the editor codepage is 
     3139.B UTF-8 
     3140. 
     3141.PP 
     3142.B Escaping method 
     3143.PP 
     3144Here user can choose one of escape styles. 
     3145.PP 
     3146.I C-style 
     3147This select the C string literal style escape method. Escape character: 
     3148.IR "\\ " (backslash) 
     3149.TP 
     3150Known escape sequences: 
     3151.br 
     3152.B \\\\\\\\ 
     3153insert a \\ (backslash) 
     3154.br 
     3155.B \\\\a 
     3156insert a bell (decimal 7, BEL) character 
     3157.br 
     3158.B \\\\b 
     3159insert a backspace (decimal 8, BS) character 
     3160.br 
     3161.B \\\\t 
     3162insert a horizontal tab (decimal 9, HT) character 
     3163.br 
     3164.B \\\\n 
     3165insert a line feed (decimal 10, LF) character 
     3166.br 
     3167.B \\\\v 
     3168insert a vertical tab (decimal 11, VT) character 
     3169.br 
     3170.B \\\\f 
     3171insert a form feed (decimal 12, FF) character 
     3172.br 
     3173.B \\\\r 
     3174insert a carriage return (decimal 13, CR) character 
     3175.br 
     3176.B \\\\e 
     3177insert an escape (decimal 27, ESC) character 
     3178.br 
     3179.B \\\\xhh 
     3180insert a character represented by number `hh' (hexadecimal), 
     3181where `h' between 0-9 and a-f (or A-F). 
     3182.br 
     3183.B \\\\ooo 
     3184insert a character represented by number `ooo' (octal), 
     3185where `o' between 0-7. If `ooo' greater than 377o 
     3186a warning message pop up for the user. 
     3187.PP 
     3188For example, the 
     3189.B The\\\\tquick\\\\x09brown\\\\040fox\\\\njumps\\\\ over 
     3190insert the string: 
     3191.PP 
     3192The     quick   brown fox 
     3193.br 
     3194jumps\\\\ over 
     3195.PP 
     3196.I HTML-style 
     3197This select the HTML style escape method. Escape character: 
     3198.IR "& " (at) 
     3199.TP 
     3200Escape sequence: 
     3201.br 
     3202.B &entity; 
     3203insert a character represented by HTML entity name `entity'. 
     3204.br 
     3205.B &#ddddd; 
     3206insert a unicode character represented by number `ddddd' (decimal), 
     3207where `d' between 0-9. 
     3208.br 
     3209.B &#xhhhh; 
     3210insert a unicode character represented by number `hhhh' (hexadecimal), 
     3211where `h' between 0-9 and a-f (or A-F). 
     3212.PP 
     3213For example, the 
     3214.B The	quick	brown fox
jumps\ over 
     3215insert the same string as above. 
     3216.PP 
     3217.I URL-style 
     3218This select the URL style escape method. Escape character: 
     3219.IR "% " (percent) 
     3220.PP 
     3221Escape sequence: 
     3222.br 
     3223.B %hh 
     3224insert a character represented by number `hh' (hexadecimal), 
     3225where `h' between 0-9 and a-f (or A-F). You can use %25 for a literal %. 
     3226.PP 
     3227For example, the 
     3228.B The%09quick%09brown%20fox%0ajumps%5C%20over 
     3229insert the same string as above. 
     3230.PP 
     3231.I Hex-string 
     3232This select the hex-string style. There is no escape character, but every 
     3233two character represent a hexadecimal number (`hh') 
     3234where `h' between 0-9 and a-f (or A-F) 
     3235.PP 
     3236For example, the 
     3237.B 54686509717569636B0962726F776E20666F780A6A756D7073206F766572 
     3238insert the same string as above. 
     3239.PP 
     3240.I Numpad-style 
     3241This select the DOS/Windows ALT+numpad style escape method. Escape character: 
     3242.IR "^ " (caret) 
     3243.PP 
     3244Escape sequences: 
     3245.br 
     3246.B ^ddd 
     3247insert a character represented by number `ddd' (decimal), 
     3248where `d' between 0-9. You can use ^94 for a literal ^. 
     3249You sould use the correct codepage to the perfect characters. 
     3250(CP437 for the original DOS OEM characters) 
     3251.PP 
     3252For example, the 
     3253.B The^9quick^09brown^32fox^10jumps^92 over 
     3254insert the same string as above. 
     3255.PP 
     3256.B Other options 
     3257.PP 
     3258.I Accept unicode 
     3259When checked, 
     3260.B C escape method 
     3261, 
     3262.B URL escape method 
     3263and 
     3264.B Numpad escape method 
     3265accept 
     3266.B \\\\uhhhh 
     3267, 
     3268.B %uhhhh 
     3269and 
     3270.B ^+hhhh 
     3271escape sequences, insert a unicode character represented 
     3272by number `hhhh' (hexadecimal), where `h' between 0-9 and 
     3273a-f (or A-F). 
     3274.PP 
     3275.I Insert invalid chars 
     3276When checked, 
     3277.B Hex-string escape method 
     3278accept and insert non hexadecimal characters (out of 0-9, a-f, and A-F) 
     3279as is. For example: Th65 insert the 
     3280.B The 
     3281string. 
     3282.PP 
     3283.I Show warnings 
     3284When checked, 
     3285.B out of range 
     3286octal numbers (greather than 377o) in 
     3287.BR "C-style escape method" , 
     3288.B out of range 
     3289decimal numbers (greather than 255d) in 
     3290.B Numpad-style escape method 
     3291and 
     3292.B character code conversion errors 
     3293pop up a warning message for the users. 
     3294.br 
     3295Please note, if you use unicode (UTF-16) escape sequences than 
     3296an aditional character code conversion occur from UTF-16 to 
     3297the 
     3298.B "selected" 
     3299(input) codepage. 
     3300.br 
     3301For example, if the selected codepage is 
     3302.B CP437 
     3303, the editor codepage is  
     3304.B ISO-8859-1 
     3305and the string is 
     3306.B \\\\u00EAtre \\\\x82crits 
     3307than first 
     3308.B \\\\u00EA 
     3309converted to 
     3310.B \\\\x88 
     3311than the whole string converted from 
     3312.B CP437 
     3313to 
     3314.B ISO-8859-1 
     3315. 
     3316.PP 
     3317.B Insert text from a file 
     3318.PP 
     3319Press  
     3320.I "[From file]" 
     3321to read and insert escaped text from a file. 
     3322 
     3323. 
     3324.PP 
     3325.B Process marked text 
     3326.PP 
     3327Press  
     3328.I [Marked] 
     3329to unescape and reencode marked text. If there is no marked text, editor ask 
     3330to work on current line or the whole file. 
     3331 
    31183332.\"NODE "Virtual File System" 
    31193333.SH "Virtual File System" 
    31203334The Midnight Commander is provided with a code layer to access the file 
  • lib/keybind.c

    diff --git a/lib/keybind.c b/lib/keybind.c
    index eedea6b..2a1261b 100644
    a b static name_keymap_t command_names[] = { 
    312312    {"BlockShiftLeft", CK_BlockShiftLeft}, 
    313313    {"BlockShiftRight", CK_BlockShiftRight}, 
    314314    {"InsertLiteral", CK_InsertLiteral}, 
     315    {"InsertEstring", CK_InsertEstring}, 
    315316    {"ShowTabTws", CK_ShowTabTws}, 
    316317    {"SyntaxOnOff", CK_SyntaxOnOff}, 
    317318    {"SyntaxChoose", CK_SyntaxChoose}, 
  • lib/keybind.h

    diff --git a/lib/keybind.h b/lib/keybind.h
    index 5bfb81b..0c2736d 100644
    a b enum 
    301301    CK_SyntaxOnOff, 
    302302    CK_SyntaxChoose, 
    303303    CK_InsertLiteral, 
     304    CK_InsertEstring, 
    304305    CK_ExternalCommand, 
    305306    CK_Date, 
    306307    CK_Mail, 
  • misc/mc.default.keymap

    diff --git a/misc/mc.default.keymap b/misc/mc.default.keymap
    index f627fad..ab617b0 100644
    a b BookmarkPrev = alt-i 
    321321# History = 
    322322Shell = ctrl-o 
    323323InsertLiteral = ctrl-q 
     324InsertEstring = ctrl-w 
    324325# MacroStartRecord = 
    325326# MacroStopRecord = 
    326327MacroStartStopRecord = ctrl-r 
  • misc/mc.emacs.keymap

    diff --git a/misc/mc.emacs.keymap b/misc/mc.emacs.keymap
    index 1f89773..708a9a9 100644
    a b Menu = f9 
    320320# History = 
    321321Shell = ctrl-o 
    322322InsertLiteral = ctrl-q 
     323InsertEstring = ctrl-w 
    323324# MacroStartRecord = 
    324325# MacroStopRecord = 
    325326MacroStartStopRecord = ctrl-r 
  • src/editor/Makefile.am

    diff --git a/src/editor/Makefile.am b/src/editor/Makefile.am
    index 0ca0fc5..3aceec0 100644
    a b libedit_la_SOURCES = \ 
    1515        editcmd.c \ 
    1616        editcmd_dialogs.c editcmd_dialogs.h \ 
    1717        editdraw.c \ 
     18        editestring.c \ 
    1819        editmenu.c \ 
    1920        editoptions.c \ 
    2021        editwidget.c editwidget.h \ 
  • src/editor/edit-impl.h

    diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h
    index e840d30..eca7af8 100644
    a b  
    6969 
    7070#define LB_NAMES (LB_MAC + 1) 
    7171 
     72#define ESC_NAMES (ESC_NUMP + 1) 
     73 
    7274#define get_sys_error(s) (s) 
    7375 
    7476#define edit_error_dialog(h,s) query_dialog (h, s, D_ERROR, 1, _("&Dismiss")) 
    typedef enum 
    9496    EDIT_DO_BACKUP 
    9597} edit_save_mode_t; 
    9698 
     99/* escape styles */ 
     100typedef enum 
     101{ 
     102    ESC_C = 0, 
     103    ESC_HTML, 
     104    ESC_URL, 
     105    ESC_HEX, 
     106    ESC_NUMP 
     107} EscapeStyles; 
     108 
    97109/*** structures declarations (and typedefs of structures)*****************************************/ 
    98110 
    99111/* search/replace options */ 
    gboolean edit_paste_from_X_buf_cmd (WEdit * edit); 
    254266 
    255267void edit_select_codepage_cmd (WEdit * edit); 
    256268void edit_insert_literal_cmd (WEdit * edit); 
     269void edit_insert_estring_cmd (WEdit * edit); 
    257270gboolean edit_execute_macro (WEdit * edit, int hotkey); 
    258271void edit_begin_end_macro_cmd (WEdit * edit); 
    259272void edit_begin_end_repeat_cmd (WEdit * edit); 
  • src/editor/edit.c

    diff --git a/src/editor/edit.c b/src/editor/edit.c
    index 4e9fb2d..d49529c 100644
    a b edit_find_filter (const vfs_path_t * filename_vpath) 
    204204 
    205205/* --------------------------------------------------------------------------------------------- */ 
    206206 
    207 static char * 
    208 edit_get_filter (const vfs_path_t * filename_vpath) 
    209 { 
    210     int i; 
    211     char *p, *quoted_name; 
    212  
    213     i = edit_find_filter (filename_vpath); 
    214     if (i < 0) 
    215         return NULL; 
    216  
    217     quoted_name = name_quote (vfs_path_as_str (filename_vpath), 0); 
    218     p = g_strdup_printf (all_filters[i].read, quoted_name); 
    219     g_free (quoted_name); 
    220     return p; 
    221 } 
    222  
    223 /* --------------------------------------------------------------------------------------------- */ 
    224  
    225207static off_t 
    226208edit_insert_stream (WEdit * edit, FILE * f) 
    227209{ 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    38393821    case CK_InsertLiteral: 
    38403822        edit_insert_literal_cmd (edit); 
    38413823        break; 
     3824    case CK_InsertEstring: 
     3825        edit_insert_estring_cmd (edit); 
     3826        break; 
    38423827    case CK_MacroStartStopRecord: 
    38433828        edit_begin_end_macro_cmd (edit); 
    38443829        break; 
    edit_move_down (WEdit * edit, long i, gboolean do_scroll) 
    39623947} 
    39633948 
    39643949/* --------------------------------------------------------------------------------------------- */ 
     3950 
     3951char * 
     3952edit_get_filter (const vfs_path_t * filename_vpath) 
     3953{ 
     3954    int i; 
     3955    char *p, *quoted_name; 
     3956 
     3957    i = edit_find_filter (filename_vpath); 
     3958    if (i < 0) 
     3959        return NULL; 
     3960 
     3961    quoted_name = name_quote (vfs_path_as_str (filename_vpath), 0); 
     3962    p = g_strdup_printf (all_filters[i].read, quoted_name); 
     3963    g_free (quoted_name); 
     3964    return p; 
     3965} 
     3966 
     3967/* --------------------------------------------------------------------------------------------- */ 
     3968 
  • src/editor/edit.h

    diff --git a/src/editor/edit.h b/src/editor/edit.h
    index 2382d73..81b38b3 100644
    a b gboolean edit_files (const GList * files); 
    7070char *edit_get_file_name (const WEdit * edit); 
    7171long edit_get_curs_col (const WEdit * edit); 
    7272const char *edit_get_syntax_type (const WEdit * edit); 
     73char *edit_get_filter (const vfs_path_t * filename_vpath); 
    7374 
    7475/*** inline functions ****************************************************************************/ 
    7576#endif /* MC__EDIT_H */ 
  • new file src/editor/editestring.c

    diff --git a/src/editor/editestring.c b/src/editor/editestring.c
    new file mode 100644
    index 0000000..96dfeee
    - +  
     1/* 
     2   Editor unescape reencode and insert string 
     3 
     4   Copyright (C) 2013 
     5   The Free Software Foundation, Inc. 
     6 
     7   Written by: 
     8   Gergely Szasz <szaszg@hu.inter.net> 2013 
     9 
     10   This file is part of the Midnight Commander. 
     11 
     12   The Midnight Commander is free software: you can redistribute it 
     13   and/or modify it under the terms of the GNU General Public License as 
     14   published by the Free Software Foundation, either version 3 of the License, 
     15   or (at your option) any later version. 
     16 
     17   The Midnight Commander is distributed in the hope that it will be useful, 
     18   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     20   GNU General Public License for more details. 
     21 
     22   You should have received a copy of the GNU General Public License 
     23   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
     24 */ 
     25 
     26/** \file 
     27 *  \brief Source: editor unescape reencode and insert string 
     28 *  \author Gergely Szasz 
     29 *  \date 2013 
     30 */ 
     31 
     32 
     33#include <config.h> 
     34 
     35#ifdef HAVE_ASSERT_H 
     36#include <assert.h> 
     37#endif 
     38#include <ctype.h> 
     39 
     40#include <stdio.h> 
     41#include <stdarg.h> 
     42#include <sys/types.h> 
     43#include <unistd.h> 
     44#include <string.h> 
     45#include <errno.h> 
     46#include <sys/stat.h> 
     47#include <stdlib.h> 
     48#include <fcntl.h> 
     49 
     50#include "lib/global.h" 
     51#include "lib/tty/tty.h" 
     52#include "lib/tty/key.h"        /* XCTRL */ 
     53#include "lib/mcconfig.h" 
     54#include "lib/skin.h" 
     55#include "lib/strutil.h"        /* utf string functions */ 
     56#include "lib/lock.h" 
     57#include "lib/util.h"           /* tilde_expand() */ 
     58#include "lib/vfs/vfs.h" 
     59#include "lib/widget.h" 
     60#include "lib/event.h"          /* mc_event_raise() */ 
     61#ifdef HAVE_CHARSET 
     62#include "lib/charsets.h" 
     63#endif 
     64 
     65#include "src/history.h" 
     66#include "src/setup.h"          /* option_tab_spacing */ 
     67#ifdef HAVE_CHARSET 
     68#include "src/selcodepage.h" 
     69#endif 
     70#include "src/keybind-defaults.h" 
     71#include "src/util.h"           /* check_for_default() */ 
     72#include "src/filemanager/layout.h"     /* mc_refresh()  */ 
     73 
     74#include "edit-impl.h" 
     75#include "editwidget.h" 
     76#include "editcmd_dialogs.h" 
     77#ifdef HAVE_ASPELL 
     78#include "spell.h" 
     79#include "spell_dialogs.h" 
     80#endif 
     81#include "etags.h" 
     82#include "etags.h" 
     83 
     84/*** global variables ****************************************************************************/ 
     85 
     86 
     87/*** file scope macro definitions ****************************************************************/ 
     88 
     89#define UNUSED_ARG(x) {(void)(x);} 
     90 
     91#define RECODE_LABEL 6 
     92 
     93#define TEMP_BUF_LEN 1024 
     94 
     95#define B_FILE (B_USER + 1) 
     96#define B_MARK (B_USER + 2) 
     97 
     98/*** file scope type declarations ****************************************************************/ 
     99 
     100typedef struct 
     101{ 
     102    const char *name; 
     103    gint32 u; 
     104} html_enc_t; 
     105 
     106/*** file scope variables ************************************************************************/ 
     107 
     108/* include html entities table for edit_insert_estring () */ 
     109#include "html_enc_table.h" 
     110 
     111/* --------------------------------------------------------------------------------------------- */ 
     112/*** file scope functions ************************************************************************/ 
     113/* --------------------------------------------------------------------------------------------- */ 
     114 
     115static void 
     116edit_utf16recode (GIConv cnv, guint32 u, GString **out, int *show_warn, int curr_index) 
     117{ 
     118    char str[4]; 
     119#ifdef HAVE_CHARSET 
     120    gchar *ostr; 
     121    gsize olen; 
     122    GError *err = NULL; 
     123 
     124    str[0] = u & 0xff; 
     125    str[1] = (u >> 8) & 0xff; 
     126    str[2] = (u >> 16) & 0xff; 
     127    str[3] = (u >> 24) & 0xff; 
     128    ostr = g_convert_with_iconv (str, 4, cnv, NULL, &olen, &err); 
     129    if (*show_warn && (err != NULL || ostr == NULL)) 
     130    { 
     131        char *tmp; 
     132        tmp = g_strdup_printf (_("Error when reencoding string at %u:\n%s"), curr_index, 
     133                               err == NULL ? "No result from conversion!" : err->message); 
     134        if (query_dialog (_("Warning"), tmp, D_ERROR, 2, _("&Dismiss"), _("Dismiss &All")) == 1) 
     135            *show_warn = 0; 
     136        g_free (tmp); 
     137    } 
     138    if (ostr != NULL) 
     139    { 
     140        *out = g_string_append (*out, ostr); 
     141        g_free (ostr); 
     142    } 
     143#else 
     144    UNUSED_ARG (cnv); 
     145    UNUSED_ARG (show_warn); 
     146    /* convert UTF-16 to UTF-8 */ 
     147    if (u <= 0x7f) 
     148    { 
     149        str[0] = u; 
     150        str[1] = '\0'; 
     151    } 
     152    else if (u > 0x07FF) 
     153    { 
     154        str[0] = 0xe0 | ((u >> 12) & 0x0f); 
     155        str[1] = 0x80 | ((u >>  6) & 0x3f); 
     156        str[2] = 0x80 | (u & 0x3f); 
     157        str[3] = '\0'; 
     158    } else { 
     159        str[0] = 0xc0 | ((u >>  6) & 0x1f); 
     160        str[1] = 0x80 | ((u >>  0) & 0x3f); 
     161        str[2] = '\0'; 
     162    } 
     163    *out = g_string_append (*out, str); 
     164#endif /* HAVE_CHARSET */ 
     165} 
     166 
     167/* --------------------------------------------------------------------------------------------- */ 
     168/*** public functions ****************************************************************************/ 
     169/* --------------------------------------------------------------------------------------------- */ 
     170 
     171void 
     172edit_insert_estring_cmd (WEdit * edit) 
     173{ 
     174    char *string; 
     175    static int esc_style = ESC_C; 
     176    static int show_warn = 1; 
     177    static int accept_u = 1; 
     178    static int accept_i = 1; 
     179    const char *esc_names[ESC_NAMES] = { 
     180        N_("&C-style"), 
     181        N_("&HTML-style"), 
     182        N_("&URL-style"), 
     183        N_("He&x-string"), 
     184        N_("&Numpad-style") 
     185    }; 
     186    int ret; 
     187    int mark = 0; 
     188#ifdef HAVE_CHARSET 
     189    GString *str_recode = NULL; 
     190    const char *str_recode_tpl = N_("Recode: %s%s%s"); 
     191    static int cp_id = -1; 
     192    int cp_to, recode; 
     193#endif /* HAVE_CHARSET */ 
     194 
     195    quick_widget_t quick_widgets[] = { 
     196        /* *INDENT-OFF* */ 
     197        QUICK_LABELED_INPUT (N_("Enter string:"), input_label_above, INPUT_LAST_TEXT, 
     198                             "insert-escaped-string", &string, NULL, FALSE, FALSE, 
     199                             INPUT_COMPLETE_NONE), 
     200//        QUICK_BUTTON (N_("Insert from &File..."), B_FILE, NULL, NULL), 
     201        QUICK_SEPARATOR (TRUE), 
     202        QUICK_START_COLUMNS, 
     203#ifdef HAVE_CHARSET 
     204            QUICK_BUTTON (N_("&Encoding..."), B_USER, NULL, NULL), 
     205#else 
     206            QUICK_SEPARATOR (FALSE), 
     207#endif /* HAVE_CHARSET */ 
     208            QUICK_RADIO (ESC_NAMES, esc_names, (int *) &esc_style, NULL), 
     209        QUICK_NEXT_COLUMN, 
     210            QUICK_LABEL(NULL, NULL), 
     211            QUICK_SEPARATOR (FALSE), 
     212            QUICK_CHECKBOX (N_("&Accept unicode"), &accept_u, NULL), 
     213            QUICK_CHECKBOX (N_("&Insert invalid chars"), &accept_i, NULL), 
     214            QUICK_CHECKBOX (N_("&Show warnings"), &show_warn, NULL), 
     215        QUICK_STOP_COLUMNS, 
     216        QUICK_START_BUTTONS (TRUE, TRUE),                                           \ 
     217            QUICK_BUTTON (N_("&OK"), B_ENTER, NULL, NULL),                          \ 
     218            QUICK_BUTTON (N_("&From File"), B_FILE, NULL, NULL), 
     219            QUICK_BUTTON (N_("&Marked"), B_MARK, NULL, NULL), 
     220            QUICK_BUTTON (N_("&Cancel"), B_CANCEL, NULL, NULL), 
     221        QUICK_END 
     222        /* *INDENT-ON* */ 
     223    }; 
     224 
     225    quick_dialog_t qdlg = { 
     226        -1, -1, 64, 
     227        N_("Unescape, reencode and insert string"), "[Internal File Editor / estring]", 
     228        quick_widgets, NULL, NULL 
     229    }; 
     230 
     231#ifdef HAVE_CHARSET 
     232    cp_to = mc_global.source_codepage >= 
     233                         0 ? mc_global.source_codepage : mc_global.display_codepage; 
     234    cp_id = cp_id == -1 ? cp_to : cp_id; 
     235    recode = (cp_id != cp_to); 
     236    str_recode = g_string_new (""); 
     237    g_string_printf (str_recode, str_recode_tpl, 
     238                     recode ? get_codepage_id (cp_id) : "", 
     239                     recode ? " to " : "-", 
     240                     recode ? get_codepage_id (cp_to) : ""); 
     241    quick_widgets[RECODE_LABEL].u.label.text = str_recode->str; 
     242#endif 
     243    while ((ret = quick_dialog (&qdlg)) != B_CANCEL) 
     244    { 
     245        FILE *finp = NULL; 
     246        int fdinp = -1, fdout = -1; 
     247        int insert_from_file = 0; 
     248        vfs_path_t *temp_vpath; 
     249        char *file_buff = NULL; 
     250        gsize len = 0; 
     251        GIConv cnvu = INVALID_CONV; 
     252#ifdef HAVE_CHARSET 
     253        int lcp_id = -1; 
     254#endif 
     255        /* feed from marked */ 
     256        /* feed from a file */ 
     257        if (ret == B_FILE || ret == B_MARK) 
     258        { 
     259 
     260            if (insert_from_file == 0) /* Initialize file input */ 
     261            { 
     262                char *p; 
     263                char *tmp; 
     264                char *exp = NULL; 
     265                vfs_path_t *file_vpath; 
     266 
     267                g_free (string); 
     268 
     269                if (ret != B_MARK) 
     270                { 
     271                    tmp = mc_config_get_full_path (EDIT_CLIP_FILE); 
     272                    exp = input_expand_dialog (_("Insert from file"), _("Enter file name:"), 
     273                                           MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES); 
     274                    g_free (tmp); 
     275                    if (exp == NULL || *exp == '\0') 
     276                        break; 
     277                } 
     278 
     279                fdout = mc_mkstemps (&temp_vpath, "estring", NULL); 
     280                if (fdout <= 0) 
     281                { 
     282                    edit_error_dialog (_("Error"), _("Cannot create temporary file!")); 
     283                    g_free (exp); 
     284                    break; 
     285                } 
     286                if (ret == B_MARK) 
     287                { 
     288                    int fdclip; 
     289                    off_t start_mark, end_mark; 
     290 
     291                    if (!eval_marks (edit, &start_mark, &end_mark)) 
     292                    { 
     293                        int rv; 
     294 
     295                        rv = edit_query_dialog3 (_("Warning"), 
     296                                                 _("There is no marked block.\nProcess whole file or current line?"), 
     297                                                 _("&Whole file"), _("Current &Line"), _("&Cancel")); 
     298                        switch (rv) 
     299                        { 
     300                        case 0: 
     301                            edit_set_markers (edit, 0, edit->buffer.size, 0, 0); 
     302                            eval_marks (edit, &start_mark, &end_mark); 
     303                            mark = 2;     /* later we have to reset highlite ?*/ 
     304                            break; 
     305                        case 1: 
     306                            edit->mark1 = edit_buffer_get_current_bol (&edit->buffer); 
     307                            edit->mark2 = edit_buffer_get_current_eol (&edit->buffer); 
     308                            eval_marks (edit, &start_mark, &end_mark); 
     309                            break; 
     310                        default: 
     311                            mark = -1; 
     312                            break; 
     313                        } 
     314                        if (mark == -1) 
     315                            break; 
     316                    } 
     317                    fdclip = mc_mkstemps (&file_vpath, "estring", NULL); 
     318                    if (fdclip < 0) 
     319                    { 
     320                        edit_error_dialog (_("Save block"), get_sys_error (_("Cannot create temporary file"))); 
     321                        break; 
     322                    } 
     323                    close (fdclip); 
     324//                    exp = vfs_path_to_str (file_vpath); 
     325                    exp = vfs_path_to_str_flags (file_vpath, 0, VPF_STRIP_PASSWORD); 
     326                    if (!edit_save_block (edit, exp, start_mark, end_mark)) 
     327                    { 
     328                        edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file"))); 
     329                        break; 
     330                    } 
     331                    mark = 1; 
     332                } 
     333                else 
     334                { 
     335                    file_vpath = vfs_path_from_str (exp); 
     336                } 
     337                p = edit_get_filter (file_vpath); 
     338                if (p != NULL) 
     339                { 
     340                    if (mark) 
     341                        mc_unlink (file_vpath); 
     342                    vfs_path_free (file_vpath); 
     343                    finp = (FILE *) popen (p, "r"); 
     344                    if (finp == NULL) 
     345                    { 
     346                        close (fdout); 
     347                        edit_error_dialog (_("Open filter"), get_sys_error (_("Cannot open file filter"))); 
     348                        g_free (exp); 
     349                        break; 
     350                    } 
     351                } 
     352                else 
     353                { 
     354                    fdinp = mc_open (file_vpath, O_RDONLY | O_BINARY); 
     355                    if (mark) 
     356                        mc_unlink (file_vpath); 
     357                    vfs_path_free (file_vpath); 
     358                    if (fdinp == -1) 
     359                    { 
     360                        char *errmsg; 
     361 
     362                        close (fdout); 
     363                        errmsg = g_strdup_printf (_("Cannot open file for reading: %s"), exp); 
     364                        edit_error_dialog (_("Error"), errmsg); 
     365                        g_free (errmsg); 
     366                        g_free (exp); 
     367                        break; 
     368                    } 
     369                } 
     370                g_free (exp); 
     371                file_buff = g_malloc (TEMP_BUF_LEN); 
     372                string = file_buff; 
     373                ret = B_ENTER; /* convert string */ 
     374                insert_from_file = 1; 
     375            } 
     376continue_file: 
     377            /* read next string */ 
     378            if (insert_from_file == 1) 
     379            { 
     380                size_t blocklen; 
     381                if (finp != NULL) 
     382                { 
     383                    blocklen = fread (file_buff, 1, TEMP_BUF_LEN, finp); 
     384                    if (blocklen == 0 && feof (finp)) 
     385                    { 
     386                        insert_from_file = 2; 
     387                        if (pclose (finp)) 
     388                        { 
     389                            edit_error_dialog (_("Error"), get_sys_error (_("File filter error"))); 
     390                            break; 
     391                        } 
     392                    } 
     393                } 
     394                else 
     395                { 
     396                    blocklen = mc_read (fdinp, file_buff, TEMP_BUF_LEN); 
     397                    if (blocklen <= 0) 
     398                    { 
     399                        insert_from_file = 2; 
     400                        mc_close (fdinp); 
     401                    } 
     402                } 
     403                if (insert_from_file == 2) 
     404                { 
     405                    close (fdout); 
     406                    g_free (file_buff); 
     407#ifdef HAVE_CHARSET 
     408                    recode = 0; 
     409#endif 
     410                    len = 0; /* avoid recoding and string processing */ 
     411                    if (mark && edit_block_delete_cmd (edit)) 
     412                    { 
     413                        edit_error_dialog (_("Error"), _("Cannot delete marked block")); 
     414                        mc_unlink (temp_vpath); 
     415                        vfs_path_free (temp_vpath); 
     416                        break; 
     417                    } 
     418                    if (!edit_insert_file (edit, temp_vpath)) 
     419                    { 
     420                        edit_error_dialog (_("Error"), get_sys_error (mark ?  
     421                                           _("Cannot replace marked block") : _("Cannot insert file"))); 
     422                        mc_unlink (temp_vpath); 
     423                        vfs_path_free (temp_vpath); 
     424                        break; 
     425                    } 
     426                    mc_unlink (temp_vpath); 
     427                    vfs_path_free (temp_vpath); 
     428                } 
     429                else if (blocklen > 0) 
     430                { 
     431                    len = blocklen; 
     432                } 
     433            } 
     434        } 
     435 
     436        if (ret == B_USER) 
     437        { 
     438#ifdef HAVE_CHARSET 
     439            int r; 
     440            r = select_charset (-1, -1, cp_id, FALSE); 
     441            if (r != SELECT_CHARSET_CANCEL) 
     442            { 
     443                cp_id = r == -1 ? cp_to : r; 
     444                recode = (cp_id != cp_to); 
     445                g_string_printf (str_recode, str_recode_tpl, 
     446                     recode ? get_codepage_id (cp_id) : "", 
     447                     recode ? " to " : "-", 
     448                     recode ? get_codepage_id (cp_to) : ""); 
     449                quick_widgets[RECODE_LABEL].u.label.text = str_recode->str; 
     450            } 
     451#endif /* HAVE_CHARSET */ 
     452        } 
     453        else if (ret == B_ENTER) 
     454        { 
     455            GString *out = g_string_new(""); 
     456            gsize curr_index; 
     457            int accept_u_and_conv = accept_u; 
     458 
     459#ifdef HAVE_CHARSET 
     460            /* converter for unicode escapes and HTML */ 
     461            if (accept_u || esc_style == ESC_NUMP || esc_style == ESC_HTML) 
     462            { 
     463                if (lcp_id != cp_id) 
     464                { 
     465                    if (cnvu != INVALID_CONV) 
     466                        g_iconv_close (cnvu); 
     467                    cnvu = g_iconv_open (get_codepage_id (cp_id), "UTF-16"); 
     468                    lcp_id = cp_id; 
     469                } 
     470 
     471                if (accept_u_and_conv && cnvu == INVALID_CONV) 
     472                { 
     473                    char *tmp; 
     474                    tmp = g_strdup_printf (_("Cannot initialise conversion from:\n" 
     475                                                 "UTF-16 to %s\nUTF-16 cannot accepted."), 
     476                                               get_codepage_id (cp_to)); 
     477                    edit_error_dialog (_("Warning"), tmp); 
     478                    g_free (tmp); 
     479                    accept_u_and_conv = 0; 
     480                } 
     481            } 
     482#endif 
     483            if (insert_from_file == 0) 
     484                len = strlen (string); 
     485 
     486            for (curr_index = 0; curr_index < len; curr_index++) 
     487            { 
     488                switch (esc_style) 
     489                { 
     490                case ESC_C: 
     491                    if (string[curr_index] != '\\') 
     492                    { 
     493                        out = g_string_append_c (out, string[curr_index]); 
     494                        continue; 
     495                    } 
     496                    curr_index++; 
     497                    if (curr_index == len) 
     498                        continue; 
     499                    switch (string[curr_index]) 
     500                    { 
     501                    case '\\': 
     502                        out = g_string_append_c (out, '\\'); 
     503                        continue; 
     504                    case 'a': 
     505                        out = g_string_append_c (out, '\a'); 
     506                        continue; 
     507                    case 'b': 
     508                        out = g_string_append_c (out, '\b'); 
     509                        continue; 
     510                    case 't': 
     511                        out = g_string_append_c (out, '\t'); 
     512                        continue; 
     513                    case 'n': 
     514                        out = g_string_append_c (out, '\n'); 
     515                        continue; 
     516                    case 'v': 
     517                        out = g_string_append_c (out, '\v'); 
     518                        continue; 
     519                    case 'f': 
     520                        out = g_string_append_c (out, '\f'); 
     521                        continue; 
     522                    case 'r': 
     523                        out = g_string_append_c (out, '\r'); 
     524                        continue; 
     525                    case 'e': 
     526                        out = g_string_append_c (out, '\027'); 
     527                        continue; 
     528                    case 'x': 
     529                        { 
     530                            int i, c = -1; 
     531                            for (i = 1; i <= 2; i++) 
     532                            { 
     533                                int x; 
     534                                if (curr_index + 1 >= len) 
     535                                { 
     536                                    if (c < 0) 
     537                                        out = g_string_append_c (out, 'x'); 
     538                                    continue; 
     539                                } 
     540                                x = string[++curr_index]; 
     541                                if (x >= 'a' && x <= 'f') 
     542                                    x -= 'a' - 10; 
     543                                else if (x >= 'A' && x <= 'F') 
     544                                    x -= 'A' - 10; 
     545                                else if (x >= '0' && x <= '9') 
     546                                    x -= '0'; 
     547                                else 
     548                                { 
     549                                    if (c >= 0) 
     550                                        out = g_string_append_c (out, c); 
     551                                    else 
     552                                        out = g_string_append_c (out, 'x'); 
     553                                    c = -1; 
     554                                    curr_index--; 
     555                                    break; 
     556                                } 
     557                                c = c == -1 ? 0 : c << 4; 
     558                                c |= x & 0x0f; 
     559                            } 
     560                            if (c >= 0) 
     561                                out = g_string_append_c (out, c); 
     562                        } 
     563                        continue; 
     564                    case '0': 
     565                    case '1': 
     566                    case '2': 
     567                    case '3': 
     568                    case '4': 
     569                    case '5': 
     570                    case '6': 
     571                    case '7': 
     572                        { 
     573                            int i, c = -1; 
     574 
     575                            curr_index = curr_index - 1; 
     576                            for (i = 1; i <= 3; i++) 
     577                            { 
     578                                int o; 
     579                                if (curr_index + 1 >= len) 
     580                                    break; 
     581                                o = string[++curr_index]; 
     582                                if (o >= '0' && o <= '7') 
     583                                    o -= '0'; 
     584                                else 
     585                                { 
     586                                    out = g_string_append_c (out, c&0xff); 
     587                                    out = g_string_append_c (out, o); 
     588                                    c = -1; 
     589                                    break; 
     590                                } 
     591                                c = c == -1 ? 0 : c << 3; 
     592                                c |= o & 0x0f; 
     593                            } 
     594                            if (c > 0xff && show_warn) 
     595                            { 
     596                                char *tmp; 
     597 
     598                                tmp = g_strdup_printf (_("Octal value out " 
     599                                      "of range (000-377) at %u: %03o\n" 
     600                                      "Value converted to: %03o"), 
     601                                      curr_index, c, c&0xff); 
     602                                if (query_dialog (_("Warning"), tmp, D_ERROR, 2, _("&Dismiss"), _("Dismiss &All")) == 1) 
     603                                    show_warn = 0; 
     604 
     605                                g_free (tmp); 
     606                            } 
     607                            if (c >= 0) 
     608                                out = g_string_append_c (out, c&0xff); 
     609                            continue; 
     610                        } 
     611                    case 'u': 
     612                        if (accept_u_and_conv) 
     613                        { 
     614                            gint32 u = -1; 
     615                            int i; 
     616                            for (i = 1; i <= 4; i++) 
     617                            { 
     618                                int x; 
     619                                if (curr_index + 1 >= len) 
     620                                { 
     621                                    if (u < 0) 
     622                                        out = g_string_append_c (out, 'u'); 
     623                                    break; 
     624                                } 
     625                                x = string[++curr_index]; 
     626                                if (x >= 'a' && x <= 'f') 
     627                                    x -= 'a' - 10; 
     628                                else if (x >= 'A' && x <= 'F') 
     629                                    x -= 'A' - 10; 
     630                                else if (x >= '0' && x <= '9') 
     631                                    x -= '0'; 
     632                                else 
     633                                { 
     634                                    if (u < 0) 
     635                                    { 
     636                                        out = g_string_append_c (out, 'x'); 
     637                                    } 
     638                                    curr_index--; 
     639                                    break; 
     640                                } 
     641                                u = u == -1 ? 0 : u << 4; 
     642                                u |= x & 0x0f; 
     643                            } 
     644                            if (u >= 0) 
     645                                edit_utf16recode (cnvu, u, &out, &show_warn, curr_index); 
     646                        } 
     647                        continue; 
     648                    default: 
     649                        out = g_string_append_c (out, string[curr_index]); 
     650                        continue; 
     651                    } 
     652                    break; 
     653                case ESC_HTML: 
     654                    if (string[curr_index] != '&' || cnvu == INVALID_CONV) 
     655                    { 
     656                        out = g_string_append_c (out, string[curr_index]); 
     657                        continue; 
     658                    } 
     659                    curr_index++; 
     660                    if (curr_index == len) 
     661                    { 
     662                        out = g_string_append_c (out, '&'); 
     663                        continue; 
     664                    } 
     665                    else if (string[curr_index] != '#') 
     666                    { 
     667                        gsize i; 
     668                        int hlen; 
     669 
     670                        for (i = curr_index; i < len; i++) 
     671                            if (string[i] == ';') 
     672                                break; 
     673                        if (string[i] != ';') 
     674                        { 
     675                            out = g_string_append_c (out, '&'); 
     676                            curr_index--; 
     677                            continue; 
     678                        } 
     679                        hlen = i - curr_index; 
     680                        for (i = 0; html_enc_table[i].name != NULL; i++) 
     681                        { 
     682                            if (strncmp (html_enc_table[i].name, 
     683                                         &string[curr_index], hlen) == 0) 
     684                                break; 
     685                        } 
     686                        if (html_enc_table[i].name == NULL) 
     687                        { 
     688                            out = g_string_append_c (out, '&'); 
     689                            curr_index--; 
     690                            continue; 
     691                        } 
     692                        edit_utf16recode (cnvu, html_enc_table[i].u, &out, &show_warn, curr_index); 
     693                        curr_index += hlen; 
     694                        continue; 
     695                    } 
     696                    else if (curr_index + 1 < len &&  
     697                             string[curr_index + 1] >= '0' && string[curr_index + 1] <= '9') 
     698                    { 
     699                        gint32 u = -1; 
     700                        int i, x = 0; 
     701 
     702                        for (i = 1; i <= 6; i++) 
     703                        { 
     704                            if (curr_index + 1 >= len) 
     705                            { 
     706                                out = g_string_append (out, "&#"); 
     707                                u = -1; 
     708                                curr_index -= i; 
     709                                break; 
     710                            } 
     711                            x = string[++curr_index]; 
     712                            if (x >= '0' && x <= '9') 
     713                                x -= '0'; 
     714                            else 
     715                                break; 
     716                            u = u == -1 ? 0 : u * 10; 
     717                            u += x; 
     718                        } 
     719                        if (x != ';') 
     720                        { 
     721                            out = g_string_append (out, "&#"); 
     722                            u = -1; 
     723                            curr_index -= i; 
     724                            continue; 
     725                        } 
     726                        if (u >= 0) 
     727                            edit_utf16recode (cnvu, u, &out, &show_warn, curr_index); 
     728                    } 
     729                    else if (curr_index + 2 < len && string[curr_index + 1] == 'x') 
     730                    { 
     731                        gint32 u = -1; 
     732                        int i, x = 0; 
     733                        curr_index++; 
     734                        for (i = 1; i <= 5; i++) 
     735                        { 
     736                            if (curr_index + 1 >= len) 
     737                            { 
     738                                out = g_string_append (out, "&#"); 
     739                                u = -1; 
     740                                curr_index -= i; 
     741                                break; 
     742                            } 
     743                            x = string[++curr_index]; 
     744                            if (x >= 'a' && x <= 'f') 
     745                                x -= 'a' - 10; 
     746                            else if (x >= 'A' && x <= 'F') 
     747                                x -= 'A' - 10; 
     748                            else if (x >= '0' && x <= '9') 
     749                                x -= '0'; 
     750                            else 
     751                                break; 
     752                            u = u == -1 ? 0 : u << 4; 
     753                            u += x; 
     754                        } 
     755                        if (x != ';') 
     756                        { 
     757                            out = g_string_append (out, "&#"); 
     758                            u = -1; 
     759                            curr_index -= i; 
     760                            continue; 
     761                        } 
     762                        if (u >= 0) 
     763                            edit_utf16recode (cnvu, u, &out, &show_warn, curr_index); 
     764                    } 
     765                    else 
     766                    { 
     767                        out = g_string_append (out, "&#"); 
     768                        continue; 
     769                    } 
     770                    break; 
     771                case ESC_URL: 
     772                    if (string[curr_index] != '%') 
     773                    { 
     774                        out = g_string_append_c (out, string[curr_index]); 
     775                        continue; 
     776                    } 
     777                    curr_index++; 
     778                    if (curr_index == len) 
     779                    { 
     780                        out = g_string_append_c (out, '%'); 
     781                        continue; 
     782                    } 
     783                    else if (accept_u_and_conv && string[curr_index] == 'u') 
     784                    { 
     785                        gint32 u = -1; 
     786                        int i; 
     787                        for (i = 1; i <= 4; i++) 
     788                        { 
     789                            int x; 
     790                            if (curr_index + 1 >= len) 
     791                            { 
     792                                if (u < 0) 
     793                                    out = g_string_append_c (out, 'u'); 
     794                                break; 
     795                            } 
     796                            x = string[++curr_index]; 
     797                            if (x >= 'a' && x <= 'f') 
     798                                x -= 'a' - 10; 
     799                            else if (x >= 'A' && x <= 'F') 
     800                                x -= 'A' - 10; 
     801                            else if (x >= '0' && x <= '9') 
     802                                x -= '0'; 
     803                            else 
     804                            { 
     805                                if (u < 0) 
     806                                { 
     807                                    out = g_string_append_c (out, 'u'); 
     808                                } 
     809                                curr_index--; 
     810                                break; 
     811                            } 
     812                            u = u == -1 ? 0 : u << 4; 
     813                            u |= x & 0x0f; 
     814                        } 
     815                        if (u >= 0) 
     816                            edit_utf16recode (cnvu, u, &out, &show_warn, curr_index); 
     817                        continue; 
     818                    } 
     819                    else 
     820                    { 
     821                        int i, c = -1; 
     822                        curr_index--; 
     823                        for (i = 0; i < 2; i++) 
     824                        { 
     825                            int x; 
     826                            if (curr_index + 1 >= len) 
     827                            { 
     828                                if (c < 0) 
     829                                    out = g_string_append_c (out, '%'); 
     830                                break; 
     831                            } 
     832                            x = string[++curr_index]; 
     833                            if (x >= 'a' && x <= 'f') 
     834                                x -= 'a' - 10; 
     835                            else if (x >= 'A' && x <= 'F') 
     836                                x -= 'A' - 10; 
     837                            else if (x >= '0' && x <= '9') 
     838                                x -= '0'; 
     839                            else 
     840                            { 
     841                                if (c >= 0) 
     842                                    out = g_string_append_c (out, c); 
     843                                else 
     844                                    out = g_string_append_c (out, '%'); 
     845                                c = -1; 
     846                                curr_index--; 
     847                                break; 
     848                            } 
     849                            c = c == -1 ? 0 : c << 4; 
     850                            c |= x & 0x0f; 
     851                        } 
     852                        if (c >= 0) 
     853                            out = g_string_append_c (out, c); 
     854                        continue; 
     855                    } 
     856                    break; 
     857                case ESC_HEX: 
     858                    if (string[curr_index] < '0' || 
     859                           string[curr_index] > '9' && string[curr_index] < 'A' || 
     860                           string[curr_index] > 'F' && string[curr_index] < 'a' || 
     861                           string[curr_index] > 'f') 
     862                    { 
     863                        if (accept_i) 
     864                            out = g_string_append_c (out, string[curr_index]); 
     865                        continue; 
     866                    } 
     867                    else 
     868                    { 
     869                        int i, c = -1; 
     870                        curr_index--; 
     871                        for (i=0; i<2; i++) 
     872                        { 
     873                            int x; 
     874                            if (curr_index + 1 == len) 
     875                            { 
     876                               break; 
     877                            } 
     878                            x = string[++curr_index]; 
     879                            if (x >= 'a' && x <= 'f') 
     880                                x -= 'a' - 10; 
     881                            else if (x >= 'A' && x <= 'F') 
     882                                x -= 'A' - 10; 
     883                            else if (x >= '0' && x <= '9') 
     884                                x -= '0'; 
     885                            else 
     886                            { 
     887                                if (c >= 0) 
     888                                    out = g_string_append_c (out, c); 
     889                                out = g_string_append_c (out, x); 
     890                                c = -1; 
     891                                break; 
     892                            } 
     893                            c = c == -1 ? 0 : c << 4; 
     894                            c |= x & 0x0f; 
     895                        } 
     896                        if (c >= 0) 
     897                            out = g_string_append_c (out, c); 
     898                        continue; 
     899                    } 
     900                case ESC_NUMP: 
     901                    if (string[curr_index] != '^') 
     902                    { 
     903                        out = g_string_append_c (out, string[curr_index]); 
     904                        continue; 
     905                    } 
     906                    curr_index++; 
     907                    if (curr_index == len) 
     908                    { 
     909                        out = g_string_append_c (out, '^'); 
     910                        continue; 
     911                    } 
     912                    else if (accept_u_and_conv && string[curr_index] == '+') 
     913                    { 
     914                        gint32 u = -1; 
     915                        int i; 
     916                        for (i = 1; i <= 4; i++) 
     917                        { 
     918                            int x; 
     919                            if (curr_index + 1 >= len) 
     920                            { 
     921                                if (u < 0) 
     922                                    out = g_string_append_c (out, '+'); 
     923                                break; 
     924                            } 
     925                            x = string[++curr_index]; 
     926                            if (x >= 'a' && x <= 'f') 
     927                                x -= 'a' - 10; 
     928                            else if (x >= 'A' && x <= 'F') 
     929                                x -= 'A' - 10; 
     930                            else if (x >= '0' && x <= '9') 
     931                                x -= '0'; 
     932                            else 
     933                            { 
     934                                if (u < 0) 
     935                                { 
     936                                    out = g_string_append_c (out, '+'); 
     937                                } 
     938                                curr_index--; 
     939                                break; 
     940                            } 
     941                            u = u == -1 ? 0 : u << 4; 
     942                            u |= x & 0x0f; 
     943                        } 
     944                        if (u >= 0) 
     945                            edit_utf16recode (cnvu, u, &out, &show_warn, curr_index); 
     946                        continue; 
     947                    } 
     948                    else 
     949                    { 
     950                        int i, c = -1; 
     951                        curr_index--; 
     952                        for (i = 0; i < 3; i++) 
     953                        { 
     954                            int x; 
     955                            if (curr_index + 1 >= len) 
     956                            { 
     957                                if (c < 0) 
     958                                    out = g_string_append_c (out, '^'); 
     959                                break; 
     960                            } 
     961                            x = string[++curr_index]; 
     962                            if (x >= '0' && x <= '9') 
     963                                x -= '0'; 
     964                            else 
     965                            { 
     966                                if (c >= 0) 
     967                                    out = g_string_append_c (out, c); 
     968                                else 
     969                                    out = g_string_append_c (out, '^'); 
     970                                c = -1; 
     971                                curr_index--; 
     972                                break; 
     973                            } 
     974                            c = c == -1 ? 0 : c * 10; 
     975                            c += x; 
     976                        } 
     977                        if (c > 0xff && show_warn) 
     978                        { 
     979                            char *tmp; 
     980 
     981                            tmp = g_strdup_printf (_("Decimal value out " 
     982                                  "of range (0-255) at %u: %3d\n" 
     983                                  "Value converted to: %3d"), 
     984                                  curr_index, c, c&0xff); 
     985                            if (query_dialog (_("Warning"), tmp, D_ERROR, 2, _("&Dismiss"), _("Dismiss &All")) == 1) 
     986                                show_warn = 0; 
     987                            g_free (tmp); 
     988                        } 
     989                        if (c >= 0) 
     990                            out = g_string_append_c (out, c&0xff); 
     991                        continue; 
     992                    } 
     993                    break; 
     994                } 
     995            } 
     996#ifdef HAVE_CHARSET 
     997            if (recode) 
     998            { 
     999                GIConv cnv; 
     1000 
     1001                cnv = g_iconv_open (get_codepage_id (cp_to), 
     1002                                    get_codepage_id (cp_id)); 
     1003 
     1004                if (cnv != INVALID_CONV) 
     1005                { 
     1006                    GError *err = NULL; 
     1007                    gchar *ostr; 
     1008 
     1009                    ostr = g_convert_with_iconv (out->str, out->len, cnv, NULL, NULL, &err); 
     1010                    if (show_warn && (err != NULL || out == NULL)) 
     1011                    { 
     1012                        char *tmp; 
     1013                        tmp = g_strdup_printf (_("Error(s) when reencoding string at %u:\n%s"), out->len, 
     1014                                               err == NULL ? "No result from conversion!" : err->message); 
     1015                        edit_error_dialog (_("Warning"), tmp); 
     1016                        g_free (tmp); 
     1017                    } 
     1018                    if (ostr != NULL) 
     1019                    { 
     1020                        g_string_truncate (out, 0); 
     1021                        g_string_append (out, ostr); 
     1022                        g_free (ostr); 
     1023                    } 
     1024                    g_iconv_close (cnv); 
     1025                } 
     1026                else 
     1027                { 
     1028                        char *tmp; 
     1029                        tmp = g_strdup_printf (_("Cannot initialise conversion from: %s to %s"), 
     1030                                               get_codepage_id (cp_to), 
     1031                                               get_codepage_id (cp_id)); 
     1032                        edit_error_dialog (_("Warning"), tmp); 
     1033                        g_free (tmp); 
     1034                } 
     1035            } 
     1036#endif /* HAVE_CHARSET */ 
     1037            if (insert_from_file) 
     1038            { 
     1039                if (insert_from_file != 2) 
     1040                { 
     1041 
     1042                    if (write (fdout, out->str, out->len) != (ssize_t)out->len) 
     1043                    { 
     1044                        edit_error_dialog (_("Error"), get_sys_error (_("Cannot write temporary file"))); 
     1045                        break; 
     1046                    } 
     1047                    goto continue_file; 
     1048                } 
     1049            } 
     1050            else 
     1051            { 
     1052                for (len = 0; len < out->len; len++) 
     1053                    edit_insert (edit, out->str[len]); 
     1054                g_string_free (out, TRUE); 
     1055            } 
     1056#ifdef HAVE_CHARSET 
     1057            if (cnvu != INVALID_CONV) 
     1058                g_iconv_close (cnvu); 
     1059#endif /* HAVE_CHARSET */ 
     1060            if (insert_from_file == 0) 
     1061                g_free (string); 
     1062            break; 
     1063        } 
     1064        if (insert_from_file == 0) 
     1065            g_free (string); 
     1066    } 
     1067#ifdef HAVE_CHARSET 
     1068    g_string_free (str_recode, TRUE); 
     1069#endif /* HAVE_CHARSET */ 
     1070} 
  • src/editor/editmenu.c

    diff --git a/src/editor/editmenu.c b/src/editor/editmenu.c
    index a55636d..249d888 100644
    a b create_format_menu (void) 
    204204 
    205205    entries = 
    206206        g_list_prepend (entries, menu_entry_create (_("Insert &literal..."), CK_InsertLiteral)); 
     207    entries = 
     208        g_list_prepend (entries, menu_entry_create (_("Insert esc&aped string..."), CK_InsertEstring)); 
    207209    entries = g_list_prepend (entries, menu_entry_create (_("Insert &date/time"), CK_Date)); 
    208210    entries = g_list_prepend (entries, menu_separator_create ()); 
    209211    entries = 
  • new file src/editor/html_enc_table.h

    diff --git a/src/editor/html_enc_table.h b/src/editor/html_enc_table.h
    new file mode 100644
    index 0000000..446c032
    - +  
     1static html_enc_t html_enc_table[] = 
     2{ 
     3    {"quot", 0x0022}, 
     4    {"amp", 0x0026}, 
     5    {"apos", 0x0027}, 
     6    {"lt", 0x003C}, 
     7    {"gt", 0x003E}, 
     8    {"nbsp", 0x00A0}, 
     9    {"iexcl", 0x00A1}, 
     10    {"cent", 0x00A2}, 
     11    {"pound", 0x00A3}, 
     12    {"curren", 0x00A4}, 
     13    {"yen", 0x00A5}, 
     14    {"brvbar", 0x00A6}, 
     15    {"sect", 0x00A7}, 
     16    {"uml", 0x00A8}, 
     17    {"copy", 0x00A9}, 
     18    {"ordf", 0x00AA}, 
     19    {"laquo", 0x00AB}, 
     20    {"not", 0x00AC}, 
     21    {"shy", 0x00AD}, 
     22    {"reg", 0x00AE}, 
     23    {"macr", 0x00AF}, 
     24    {"deg", 0x00B0}, 
     25    {"plusmn", 0x00B1}, 
     26    {"sup2", 0x00B2}, 
     27    {"sup3", 0x00B3}, 
     28    {"acute", 0x00B4}, 
     29    {"micro", 0x00B5}, 
     30    {"para", 0x00B6}, 
     31    {"middot", 0x00B7}, 
     32    {"cedil", 0x00B8}, 
     33    {"sup1", 0x00B9}, 
     34    {"ordm", 0x00BA}, 
     35    {"raquo", 0x00BB}, 
     36    {"frac14", 0x00BC}, 
     37    {"frac12", 0x00BD}, 
     38    {"frac34", 0x00BE}, 
     39    {"iquest", 0x00BF}, 
     40    {"Agrave", 0x00C0}, 
     41    {"Aacute", 0x00C1}, 
     42    {"Acirc", 0x00C2}, 
     43    {"Atilde", 0x00C3}, 
     44    {"Auml", 0x00C4}, 
     45    {"Aring", 0x00C5}, 
     46    {"AElig", 0x00C6}, 
     47    {"Ccedil", 0x00C7}, 
     48    {"Egrave", 0x00C8}, 
     49    {"Eacute", 0x00C9}, 
     50    {"Ecirc", 0x00CA}, 
     51    {"Euml", 0x00CB}, 
     52    {"Igrave", 0x00CC}, 
     53    {"Iacute", 0x00CD}, 
     54    {"Icirc", 0x00CE}, 
     55    {"Iuml", 0x00CF}, 
     56    {"ETH", 0x00D0}, 
     57    {"Ntilde", 0x00D1}, 
     58    {"Ograve", 0x00D2}, 
     59    {"Oacute", 0x00D3}, 
     60    {"Ocirc", 0x00D4}, 
     61    {"Otilde", 0x00D5}, 
     62    {"Ouml", 0x00D6}, 
     63    {"times", 0x00D7}, 
     64    {"Oslash", 0x00D8}, 
     65    {"Ugrave", 0x00D9}, 
     66    {"Uacute", 0x00DA}, 
     67    {"Ucirc", 0x00DB}, 
     68    {"Uuml", 0x00DC}, 
     69    {"Yacute", 0x00DD}, 
     70    {"THORN", 0x00DE}, 
     71    {"szlig", 0x00DF}, 
     72    {"agrave", 0x00E0}, 
     73    {"aacute", 0x00E1}, 
     74    {"acirc", 0x00E2}, 
     75    {"atilde", 0x00E3}, 
     76    {"auml", 0x00E4}, 
     77    {"aring", 0x00E5}, 
     78    {"aelig", 0x00E6}, 
     79    {"ccedil", 0x00E7}, 
     80    {"egrave", 0x00E8}, 
     81    {"eacute", 0x00E9}, 
     82    {"ecirc", 0x00EA}, 
     83    {"euml", 0x00EB}, 
     84    {"igrave", 0x00EC}, 
     85    {"iacute", 0x00ED}, 
     86    {"icirc", 0x00EE}, 
     87    {"iuml", 0x00EF}, 
     88    {"eth", 0x00F0}, 
     89    {"ntilde", 0x00F1}, 
     90    {"ograve", 0x00F2}, 
     91    {"oacute", 0x00F3}, 
     92    {"ocirc", 0x00F4}, 
     93    {"otilde", 0x00F5}, 
     94    {"ouml", 0x00F6}, 
     95    {"divide", 0x00F7}, 
     96    {"oslash", 0x00F8}, 
     97    {"ugrave", 0x00F9}, 
     98    {"uacute", 0x00FA}, 
     99    {"ucirc", 0x00FB}, 
     100    {"uuml", 0x00FC}, 
     101    {"yacute", 0x00FD}, 
     102    {"thorn", 0x00FE}, 
     103    {"yuml", 0x00FF}, 
     104    {"OElig", 0x0152}, 
     105    {"oelig", 0x0153}, 
     106    {"Scaron", 0x0160}, 
     107    {"scaron", 0x0161}, 
     108    {"Yuml", 0x0178}, 
     109    {"fnof", 0x0192}, 
     110    {"circ", 0x02C6}, 
     111    {"tilde", 0x02DC}, 
     112    {"Alpha", 0x0391}, 
     113    {"Beta", 0x0392}, 
     114    {"Gamma", 0x0393}, 
     115    {"Delta", 0x0394}, 
     116    {"Epsilon", 0x0395}, 
     117    {"Zeta", 0x0396}, 
     118    {"Eta", 0x0397}, 
     119    {"Theta", 0x0398}, 
     120    {"Iota", 0x0399}, 
     121    {"Kappa", 0x039A}, 
     122    {"Lambda", 0x039B}, 
     123    {"Mu", 0x039C}, 
     124    {"Nu", 0x039D}, 
     125    {"Xi", 0x039E}, 
     126    {"Omicron", 0x039F}, 
     127    {"Pi", 0x03A0}, 
     128    {"Rho", 0x03A1}, 
     129    {"Sigma", 0x03A3}, 
     130    {"Tau", 0x03A4}, 
     131    {"Upsilon", 0x03A5}, 
     132    {"Phi", 0x03A6}, 
     133    {"Chi", 0x03A7}, 
     134    {"Psi", 0x03A8}, 
     135    {"Omega", 0x03A9}, 
     136    {"alpha", 0x03B1}, 
     137    {"beta", 0x03B2}, 
     138    {"gamma", 0x03B3}, 
     139    {"delta", 0x03B4}, 
     140    {"epsilon", 0x03B5}, 
     141    {"zeta", 0x03B6}, 
     142    {"eta", 0x03B7}, 
     143    {"theta", 0x03B8}, 
     144    {"iota", 0x03B9}, 
     145    {"kappa", 0x03BA}, 
     146    {"lambda", 0x03BB}, 
     147    {"mu", 0x03BC}, 
     148    {"nu", 0x03BD}, 
     149    {"xi", 0x03BE}, 
     150    {"omicron", 0x03BF}, 
     151    {"pi", 0x03C0}, 
     152    {"rho", 0x03C1}, 
     153    {"sigmaf", 0x03C2}, 
     154    {"sigma", 0x03C3}, 
     155    {"tau", 0x03C4}, 
     156    {"upsilon", 0x03C5}, 
     157    {"phi", 0x03C6}, 
     158    {"chi", 0x03C7}, 
     159    {"psi", 0x03C8}, 
     160    {"omega", 0x03C9}, 
     161    {"thetasym", 0x03D1}, 
     162    {"upsih", 0x03D2}, 
     163    {"piv", 0x03D6}, 
     164    {"ensp", 0x2002}, 
     165    {"emsp", 0x2003}, 
     166    {"thinsp", 0x2009}, 
     167    {"zwnj", 0x200C}, 
     168    {"zwj", 0x200D}, 
     169    {"lrm", 0x200E}, 
     170    {"rlm", 0x200F}, 
     171    {"ndash", 0x2013}, 
     172    {"mdash", 0x2014}, 
     173    {"lsquo", 0x2018}, 
     174    {"rsquo", 0x2019}, 
     175    {"sbquo", 0x201A}, 
     176    {"ldquo", 0x201C}, 
     177    {"rdquo", 0x201D}, 
     178    {"bdquo", 0x201E}, 
     179    {"dagger", 0x2020}, 
     180    {"Dagger", 0x2021}, 
     181    {"bull", 0x2022}, 
     182    {"hellip", 0x2026}, 
     183    {"permil", 0x2030}, 
     184    {"prime", 0x2032}, 
     185    {"Prime", 0x2033}, 
     186    {"lsaquo", 0x2039}, 
     187    {"rsaquo", 0x203A}, 
     188    {"oline", 0x203E}, 
     189    {"frasl", 0x2044}, 
     190    {"euro", 0x20AC}, 
     191    {"image", 0x2111}, 
     192    {"weierp", 0x2118}, 
     193    {"real", 0x211C}, 
     194    {"trade", 0x2122}, 
     195    {"alefsym", 0x2135}, 
     196    {"larr", 0x2190}, 
     197    {"uarr", 0x2191}, 
     198    {"rarr", 0x2192}, 
     199    {"darr", 0x2193}, 
     200    {"harr", 0x2194}, 
     201    {"crarr", 0x21B5}, 
     202    {"lArr", 0x21D0}, 
     203    {"uArr", 0x21D1}, 
     204    {"rArr", 0x21D2}, 
     205    {"dArr", 0x21D3}, 
     206    {"hArr", 0x21D4}, 
     207    {"forall", 0x2200}, 
     208    {"part", 0x2202}, 
     209    {"exist", 0x2203}, 
     210    {"empty", 0x2205}, 
     211    {"nabla", 0x2207}, 
     212    {"isin", 0x2208}, 
     213    {"notin", 0x2209}, 
     214    {"ni", 0x220B}, 
     215    {"prod", 0x220F}, 
     216    {"sum", 0x2211}, 
     217    {"minus", 0x2212}, 
     218    {"lowast", 0x2217}, 
     219    {"radic", 0x221A}, 
     220    {"prop", 0x221D}, 
     221    {"infin", 0x221E}, 
     222    {"ang", 0x2220}, 
     223    {"and", 0x2227}, 
     224    {"or", 0x2228}, 
     225    {"cap", 0x2229}, 
     226    {"cup", 0x222A}, 
     227    {"int", 0x222B}, 
     228    {"there4", 0x2234}, 
     229    {"sim", 0x223C}, 
     230    {"cong", 0x2245}, 
     231    {"asymp", 0x2248}, 
     232    {"ne", 0x2260}, 
     233    {"equiv", 0x2261}, 
     234    {"le", 0x2264}, 
     235    {"ge", 0x2265}, 
     236    {"sub", 0x2282}, 
     237    {"sup", 0x2283}, 
     238    {"nsub", 0x2284}, 
     239    {"sube", 0x2286}, 
     240    {"supe", 0x2287}, 
     241    {"oplus", 0x2295}, 
     242    {"otimes", 0x2297}, 
     243    {"perp", 0x22A5}, 
     244    {"sdot", 0x22C5}, 
     245    {"vellip", 0x22EE}, 
     246    {"lceil", 0x2308}, 
     247    {"rceil", 0x2309}, 
     248    {"lfloor", 0x230A}, 
     249    {"rfloor", 0x230B}, 
     250    {"lang", 0x2329}, 
     251    {"rang", 0x232A}, 
     252    {"loz", 0x25CA}, 
     253    {"spades", 0x2660}, 
     254    {"clubs", 0x2663}, 
     255    {"hearts", 0x2665}, 
     256    {"diams", 0x2666}, 
     257    {NULL, 0} 
     258}; 
  • src/keybind-defaults.c

    diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c
    index 11d636e..069c5ef 100644
    a b static const global_keymap_ini_t default_editor_keymap[] = { 
    397397    {"MarkColumnPageUp", "alt-pgup"}, 
    398398    {"MarkColumnPageDown", "alt-pgdn"}, 
    399399    {"InsertLiteral", "ctrl-q"}, 
     400    {"InsertEstring", "ctrl-w"}, 
    400401    {"Complete", "alt-tab"}, 
    401402    {"MatchBracket", "alt-b"}, 
    402403    {"ParagraphFormat", "alt-p"},