1
/* LIBGIMP - The GIMP Library
2
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
5
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
27
#include <glib-object.h>
29
#include "gimpbasetypes.h"
30
#include "gimputils.h"
32
#include "libgimp/libgimp-intl.h"
37
* @str: an UTF-8 encoded string (or %NULL)
38
* @max_chars: the maximum number of characters before the string get
41
* Creates a (possibly trimmed) copy of @str. The string is cut if it
42
* exceeds @max_chars characters or on the first newline. The fact
43
* that the string was trimmed is indicated by appending an ellipsis.
45
* Returns: A (possibly trimmed) copy of @str which should be freed
46
* using g_free() when it is not needed any longer.
49
gimp_utf8_strtrim (const gchar *str,
52
/* FIXME: should we make this translatable? */
53
static const gchar *ellipsis = "...";
54
static const gint e_len = 3;
59
const gchar *newline = NULL;
63
for (p = str; *p; p = g_utf8_next_char (p))
65
if (++chars > max_chars)
68
unichar = g_utf8_get_char (p);
70
switch (g_unichar_break_type (unichar))
72
case G_UNICODE_BREAK_MANDATORY:
73
case G_UNICODE_BREAK_LINE_FEED:
86
gchar *trimmed = g_new (gchar, len + e_len + 2);
88
memcpy (trimmed, str, len);
92
g_strlcpy (trimmed + len, ellipsis, e_len + 1);
97
return g_strdup (str);
105
* @str: The string to be converted to UTF-8.
106
* @len: The length of the string, or -1 if the string
108
* @warning_format: The message format for the warning message if conversion
109
* to UTF-8 fails. See the <function>printf()</function>
111
* @Varargs: The parameters to insert into the format string.
113
* This function takes any string (UTF-8 or not) and always returns a valid
116
* If @str is valid UTF-8, a copy of the string is returned.
118
* If UTF-8 validation fails, g_locale_to_utf8() is tried and if it
119
* succeeds the resulting string is returned.
121
* Otherwise, the portion of @str that is UTF-8, concatenated
122
* with "(invalid UTF-8 string)" is returned. If not even the start
123
* of @str is valid UTF-8, only "(invalid UTF-8 string)" is returned.
125
* Return value: The UTF-8 string as described above.
128
gimp_any_to_utf8 (const gchar *str,
130
const gchar *warning_format,
133
const gchar *start_invalid;
136
g_return_val_if_fail (str != NULL, NULL);
138
if (g_utf8_validate (str, len, &start_invalid))
141
utf8 = g_strdup (str);
143
utf8 = g_strndup (str, len);
147
utf8 = g_locale_to_utf8 (str, len, NULL, NULL, NULL);
154
va_list warning_args;
156
va_start (warning_args, warning_format);
158
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE,
159
warning_format, warning_args);
161
va_end (warning_args);
164
if (start_invalid > str)
168
tmp = g_strndup (str, start_invalid - str);
169
utf8 = g_strconcat (tmp, _("(invalid UTF-8 string)"), NULL);
174
utf8 = g_strdup (_("(invalid UTF-8 string)"));
182
* gimp_filename_to_utf8:
183
* @filename: The filename to be converted to UTF-8.
185
* Convert a filename in the filesystem's encoding to UTF-8
186
* temporarily. The return value is a pointer to a string that is
187
* guaranteed to be valid only during the current iteration of the
188
* main loop or until the next call to gimp_filename_to_utf8().
190
* The only purpose of this function is to provide an easy way to pass
191
* a filename in the filesystem encoding to a function that expects an
192
* UTF-8 encoded filename.
194
* Return value: A temporarily valid UTF-8 representation of @filename.
195
* This string must not be changed or freed.
198
gimp_filename_to_utf8 (const gchar *filename)
200
/* Simpleminded implementation, but at least allocates just one copy
201
* of each translation. Could check if already UTF-8, and if so
202
* return filename as is. Could perhaps (re)use a suitably large
203
* cyclic buffer, but then would have to verify that all calls
204
* really need the return value just for a "short" time.
207
static GHashTable *ht = NULL;
208
gchar *filename_utf8;
214
ht = g_hash_table_new (g_str_hash, g_str_equal);
216
filename_utf8 = g_hash_table_lookup (ht, filename);
220
filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
221
g_hash_table_insert (ht, g_strdup (filename), filename_utf8);
224
return filename_utf8;
230
* @str: underline infested string (or %NULL)
232
* This function returns a copy of @str stripped of underline
233
* characters. This comes in handy when needing to strip mnemonics
234
* from menu paths etc.
236
* In some languages, mnemonics are handled by adding the mnemonic
237
* character in brackets (like "File (_F)"). This function recognizes
238
* this construct and removes the whole bracket construction to get
239
* rid of the mnemonic (see bug #157561).
241
* Return value: A (possibly stripped) copy of @str which should be
242
* freed using g_free() when it is not needed any longer.
245
gimp_strip_uline (const gchar *str)
249
gboolean past_bracket = FALSE;
254
p = escaped = g_strdup (str);
260
/* "__" means a literal "_" in the menu path */
267
/* find the "(_X)" construct and remove it entirely */
268
if (past_bracket && str[1] && *(g_utf8_next_char (str + 1)) == ')')
270
str = g_utf8_next_char (str + 1) + 1;
280
past_bracket = (*str == '(');
293
* @str: Underline infested string (or %NULL)
295
* This function returns a copy of @str with all underline converted
296
* to two adjacent underlines. This comes in handy when needing to display
297
* strings with underlines (like filenames) in a place that would convert
300
* Return value: A (possibly escaped) copy of @str which should be
301
* freed using g_free() when it is not needed any longer.
306
gimp_escape_uline (const gchar *str)
315
for (p = (gchar *) str; *p; p++)
319
p = escaped = g_malloc (strlen (str) + n_ulines + 1);
335
* gimp_enum_get_desc:
336
* @enum_class: a #GEnumClass
337
* @value: a value from @enum_class
339
* Retrieves #GimpEnumDesc associated with the given value, or %NULL.
341
* Return value: the value's #GimpEnumDesc.
346
gimp_enum_get_desc (GEnumClass *enum_class,
349
const GimpEnumDesc *value_desc;
351
g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
353
value_desc = gimp_enum_get_value_descriptions (G_TYPE_FROM_CLASS (enum_class));
357
while (value_desc->value_desc)
359
if (value_desc->value == value)
360
return (GimpEnumDesc *) value_desc;
370
* gimp_enum_get_value:
371
* @enum_type: the #GType of a registered enum
372
* @value: an integer value
373
* @value_name: return location for the value's name (or %NULL)
374
* @value_nick: return location for the value's nick (or %NULL)
375
* @value_desc: return location for the value's translated desc (or %NULL)
376
* @value_help: return location for the value's translated help (or %NULL)
378
* Checks if @value is valid for the enum registered as @enum_type.
379
* If the value exists in that enum, its name, nick and its translated
380
* desc and help are returned (if @value_name, @value_nick, @value_desc
381
* and @value_help are not %NULL).
383
* Return value: %TRUE if @value is valid for the @enum_type,
389
gimp_enum_get_value (GType enum_type,
391
const gchar **value_name,
392
const gchar **value_nick,
393
const gchar **value_desc,
394
const gchar **value_help)
396
GEnumClass *enum_class;
397
GEnumValue *enum_value;
398
gboolean success = FALSE;
400
g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), FALSE);
402
enum_class = g_type_class_ref (enum_type);
403
enum_value = g_enum_get_value (enum_class, value);
408
*value_name = enum_value->value_name;
411
*value_nick = enum_value->value_nick;
413
if (value_desc || value_help)
415
GimpEnumDesc *enum_desc;
417
enum_desc = gimp_enum_get_desc (enum_class, value);
420
*value_desc = ((enum_desc && enum_desc->value_desc) ?
421
dgettext (gimp_type_get_translation_domain (enum_type),
422
enum_desc->value_desc) :
426
*value_help = ((enum_desc && enum_desc->value_desc) ?
427
dgettext (gimp_type_get_translation_domain (enum_type),
428
enum_desc->value_help) :
435
g_type_class_unref (enum_class);
441
* gimp_enum_value_get_desc:
442
* @enum_class: a #GEnumClass
443
* @enum_value: a #GEnumValue from @enum_class
445
* Retrieves the translated desc for a given @enum_value.
447
* Return value: the translated desc of the enum value
452
gimp_enum_value_get_desc (GEnumClass *enum_class,
453
GEnumValue *enum_value)
455
GType type = G_TYPE_FROM_CLASS (enum_class);
456
GimpEnumDesc *enum_desc;
458
enum_desc = gimp_enum_get_desc (enum_class, enum_value->value);
460
if (enum_desc && enum_desc->value_desc)
461
return dgettext (gimp_type_get_translation_domain (type),
462
enum_desc->value_desc);
464
return enum_value->value_name;
468
* gimp_enum_value_get_help:
469
* @enum_class: a #GEnumClass
470
* @enum_value: a #GEnumValue from @enum_class
472
* Retrieves the translated help for a given @enum_value.
474
* Return value: the translated help of the enum value
479
gimp_enum_value_get_help (GEnumClass *enum_class,
480
GEnumValue *enum_value)
482
GType type = G_TYPE_FROM_CLASS (enum_class);
483
GimpEnumDesc *enum_desc;
485
enum_desc = gimp_enum_get_desc (enum_class, enum_value->value);
487
if (enum_desc && enum_desc->value_help)
488
return dgettext (gimp_type_get_translation_domain (type),
489
enum_desc->value_help);
495
* gimp_flags_get_first_desc:
496
* @flags_class: a #GFlagsClass
497
* @value: a value from @flags_class
499
* Retrieves the first #GimpFlagsDesc that matches the given value, or %NULL.
501
* Return value: the value's #GimpFlagsDesc.
506
gimp_flags_get_first_desc (GFlagsClass *flags_class,
509
const GimpFlagsDesc *value_desc;
511
g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
513
value_desc = gimp_flags_get_value_descriptions (G_TYPE_FROM_CLASS (flags_class));
517
while (value_desc->value_desc)
519
if ((value_desc->value & value) == value_desc->value)
520
return (GimpFlagsDesc *) value_desc;
530
* gimp_flags_get_first_value:
531
* @flags_type: the #GType of registered flags
532
* @value: an integer value
533
* @value_name: return location for the value's name (or %NULL)
534
* @value_nick: return location for the value's nick (or %NULL)
535
* @value_desc: return location for the value's translated desc (or %NULL)
536
* @value_help: return location for the value's translated help (or %NULL)
538
* Checks if @value is valid for the flags registered as @flags_type.
539
* If the value exists in that flags, its name, nick and its translated
540
* desc and help are returned (if @value_name, @value_nick, @value_desc
541
* and @value_help are not %NULL).
543
* Return value: %TRUE if @value is valid for the @flags_type,
549
gimp_flags_get_first_value (GType flags_type,
551
const gchar **value_name,
552
const gchar **value_nick,
553
const gchar **value_desc,
554
const gchar **value_help)
556
GFlagsClass *flags_class;
557
GFlagsValue *flags_value;
559
g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), FALSE);
561
flags_class = g_type_class_peek (flags_type);
562
flags_value = g_flags_get_first_value (flags_class, value);
567
*value_name = flags_value->value_name;
570
*value_nick = flags_value->value_nick;
572
if (value_desc || value_help)
574
GimpFlagsDesc *flags_desc;
576
flags_desc = gimp_flags_get_first_desc (flags_class, value);
579
*value_desc = ((flags_desc && flags_desc->value_desc) ?
580
dgettext (gimp_type_get_translation_domain (flags_type),
581
flags_desc->value_desc) :
585
*value_help = ((flags_desc && flags_desc->value_desc) ?
586
dgettext (gimp_type_get_translation_domain (flags_type),
587
flags_desc->value_help) :
598
* gimp_flags_value_get_desc:
599
* @flags_class: a #GFlagsClass
600
* @flags_value: a #GFlagsValue from @flags_class
602
* Retrieves the translated desc for a given @flags_value.
604
* Return value: the translated desc of the flags value
609
gimp_flags_value_get_desc (GFlagsClass *flags_class,
610
GFlagsValue *flags_value)
612
GType type = G_TYPE_FROM_CLASS (flags_class);
613
GimpFlagsDesc *flags_desc;
615
flags_desc = gimp_flags_get_first_desc (flags_class, flags_value->value);
617
if (flags_desc->value_desc)
618
return dgettext (gimp_type_get_translation_domain (type),
619
flags_desc->value_desc);
621
return flags_value->value_name;
625
* gimp_flags_value_get_help:
626
* @flags_class: a #GFlagsClass
627
* @flags_value: a #GFlagsValue from @flags_class
629
* Retrieves the translated help for a given @flags_value.
631
* Return value: the translated help of the flags value
636
gimp_flags_value_get_help (GFlagsClass *flags_class,
637
GFlagsValue *flags_value)
639
GType type = G_TYPE_FROM_CLASS (flags_class);
640
GimpFlagsDesc *flags_desc;
642
flags_desc = gimp_flags_get_first_desc (flags_class, flags_value->value);
644
if (flags_desc->value_help)
645
return dgettext (gimp_type_get_translation_domain (type),
646
flags_desc->value_help);