~jcowgill/ubuntu/trusty/easytag/bug-1295882

« back to all changes in this revision

Viewing changes to src/charset.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2006-04-15 15:47:47 UTC
  • mfrom: (1.2.2 upstream) (3.1.1 dapper)
  • Revision ID: james.westby@ubuntu.com-20060415154747-vr4eqoxwcrgs2ps1
* New upstream version:
  - New logo and icons,
  - Added ability to display all albums of an artist in the 'Artist / Album'
    view,
  - Added detection of the bugged version of id3lib when writting ID3 tag to 
    Unicode to inform the user (a patch for id3lib is supplied in package
    source),
  - For Ogg files, the field DESCRIPTION is also used for the comment,
  - Fixed stack corruption bugs in Fill Tag scanner,
  - Fixed loading disk number for FLAC tag,
  - Fixed error that displays MP3 files in red when no tag is present,
  - Fixed a crash in the CDDB window when getting tracks of a album,
  - Fixed playlist name bug when creating it in the parent directory,
  - Fixed manual CDDB search when using Squid,
  - Little fix for FLAC tags,
  - Fixed various bugs,
  - Russian translation updated,
  - Greek translation updated,
  - Spanish translation updated,
  - Japanese translation updated,
  - Czech translation updated,
  - Brazilian Portuguese translation updated
  - Danish translation updated,
  - Italian translation updated,
  - Hungarian translation updated,
  - German translation updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "charset.h"
35
35
#include "setting.h"
36
36
 
 
37
#ifdef WIN32
 
38
    #include "win32dep.h"
 
39
#endif
37
40
 
38
41
 
39
42
/****************
80
83
    {N_("Turkish (Windows-1254)"),            "windows-1254"  },
81
84
    {N_("Unicode (UTF-7)"),                   "UTF-7"         },
82
85
    {N_("Unicode (UTF-8)"),                   "UTF-8"         },
 
86
    
83
87
    {N_("Unicode (UTF-16BE)"),                "UTF-16BE"      },
84
88
    {N_("Unicode (UTF-16LE)"),                "UTF-16LE"      },
85
 
    {N_("Unicode (UTF-32BE)"),                "UTF-32BE"      },
86
 
    {N_("Unicode (UTF-32LE)"),                "UTF-32LE"      },
 
89
    //{N_("Unicode (UTF-32BE)"),                "UTF-32BE"      },
 
90
    //{N_("Unicode (UTF-32LE)"),                "UTF-32LE"      },
 
91
    
87
92
    {N_("Vietnamese (VISCII)"),               "VISCII"        },
88
93
    {N_("Vietnamese (Windows-1258)"),         "windows-1258"  },
89
94
    {N_("Visual Hebrew (ISO-8859-8)"),        "ISO-8859-8"    },
132
137
*/
133
138
};
134
139
 
 
140
static GHashTable *encodings;
135
141
 
136
142
 
137
143
 
140
146
 *************/
141
147
 
142
148
 
143
 
gchar *convert_string (const gchar *string, const gchar *from, const gchar *to)
 
149
/* stolen from gnome-desktop-item.c */
 
150
static gboolean
 
151
check_locale (const char *locale)
 
152
{
 
153
    GIConv cd = g_iconv_open ("UTF-8", locale);
 
154
    if ((GIConv)-1 == cd)
 
155
        return FALSE;
 
156
    g_iconv_close (cd);
 
157
    return TRUE;
 
158
}
 
159
 
 
160
/* stolen from gnome-desktop-item.c */
 
161
static void
 
162
insert_locales (GHashTable *encodings, char *enc, ...)
 
163
{
 
164
    va_list args;
 
165
    char *s;
 
166
 
 
167
    va_start (args, enc);
 
168
    for (;;) {
 
169
        s = va_arg (args, char *);
 
170
        if (s == NULL)
 
171
            break;
 
172
        g_hash_table_insert (encodings, s, enc);
 
173
    }
 
174
    va_end (args);
 
175
}
 
