mirror of https://github.com/GNOME/gimp.git
app/config/Makefile.am app/config/config-types.h new files that hold a
2003-09-15 Sven Neumann <sven@gimp.org> * app/config/Makefile.am * app/config/config-types.h * app/config/gimpxmlparser.[ch]: new files that hold a simple XML parser based on GMarkupParser. It's not a full-featured XML parser; it only adds transparent handling of encodings to GMarkupParser and provides a convenient API to deal with files or IO channels. * app/vectors/gimpvectors-import.c: use the new GimpXmlParser. * app/vectors/gimpvectors-export.c: write encoding attribute. * app/tips-dialog.c * app/tips-parser.c: use the new GimpXmlParser. * app/vectors/Makefile.am: had to add one of those truly ugly hacks here in order to get the application linked.
This commit is contained in:
parent
b83e77dc48
commit
80bd6f1c2b
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2003-09-15 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/config/Makefile.am
|
||||
* app/config/config-types.h
|
||||
* app/config/gimpxmlparser.[ch]: new files that hold a simple XML
|
||||
parser based on GMarkupParser. It's not a full-featured XML parser;
|
||||
it only adds transparent handling of encodings to GMarkupParser
|
||||
and provides a convenient API to deal with files or IO channels.
|
||||
|
||||
* app/vectors/gimpvectors-import.c: use the new GimpXmlParser.
|
||||
|
||||
* app/vectors/gimpvectors-export.c: write encoding attribute.
|
||||
|
||||
* app/tips-dialog.c
|
||||
* app/tips-parser.c: use the new GimpXmlParser.
|
||||
|
||||
* app/vectors/Makefile.am: had to add one of those truly ugly
|
||||
hacks here in order to get the application linked.
|
||||
|
||||
2003-09-15 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/widgets/gimpitemtreeview.c (gimp_item_tree_view_constructor):
|
||||
|
|
|
@ -37,7 +37,9 @@ libappconfig_a_SOURCES = \
|
|||
gimprc.h \
|
||||
gimprc-blurbs.h \
|
||||
gimpscanner.c \
|
||||
gimpscanner.h
|
||||
gimpscanner.h \
|
||||
gimpxmlparser.c \
|
||||
gimpxmlparser.h
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DG_LOG_DOMAIN=\"Gimp-Config\" \
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct _GimpPluginConfig GimpPluginConfig;
|
|||
typedef struct _GimpRc GimpRc;
|
||||
|
||||
typedef struct _GimpConfigWriter GimpConfigWriter;
|
||||
typedef struct _GimpXmlParser GimpXmlParser;
|
||||
|
||||
|
||||
#endif /* __CONFIG_TYPES_H__ */
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* GimpXmlParser
|
||||
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "config-types.h"
|
||||
|
||||
#include "gimpxmlparser.h"
|
||||
|
||||
|
||||
struct _GimpXmlParser
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
};
|
||||
|
||||
|
||||
static gchar * parse_encoding (const gchar *text,
|
||||
gint text_len);
|
||||
|
||||
|
||||
/**
|
||||
* gimp_xml_parser_new:
|
||||
* @parser: a #GMarkupParser
|
||||
* @user_data: user data to pass to #GMarkupParser functions
|
||||
*
|
||||
* GimpXmlParser is a thin wrapper around GMarkupParser. This function
|
||||
* creates one for you and sets up a GMarkupParseContext.
|
||||
*
|
||||
* Return value: a new #GimpXmlParser
|
||||
**/
|
||||
GimpXmlParser *
|
||||
gimp_xml_parser_new (const GMarkupParser *markup_parser,
|
||||
gpointer user_data)
|
||||
{
|
||||
GimpXmlParser *parser;
|
||||
|
||||
g_return_val_if_fail (markup_parser != NULL, NULL);
|
||||
|
||||
parser = g_new (GimpXmlParser, 1);
|
||||
|
||||
parser->context = g_markup_parse_context_new (markup_parser,
|
||||
0, user_data, NULL);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_xml_parser_parse_file:
|
||||
* @parser: a #GimpXmlParser
|
||||
* @filename: name of a file to parse
|
||||
* @error: return location for possible errors
|
||||
*
|
||||
* This function creates a GIOChannel for @filename and calls
|
||||
* gimp_xml_parser_parse_io_channel() for you.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
gimp_xml_parser_parse_file (GimpXmlParser *parser,
|
||||
const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
GIOChannel *io;
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (parser != NULL, FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
io = g_io_channel_new_file (filename, "r", error);
|
||||
if (!io)
|
||||
return FALSE;
|
||||
|
||||
success = gimp_xml_parser_parse_io_channel (parser, io, error);
|
||||
|
||||
g_io_channel_unref (io);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_xml_parser_parse_io_channel:
|
||||
* @parser: a #GimpXmlParser
|
||||
* @io: a #GIOChannel
|
||||
* @error: return location for possible errors
|
||||
*
|
||||
* Makes @parser read from the specified @io channel. This function
|
||||
* returns when the GIOChannel becomes empty (end of file) or an
|
||||
* error occurs, either reading from @io or parsing the read data.
|
||||
*
|
||||
* This function tries to determine the character encoding from the
|
||||
* XML header and converts the content to UTF-8 for you.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
gimp_xml_parser_parse_io_channel (GimpXmlParser *parser,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
GIOStatus status;
|
||||
guchar buffer[8196];
|
||||
gsize len = 0;
|
||||
gsize bytes;
|
||||
const gchar *io_encoding;
|
||||
gchar *encoding = NULL;
|
||||
|
||||
g_return_val_if_fail (parser != NULL, FALSE);
|
||||
g_return_val_if_fail (io != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
io_encoding = g_io_channel_get_encoding (io);
|
||||
if (io_encoding && strcmp (io_encoding, "UTF-8"))
|
||||
{
|
||||
g_warning ("gimp_xml_parser_parse_io_channel():\n"
|
||||
"The encoding has already been set on this GIOChannel!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* try to determine the encoding */
|
||||
while (len < sizeof (buffer) && !encoding)
|
||||
{
|
||||
status = g_io_channel_read_chars (io,
|
||||
buffer + len, 1, &bytes, error);
|
||||
len += bytes;
|
||||
|
||||
if (status == G_IO_STATUS_ERROR)
|
||||
return FALSE;
|
||||
if (status == G_IO_STATUS_EOF)
|
||||
break;
|
||||
|
||||
encoding = parse_encoding (buffer, len);
|
||||
}
|
||||
|
||||
if (encoding)
|
||||
{
|
||||
if (!g_io_channel_set_encoding (io, encoding, error))
|
||||
return FALSE;
|
||||
|
||||
g_free (encoding);
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!g_markup_parse_context_parse (parser->context, buffer, len, error))
|
||||
return FALSE;
|
||||
|
||||
status = g_io_channel_read_chars (io,
|
||||
buffer, sizeof (buffer), &len, error);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case G_IO_STATUS_ERROR:
|
||||
return FALSE;
|
||||
case G_IO_STATUS_EOF:
|
||||
return g_markup_parse_context_end_parse (parser->context, error);
|
||||
case G_IO_STATUS_NORMAL:
|
||||
case G_IO_STATUS_AGAIN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_xml_parser_free:
|
||||
* @parser: a #GimpXmlParser
|
||||
*
|
||||
* Frees the resources allocated for @parser. You must not access
|
||||
* @parser after calling this function.
|
||||
**/
|
||||
void
|
||||
gimp_xml_parser_free (GimpXmlParser *parser)
|
||||
{
|
||||
g_return_if_fail (parser != NULL);
|
||||
|
||||
g_markup_parse_context_free (parser->context);
|
||||
g_free (parser);
|
||||
}
|
||||
|
||||
|
||||
static gchar *
|
||||
parse_encoding (const gchar *text,
|
||||
gint text_len)
|
||||
{
|
||||
const gchar *start;
|
||||
const gchar *end;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (text, NULL);
|
||||
|
||||
if (text_len < 20)
|
||||
return NULL;
|
||||
|
||||
start = g_strstr_len (text, text_len, "<?xml");
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
end = g_strstr_len (start, text_len - (start - text), "?>");
|
||||
if (!end)
|
||||
return NULL;
|
||||
|
||||
text_len = end - start;
|
||||
if (text_len < 12)
|
||||
return NULL;
|
||||
|
||||
start = g_strstr_len (start + 1, text_len - 1, "encoding=");
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
start += 9;
|
||||
if (*start != '\"' && *start != '\'')
|
||||
return NULL;
|
||||
|
||||
text_len = end - start;
|
||||
if (text_len < 1)
|
||||
return NULL;
|
||||
|
||||
for (i = 1; i < text_len; i++)
|
||||
if (start[i] == start[0])
|
||||
break;
|
||||
|
||||
if (i == text_len || i < 3)
|
||||
return NULL;
|
||||
|
||||
return g_strndup (start + 1, i - 1);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* GimpXmlParser
|
||||
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_XML_PARSER_H__
|
||||
#define __GIMP_XML_PARSER_H__
|
||||
|
||||
|
||||
GimpXmlParser * gimp_xml_parser_new (const GMarkupParser *markup_parser,
|
||||
gpointer user_data);
|
||||
gboolean gimp_xml_parser_parse_file (GimpXmlParser *parser,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
gboolean gimp_xml_parser_parse_io_channel (GimpXmlParser *parser,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
void gimp_xml_parser_free (GimpXmlParser *parser);
|
||||
|
||||
|
||||
#endif /* __GIMP_XML_PARSER_H__ */
|
|
@ -79,16 +79,37 @@ tips_dialog_create (Gimp *gimp)
|
|||
GError *error = NULL;
|
||||
gchar *filename;
|
||||
|
||||
filename = g_build_filename (gimp_data_directory (), "tips",
|
||||
filename = g_build_filename (gimp_data_directory (), "tips",
|
||||
"gimp-tips.xml", NULL);
|
||||
|
||||
tips = gimp_tips_from_file (filename, &error);
|
||||
g_free (filename);
|
||||
|
||||
if (error)
|
||||
if (!tips)
|
||||
{
|
||||
tips = g_list_prepend (tips,
|
||||
gimp_tip_new (_("<b>The GIMP tips file could not be parsed correctly!</b>"), error->message));
|
||||
GimpTip *tip;
|
||||
|
||||
if (error->code == G_FILE_ERROR_NOENT)
|
||||
{
|
||||
tip = gimp_tip_new (_("<b>Your GIMP tips file appears to be missing!</b>"),
|
||||
NULL);
|
||||
tip->thetip = g_strdup_printf (_("There should be a file called '%s'. "
|
||||
"Please check your installation."),
|
||||
filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
tip = gimp_tip_new (_("<b>The GIMP tips file could not be parsed!</b>"),
|
||||
error->message);
|
||||
}
|
||||
|
||||
tips = g_list_prepend (tips, tip);
|
||||
g_error_free (error);
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
g_printerr ("Error while parsing '%s': %s",
|
||||
filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +143,7 @@ tips_dialog_create (Gimp *gimp)
|
|||
config);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (tips_dialog), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (tips_dialog), vbox);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
|
@ -151,7 +172,7 @@ tips_dialog_create (Gimp *gimp)
|
|||
gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
|
||||
gtk_widget_show (vbox2);
|
||||
|
||||
filename = g_build_filename (gimp_data_directory (),
|
||||
filename = g_build_filename (gimp_data_directory (),
|
||||
"images", "wilber-tips.png", NULL);
|
||||
wilber = gdk_pixbuf_new_from_file (filename, NULL);
|
||||
g_free (filename);
|
||||
|
@ -250,7 +271,7 @@ tips_set_labels (GimpTip *tip)
|
|||
gtk_widget_show (welcome_label);
|
||||
else
|
||||
gtk_widget_hide (welcome_label);
|
||||
|
||||
|
||||
gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome);
|
||||
gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip);
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "config/config-types.h"
|
||||
#include "config/gimpxmlparser.h"
|
||||
|
||||
#include "tips-parser.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
@ -51,7 +53,6 @@ typedef enum
|
|||
typedef struct _TipsParser TipsParser;
|
||||
struct _TipsParser
|
||||
{
|
||||
const gchar *filename;
|
||||
TipsParserState state;
|
||||
TipsParserState last_known_state;
|
||||
const gchar *locale;
|
||||
|
@ -80,9 +81,6 @@ static void tips_parser_characters (GMarkupParseContext *context,
|
|||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void tips_parser_error (GMarkupParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
static void tips_parser_start_markup (TipsParser *parser,
|
||||
const gchar *markup_name);
|
||||
|
@ -103,7 +101,7 @@ static const GMarkupParser markup_parser =
|
|||
tips_parser_end_element,
|
||||
tips_parser_characters,
|
||||
NULL, /* passthrough */
|
||||
tips_parser_error
|
||||
NULL /* error */
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,44 +132,30 @@ gimp_tip_free (GimpTip *tip)
|
|||
* gimp_tips_from_file:
|
||||
* @filename: the name of the tips file to parse
|
||||
* @error: return location for a #GError
|
||||
*
|
||||
*
|
||||
* Reads a gimp-tips XML file, creates a new #GimpTip for
|
||||
* each tip entry and returns a #GList of them. If a parser
|
||||
* error occurs at some point, the uncompleted list is
|
||||
* returned and @error is set (unless @error is %NULL).
|
||||
* The message set in @error contains a detailed description
|
||||
* of the problem.
|
||||
*
|
||||
*
|
||||
* Return value: a #Glist of #GimpTips.
|
||||
**/
|
||||
GList *
|
||||
gimp_tips_from_file (const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
TipsParser *parser;
|
||||
const gchar *tips_locale;
|
||||
FILE *fp;
|
||||
gsize bytes;
|
||||
gchar buf[4096];
|
||||
GList *tips = NULL;
|
||||
GimpXmlParser *xml_parser;
|
||||
TipsParser *parser;
|
||||
const gchar *tips_locale;
|
||||
GList *tips = NULL;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
_("Your GIMP tips file appears to be missing! "
|
||||
"There should be a file called '%s'. "
|
||||
"Please check your installation."), filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parser = g_new0 (TipsParser, 1);
|
||||
parser->filename = filename;
|
||||
parser->value = g_string_new (NULL);
|
||||
parser->value = g_string_new (NULL);
|
||||
|
||||
/* This is a special string to specify the language identifier to
|
||||
look for in the gimp-tips.xml file. Please translate the C in it
|
||||
|
@ -189,17 +173,11 @@ gimp_tips_from_file (const gchar *filename,
|
|||
else
|
||||
g_warning ("Wrong translation for 'tips-locale:', fix the translation!");
|
||||
|
||||
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
|
||||
xml_parser = gimp_xml_parser_new (&markup_parser, parser);
|
||||
|
||||
while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 &&
|
||||
g_markup_parse_context_parse (context, buf, bytes, error))
|
||||
;
|
||||
gimp_xml_parser_parse_file (xml_parser, filename, error);
|
||||
|
||||
if (error == NULL || *error == NULL)
|
||||
g_markup_parse_context_end_parse (context, error);
|
||||
|
||||
fclose (fp);
|
||||
g_markup_parse_context_free (context);
|
||||
gimp_xml_parser_free (xml_parser);
|
||||
|
||||
tips = g_list_reverse (parser->tips);
|
||||
|
||||
|
@ -249,7 +227,7 @@ tips_parser_start_element (GMarkupParseContext *context,
|
|||
else
|
||||
tips_parser_start_unknown (parser);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_TIP:
|
||||
if (strcmp (element_name, "welcome") == 0)
|
||||
{
|
||||
|
@ -264,10 +242,10 @@ tips_parser_start_element (GMarkupParseContext *context,
|
|||
else
|
||||
tips_parser_start_unknown (parser);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_WELCOME:
|
||||
case TIPS_IN_THETIP:
|
||||
if (strcmp (element_name, "b" ) == 0 ||
|
||||
if (strcmp (element_name, "b" ) == 0 ||
|
||||
strcmp (element_name, "big") == 0 ||
|
||||
strcmp (element_name, "tt" ) == 0)
|
||||
tips_parser_start_markup (parser, element_name);
|
||||
|
@ -304,7 +282,7 @@ tips_parser_end_element (GMarkupParseContext *context,
|
|||
parser->current_tip = NULL;
|
||||
parser->state = TIPS_IN_TIPS;
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_WELCOME:
|
||||
if (parser->markup_depth == 0)
|
||||
{
|
||||
|
@ -350,7 +328,7 @@ tips_parser_characters (GMarkupParseContext *context,
|
|||
{
|
||||
gint i;
|
||||
|
||||
/* strip tabs, newlines and adjacent whitespace */
|
||||
/* strip tabs, newlines and adjacent whitespace */
|
||||
for (i = 0; i < text_len; i++)
|
||||
{
|
||||
if (text[i] != ' ' &&
|
||||
|
@ -367,16 +345,6 @@ tips_parser_characters (GMarkupParseContext *context,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tips_parser_error (GMarkupParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
TipsParser *parser = (TipsParser *) user_data;
|
||||
|
||||
g_warning ("%s: %s", parser->filename, error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
tips_parser_start_markup (TipsParser *parser,
|
||||
const gchar *markup_name)
|
||||
|
@ -411,7 +379,7 @@ tips_parser_end_unknown (TipsParser *parser)
|
|||
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN);
|
||||
|
||||
parser->unknown_depth--;
|
||||
|
||||
|
||||
if (parser->unknown_depth == 0)
|
||||
parser->state = parser->last_known_state;
|
||||
}
|
||||
|
@ -428,7 +396,7 @@ tips_parser_parse_locale (TipsParser *parser,
|
|||
if (strcmp (*names, "xml:lang") == 0 && **values)
|
||||
{
|
||||
parser->locale_state = (parser->locale &&
|
||||
strcmp (*values, parser->locale) == 0 ?
|
||||
strcmp (*values, parser->locale) == 0 ?
|
||||
TIPS_LOCALE_MATCH : TIPS_LOCALE_MISMATCH);
|
||||
}
|
||||
|
||||
|
@ -439,7 +407,7 @@ tips_parser_parse_locale (TipsParser *parser,
|
|||
|
||||
static void
|
||||
tips_parser_set_by_locale (TipsParser *parser,
|
||||
gchar **dest)
|
||||
gchar **dest)
|
||||
{
|
||||
switch (parser->locale_state)
|
||||
{
|
||||
|
@ -459,7 +427,7 @@ tips_parser_set_by_locale (TipsParser *parser,
|
|||
g_free (*dest);
|
||||
*dest = g_strdup (parser->value->str);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_LOCALE_MISMATCH:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79,16 +79,37 @@ tips_dialog_create (Gimp *gimp)
|
|||
GError *error = NULL;
|
||||
gchar *filename;
|
||||
|
||||
filename = g_build_filename (gimp_data_directory (), "tips",
|
||||
filename = g_build_filename (gimp_data_directory (), "tips",
|
||||
"gimp-tips.xml", NULL);
|
||||
|
||||
tips = gimp_tips_from_file (filename, &error);
|
||||
g_free (filename);
|
||||
|
||||
if (error)
|
||||
if (!tips)
|
||||
{
|
||||
tips = g_list_prepend (tips,
|
||||
gimp_tip_new (_("<b>The GIMP tips file could not be parsed correctly!</b>"), error->message));
|
||||
GimpTip *tip;
|
||||
|
||||
if (error->code == G_FILE_ERROR_NOENT)
|
||||
{
|
||||
tip = gimp_tip_new (_("<b>Your GIMP tips file appears to be missing!</b>"),
|
||||
NULL);
|
||||
tip->thetip = g_strdup_printf (_("There should be a file called '%s'. "
|
||||
"Please check your installation."),
|
||||
filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
tip = gimp_tip_new (_("<b>The GIMP tips file could not be parsed!</b>"),
|
||||
error->message);
|
||||
}
|
||||
|
||||
tips = g_list_prepend (tips, tip);
|
||||
g_error_free (error);
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
g_printerr ("Error while parsing '%s': %s",
|
||||
filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +143,7 @@ tips_dialog_create (Gimp *gimp)
|
|||
config);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (tips_dialog), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (tips_dialog), vbox);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
|
@ -151,7 +172,7 @@ tips_dialog_create (Gimp *gimp)
|
|||
gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
|
||||
gtk_widget_show (vbox2);
|
||||
|
||||
filename = g_build_filename (gimp_data_directory (),
|
||||
filename = g_build_filename (gimp_data_directory (),
|
||||
"images", "wilber-tips.png", NULL);
|
||||
wilber = gdk_pixbuf_new_from_file (filename, NULL);
|
||||
g_free (filename);
|
||||
|
@ -250,7 +271,7 @@ tips_set_labels (GimpTip *tip)
|
|||
gtk_widget_show (welcome_label);
|
||||
else
|
||||
gtk_widget_hide (welcome_label);
|
||||
|
||||
|
||||
gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome);
|
||||
gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip);
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "config/config-types.h"
|
||||
#include "config/gimpxmlparser.h"
|
||||
|
||||
#include "tips-parser.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
@ -51,7 +53,6 @@ typedef enum
|
|||
typedef struct _TipsParser TipsParser;
|
||||
struct _TipsParser
|
||||
{
|
||||
const gchar *filename;
|
||||
TipsParserState state;
|
||||
TipsParserState last_known_state;
|
||||
const gchar *locale;
|
||||
|
@ -80,9 +81,6 @@ static void tips_parser_characters (GMarkupParseContext *context,
|
|||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void tips_parser_error (GMarkupParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
static void tips_parser_start_markup (TipsParser *parser,
|
||||
const gchar *markup_name);
|
||||
|
@ -103,7 +101,7 @@ static const GMarkupParser markup_parser =
|
|||
tips_parser_end_element,
|
||||
tips_parser_characters,
|
||||
NULL, /* passthrough */
|
||||
tips_parser_error
|
||||
NULL /* error */
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,44 +132,30 @@ gimp_tip_free (GimpTip *tip)
|
|||
* gimp_tips_from_file:
|
||||
* @filename: the name of the tips file to parse
|
||||
* @error: return location for a #GError
|
||||
*
|
||||
*
|
||||
* Reads a gimp-tips XML file, creates a new #GimpTip for
|
||||
* each tip entry and returns a #GList of them. If a parser
|
||||
* error occurs at some point, the uncompleted list is
|
||||
* returned and @error is set (unless @error is %NULL).
|
||||
* The message set in @error contains a detailed description
|
||||
* of the problem.
|
||||
*
|
||||
*
|
||||
* Return value: a #Glist of #GimpTips.
|
||||
**/
|
||||
GList *
|
||||
gimp_tips_from_file (const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
TipsParser *parser;
|
||||
const gchar *tips_locale;
|
||||
FILE *fp;
|
||||
gsize bytes;
|
||||
gchar buf[4096];
|
||||
GList *tips = NULL;
|
||||
GimpXmlParser *xml_parser;
|
||||
TipsParser *parser;
|
||||
const gchar *tips_locale;
|
||||
GList *tips = NULL;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
_("Your GIMP tips file appears to be missing! "
|
||||
"There should be a file called '%s'. "
|
||||
"Please check your installation."), filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parser = g_new0 (TipsParser, 1);
|
||||
parser->filename = filename;
|
||||
parser->value = g_string_new (NULL);
|
||||
parser->value = g_string_new (NULL);
|
||||
|
||||
/* This is a special string to specify the language identifier to
|
||||
look for in the gimp-tips.xml file. Please translate the C in it
|
||||
|
@ -189,17 +173,11 @@ gimp_tips_from_file (const gchar *filename,
|
|||
else
|
||||
g_warning ("Wrong translation for 'tips-locale:', fix the translation!");
|
||||
|
||||
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
|
||||
xml_parser = gimp_xml_parser_new (&markup_parser, parser);
|
||||
|
||||
while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 &&
|
||||
g_markup_parse_context_parse (context, buf, bytes, error))
|
||||
;
|
||||
gimp_xml_parser_parse_file (xml_parser, filename, error);
|
||||
|
||||
if (error == NULL || *error == NULL)
|
||||
g_markup_parse_context_end_parse (context, error);
|
||||
|
||||
fclose (fp);
|
||||
g_markup_parse_context_free (context);
|
||||
gimp_xml_parser_free (xml_parser);
|
||||
|
||||
tips = g_list_reverse (parser->tips);
|
||||
|
||||
|
@ -249,7 +227,7 @@ tips_parser_start_element (GMarkupParseContext *context,
|
|||
else
|
||||
tips_parser_start_unknown (parser);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_TIP:
|
||||
if (strcmp (element_name, "welcome") == 0)
|
||||
{
|
||||
|
@ -264,10 +242,10 @@ tips_parser_start_element (GMarkupParseContext *context,
|
|||
else
|
||||
tips_parser_start_unknown (parser);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_WELCOME:
|
||||
case TIPS_IN_THETIP:
|
||||
if (strcmp (element_name, "b" ) == 0 ||
|
||||
if (strcmp (element_name, "b" ) == 0 ||
|
||||
strcmp (element_name, "big") == 0 ||
|
||||
strcmp (element_name, "tt" ) == 0)
|
||||
tips_parser_start_markup (parser, element_name);
|
||||
|
@ -304,7 +282,7 @@ tips_parser_end_element (GMarkupParseContext *context,
|
|||
parser->current_tip = NULL;
|
||||
parser->state = TIPS_IN_TIPS;
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_IN_WELCOME:
|
||||
if (parser->markup_depth == 0)
|
||||
{
|
||||
|
@ -350,7 +328,7 @@ tips_parser_characters (GMarkupParseContext *context,
|
|||
{
|
||||
gint i;
|
||||
|
||||
/* strip tabs, newlines and adjacent whitespace */
|
||||
/* strip tabs, newlines and adjacent whitespace */
|
||||
for (i = 0; i < text_len; i++)
|
||||
{
|
||||
if (text[i] != ' ' &&
|
||||
|
@ -367,16 +345,6 @@ tips_parser_characters (GMarkupParseContext *context,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tips_parser_error (GMarkupParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
TipsParser *parser = (TipsParser *) user_data;
|
||||
|
||||
g_warning ("%s: %s", parser->filename, error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
tips_parser_start_markup (TipsParser *parser,
|
||||
const gchar *markup_name)
|
||||
|
@ -411,7 +379,7 @@ tips_parser_end_unknown (TipsParser *parser)
|
|||
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN);
|
||||
|
||||
parser->unknown_depth--;
|
||||
|
||||
|
||||
if (parser->unknown_depth == 0)
|
||||
parser->state = parser->last_known_state;
|
||||
}
|
||||
|
@ -428,7 +396,7 @@ tips_parser_parse_locale (TipsParser *parser,
|
|||
if (strcmp (*names, "xml:lang") == 0 && **values)
|
||||
{
|
||||
parser->locale_state = (parser->locale &&
|
||||
strcmp (*values, parser->locale) == 0 ?
|
||||
strcmp (*values, parser->locale) == 0 ?
|
||||
TIPS_LOCALE_MATCH : TIPS_LOCALE_MISMATCH);
|
||||
}
|
||||
|
||||
|
@ -439,7 +407,7 @@ tips_parser_parse_locale (TipsParser *parser,
|
|||
|
||||
static void
|
||||
tips_parser_set_by_locale (TipsParser *parser,
|
||||
gchar **dest)
|
||||
gchar **dest)
|
||||
{
|
||||
switch (parser->locale_state)
|
||||
{
|
||||
|
@ -459,7 +427,7 @@ tips_parser_set_by_locale (TipsParser *parser,
|
|||
g_free (*dest);
|
||||
*dest = g_strdup (parser->value->str);
|
||||
break;
|
||||
|
||||
|
||||
case TIPS_LOCALE_MISMATCH:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -35,4 +35,6 @@ libappvectors_a_SOURCES = \
|
|||
gimpvectors-preview.c \
|
||||
gimpvectors-preview.h
|
||||
|
||||
## This is a truly ugly hack
|
||||
libappvectors_a_LIBADD = ../config/gimpxmlparser.o
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ gimp_vectors_export (const GimpImage *image,
|
|||
}
|
||||
|
||||
fprintf (file,
|
||||
"<?xml version=\"1.0\" standalone=\"no\"?>\n"
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n"
|
||||
" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n");
|
||||
fprintf (file,
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -34,6 +33,8 @@
|
|||
|
||||
#include "vectors-types.h"
|
||||
|
||||
#include "config/gimpxmlparser.h"
|
||||
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
|
||||
|
@ -134,32 +135,19 @@ gimp_vectors_import (GimpImage *image,
|
|||
gboolean merge,
|
||||
GError **error)
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
FILE *file;
|
||||
GQueue *stack;
|
||||
GList *paths;
|
||||
SvgHandler *base;
|
||||
gboolean success = TRUE;
|
||||
gsize bytes;
|
||||
gchar buf[4096];
|
||||
GimpXmlParser *parser;
|
||||
GQueue *stack;
|
||||
GList *paths;
|
||||
SvgHandler *base;
|
||||
gboolean success = TRUE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
file = fopen (filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
_("Failed to open file: '%s': %s"),
|
||||
filename, g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
stack = g_queue_new ();
|
||||
|
||||
/* the base of the stack, defines the size of the view-port */
|
||||
|
||||
base = g_new0 (SvgHandler, 1);
|
||||
base->name = "image";
|
||||
base->width = image->width;
|
||||
|
@ -167,17 +155,11 @@ gimp_vectors_import (GimpImage *image,
|
|||
|
||||
g_queue_push_head (stack, base);
|
||||
|
||||
context = g_markup_parse_context_new (&markup_parser, 0, stack, NULL);
|
||||
parser = gimp_xml_parser_new (&markup_parser, stack);
|
||||
|
||||
while (success &&
|
||||
(bytes = fread (buf, sizeof (gchar), sizeof (buf), file)) > 0)
|
||||
success = g_markup_parse_context_parse (context, buf, bytes, error);
|
||||
success = gimp_xml_parser_parse_file (parser, filename, error);
|
||||
|
||||
if (success)
|
||||
success = g_markup_parse_context_end_parse (context, error);
|
||||
|
||||
fclose (file);
|
||||
g_markup_parse_context_free (context);
|
||||
gimp_xml_parser_free (parser);
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue