/* gcompris - wordprocessor.c
*
* Copyright (C) 2006, 2008 Bruno Coudoin
*
* 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 3 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, see .
*/
#include
#include
#include
#include "gcompris/gcompris.h"
/*
* Predefined styles
* -----------------
*/
typedef struct {
gchar *name;
gchar *font;
PangoWeight weight;
GtkJustification justification;
gint left_margin;
gint pixels_above_lines;
gint pixels_below_lines;
} style_t;
#define NUMBER_OF_STYLE 4 /* h1 h2 h3 p */
static GtkTextTag *tag_list[NUMBER_OF_STYLE];
/*
* The document styles
*/
typedef struct {
gchar *name;
style_t style[NUMBER_OF_STYLE];
} doctype_t;
doctype_t type_normal =
{
.name = N_("Research"),
.style = {
{ "h1", "Serif 30", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
{ "h2", "Serif 26", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
{ "h3", "Serif 20", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
{ "p", "Serif 16", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
}
};
doctype_t type_letter =
{
.name = N_("Sentimental"),
.style = {
{ "h1", "Serif 26", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
{ "h2", "Serif 20", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
{ "h3", "Serif 16", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 10, 20, 12 },
{ "p", "Serif 14", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
},
};
doctype_t type_small =
{
.name = N_("Official"),
.style = {
{ "h1", "Serif 18", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
{ "h2", "Serif 16", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
{ "h3", "Serif 14", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 10, 20, 12 },
{ "p", "Serif 12", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
},
};
doctype_t type_text =
{
.name = N_("Text"),
.style = {
{ "h1", "Serif 12", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
{ "h2", "Serif 12", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
{ "h3", "Serif 12", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
{ "p", "Serif 12", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
},
};
doctype_t type_big =
{
.name = N_("Flyer"),
.style = {
{ "h1", "Serif 34", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
{ "h2", "Serif 30", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
{ "h3", "Serif 26", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
{ "p", "Serif 18", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
},
};
#define NUMBER_OF_DOCTYPE 5
static doctype_t *doctype_list[NUMBER_OF_DOCTYPE];
/*
* The color styles
*/
#define NUMBER_OF_COLOR_STYLE 4
static gchar *color_style_list[NUMBER_OF_COLOR_STYLE][NUMBER_OF_STYLE+1] =
{
{N_("Spring"), "red", "blue", "lightblue", "black"},
{N_("Summer"), "DeepPink", "HotPink", "MediumOrchid", "black"},
{N_("Autumn"), "blue", "red", "lightblue", "black"},
{N_("Winter"), "black", "black", "black", "black"},
};
static GcomprisBoard *gcomprisBoard = NULL;
static gboolean board_paused = TRUE;
static GtkWidget *gtk_combo_styles = NULL;
static GtkWidget *gtk_combo_colors = NULL;
static GtkWidget *gtk_button_style[NUMBER_OF_STYLE];
static GtkWidget *sw = NULL;
static void start_board (GcomprisBoard *agcomprisBoard);
static void pause_board (gboolean pause);
static void end_board (void);
static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
static void set_level (guint level);
static gboolean key_release_event (GtkWidget *text_view,
GdkEventKey *event);
static GooCanvasItem *boardRootItem = NULL;
static GooCanvasItem *wordprocessor_create(void);
static void wordprocessor_destroy_all_items(void);
static void item_event(GtkWidget *item, gchar *data);
static int display_style_buttons(GooCanvasItem *boardRootItem,
int x,
int y);
static void create_tags (GtkTextBuffer *buffer, doctype_t *doctype);
static void set_default_tag (GtkTextBuffer *buffer, GtkTextTag *tag);
static void display_style_selector(GooCanvasItem *boardRootItem, double y);
static void display_color_style_selector(GooCanvasItem *boardRootItem, double y);
static void item_event_style_selection (GtkComboBox *widget, void *data);
static void item_event_color_style_selection (GtkComboBox *widget, void *data);
static gboolean save_event (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gchar *data);
static gboolean load_event (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gchar *data);
static int get_style_index(gchar *style);
static int get_style_current_index();
static gint get_color_style_index(gchar *color_style);
static gint get_color_style_current_index();
static GtkTextTag *get_tag_from_name(gchar *name);
static void apply_style(int style_index);
static void apply_color_style(int style_index);
#define word_area_x1 120
#define word_area_y1 20
#define word_area_width 650
#define word_area_height 485
#define combo_style_x1 5
#define combo_style_width 105
static GtkTextBuffer *buffer;
static GtkWidget *view;
GtkTextTag *selected_tag;
/* Description of this plugin */
static BoardPlugin menu_bp =
{
NULL,
NULL,
"Wordprocessor",
"A basic word processor",
"Bruno Coudoin ",
NULL,
NULL,
NULL,
NULL,
start_board,
pause_board,
end_board,
is_our_board,
NULL,
NULL,
set_level,
NULL,
NULL,
NULL,
NULL
};
/*
* Main entry point mandatory for each Gcompris's game
* ---------------------------------------------------
*
*/
GET_BPLUGIN_INFO(wordprocessor)
/*
* in : boolean TRUE = PAUSE : FALSE = CONTINUE
*
*/
static void pause_board (gboolean pause)
{
int i;
if(gcomprisBoard==NULL)
return;
/* Widgets don't like being overlapped */
if(pause)
{
gtk_widget_hide(GTK_WIDGET(sw));
gtk_widget_hide(GTK_WIDGET(gtk_combo_styles));
gtk_widget_hide(GTK_WIDGET(gtk_combo_colors));
for(i=0; ilevel=1;
gcomprisBoard->maxlevel=1;
gcomprisBoard->sublevel=1;
gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
gc_bar_set(0);
gc_bar_location(10, -1, 0.6);
gc_set_default_background(goo_canvas_get_root_item(gcomprisBoard->canvas));
wordprocessor_create();
pause_board(FALSE);
}
}
/* ======================================= */
static void end_board ()
{
if(gcomprisBoard!=NULL)
{
pause_board(TRUE);
wordprocessor_destroy_all_items();
}
gcomprisBoard = NULL;
}
/* ======================================= */
static void set_level (guint level)
{
}
/* ======================================= */
static gboolean is_our_board (GcomprisBoard *gcomprisBoard)
{
if (gcomprisBoard)
{
if(g_ascii_strcasecmp(gcomprisBoard->type, "wordprocessor")==0)
{
/* Set the plugin entry */
gcomprisBoard->plugin=&menu_bp;
return TRUE;
}
}
return FALSE;
}
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
/* ==================================== */
/* Destroy all the items */
static void wordprocessor_destroy_all_items()
{
if(boardRootItem!=NULL)
goo_canvas_item_remove(boardRootItem);
boardRootItem = NULL;
}
/* ==================================== */
static GooCanvasItem *wordprocessor_create()
{
GooCanvasItem *item = NULL;
GdkPixbuf *pixmap;
double y;
boardRootItem = goo_canvas_group_new (goo_canvas_get_root_item(gcomprisBoard->canvas),
NULL);
selected_tag = NULL;
view = gtk_text_view_new ();
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
/* Change left margin throughout the widget */
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 1);
g_signal_connect (view, "key-release-event",
G_CALLBACK (key_release_event), NULL);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_ALWAYS);
gtk_container_add (GTK_CONTAINER (sw), view);
item = goo_canvas_widget_new (boardRootItem,
GTK_WIDGET(sw),
word_area_x1,
word_area_y1,
word_area_width,
word_area_height,
"anchor", GTK_ANCHOR_NW,
NULL);
gtk_widget_show(GTK_WIDGET(view));
gtk_widget_show(GTK_WIDGET(sw));
/*
* Create the default style tags
*/
doctype_list[0] = &type_text;
doctype_list[1] = &type_normal;
doctype_list[2] = &type_letter;
doctype_list[3] = &type_small;
doctype_list[4] = &type_big;
y = 20.0;
/*
* The save button
*/
pixmap = gc_pixmap_load("wordprocessor/tool-save.png");
item = \
goo_canvas_image_new (boardRootItem,
pixmap,
17.0,
y,
NULL);
#if GDK_PIXBUF_MAJOR <= 2 && GDK_PIXBUF_MINOR <= 24
gdk_pixbuf_unref(pixmap);
#else
g_object_unref(pixmap);
#endif
g_signal_connect(item, "button_press_event",
(GCallback) save_event, buffer);
gc_item_focus_init(item, NULL);
/*
* The load button
*/
pixmap = gc_pixmap_load("wordprocessor/tool-load.png");
item = \
goo_canvas_image_new (boardRootItem,
pixmap,
60.0,
y,
NULL);
#if GDK_PIXBUF_MAJOR <= 2 && GDK_PIXBUF_MINOR <= 24
gdk_pixbuf_unref(pixmap);
#else
g_object_unref(pixmap);
#endif
g_signal_connect(item, "button_press_event",
(GCallback) load_event, buffer);
gc_item_focus_init(item, NULL);
y += 45;
/*
* Display the style buttons
*/
y = display_style_buttons(boardRootItem,
20.0,
y);
y += 20;
display_style_selector(boardRootItem, y);
y += 40;
display_color_style_selector(boardRootItem, y);
/* Now we can create the tags */
create_tags(buffer, doctype_list[0]);
gtk_widget_grab_focus(view);
return NULL;
}
/*
* Display the style buttons
*
* \return the new y coordinate
*/
static int
display_style_buttons(GooCanvasItem *boardRootItem,
int x,
int y)
{
int offset_y = 40;
int i = 0;
static gchar *styles_tab[] = { N_("Title"), "h1",
N_("Heading 1"), "h2",
N_("Heading 2"), "h3",
N_("Text"), "p",
NULL, NULL };
while(styles_tab[i*2])
{
gtk_button_style[i] = gtk_button_new_with_label(gettext(styles_tab[i*2]));
goo_canvas_widget_new (boardRootItem,
GTK_WIDGET(gtk_button_style[i]),
combo_style_x1,
y,
combo_style_width,
35.0,
"anchor", GTK_ANCHOR_NW,
NULL);
g_signal_connect(GTK_OBJECT(gtk_button_style[i]), "pressed",
(GCallback)item_event, styles_tab[i*2+1] );
y += offset_y;
i++;
}
return(y);
}
/* \brief callback on a style button (h1, h2, h3, p)
*
*
*/
static void
item_event(GtkWidget *button, gchar *data)
{
GtkTextIter iter_start, iter_end;
gchar *current_style_name;
if(board_paused)
return;
current_style_name = (char *)data;
selected_tag = get_tag_from_name(current_style_name);
set_default_tag(buffer, selected_tag);
gtk_text_buffer_get_iter_at_mark(buffer,
&iter_start,
gtk_text_buffer_get_insert (buffer));
gtk_text_iter_set_line_offset(&iter_start, 0);
iter_end = iter_start;
gtk_text_iter_forward_to_line_end(&iter_end);
gtk_text_buffer_remove_all_tags(buffer,
&iter_start,
&iter_end);
gtk_text_buffer_apply_tag_by_name(buffer,
current_style_name,
&iter_start,
&iter_end);
gtk_widget_grab_focus(view);
return;
}
/* Create a bunch of tags. Note that it's also possible to
* create tags with gtk_text_tag_new() then add them to the
* tag table for the buffer, gtk_text_buffer_create_tag() is
* just a convenience function. Also note that you don't have
* to give tags a name; pass NULL for the name to create an
* anonymous tag.
*
* In any real app, another useful optimization would be to create
* a GtkTextTagTable in advance, and reuse the same tag table for
* all the buffers with the same tag set, instead of creating
* new copies of the same tags for every buffer.
*
* Tags are assigned default priorities in order of addition to the
* tag table. That is, tags created later that affect the same text
* property affected by an earlier tag will override the earlier
* tag. You can modify tag priorities with
* gtk_text_tag_set_priority().
*/
static void
create_tags (GtkTextBuffer *buffer, doctype_t *doctype)
{
gint i;
gint c = get_color_style_current_index();
for(i=0; istyle[i].name,
"weight", doctype->style[i].weight,
"font", doctype->style[i].font,
"justification", doctype->style[i].justification,
"left-margin", doctype->style[i].left_margin,
"pixels-above-lines", doctype->style[i].pixels_above_lines,
"pixels-below-lines", doctype->style[i].pixels_below_lines,
"foreground",color_style_list[c][i+1],
NULL);
tag_list[i] = tag;
g_object_set_data (G_OBJECT (tag), "style", &doctype->style[i]);
}
/* Point to the last style */
i--;
set_default_tag(buffer, tag_list[i]);
}
/*
* Set the default style
*/
static void
set_default_tag (GtkTextBuffer *buffer, GtkTextTag *tag)
{
PangoFontDescription *font_desc;
GdkColor *color = (GdkColor *)g_malloc(sizeof(GdkColor));
int val;
GtkJustification justification;
if(!tag)
return;
g_object_get (G_OBJECT (tag), "foreground-gdk", &color, NULL);
g_object_get (G_OBJECT (tag), "font-desc", &font_desc, NULL);
gtk_widget_modify_font (view, font_desc);
gtk_widget_modify_text (view, GTK_STATE_NORMAL, color);
g_object_get (G_OBJECT (tag), "left-margin", &val, NULL);
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), val);
g_object_get (G_OBJECT (tag), "justification", &justification, NULL);
gtk_text_view_set_justification(GTK_TEXT_VIEW (view), justification);
g_object_get (G_OBJECT (tag), "pixels-below-lines", &val, NULL);
gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW (view), val);
g_object_get (G_OBJECT (tag), "pixels-above-lines", &val, NULL);
gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW (view), val);
}
static GtkTextTag *
get_tag_from_name(gchar *tag_name)
{
gint i;
for(i=0; iname));
goo_canvas_widget_new (boardRootItem,
GTK_WIDGET(gtk_combo_styles),
combo_style_x1,
y,
combo_style_width,
35.0,
"anchor", GTK_ANCHOR_NW,
NULL);
gtk_widget_show(GTK_WIDGET(gtk_combo_styles));
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_styles), 0);
g_signal_connect(G_OBJECT(gtk_combo_styles),
"changed",
G_CALLBACK(item_event_style_selection),
NULL);
}
/*
* Create the combo with the color styles
* --------------------------------------
*/
static void
display_color_style_selector(GooCanvasItem *boardRootItem, double y)
{
int i = 0;
gtk_combo_colors = gtk_combo_box_new_text();
while (i < NUMBER_OF_COLOR_STYLE)
gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_combo_colors),
gettext(color_style_list[i++][0]));
goo_canvas_widget_new (boardRootItem,
GTK_WIDGET(gtk_combo_colors),
combo_style_x1,
y,
combo_style_width,
35.0,
"anchor", GTK_ANCHOR_NW,
NULL);
gtk_widget_show(GTK_WIDGET(gtk_combo_colors));
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_colors), 0);
g_signal_connect(G_OBJECT(gtk_combo_colors),
"changed",
G_CALLBACK(item_event_color_style_selection),
NULL);
}
static int
get_style_index(gchar *style)
{
int i;
/* Search the doctype */
for(i=0; iname), style)==0)
return(i);
return(0);
}
static int
get_style_current_index()
{
return( get_style_index(gtk_combo_box_get_active_text(GTK_COMBO_BOX(gtk_combo_styles))) );
}
static void
apply_style(int style_index)
{
int i = style_index;
int j;
for(j=0; jstyle[j].weight,
"font", doctype_list[i]->style[j].font,
"justification", doctype_list[i]->style[j].justification,
"left-margin", doctype_list[i]->style[j].left_margin,
"pixels-above-lines", doctype_list[i]->style[j].pixels_above_lines,
"pixels-below-lines", doctype_list[i]->style[j].pixels_below_lines,
NULL);
}
}
/* Set a new style from the combo box selection
*
*/
static void
item_event_style_selection (GtkComboBox *widget,
void *data)
{
apply_style(get_style_current_index());
gtk_widget_grab_focus(view);
}
static gint
get_color_style_index(gchar *color_style)
{
int i;
/* Search the color style */
for(i=0; inext)
{
GtkTextTag *tag = tagp->data;
gchar *name;
g_object_get (G_OBJECT (tag), "name", &name, NULL);
set_default_tag(buffer, tag);
gtk_text_buffer_apply_tag_by_name(buffer,
name,
&iter_start,
&iter_end);
g_free(name);
selected_tag = NULL;
}
if (tags)
g_slist_free (tags);
else
{
/* Set the default style */
if(selected_tag)
{
set_default_tag(buffer, selected_tag);
gtk_text_buffer_apply_tag(buffer,
selected_tag,
&iter_start,
&iter_end);
}
else
{
set_default_tag(buffer, tag_list[NUMBER_OF_STYLE-1]);
gtk_text_buffer_apply_tag(buffer,
tag_list[NUMBER_OF_STYLE-1],
&iter_start,
&iter_end);
}
}
}
return FALSE;
}
// assumes UTF-8 or UTF-16 as encoding,
static char *
escape(char *input)
{
gsize size = strlen(input)*6; /* 6 is the most increase we can get */
gchar *result = g_malloc(size);
int i;
int o = 0;
result[0] = '\0';
for(i = 0; i < strlen(input); i++)
{
char c = input[i];
if(c == '<')
o = g_strlcat(result, "<", size);
else if(c == '>')
o = g_strlcat(result, ">", size);
else if(c == '&')
o = g_strlcat(result, "&", size);
else if(c == '"')
o = g_strlcat(result, """, size);
else if(c == '\'')
o = g_strlcat(result, "'", size);
else
{
result[o++] = c;
result[o+1] = '\0';
}
}
g_free(input);
return result;
}
static void
save_buffer(gchar *file, gchar *file_type, void *unused)
{
GtkTextIter iter_start, iter_end;
GSList *tags = NULL, *tagp = NULL;
gchar *tag_name;
FILE *filefd;
int style_index = get_style_current_index();
int color_index = get_color_style_current_index();
filefd = g_fopen(file, "w+");
/*
* XHTML Header
*/
fprintf(filefd,
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"GCompris\n",
doctype_list[style_index]->name,
color_style_list[color_index][0]);
/*
* HTML Style
*/
fprintf(filefd,
"\n"
"\n");
/*
* Header end
*/
fprintf(filefd,
"\n");
gtk_text_buffer_get_iter_at_offset(buffer,
&iter_start,
0);
do
{
iter_end = iter_start;
gtk_text_iter_forward_to_line_end(&iter_end);
if(gtk_text_iter_ends_line(&iter_start))
continue;
tags = gtk_text_iter_get_tags (&iter_start);
if(g_slist_length(tags) == 0)
{
gtk_text_iter_backward_char (&iter_end);
tags = gtk_text_iter_get_tags (&iter_end);
gtk_text_iter_forward_char (&iter_end);
}
tag_name = "p";
for (tagp = tags; tagp != NULL; tagp = tagp->next)
{
GtkTextTag *tag = tagp->data;
g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
}
fprintf(filefd, "<%s>", tag_name);
char *result = escape(gtk_text_buffer_get_text(buffer,
&iter_start,
&iter_end,
0));
for (tagp = tags; tagp != NULL; tagp = tagp->next)
{
GtkTextTag *tag = tagp->data;
g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
}
fprintf(filefd, "%s%s>\n", result, tag_name);
g_free(result);
if (tags)
g_slist_free (tags);
} while(gtk_text_iter_forward_line(&iter_start));
/*
* HTML Footer
*/
fprintf(filefd, ""
"\n"
"\n");
fclose(filefd);
pause_board(FALSE);
}
static gboolean
save_event (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gchar *data)
{
if (event->button != 1)
return FALSE;
pause_board(TRUE);
gc_selector_file_save(gcomprisBoard,
"wordprocessor",
".xhtml",
save_buffer, NULL);
return FALSE;
}
static void
load_buffer(gchar *file, gchar *file_type, void *unused)
{
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
xmlDocPtr doc;
xmlNodePtr node;
GtkTextIter iter_start, iter_end;
/* parse the new file and put the result into newdoc */
doc = xmlParseFile(file);
/* in case something went wrong */
if(!doc)
return;
/* Get the root element node */
node = xmlDocGetRootElement(doc);
for(node = node; node != NULL; node = node->next)
if ( g_ascii_strcasecmp((char *)node->name, "html") == 0 &&
node->children )
break;
if(!node)
goto done;
for(node = node->children; node != NULL; node = node->next)
{
if ( g_ascii_strcasecmp((char *)node->name, "head") == 0 &&
node->children )
{
/* Search and apply the saved style in the META */
xmlNodePtr snode;
for(snode = node->children; snode != NULL; snode = snode->next)
{
if ( ( g_ascii_strcasecmp((char *)snode->name, "meta") == 0 ) &&
xmlHasProp(snode, BAD_CAST "http-equiv") )
{
xmlChar *key = xmlGetProp(snode, BAD_CAST "http-equiv");
xmlChar *content = xmlGetProp(snode, BAD_CAST "content");
if(g_ascii_strcasecmp((char *)key, "GCompris-doctype") == 0)
{
int style_index = get_style_index(gettext((char *)content));
apply_style(style_index);
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_styles),
style_index);
}
if(g_ascii_strcasecmp((char *)key, "GCompris-color-style") == 0)
{
int cstyle_index = get_color_style_index(gettext((char *)content));
apply_color_style(cstyle_index);
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_colors),
cstyle_index);
}
xmlFree(key);
xmlFree(content);
}
}
}
if ( g_ascii_strcasecmp((char *)node->name, "body") == 0 &&
node->children )
break;
}
if(!node)
goto done;
gtk_text_buffer_get_start_iter(buffer,
&iter_start);
gtk_text_buffer_get_end_iter(buffer,
&iter_end);
gtk_text_buffer_delete(buffer,
&iter_start,
&iter_end);
gtk_text_buffer_get_start_iter(buffer,
&iter_start);
for(node = node->children; node != NULL; node = node->next)
{
if ( g_ascii_strcasecmp((char *)node->name, "h1") == 0 ||
g_ascii_strcasecmp((char *)node->name, "h2") == 0 ||
g_ascii_strcasecmp((char *)node->name, "h3") == 0 ||
g_ascii_strcasecmp((char *)node->name, "p") == 0 )
{
xmlChar *content;
content = xmlNodeGetContent(node);
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter_start,
(char *)content,
strlen((char *)content),
(char *)node->name,
NULL);
xmlFree(content);
gtk_text_buffer_get_end_iter(buffer,
&iter_start);
gtk_text_buffer_insert(buffer,&iter_start, "\n", 1);
gtk_text_buffer_get_end_iter(buffer,
&iter_start);
}
}
done:
xmlFreeDoc(doc);
}
static gboolean
load_event (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gchar *data)
{
if (event->button != 1)
return FALSE;
pause_board(TRUE);
gc_selector_file_load(gcomprisBoard,
"wordprocessor",
".xhtml",
load_buffer, NULL);
return FALSE;
}