176
 
 
177
/* stolen from gnome-desktop-item.c */
 
178
/* make a standard conversion table from the desktop standard spec */
 
179
void
 
180
Charset_Insert_Locales_Init (void)
 
181
{
 
182
    encodings = g_hash_table_new (g_str_hash, g_str_equal);
 
183
 
 
184
    /* "C" is plain ascii */
 
185
    insert_locales (encodings, "ASCII", "C", NULL);
 
186
 
 
187
    insert_locales (encodings, "ARMSCII-8", "by", NULL);
 
188
    insert_locales (encodings, "BIG5", "zh_TW", NULL);
 
189
    insert_locales (encodings, "CP1251", "be", "bg", NULL);
 
190
    if (check_locale ("EUC-CN")) {
 
191
        insert_locales (encodings, "EUC-CN", "zh_CN", NULL);
 
192
    } else {
 
193
        insert_locales (encodings, "GB2312", "zh_CN", NULL);
 
194
    }
 
195
    insert_locales (encodings, "EUC-JP", "ja", NULL);
 
196
    insert_locales (encodings, "EUC-KR", "ko", NULL);
 
197
    /*insert_locales (encodings, "GEORGIAN-ACADEMY", NULL);*/
 
198
    insert_locales (encodings, "GEORGIAN-PS", "ka", NULL);
 
199
    insert_locales (encodings, "ISO-8859-1", "br", "ca", "da", "de", "en", "es", "eu", "fi", "fr", "gl", "it", "nl", "wa", "no", "pt", "pt", "sv", NULL);
 
200
    insert_locales (encodings, "ISO-8859-2", "cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", NULL);
 
201
    insert_locales (encodings, "ISO-8859-3", "eo", NULL);
 
202
    insert_locales (encodings, "ISO-8859-5", "mk", "sp", NULL);
 
203
    insert_locales (encodings, "ISO-8859-7", "el", NULL);
 
204
    insert_locales (encodings, "ISO-8859-9", "tr", NULL);
 
205
    insert_locales (encodings, "ISO-8859-13", "lt", "lv", "mi", NULL);
 
206
    insert_locales (encodings, "ISO-8859-14", "ga", "cy", NULL);
 
207
    insert_locales (encodings, "ISO-8859-15", "et", NULL);
 
208
    insert_locales (encodings, "KOI8-R", "ru", NULL);
 
209
    insert_locales (encodings, "KOI8-U", "uk", NULL);
 
210
    if (check_locale ("TCVN-5712")) {
 
211
        insert_locales (encodings, "TCVN-5712", "vi", NULL);
 
212
    } else {
 
213
        insert_locales (encodings, "TCVN", "vi", NULL);
 
214
    }
 
215
    insert_locales (encodings, "TIS-620", "th", NULL);
 
216
    /*insert_locales (encodings, "VISCII", NULL);*/
 
217
}
 
218
 
 
219
void
 
220
Charset_Insert_Locales_Destroy (void)
 
221
{
 
222
    g_hash_table_destroy (encodings);
 
223
}
 
224
 
 
225
/* stolen from gnome-desktop-item.c */
 
226
const char *
 
227
get_encoding_from_locale (const char *locale)
 
228
{
 
229
    char lang[3];
 
230
    const char *encoding;
 
231
 
 
232
    if (locale == NULL)
 
233
        return NULL;
 
234
 
 
235
    /* if locale includes encoding, use it *//*
 
236
    encoding = strchr (locale, '.');
 
237
    if (encoding != NULL) {
 
238
        return encoding+1;
 
239
    }*/
 
240
    /* if locale includes encoding (that isn't UTF-8), use it */
 
241
    encoding = strchr (locale, '.');
 
242
    if (encoding != NULL && strncmp (encoding, ".UTF-8", 6)) {
 
243
        return encoding+1;
 
244
    }
 
245
 
 
246
    /* first try the entire locale (at this point ll_CC) */
 
247
    encoding = g_hash_table_lookup (encodings, locale);
 
248
    if (encoding != NULL)
 
249
        return encoding;
 
250
 
 
251
    /* Try just the language */
 
252
    strncpy (lang, locale, 2);
 
253
    lang[2] = '\0';
 
254
    return g_hash_table_lookup (encodings, lang);
 
255
}
 
