1
/* gcompris - wordprocessor.c
3
* Copyright (C) 2006, 2008 Bruno Coudoin
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, see <http://www.gnu.org/licenses/>.
20
#include <glib/gstdio.h>
21
#include <libxml/HTMLparser.h>
23
#include "gcompris/gcompris.h"
33
GtkJustification justification;
35
gint pixels_above_lines;
36
gint pixels_below_lines;
39
#define NUMBER_OF_STYLE 4 /* h1 h2 h3 p */
41
static GtkTextTag *tag_list[NUMBER_OF_STYLE];
49
style_t style[NUMBER_OF_STYLE];
52
doctype_t type_normal =
54
.name = N_("Research"),
56
{ "h1", "Serif 30", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
57
{ "h2", "Serif 26", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
58
{ "h3", "Serif 20", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
59
{ "p", "Serif 16", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
63
doctype_t type_letter =
65
.name = N_("Sentimental"),
67
{ "h1", "Serif 26", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
68
{ "h2", "Serif 20", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
69
{ "h3", "Serif 16", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 10, 20, 12 },
70
{ "p", "Serif 14", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
74
doctype_t type_small =
76
.name = N_("Official"),
78
{ "h1", "Serif 18", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
79
{ "h2", "Serif 16", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
80
{ "h3", "Serif 14", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 10, 20, 12 },
81
{ "p", "Serif 12", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
89
{ "h1", "Serif 12", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
90
{ "h2", "Serif 12", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
91
{ "h3", "Serif 12", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
92
{ "p", "Serif 12", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
100
{ "h1", "Serif 34", PANGO_WEIGHT_ULTRABOLD, GTK_JUSTIFY_CENTER, 0, 40, 20 },
101
{ "h2", "Serif 30", PANGO_WEIGHT_BOLD, GTK_JUSTIFY_LEFT, 0, 30, 15 },
102
{ "h3", "Serif 26", PANGO_WEIGHT_SEMIBOLD, GTK_JUSTIFY_LEFT, 15, 20, 12 },
103
{ "p", "Serif 18", PANGO_WEIGHT_NORMAL, GTK_JUSTIFY_LEFT, 30, 3, 3 }
106
#define NUMBER_OF_DOCTYPE 5
107
static doctype_t *doctype_list[NUMBER_OF_DOCTYPE];
112
#define NUMBER_OF_COLOR_STYLE 4
113
static gchar *color_style_list[NUMBER_OF_COLOR_STYLE][NUMBER_OF_STYLE+1] =
115
{N_("Spring"), "red", "blue", "lightblue", "black"},
116
{N_("Summer"), "DeepPink", "HotPink", "MediumOrchid", "black"},
117
{N_("Autumn"), "blue", "red", "lightblue", "black"},
118
{N_("Winter"), "black", "black", "black", "black"},
121
static GcomprisBoard *gcomprisBoard = NULL;
122
static gboolean board_paused = TRUE;
123
static GtkWidget *gtk_combo_styles = NULL;
124
static GtkWidget *gtk_combo_colors = NULL;
125
static GtkWidget *gtk_button_style[NUMBER_OF_STYLE];
126
static GtkWidget *sw = NULL;
128
static void start_board (GcomprisBoard *agcomprisBoard);
129
static void pause_board (gboolean pause);
130
static void end_board (void);
131
static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
132
static void set_level (guint level);
133
static gboolean key_release_event (GtkWidget *text_view,
136
static GooCanvasItem *boardRootItem = NULL;
138
static GooCanvasItem *wordprocessor_create(void);
139
static void wordprocessor_destroy_all_items(void);
140
static void item_event(GtkWidget *item, gchar *data);
141
static int display_style_buttons(GooCanvasItem *boardRootItem,
144
static void create_tags (GtkTextBuffer *buffer, doctype_t *doctype);
145
static void set_default_tag (GtkTextBuffer *buffer, GtkTextTag *tag);
146
static void display_style_selector(GooCanvasItem *boardRootItem, double y);
147
static void display_color_style_selector(GooCanvasItem *boardRootItem, double y);
148
static void item_event_style_selection (GtkComboBox *widget, void *data);
149
static void item_event_color_style_selection (GtkComboBox *widget, void *data);
150
static gboolean save_event (GooCanvasItem *item,
151
GooCanvasItem *target,
152
GdkEventButton *event,
154
static gboolean load_event (GooCanvasItem *item,
155
GooCanvasItem *target,
156
GdkEventButton *event,
158
static int get_style_index(gchar *style);
159
static int get_style_current_index();
160
static gint get_color_style_index(gchar *color_style);
161
static gint get_color_style_current_index();
162
static GtkTextTag *get_tag_from_name(gchar *name);
163
static void apply_style(int style_index);
164
static void apply_color_style(int style_index);
166
#define word_area_x1 120
167
#define word_area_y1 20
168
#define word_area_width 650
169
#define word_area_height 485
171
#define combo_style_x1 5
172
#define combo_style_width 105
174
static GtkTextBuffer *buffer;
175
static GtkWidget *view;
176
GtkTextTag *selected_tag;
178
/* Description of this plugin */
179
static BoardPlugin menu_bp =
184
"A basic word processor",
185
"Bruno Coudoin <bruno.coudoin@free.fr>",
204
* Main entry point mandatory for each Gcompris's game
205
* ---------------------------------------------------
209
GET_BPLUGIN_INFO(wordprocessor)
212
* in : boolean TRUE = PAUSE : FALSE = CONTINUE
215
static void pause_board (gboolean pause)
219
if(gcomprisBoard==NULL)
222
/* Widgets don't like being overlapped */
225
gtk_widget_hide(GTK_WIDGET(sw));
226
gtk_widget_hide(GTK_WIDGET(gtk_combo_styles));
227
gtk_widget_hide(GTK_WIDGET(gtk_combo_colors));
228
for(i=0; i<NUMBER_OF_STYLE; i++)
229
gtk_widget_hide(gtk_button_style[i]);
233
gtk_widget_show(GTK_WIDGET(sw));
234
gtk_widget_show(GTK_WIDGET(gtk_combo_styles));
235
gtk_widget_show(GTK_WIDGET(gtk_combo_colors));
236
for(i=0; i<NUMBER_OF_STYLE; i++)
237
gtk_widget_show(gtk_button_style[i]);
240
board_paused = pause;
245
static void start_board (GcomprisBoard *agcomprisBoard)
248
if(agcomprisBoard!=NULL)
250
gcomprisBoard=agcomprisBoard;
251
gcomprisBoard->level=1;
252
gcomprisBoard->maxlevel=1;
253
gcomprisBoard->sublevel=1;
254
gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
256
gc_bar_location(10, -1, 0.6);
258
gc_set_default_background(goo_canvas_get_root_item(gcomprisBoard->canvas));
260
wordprocessor_create();
266
/* ======================================= */
267
static void end_board ()
269
if(gcomprisBoard!=NULL)
272
wordprocessor_destroy_all_items();
274
gcomprisBoard = NULL;
277
/* ======================================= */
278
static void set_level (guint level)
281
/* ======================================= */
282
static gboolean is_our_board (GcomprisBoard *gcomprisBoard)
286
if(g_strcasecmp(gcomprisBoard->type, "wordprocessor")==0)
288
/* Set the plugin entry */
289
gcomprisBoard->plugin=&menu_bp;
297
/*-------------------------------------------------------------------------------*/
298
/*-------------------------------------------------------------------------------*/
299
/* ==================================== */
300
/* Destroy all the items */
301
static void wordprocessor_destroy_all_items()
303
if(boardRootItem!=NULL)
304
goo_canvas_item_remove(boardRootItem);
306
boardRootItem = NULL;
308
/* ==================================== */
309
static GooCanvasItem *wordprocessor_create()
311
GooCanvasItem *item = NULL;
315
boardRootItem = goo_canvas_group_new (goo_canvas_get_root_item(gcomprisBoard->canvas),
320
view = gtk_text_view_new ();
321
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
322
/* Change left margin throughout the widget */
323
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 1);
324
g_signal_connect (view, "key-release-event",
325
G_CALLBACK (key_release_event), NULL);
327
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
330
sw = gtk_scrolled_window_new (NULL, NULL);
331
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
332
GTK_POLICY_AUTOMATIC,
334
gtk_container_add (GTK_CONTAINER (sw), view);
336
item = goo_canvas_widget_new (boardRootItem,
342
"anchor", GTK_ANCHOR_NW,
344
gtk_widget_show(GTK_WIDGET(view));
345
gtk_widget_show(GTK_WIDGET(sw));
348
* Create the default style tags
350
doctype_list[0] = &type_text;
351
doctype_list[1] = &type_normal;
352
doctype_list[2] = &type_letter;
353
doctype_list[3] = &type_small;
354
doctype_list[4] = &type_big;
360
pixmap = gc_pixmap_load("wordprocessor/tool-save.png");
362
goo_canvas_image_new (boardRootItem,
367
gdk_pixbuf_unref(pixmap);
368
g_signal_connect(item, "button_press_event",
369
(GtkSignalFunc) save_event, buffer);
370
gc_item_focus_init(item, NULL);
376
pixmap = gc_pixmap_load("wordprocessor/tool-load.png");
378
goo_canvas_image_new (boardRootItem,
383
gdk_pixbuf_unref(pixmap);
384
g_signal_connect(item, "button_press_event",
385
(GtkSignalFunc) load_event, buffer);
386
gc_item_focus_init(item, NULL);
391
* Display the style buttons
393
y = display_style_buttons(boardRootItem,
398
display_style_selector(boardRootItem, y);
401
display_color_style_selector(boardRootItem, y);
403
/* Now we can create the tags */
404
create_tags(buffer, doctype_list[0]);
406
gtk_widget_grab_focus(view);
412
* Display the style buttons
414
* \return the new y coordinate
417
display_style_buttons(GooCanvasItem *boardRootItem,
423
static gchar *styles_tab[] = { N_("Title"), "h1",
424
N_("Heading 1"), "h2",
425
N_("Heading 2"), "h3",
429
while(styles_tab[i*2])
431
gtk_button_style[i] = gtk_button_new_with_label(gettext(styles_tab[i*2]));
433
goo_canvas_widget_new (boardRootItem,
434
GTK_WIDGET(gtk_button_style[i]),
439
"anchor", GTK_ANCHOR_NW,
442
g_signal_connect(GTK_OBJECT(gtk_button_style[i]), "pressed",
443
(GtkSignalFunc)item_event, styles_tab[i*2+1] );
453
/* \brief callback on a style button (h1, h2, h3, p)
458
item_event(GtkWidget *button, gchar *data)
460
GtkTextIter iter_start, iter_end;
461
gchar *current_style_name;
466
current_style_name = (char *)data;
468
selected_tag = get_tag_from_name(current_style_name);
469
set_default_tag(buffer, selected_tag);
471
gtk_text_buffer_get_iter_at_mark(buffer,
473
gtk_text_buffer_get_insert (buffer));
474
gtk_text_iter_set_line_offset(&iter_start, 0);
476
iter_end = iter_start;
477
gtk_text_iter_forward_to_line_end(&iter_end);
479
gtk_text_buffer_remove_all_tags(buffer,
483
gtk_text_buffer_apply_tag_by_name(buffer,
488
gtk_widget_grab_focus(view);
493
/* Create a bunch of tags. Note that it's also possible to
494
* create tags with gtk_text_tag_new() then add them to the
495
* tag table for the buffer, gtk_text_buffer_create_tag() is
496
* just a convenience function. Also note that you don't have
497
* to give tags a name; pass NULL for the name to create an
500
* In any real app, another useful optimization would be to create
501
* a GtkTextTagTable in advance, and reuse the same tag table for
502
* all the buffers with the same tag set, instead of creating
503
* new copies of the same tags for every buffer.
505
* Tags are assigned default priorities in order of addition to the
506
* tag table. That is, tags created later that affect the same text
507
* property affected by an earlier tag will override the earlier
508
* tag. You can modify tag priorities with
509
* gtk_text_tag_set_priority().
513
create_tags (GtkTextBuffer *buffer, doctype_t *doctype)
516
gint c = get_color_style_current_index();
518
for(i=0; i<NUMBER_OF_STYLE; i++)
522
tag = gtk_text_buffer_create_tag (buffer, doctype->style[i].name,
523
"weight", doctype->style[i].weight,
524
"font", doctype->style[i].font,
525
"justification", doctype->style[i].justification,
526
"left-margin", doctype->style[i].left_margin,
527
"pixels-above-lines", doctype->style[i].pixels_above_lines,
528
"pixels-below-lines", doctype->style[i].pixels_below_lines,
529
"foreground",color_style_list[c][i+1],
532
g_object_set_data (G_OBJECT (tag), "style", &doctype->style[i]);
535
/* Point to the last style */
538
set_default_tag(buffer, tag_list[i]);
542
* Set the default style
545
set_default_tag (GtkTextBuffer *buffer, GtkTextTag *tag)
547
PangoFontDescription *font_desc;
548
GdkColor *color = (GdkColor *)g_malloc(sizeof(GdkColor));
550
GtkJustification justification;
555
g_object_get (G_OBJECT (tag), "foreground-gdk", &color, NULL);
556
g_object_get (G_OBJECT (tag), "font-desc", &font_desc, NULL);
558
gtk_widget_modify_font (view, font_desc);
559
gtk_widget_modify_text (view, GTK_STATE_NORMAL, color);
561
g_object_get (G_OBJECT (tag), "left-margin", &val, NULL);
562
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), val);
564
g_object_get (G_OBJECT (tag), "justification", &justification, NULL);
565
gtk_text_view_set_justification(GTK_TEXT_VIEW (view), justification);
567
g_object_get (G_OBJECT (tag), "pixels-below-lines", &val, NULL);
568
gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW (view), val);
570
g_object_get (G_OBJECT (tag), "pixels-above-lines", &val, NULL);
571
gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW (view), val);
575
get_tag_from_name(gchar *tag_name)
579
for(i=0; i<NUMBER_OF_STYLE; i++)
582
g_object_get(G_OBJECT (tag_list[i]), "name", &name, NULL);
583
if(strcmp(name, tag_name)==0)
587
return(tag_list[i-1]);
591
* Create the combo with the styles
592
* --------------------------------
595
display_style_selector(GooCanvasItem *boardRootItem, double y)
599
gtk_combo_styles = gtk_combo_box_new_text();
601
while (i < NUMBER_OF_DOCTYPE)
602
gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_combo_styles),
603
gettext(doctype_list[i++]->name));
605
goo_canvas_widget_new (boardRootItem,
606
GTK_WIDGET(gtk_combo_styles),
611
"anchor", GTK_ANCHOR_NW,
614
gtk_widget_show(GTK_WIDGET(gtk_combo_styles));
615
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_styles), 0);
617
g_signal_connect(G_OBJECT(gtk_combo_styles),
619
G_CALLBACK(item_event_style_selection),
624
* Create the combo with the color styles
625
* --------------------------------------
628
display_color_style_selector(GooCanvasItem *boardRootItem, double y)
632
gtk_combo_colors = gtk_combo_box_new_text();
634
while (i < NUMBER_OF_COLOR_STYLE)
635
gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_combo_colors),
636
gettext(color_style_list[i++][0]));
638
goo_canvas_widget_new (boardRootItem,
639
GTK_WIDGET(gtk_combo_colors),
644
"anchor", GTK_ANCHOR_NW,
647
gtk_widget_show(GTK_WIDGET(gtk_combo_colors));
648
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_colors), 0);
650
g_signal_connect(G_OBJECT(gtk_combo_colors),
652
G_CALLBACK(item_event_color_style_selection),
657
get_style_index(gchar *style)
661
/* Search the doctype */
662
for(i=0; i<NUMBER_OF_DOCTYPE; i++)
663
if(strcmp(gettext(doctype_list[i]->name), style)==0)
670
get_style_current_index()
672
return( get_style_index(gtk_combo_box_get_active_text(GTK_COMBO_BOX(gtk_combo_styles))) );
676
apply_style(int style_index)
681
for(j=0; j<NUMBER_OF_STYLE; j++)
683
g_object_set(tag_list[j],
684
"weight", doctype_list[i]->style[j].weight,
685
"font", doctype_list[i]->style[j].font,
686
"justification", doctype_list[i]->style[j].justification,
687
"left-margin", doctype_list[i]->style[j].left_margin,
688
"pixels-above-lines", doctype_list[i]->style[j].pixels_above_lines,
689
"pixels-below-lines", doctype_list[i]->style[j].pixels_below_lines,
694
/* Set a new style from the combo box selection
698
item_event_style_selection (GtkComboBox *widget,
702
apply_style(get_style_current_index());
704
gtk_widget_grab_focus(view);
708
get_color_style_index(gchar *color_style)
712
/* Search the color style */
713
for(i=0; i<NUMBER_OF_COLOR_STYLE; i++)
714
if(strcmp(gettext(color_style_list[i][0]), color_style)==0)
721
get_color_style_current_index()
723
return( get_color_style_index(gtk_combo_box_get_active_text(GTK_COMBO_BOX(gtk_combo_colors))) );
727
apply_color_style(int color_style_index)
729
int i = color_style_index;
732
/* Change the color */
733
for(j=0; j<NUMBER_OF_STYLE; j++)
734
g_object_set(tag_list[j],
735
"foreground",color_style_list[i][j+1],
739
/* Set a new color style from the combo box selection
743
item_event_color_style_selection (GtkComboBox *widget,
746
apply_color_style(get_color_style_current_index());
747
gtk_widget_grab_focus(view);
751
/* Catch all typing events to apply the proper tags
755
key_release_event (GtkWidget *text_view,
758
GtkTextIter iter_start, iter_end;
759
GtkTextBuffer *buffer;
762
GSList *tags = NULL, *tagp = NULL;
764
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
766
gtk_text_buffer_get_iter_at_mark(buffer,
768
gtk_text_buffer_get_insert (buffer));
769
gtk_text_iter_set_line_offset(&iter_start, 0);
771
iter_end = iter_start;
772
gtk_text_iter_forward_to_line_end(&iter_end);
774
tags = gtk_text_iter_get_tags (&iter_start);
776
if(g_slist_length(tags) == 0)
778
gtk_text_iter_backward_char (&iter_end);
779
tags = gtk_text_iter_get_tags (&iter_end);
780
gtk_text_iter_forward_char (&iter_end);
783
for (tagp = tags; tagp != NULL; tagp = tagp->next)
785
GtkTextTag *tag = tagp->data;
787
g_object_get (G_OBJECT (tag), "name", &name, NULL);
789
set_default_tag(buffer, tag);
790
gtk_text_buffer_apply_tag_by_name(buffer,
802
/* Set the default style */
805
set_default_tag(buffer, selected_tag);
807
gtk_text_buffer_apply_tag(buffer,
814
set_default_tag(buffer, tag_list[NUMBER_OF_STYLE-1]);
816
gtk_text_buffer_apply_tag(buffer,
817
tag_list[NUMBER_OF_STYLE-1],
827
// assumes UTF-8 or UTF-16 as encoding,
831
gsize size = strlen(input)*6; /* 6 is the most increase we can get */
832
gchar *result = g_malloc(size);
838
for(i = 0; i < strlen(input); i++)
842
o = g_strlcat(result, "<", size);
844
o = g_strlcat(result, ">", size);
846
o = g_strlcat(result, "&", size);
848
o = g_strlcat(result, """, size);
850
o = g_strlcat(result, "'", size);
862
save_buffer(gchar *file, gchar *file_type, void *unused)
864
GtkTextIter iter_start, iter_end;
865
GSList *tags = NULL, *tagp = NULL;
868
int style_index = get_style_current_index();
869
int color_index = get_color_style_current_index();
871
filefd = g_fopen(file, "w+");
877
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
878
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
879
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
881
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
882
"<meta http-equiv=\"GCompris-doctype\" content=\"%s\" />\n"
883
"<meta http-equiv=\"GCompris-color-style\" content=\"%s\" />\n"
884
"<title>GCompris</title>\n",
885
doctype_list[style_index]->name,
886
color_style_list[color_index][0]);
892
"<style type=\"text/css\">\n");
896
int font_size[NUMBER_OF_STYLE] = { 28, 22, 16, 12 };
897
char *align[NUMBER_OF_STYLE] = { "center", "left", "left", "justify" };
898
int left_margin[NUMBER_OF_STYLE] = { 0, 10, 20, 30 };
900
for(i=0; i<NUMBER_OF_STYLE; i++)
902
style_t style = doctype_list[style_index]->style[i];
906
" font-size : %dpx;\n"
907
" text-align : %s;\n"
908
" margin-left : %dpx;\n"
911
color_style_list[color_index][i+1],
928
gtk_text_buffer_get_iter_at_offset(buffer,
934
iter_end = iter_start;
935
gtk_text_iter_forward_to_line_end(&iter_end);
937
if(gtk_text_iter_ends_line(&iter_start))
940
tags = gtk_text_iter_get_tags (&iter_start);
941
if(g_slist_length(tags) == 0)
943
gtk_text_iter_backward_char (&iter_end);
944
tags = gtk_text_iter_get_tags (&iter_end);
945
gtk_text_iter_forward_char (&iter_end);
949
for (tagp = tags; tagp != NULL; tagp = tagp->next)
951
GtkTextTag *tag = tagp->data;
952
g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
955
fprintf(filefd, "<%s>", tag_name);
957
char *result = escape(gtk_text_buffer_get_text(buffer,
962
for (tagp = tags; tagp != NULL; tagp = tagp->next)
964
GtkTextTag *tag = tagp->data;
965
g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
968
fprintf(filefd, "%s</%s>\n", result, tag_name);
974
} while(gtk_text_iter_forward_line(&iter_start));
990
save_event (GooCanvasItem *item,
991
GooCanvasItem *target,
992
GdkEventButton *event,
995
if (event->button != 1)
1000
gc_selector_file_save(gcomprisBoard,
1009
load_buffer(gchar *file, gchar *file_type, void *unused)
1011
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
1014
GtkTextIter iter_start, iter_end;
1016
/* parse the new file and put the result into newdoc */
1017
doc = xmlParseFile(file);
1019
/* in case something went wrong */
1023
/* Get the root element node */
1024
node = xmlDocGetRootElement(doc);
1026
for(node = node; node != NULL; node = node->next)
1027
if ( g_strcasecmp((char *)node->name, "html") == 0 &&
1034
for(node = node->children; node != NULL; node = node->next)
1036
if ( g_strcasecmp((char *)node->name, "head") == 0 &&
1039
/* Search and apply the saved style in the META */
1041
for(snode = node->children; snode != NULL; snode = snode->next)
1043
if ( ( g_strcasecmp((char *)snode->name, "meta") == 0 ) &&
1044
xmlHasProp(snode, BAD_CAST "http-equiv") )
1046
xmlChar *key = xmlGetProp(snode, BAD_CAST "http-equiv");
1047
xmlChar *content = xmlGetProp(snode, BAD_CAST "content");
1049
if(g_strcasecmp((char *)key, "GCompris-doctype") == 0)
1051
int style_index = get_style_index(gettext((char *)content));
1052
apply_style(style_index);
1053
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_styles),
1057
if(g_strcasecmp((char *)key, "GCompris-color-style") == 0)
1059
int cstyle_index = get_color_style_index(gettext((char *)content));
1060
apply_color_style(cstyle_index);
1061
gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_colors),
1071
if ( g_strcasecmp((char *)node->name, "body") == 0 &&
1079
gtk_text_buffer_get_start_iter(buffer,
1081
gtk_text_buffer_get_end_iter(buffer,
1083
gtk_text_buffer_delete(buffer,
1087
gtk_text_buffer_get_start_iter(buffer,
1090
for(node = node->children; node != NULL; node = node->next)
1093
if ( g_strcasecmp((char *)node->name, "h1") == 0 ||
1094
g_strcasecmp((char *)node->name, "h2") == 0 ||
1095
g_strcasecmp((char *)node->name, "h3") == 0 ||
1096
g_strcasecmp((char *)node->name, "p") == 0 )
1099
content = xmlNodeGetContent(node);
1100
gtk_text_buffer_insert_with_tags_by_name(buffer,
1103
strlen((char *)content),
1107
gtk_text_buffer_get_end_iter(buffer,
1109
gtk_text_buffer_insert(buffer,&iter_start, "\n", 1);
1111
gtk_text_buffer_get_end_iter(buffer,
1123
load_event (GooCanvasItem *item,
1124
GooCanvasItem *target,
1125
GdkEventButton *event,
1128
if (event->button != 1)
1133
gc_selector_file_load(gcomprisBoard,