256
 
 
257
 
 
258
/*
 
259
 * Return the locale from LANG if exists, else from LC_ALL
 
260
 *
 
261
 * http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html#tag_08_02
 
262
 * 
 
263
 * LANG
 
264
 *     This variable shall determine the locale category for native language,
 
265
 *     local customs, and coded character set in the absence of the LC_ALL and
 
266
 *     other LC_* ( LC_COLLATE , LC_CTYPE , LC_MESSAGES , LC_MONETARY , LC_NUMERIC ,
 
267
 *     LC_TIME ) environment variables. This can be used by applications to 
 
268
 *     determine the language to use for error messages and instructions, collating
 
269
 *     sequences, date formats, and so on.
 
270
 * LC_ALL
 
271
 *     This variable shall determine the values for all locale categories. The
 
272
 *     value of the LC_ALL environment variable has precedence over any of the
 
273
 *     other environment variables starting with LC_ ( LC_COLLATE , LC_CTYPE ,
 
274
 *     LC_MESSAGES , LC_MONETARY , LC_NUMERIC , LC_TIME ) and the LANG environment
 
275
 *     variable.
 
276
 * LC_COLLATE
 
277
 *     This variable shall determine the locale category for character collation.
 
278
 *     It determines collation information for regular expressions and sorting,
 
279
 *     including equivalence classes and multi-character collating elements, in
 
280
 *     various utilities and the strcoll() and strxfrm() functions. Additional
 
281
 *     semantics of this variable, if any, are implementation-defined.
 
282
 * LC_CTYPE
 
283
 *     This variable shall determine the locale category for character handling
 
284
 *     functions, such as tolower(), toupper(), and isalpha(). This environment
 
285
 *     variable determines the interpretation of sequences of bytes of text data
 
286
 *     as characters (for example, single as opposed to multi-byte characters),
 
287
 *     the classification of characters (for example, alpha, digit, graph), and
 
288
 *     the behavior of character classes. Additional semantics of this variable,
 
289
 *    if any, are implementation-defined.
 
290
 * LC_MESSAGES
 
291
 *     This variable shall determine the locale category for processing affirmative
 
292
 *     and negative responses and the language and cultural conventions in which
 
293
 *     messages should be written. [XSI] [Option Start]  It also affects the behavior
 
294
 *     of the catopen() function in determining the message catalog. [Option End]
 
295
 *     Additional semantics of this variable, if any, are implementation-defined.
 
296
 *     The language and cultural conventions of diagnostic and informative messages
 
297
 *     whose format is unspecified by IEEE Std 1003.1-2001 should be affected by
 
298
 *     the setting of LC_MESSAGES .
 
299
 * LC_MONETARY
 
300
 *     This variable shall determine the locale category for monetary-related
 
301
 *     numeric formatting information. Additional semantics of this variable, if
 
302
 *     any, are implementation-defined.
 
303
 * LC_NUMERIC
 
304
 *     This variable shall determine the locale category for numeric formatting
 
305
 *     (for example, thousands separator and radix character) information in
 
306
 *     various utilities as well as the formatted I/O operations in printf() and
 
307
 *     scanf() and the string conversion functions in strtod(). Additional semantics
 
308
 *     of this variable, if any, are implementation-defined.
 
309
 * LC_TIME
 
310
 *     This variable shall determine the locale category for date and time formatting
 
311
 *     information. It affects the behavior of the time functions in strftime().
 
312
 *     Additional semantics of this variable, if any, are implementation-defined.
 
313
 * 
 
314
 * 
 
315
 * The values of locale categories shall be determined by a precedence order; the
 
316
 * first condition met below determines the value:
 
317
 * 
 
318
 *    1. If the LC_ALL environment variable is defined and is not null, the value
 
319
 *       of LC_ALL shall be used.
 
320
 *    2. If the LC_* environment variable ( LC_COLLATE , LC_CTYPE , LC_MESSAGES ,
 
321
 *       LC_MONETARY , LC_NUMERIC , LC_TIME ) is defined and is not null, the value
 
322
 *       of the environment variable shall be used to initialize the category that
 
323
 *       corresponds to the environment variable.
 
324
 *    3. If the LANG environment variable is defined and is not null, the value of
 
325
 *       the LANG environment variable shall be used.
 
326
 *    4. If the LANG environment variable is not set or is set to the empty string,
 
327
 *       the implementation-defined default locale shall be used.
 
328
 * 
 
329
 */
 
330
const gchar *get_locale (void)
 
331
{
 
332
    if (g_getenv("LC_ALL"))
 
333
        return g_getenv("LC_ALL");
 
334
    
 
335
    else if (g_getenv("LC_CTYPE"))
 
336
        return g_getenv("LC_CTYPE");
 
337
    
 
338
    else if (g_getenv("LANG"))
 
339
        return g_getenv("LANG");
 
340
    
 
341
    else
 
342
        return NULL;
 
343
}
 
344
 
 
345
 
 
346
 
 
347
 
 
348
/*
 
349
 * convert_string : (don't use with UTF-16 strings)
 
350
 *  - display_error : if TRUE, may return an escaped string and display an error 
 
351
 *                    message (if conversion fails).
 
352
 */
 
353
gchar *convert_string (const gchar *string, const gchar *from_codeset,
 
354
                       const gchar *to_codeset, const gboolean display_error)
 
355
{
 
356
    return convert_string_1(string, -1, from_codeset, to_codeset, display_error);
 
357
}
 
358
/* Length must be passed, as the string might be Unicode, in which case we can't
 
359
 * count zeroes (see strlen call below). */
 
360
gchar *convert_string_1 (const gchar *string, gssize length, const gchar *from_codeset,
 
361
                         const gchar *to_codeset, const gboolean display_error)
144
362
{
145
363
    gchar *output;
146
364
    GError *error = NULL;
 
365
    gsize bytes_written;
147
366
 
148
367
    if (!string)
149
368
        return NULL;
150
 
 
151
 
    output = g_convert(string, -1, to, from, NULL, NULL, &error);
152
 
 
153
 
    //g_message("converting %s from %s to %s", string, from, to);
 
369
    
 
370
    output = g_convert(string, length, to_codeset, from_codeset, NULL, &bytes_written, &error);
 
371
    //output = g_convert_with_fallback(string, length, to_codeset, from_codeset, "?", NULL, &bytes_written, &error);
154
372
 
155
373
    if (output == NULL)
156
374
    {
157
375
        gchar *escaped_str = g_strescape(string, NULL);
158
 
        g_warning("convert_string(): Failed conversion from charset '%s' to '%s'. "
159
 
                  "String '%s'. Errcode %d (%s).\n",
160
 
                  from, to, escaped_str, error->code, error->message);
 
376
        if (display_error)
 
377
        {
 
378
            g_warning("convert_string(): Failed conversion from charset '%s' to '%s'. "
 
379
                      "String '%s'. Errcode %d (%s).\n",
 
380
                      from_codeset, to_codeset, escaped_str, error->code, error->message);
 
381
        }
161
382
        g_free(escaped_str);
162
383
        g_error_free(error);
163
 
        return g_strdup(string);
 
384
        // Return the input string without converting it. If the string is 
 
385
        // displayed in the UI, it must be in UTF-8!
 
386
        if ( (g_ascii_strcasecmp(to_codeset, "UTF-8"))
 
387
        ||   (g_utf8_validate(string, -1, NULL)) )
 
388
        {
 
389
            return g_strdup(string);
 
390
        }
 
391
    }else
 
392
    {
 
393
        // Patch from Alexey Illarionov:
 
394
        //    g_convert returns null-terminated string only with one \0 at the
 
395
        // end. It can cause some garbage at the end of a string for UTF-16. 
 
396
        // The second \0 should be set manually.
 
397
        output = g_realloc(output, bytes_written + 2);
 
398
        if (output != NULL)
 
399
            output[bytes_written] = output[bytes_written + 1] = 0;
164
400
    }
 
401
    
 
402
    //g_print("from %s => len: %d, string: '%s'\n     (%x %x %x %x %x %x %x %x)\n",from_codeset,length,string,string[0],string[1],string[2],string[3],string[4],string[5],string[6],string[7]);
 
403
    //g_print("to   %s => len: %d, output: '%s'\n     (%x %x %x %x %x %x %x %x)\n\n",to_codeset,bytes_written+2,output,output[0],output[1],output[2],output[3],output[4],output[5],output[6],output[7]);
165
404
 
166
405
    return output;
167
406
}
191
430
        g_free(escaped_str);
192
431
 
193
432
        if (g_utf8_validate(string, -1, NULL))
194
 
            g_warning("convert_to_utf8(): String was valid UTF8.\n");
 
433
            g_warning("convert_to_utf8(): String was valid UTF-8.\n");
195
434
        else
196
 
            g_warning("convert_to_utf8(): String was INVALID UTF8.\n");
 
435
            g_warning("convert_to_utf8(): String was INVALID UTF-8.\n");
197
436
 
198
437
        g_error_free(error);
199
438
        return g_strdup(string);
223
462
        g_free(escaped_str);
224
463
 
225
464
        if (g_utf8_validate(string, -1, NULL))
226
 
            g_warning("convert_from_utf8(): String was valid UTF8.\n");
 
465
            g_warning("convert_from_utf8(): String was valid UTF-8.\n");
227
466
        else
228
 
            g_warning("convert_from_utf8(): String was INVALID UTF8.\n");
 
467
            g_warning("convert_from_utf8(): String was INVALID UTF-8.\n");
229
468
 
230
469
        g_error_free(error);
231
470
        return g_strdup(string);
237
476
 
238
477
 
239
478
/*
240
 
 * Conversion with ISO-8859-1 for ID3v2.3 tags (current_charset <===> ISO-8859-1)
241
 
 */
242
 
char *convert_to_iso88591 (const char *string)
243
 
{
244
 
    const gchar *charset;
245
 
    g_get_charset(&charset);
246
 
 
247
 
    /* No conversion needed */
248
 
    if (strcmp(charset, "ANSI_X3.4-1968") == 0)
249
 
        return g_strdup(string);
250
 
 
251
 
    return convert_string(string, charset, "ISO-8859-1");
252
 
}
253
 
 
254
 
char *convert_from_iso88591 (const char *string)
255
 
{
256
 
    const gchar *charset;
257
 
    g_get_charset(&charset);
258
 
 
259
 
    /* No conversion needed */
260
 
    if (strcmp(charset, "ANSI_X3.4-1968") == 0)
261
 
        return g_strdup(string);
262
 
 
263
 
    return convert_string(string, "ISO-8859-1", charset);
264
 
}
265
 
 
266
 
 
267
 
 
268
 
/*
269
 
 * Conversion with "this_charset" for ID3v2.3 tags (current_charset <===> this_charset)
270
 
 */
271
 
// Convert from the locale charset to 'this_charset'
272
 
char *convert_to_this_charset (const char *string, char *this_charset)
273
 
{
274
 
    const gchar *charset;
275
 
    g_get_charset(&charset);
276
 
 
277
 
    return convert_string(string, charset, this_charset);
278
 
}
279
 
 
280
 
// Convert from 'this_charset' to the locale charset
281
 
char *convert_from_this_charset (const char *string, char *this_charset)
282
 
{
283
 
    const gchar *charset;
284
 
    g_get_charset(&charset);
285
 
 
286
 
    return convert_string(string, this_charset, charset);
287
 
}
288
 
 
289
 
 
290
 
 
291
 
/*
292
 
 * Conversion functions using default parameters set by user in the preference window. (USER_CHARACTER_SET <===> FILE_CHARACTER_SET)
293
 
 */
294
 
char *convert_from_user_to_file (const char *string)
295
 
{
296
 
    char *file_charset = FILE_CHARACTER_SET;
297
 
    char *user_charset = USER_CHARACTER_SET;
298
 
 
299
 
    return convert_string(string,user_charset,file_charset);
300
 
}
301
 
 
302
 
char *convert_from_file_to_user (const char *string)
303
 
{
304
 
    char *file_charset = FILE_CHARACTER_SET;
305
 
    char *user_charset = USER_CHARACTER_SET;
306
 
 
307
 
    return convert_string(string,file_charset,user_charset);
308
 
}
309
 
 
310
 
 
311
 
/*
312
 
 * Functions to translate filename to/from UTF-8
313
 
 * Based around the ideas under "File Name Encodings" at
314
 
 *    http://developer.gnome.org/doc/API/2.0/glib/glib-Character-Set-Conversion.html
 
479
 * Convert a string from the filename system encoding to UTF-8.
 
480
 *  - conversion OK : returns the UTF-8 string (new allocated)
 
481
 *  - conversion KO : tries others encodings else returns an 'escaped' string
315
482
 */
316
483
gchar *filename_to_display (const gchar *string)
317
484
{
318
 
    GError *error = NULL;
319
 
    gchar *temp = g_filename_to_utf8(string, -1, NULL, NULL, &error);
320
 
    if (!temp)
 
485
    gchar *ret = NULL;
 
486
    GError *error = NULL;
 
487
 
 
488
    if (!string)
 
489
        return NULL;
 
490
 
 
491
    if (g_utf8_validate(string, -1, NULL))
 
492
    {
 
493
        // String already in UTF-8
 
494
        ret = g_strdup(string);
 
495
    }else
 
496
    {
 
497
        const gchar *char_encoding;
 
498
 
 
499
        // Get encoding associated to the locale without using UTF-8 (ex , if LANG=fr_FR.UTF-8 it will return ISO-8859-1)
 
500
        char_encoding = get_encoding_from_locale(get_locale());
 
501
        if (char_encoding)
 
502
        {
 
503
            //g_print("> char_encoding: %s\n",char_encoding);
 
504
            error = NULL;
 
505
            ret = g_convert(string, -1, "UTF-8", char_encoding, NULL, NULL, &error);
 
506
        }
 
507
 
 
508
        if (!ret)
 
509
        {
 
510
            // Failing that, try ISO-8859-1
 
511
            error = NULL;
 
512
            ret = g_convert(string, -1, "UTF-8", "ISO-8859-1", NULL, NULL, &error);
 
513
        }
 
514
 
 
515
        if (!ret)
 
516
        {
 
517
            gchar *escaped_str = g_strescape(string, NULL);
 
518
            g_warning(_("The filename '%s' couldn't be converted into UTF-8 (%s).\n"),
 
519
                        escaped_str, error && error->message ? error->message : _("Invalid UTF-8"));
 
520
            g_clear_error(&error);
 
521
 
 
522
            ret = escaped_str;
 
523
        }
 
524
    }
 
525
 
 
526
#ifdef WIN32
 
527
    ET_Win32_Path_Remove_Trailing_Slash(ret);
 
528
    ET_Win32_Path_Replace_Slashes(ret);
 
529
#endif
 
530
 
 
531
    return ret;
 
532
}
 
533
 
 
534
/*
 
535
 * Convert a string from UTF-8 to the filename system encoding.
 
536
 *  - conversion OK : returns the string in filename system encoding (new allocated)
 
537
 *  - conversion KO : display error message + returns nothing!
 
538
 */
 
539
gchar *filename_from_display (const gchar *string)
 
540
{
 
541
    GError *error = NULL;
 
542
    gchar *ret = NULL;
 
543
    const gchar *char_encoding = NULL;
 
544
    //const gchar *filename_encoding = NULL;
 
545
 
 
546
    if (!string) return NULL;
 
547
    
 
548
    // Get system encoding from LANG if found (ex : fr_FR.UTF-8 => UTF-8)
 
549
    if (get_locale())
 
550
        char_encoding = strchr(get_locale(), '.');
 
551
    
 
552
    if (char_encoding)
 
553
        char_encoding = char_encoding+1; // Skip the '.'
 
554
    if (char_encoding)
 
555
    {
 
556
        error = NULL;
 
557
        
 
558
        if (FILENAME_CHARACTER_SET_OTHER)
 
559
        {
 
560
            ret = g_convert(string, -1, char_encoding, "UTF-8", NULL, NULL, &error);
 
561
            
 
562
        }else if (FILENAME_CHARACTER_SET_APPROXIMATE)
 
563
        {
 
564
            // iconv_open (3):
 
565
            // When the string "//TRANSLIT" is appended to tocode, transliteration
 
566
            // is activated. This means that when a character cannot be represented
 
567
            // in the target character set, it can be approximated through one or
 
568
            // several similarly looking characters.
 
569
            gchar *enc = g_strconcat(char_encoding, "//TRANSLIT", NULL);
 
570
            ret = g_convert(string, -1, enc, "UTF-8", NULL, NULL, &error);
 
571
            g_free(enc);
 
572
            
 
573
        }else if (FILENAME_CHARACTER_SET_DISCARD)
 
574
        {
 
575
            // iconv_open (3):
 
576
            // When the string "//IGNORE" is appended to tocode, characters that
 
577
            // cannot be represented in the target character set will be silently
 
578
            // discarded.
 
579
            gchar *enc = g_strconcat(char_encoding, "//IGNORE", NULL);
 
580
            ret = g_convert(string, -1, enc, "UTF-8", NULL, NULL, &error);
 
581
            g_free(enc);
 
582
        }
 
583
    }
 
584
    
 
585
    if (!ret)
 
586
    {
 
587
        // Get system encoding from locale in LANG if found (ex : fr_FR.UTF-8 => fr_FR => ISO-8859-1)
 
588
        char_encoding = get_encoding_from_locale(get_locale());
 
589
        if (char_encoding)
 
590
        {
 
591
            //g_print("> char_encoding: %s\n",char_encoding);
 
592
            error = NULL;
 
593
            ret = g_convert(string, -1, char_encoding, "UTF-8", NULL, NULL, &error);
 
594
        }
 
595
    }
 
596
        
 
597
    if (!ret)
 
598
    {
 
599
        // Failing that, try ISO-8859-1
 
600
        error = NULL;
 
601
        ret = g_convert(string, -1, "ISO-8859-1", "UTF-8", NULL, NULL, &error);
 
602
    }
 
603
 
 
604
    if (!ret)
 
605
    {
 
606
        if (g_utf8_validate(string, -1, NULL))
 
607
        {
 
608
            // String already in UTF-8
 
609
            ret = g_strdup(string);
 
610
        }
 
611
    }
 
612
    
 
613
    if (!ret)
321
614
    {
322
615
        // Conversion KO!
323
616
        gchar *escaped_str = g_strescape(string, NULL);
324
 
        g_warning(_("The filename '%s' couldn't be converted to UTF-8. "
325
 
                    "(Try setting the environment variable G_FILENAME_ENCODING): %s\n"),
326
 
                    escaped_str, error->message ? error->message : _("Invalid UTF-8"));
327
 
        //g_free(escaped_str);
 
617
        g_warning(_("The UTF-8 string '%s' couldn't be converted into filename encoding (%s)\n"),
 
618
                    escaped_str, error && error->message ? error->message : _("Invalid UTF-8"));
328
619
        g_clear_error(&error);
329
620
 
330
 
        //return g_strdup(string);
331
 
        return g_strdup(escaped_str); // Don't free escaped_str if used!
332
 
    }else
333
 
    {
334
 
        // Conversion OK
335
 
        return temp;
336
 
    }
337
 
}
338
 
 
339
 
gchar *filename_from_display (const gchar* string)
340
 
{
341
 
    gchar *temp = g_filename_from_utf8(string, -1, NULL, NULL, NULL);
342
 
    if (!temp)
343
 
    {
344
 
        // Conversion KO!
345
 
        gchar *escaped_str = g_strescape(string, NULL);
346
 
        g_print("WARNING: Could not convert string %s into filename encoding\n", escaped_str);
347
 
        g_free(escaped_str);
348
 
    }
349
 
 
350
 
    return temp; // We need to catch errors (e.g. temp=NULL) in the real code
 
621
        ret = escaped_str;
 
622
    }
 
623
 
 
624
#ifdef WIN32
 
625
    //ET_Win32_Path_Replace_Backslashes(ret);
 
626
#endif
 
627
 
 
628
    return ret; // We need to catch errors (e.g. temp=NULL) in the real code
351
629
}
352
630
 
353
631
 
398
676
 
399
677
/*
400
678
 * Test if the conversion is supported between two character sets ('from' and 'to)
 
679
 * (function called in the preferences window).
 
680
 * Note : for UTF-16 (2 byte for each character) we make a special test...
401
681
 */
402
 
 
403
682
gboolean test_conversion_charset (const gchar *from, const gchar *to)
404
683
{
405
684
    gchar *temp;
406
 
    GError *error = NULL;
407
 
 
 
685
    
408
686
    if (!from || !to)
409
687
        return FALSE;
410
688
    
411
689
    // Do a quick test conversion and examine error output
412
 
    temp = g_convert("a", -1, to, from, NULL, NULL, &error);
413
 
 
 
690
    if ( strcmp(from,"UTF-16BE") == 0 )
 
691
    {
 
692
        temp = convert_string_1("F\0O\0O\0\0\0", 6, from, to, FALSE);
 
693
    }else if ( strcmp(from,"UTF-16LE") == 0 )
 
694
    {
 
695
        temp = convert_string_1("\0F\0O\0O\0\0", 6, from, to, FALSE);
 
696
    }else
 
697
    {
 
698
        temp = convert_string("FOO", from, to, FALSE);
 
699
    }
 
700
    
414
701
    if (!temp)
415
702
    {
416
 
        // Error in conversion
 
703
        /*// Error in conversion
417
704
        if (error && error->code == G_CONVERT_ERROR_NO_CONVERSION)
418
705
        {
419
706
            g_print("Conversion error from '%s' to '%s' (G_CONVERT_ERROR_NO_CONVERSION)\n",from,to);
437
724
            g_print("Conversion error from '%s' to '%s' (unknown : %d)\n",from,to,error->code);
438
725
        }
439
726
        
440
 
        if (error) g_error_free(error);
 
727
        if (error)
 
728
            g_error_free(error);*/
441
729
        return FALSE;
442
730
    } else
443
731
    {
444
 
        // No error
445
 
        if (error) g_error_free(error);
 
732
        /*// No error
 
733
        if (error)
 
734
            g_error_free(error);*/
446
735
        g_free(temp);
447
736
        return TRUE;
448
737
    }