Back to index

gcompris  8.2.2
wordprocessor.c
Go to the documentation of this file.
00001 /* gcompris - wordprocessor.c
00002  *
00003  * Copyright (C) 2006 Bruno Coudoin
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include <string.h>
00021 
00022 #include "gcompris/gcompris.h"
00023 
00024 /*
00025  * Predefined styles
00026  * -----------------
00027  */
00028 typedef struct {
00029   gchar *name;
00030   gchar *font;
00031   PangoWeight weight;
00032   GtkJustification justification;
00033   gint indent;
00034   gint pixels_above_lines;
00035   gint pixels_below_lines;
00036 } style_t;
00037 
00038 #define NUMBER_OF_STYLE 4
00039 
00040 static GtkTextTag *tag_list[NUMBER_OF_STYLE];
00041 
00042 
00043 /*
00044  * The document styles
00045  */
00046 typedef struct {
00047   gchar *name;
00048   style_t style[NUMBER_OF_STYLE];
00049 } doctype_t;
00050 
00051 doctype_t type_normal =
00052   {
00053     .name = N_("Default"),
00054     .style = {
00055       { "H0", "Serif 30", PANGO_WEIGHT_ULTRABOLD,  GTK_JUSTIFY_CENTER, 0,  40, 20 },
00056       { "H1", "Serif 26", PANGO_WEIGHT_BOLD,       GTK_JUSTIFY_LEFT,   0,  30, 15 },
00057       { "H2", "Serif 20", PANGO_WEIGHT_SEMIBOLD,   GTK_JUSTIFY_LEFT,   0,  20, 12 },
00058       { "P",  "Serif 16", PANGO_WEIGHT_NORMAL,     GTK_JUSTIFY_LEFT,   30, 3,  3 }
00059     }
00060   };
00061 
00062 doctype_t type_letter =
00063   {
00064     .name = N_("Letter"),
00065     .style = {
00066       { "H0", "Serif 26", PANGO_WEIGHT_ULTRABOLD,  GTK_JUSTIFY_CENTER, 0,  40, 20 },
00067       { "H1", "Serif 20", PANGO_WEIGHT_BOLD,       GTK_JUSTIFY_LEFT,   0,  30, 15 },
00068       { "H2", "Serif 16", PANGO_WEIGHT_SEMIBOLD,   GTK_JUSTIFY_LEFT,   0,  20, 12 },
00069       { "P",  "Serif 14", PANGO_WEIGHT_NORMAL,     GTK_JUSTIFY_LEFT,   30, 3,  3 }
00070     },
00071   };
00072 
00073 doctype_t type_small =
00074   {
00075     .name = N_("Small"),
00076     .style = {
00077       { "H0", "Serif 18", PANGO_WEIGHT_ULTRABOLD,  GTK_JUSTIFY_CENTER, 0,  40, 20 },
00078       { "H1", "Serif 16", PANGO_WEIGHT_BOLD,       GTK_JUSTIFY_LEFT,   0,  30, 15 },
00079       { "H2", "Serif 14", PANGO_WEIGHT_SEMIBOLD,   GTK_JUSTIFY_LEFT,   0,  20, 12 },
00080       { "P",  "Serif 12", PANGO_WEIGHT_NORMAL,     GTK_JUSTIFY_LEFT,   30, 3,  3 }
00081     },
00082   };
00083 
00084 doctype_t type_text =
00085   {
00086     .name = N_("Text"),
00087     .style = {
00088       { "H0", "Serif 12", PANGO_WEIGHT_ULTRABOLD,  GTK_JUSTIFY_CENTER, 0,  40, 20 },
00089       { "H1", "Serif 12", PANGO_WEIGHT_BOLD,       GTK_JUSTIFY_LEFT,   0,  30, 15 },
00090       { "H2", "Serif 12", PANGO_WEIGHT_SEMIBOLD,   GTK_JUSTIFY_LEFT,   0,  20, 12 },
00091       { "P",  "Serif 12", PANGO_WEIGHT_NORMAL,     GTK_JUSTIFY_LEFT,   30, 3,  3 }
00092     },
00093   };
00094 
00095 doctype_t type_big =
00096   {
00097     .name = N_("Big"),
00098     .style = {
00099       { "H0", "Serif 34", PANGO_WEIGHT_ULTRABOLD,  GTK_JUSTIFY_CENTER, 0,  40, 20 },
00100       { "H1", "Serif 30", PANGO_WEIGHT_BOLD,       GTK_JUSTIFY_LEFT,   0,  30, 15 },
00101       { "H2", "Serif 26", PANGO_WEIGHT_SEMIBOLD,   GTK_JUSTIFY_LEFT,   0,  20, 12 },
00102       { "P",  "Serif 18", PANGO_WEIGHT_NORMAL,     GTK_JUSTIFY_LEFT,   30, 3,  3 }
00103     },
00104   };
00105 #define NUMBER_OF_DOCTYPE 5
00106 static doctype_t *doctype_list[NUMBER_OF_DOCTYPE];
00107 
00108 /*
00109  * The color styles
00110  */
00111 #define NUMBER_OF_COLOR_STYLE 4
00112 static gchar *color_style_list[NUMBER_OF_COLOR_STYLE][NUMBER_OF_STYLE+1] =
00113 {
00114   {N_("Black"), "black",  "black",  "black",  "black"},
00115   {N_("Red"), "red",  "blue",  "light blue",  "black"},
00116   {N_("Blue"), "blue",  "red",  "light blue",  "black"},
00117   {N_("Pink"), "DeepPink",  "HotPink",  "MediumOrchid",  "black"},
00118 };
00119 
00120 static GcomprisBoard *gcomprisBoard = NULL;
00121 static gboolean              board_paused = TRUE;
00122 static GtkWidget     *gtk_combo_filetypes = NULL;
00123 
00124 static void    start_board (GcomprisBoard *agcomprisBoard);
00125 static void    pause_board (gboolean pause);
00126 static void    end_board (void);
00127 static gboolean       is_our_board (GcomprisBoard *gcomprisBoard);
00128 static void    set_level (guint level);
00129 static gboolean  key_press_event (GtkWidget *text_view,
00130                               GdkEventKey *event);
00131 
00132 static GnomeCanvasGroup *boardRootItem = NULL;
00133 
00134 static GnomeCanvasItem      *wordprocessor_create(void);
00135 static void           wordprocessor_destroy_all_items(void);
00136 static gint           item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
00137 static void           display_style_buttons(GnomeCanvasGroup *boardRootItem,
00138                                           int x,
00139                                           int y);
00140 static void           create_tags (GtkTextBuffer *buffer, doctype_t *doctype);
00141 static void           set_default_style (GtkTextBuffer *buffer, style_t *style);
00142 static void           display_style_selector(GnomeCanvasGroup *boardRootItem);
00143 static void           display_color_style_selector(GnomeCanvasGroup *boardRootItem);
00144 static void           item_event_style_selection (GtkComboBox *widget, void *data);
00145 static void           item_event_color_style_selection (GtkComboBox *widget, void *data);
00146 
00147 #define word_area_x1 120
00148 #define word_area_y1 80
00149 #define word_area_width 580
00150 #define word_area_height 420
00151 
00152 #define combo_style_x1 300
00153 #define combo_style_y1 20
00154 #define combo_style_width 200
00155 
00156 #define combo_color_style_x1 500
00157 #define combo_color_style_y1 20
00158 #define combo_color_style_width 200
00159 
00160 static style_t *current_style_default;
00161 static doctype_t *current_doctype_default;
00162 static GtkTextBuffer *buffer;
00163 static GtkWidget *view;
00164 
00165 /* Description of this plugin */
00166 static BoardPlugin menu_bp =
00167   {
00168     NULL,
00169     NULL,
00170     "Wordprocessor",
00171     "A basic word processor",
00172     "Bruno Coudoin <bruno.coudoin@free.fr>",
00173     NULL,
00174     NULL,
00175     NULL,
00176     NULL,
00177     start_board,
00178     pause_board,
00179     end_board,
00180     is_our_board,
00181     NULL,
00182     NULL,
00183     set_level,
00184     NULL,
00185     NULL,
00186     NULL,
00187     NULL
00188   };
00189 
00190 /*
00191  * Main entry point mandatory for each Gcompris's game
00192  * ---------------------------------------------------
00193  *
00194  */
00195 
00196 GET_BPLUGIN_INFO(wordprocessor)
00197 
00198 /*
00199  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00200  *
00201  */
00202 static void pause_board (gboolean pause)
00203 {
00204   if(gcomprisBoard==NULL)
00205     return;
00206 
00207   board_paused = pause;
00208 }
00209 
00210 /*
00211  */
00212 static void start_board (GcomprisBoard *agcomprisBoard)
00213 {
00214 
00215   if(agcomprisBoard!=NULL)
00216     {
00217       gchar *img;
00218 
00219       gcomprisBoard=agcomprisBoard;
00220       gcomprisBoard->level=1;
00221       gcomprisBoard->maxlevel=1;
00222       gcomprisBoard->sublevel=1;
00223       gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
00224       gc_bar_set(0);
00225 
00226       img = gc_skin_image_get("gcompris-shapebg.jpg");
00227       gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
00228                            img);
00229       g_free(img);
00230 
00231       wordprocessor_create();
00232 
00233       pause_board(FALSE);
00234 
00235     }
00236 }
00237 /* ======================================= */
00238 static void end_board ()
00239 {
00240   if(gcomprisBoard!=NULL)
00241     {
00242       pause_board(TRUE);
00243       wordprocessor_destroy_all_items();
00244     }
00245   gcomprisBoard = NULL;
00246 }
00247 
00248 /* ======================================= */
00249 static void set_level (guint level)
00250 {
00251 }
00252 /* ======================================= */
00253 static gboolean is_our_board (GcomprisBoard *gcomprisBoard)
00254 {
00255   if (gcomprisBoard)
00256     {
00257       if(g_strcasecmp(gcomprisBoard->type, "wordprocessor")==0)
00258        {
00259          /* Set the plugin entry */
00260          gcomprisBoard->plugin=&menu_bp;
00261 
00262          return TRUE;
00263        }
00264     }
00265   return FALSE;
00266 }
00267 
00268 /*-------------------------------------------------------------------------------*/
00269 /*-------------------------------------------------------------------------------*/
00270 /* ==================================== */
00271 /* Destroy all the items */
00272 static void wordprocessor_destroy_all_items()
00273 {
00274   if(boardRootItem!=NULL)
00275     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00276 
00277   boardRootItem = NULL;
00278 }
00279 /* ==================================== */
00280 static GnomeCanvasItem *wordprocessor_create()
00281 {
00282   GnomeCanvasItem *item = NULL;
00283   GtkWidget *sw;
00284 
00285   boardRootItem = GNOME_CANVAS_GROUP(
00286                                  gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00287                                                      gnome_canvas_group_get_type (),
00288                                                      "x", (double) 0,
00289                                                      "y", (double) 0,
00290                                                      NULL));
00291 
00292   view = gtk_text_view_new ();
00293   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
00294   g_signal_connect (view, "key-release-event",
00295                   G_CALLBACK (key_press_event), NULL);
00296 
00297   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
00298 
00299 
00300   sw = gtk_scrolled_window_new (NULL, NULL);
00301   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
00302                               GTK_POLICY_AUTOMATIC,
00303                               GTK_POLICY_ALWAYS);
00304   gtk_container_add (GTK_CONTAINER (sw), view);
00305 
00306   item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(boardRootItem),
00307                             gnome_canvas_widget_get_type (),
00308                             "widget", GTK_WIDGET(sw),
00309                             "x", (double) word_area_x1,
00310                             "y", (double) word_area_y1,
00311                             "width", (double) word_area_width,
00312                             "height", (double) word_area_height,
00313                             "anchor", GTK_ANCHOR_NW,
00314                             "size_pixels", FALSE,
00315                             NULL);
00316   gtk_widget_show(GTK_WIDGET(view));
00317   gtk_widget_show(GTK_WIDGET(sw));
00318 
00319   /*
00320    * Create the default style tags
00321    */
00322   doctype_list[0] = &type_normal;
00323   doctype_list[1] = &type_letter;
00324   doctype_list[2] = &type_small;
00325   doctype_list[3] = &type_text;
00326   doctype_list[4] = &type_big;
00327 
00328   current_doctype_default = doctype_list[0];
00329   create_tags(buffer, current_doctype_default);
00330 
00331   /*
00332    * Display the style buttons
00333    */
00334   display_style_buttons(boardRootItem,
00335                      word_area_x1 + word_area_width + 10,
00336                      word_area_y1);
00337 
00338   display_style_selector(boardRootItem);
00339   display_color_style_selector(boardRootItem);
00340 
00341   return NULL;
00342 }
00343 
00344 /*
00345  * Display the style buttons
00346  */
00347 static void display_style_buttons(GnomeCanvasGroup *boardRootItem,
00348                               int x,
00349                               int y)
00350 {
00351   GdkPixbuf *pixmap;
00352   int offset_y, text_x, text_y;
00353   int i = 0;
00354   gchar *styles_tab[] = { _("TITLE"), "H0",
00355                        _("TITLE 1"), "H1",
00356                        _( "TITLE 2"), "H2",
00357                        _("TEXT"), "P",
00358                        NULL, NULL };
00359 
00360   pixmap = gc_skin_pixmap_load("button_small.png");
00361 
00362   offset_y = gdk_pixbuf_get_height(pixmap) + 10;
00363   text_x   = gdk_pixbuf_get_width(pixmap) / 2;
00364   text_y   = gdk_pixbuf_get_height(pixmap) / 2;
00365 
00366   while(styles_tab[i])
00367     {
00368       GnomeCanvasItem *item;
00369 
00370       item = gnome_canvas_item_new (boardRootItem,
00371                                 gnome_canvas_pixbuf_get_type (),
00372                                 "pixbuf", pixmap,
00373                                 "x", (double) x,
00374                                 "y", (double) y,
00375                                 "anchor", GTK_ANCHOR_NW,
00376                                 NULL);
00377 
00378       gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event, styles_tab[i+1] );
00379       gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) gc_item_focus_event, NULL);
00380 
00381       item = gnome_canvas_item_new (boardRootItem,
00382                                 gnome_canvas_text_get_type (),
00383                                 "text", styles_tab[i],
00384                                 "font", gc_skin_font_board_medium,
00385                                 "x", (double) x + text_x + 1,
00386                                 "y", (double) y + text_y + 1,
00387                                 "anchor", GTK_ANCHOR_CENTER,
00388                                 "fill_color_rgba", gc_skin_color_shadow,
00389                                 NULL);
00390       gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event, styles_tab[i+1] );
00391 
00392       item = gnome_canvas_item_new (boardRootItem,
00393                                 gnome_canvas_text_get_type (),
00394                                 "text", styles_tab[i],
00395                                 "font", gc_skin_font_board_medium,
00396                                 "x", (double) x + text_x,
00397                                 "y", (double) y + text_y,
00398                                 "anchor", GTK_ANCHOR_CENTER,
00399                                 "fill_color_rgba", gc_skin_color_text_button,
00400                                 NULL);
00401       gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event, styles_tab[i+1] );
00402 
00403       y += offset_y;
00404 
00405       i += 2;
00406     }
00407 
00408   gdk_pixbuf_unref(pixmap);
00409 }
00410 
00411 /* ==================================== */
00412 
00413 /* ==================================== */
00414 static gint
00415 item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
00416 {
00417 
00418   if(board_paused)
00419     return FALSE;
00420 
00421   switch (event->type)
00422     {
00423     case GDK_BUTTON_PRESS:
00424       switch(event->button.button)
00425        {
00426        case 1:
00427        case 2:
00428        case 3:
00429          {
00430            GtkTextIter    iter_start, iter_end;
00431            gchar *current_style_name;
00432 
00433            current_style_name = (char *)data;
00434 
00435            gtk_text_buffer_get_iter_at_mark(buffer,
00436                                         &iter_start,
00437                                         gtk_text_buffer_get_insert (buffer));
00438            gtk_text_iter_set_line_offset(&iter_start, 0);
00439 
00440            iter_end = iter_start;
00441            gtk_text_iter_forward_to_line_end(&iter_end);
00442 
00443            gtk_text_buffer_remove_all_tags(buffer,
00444                                        &iter_start,
00445                                        &iter_end);
00446 
00447            gtk_text_buffer_apply_tag_by_name(buffer,
00448                                          current_style_name,
00449                                          &iter_start,
00450                                          &iter_end);
00451          }
00452          break;
00453        default:
00454          break;
00455        }
00456     default:
00457       break;
00458     }
00459 
00460   return FALSE;
00461 }
00462 
00463 /* Create a bunch of tags. Note that it's also possible to
00464  * create tags with gtk_text_tag_new() then add them to the
00465  * tag table for the buffer, gtk_text_buffer_create_tag() is
00466  * just a convenience function. Also note that you don't have
00467  * to give tags a name; pass NULL for the name to create an
00468  * anonymous tag.
00469  *
00470  * In any real app, another useful optimization would be to create
00471  * a GtkTextTagTable in advance, and reuse the same tag table for
00472  * all the buffers with the same tag set, instead of creating
00473  * new copies of the same tags for every buffer.
00474  *
00475  * Tags are assigned default priorities in order of addition to the
00476  * tag table.  That is, tags created later that affect the same text
00477  * property affected by an earlier tag will override the earlier
00478  * tag.  You can modify tag priorities with
00479  * gtk_text_tag_set_priority().
00480  */
00481 
00482 static void
00483 create_tags (GtkTextBuffer *buffer, doctype_t *doctype)
00484 {
00485   gint i;
00486 
00487   for(i=0; i<NUMBER_OF_STYLE; i++)
00488     {
00489       GtkTextTag *tag;
00490 
00491       tag = gtk_text_buffer_create_tag (buffer, doctype->style[i].name,
00492                                    "weight", doctype->style[i].weight,
00493                                    "font", doctype->style[i].font,
00494                                    "justification", doctype->style[i].justification,
00495                                    "indent", doctype->style[i].indent,
00496                                    "pixels-above-lines", doctype->style[i].pixels_above_lines,
00497                                    "pixels-below-lines", doctype->style[i].pixels_below_lines,
00498                                    NULL);
00499       tag_list[i] = tag;
00500       g_object_set_data (G_OBJECT (tag), "style", &doctype->style[i]);
00501     }
00502 
00503   /* Point to the last style */
00504   i--;
00505 
00506   current_style_default = &doctype->style[i];
00507   set_default_style(buffer, current_style_default);
00508 }
00509 
00510 /*
00511  * Set the default style
00512  */
00513 static void
00514 set_default_style (GtkTextBuffer *buffer, style_t *style)
00515 {
00516   PangoFontDescription *font_desc;
00517   GdkColor color;
00518 
00519   printf("set_default_style %s\n", style->name);
00520   /* Change default font throughout the widget */
00521   font_desc = pango_font_description_from_string (style->font);
00522   gtk_widget_modify_font (view, font_desc);
00523   pango_font_description_free (font_desc);
00524 
00525   /* Change default color throughout the widget */
00526   gdk_color_parse ("black", &color);
00527   gtk_widget_modify_text (view, GTK_STATE_NORMAL, &color);
00528 
00529   /* Change left margin, justification, ... throughout the widget */
00530   gtk_text_view_set_indent (GTK_TEXT_VIEW (view), style->indent);
00531   gtk_text_view_set_justification(GTK_TEXT_VIEW (view), style->justification);
00532   gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW (view), style->pixels_below_lines);
00533   gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW (view), style->pixels_above_lines);
00534 }
00535 
00536 
00537 /*
00538  * Create the combo with the styles
00539  * --------------------------------
00540  */
00541 static void
00542 display_style_selector(GnomeCanvasGroup *boardRootItem)
00543 {
00544   int i = 0;
00545 
00546   gtk_combo_filetypes = gtk_combo_box_new_text();
00547 
00548   while (i < NUMBER_OF_DOCTYPE)
00549     gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_combo_filetypes), doctype_list[i++]->name);
00550 
00551   gnome_canvas_item_new (GNOME_CANVAS_GROUP(boardRootItem),
00552                       gnome_canvas_widget_get_type (),
00553                       "widget", GTK_WIDGET(gtk_combo_filetypes),
00554                       "x", (double) combo_style_x1,
00555                       "y", (double) combo_style_y1,
00556                       "width", (double) combo_style_width,
00557                       "height", 35.0,
00558                       "anchor", GTK_ANCHOR_NW,
00559                       "size_pixels", FALSE,
00560                       NULL);
00561 
00562   gtk_widget_show(GTK_WIDGET(gtk_combo_filetypes));
00563   gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_filetypes), 0);
00564 
00565   g_signal_connect(G_OBJECT(gtk_combo_filetypes),
00566                  "changed",
00567                  G_CALLBACK(item_event_style_selection),
00568                  NULL);
00569 }
00570 
00571 /*
00572  * Create the combo with the color styles
00573  * --------------------------------------
00574  */
00575 static void
00576 display_color_style_selector(GnomeCanvasGroup *boardRootItem)
00577 {
00578   int i = 0;
00579 
00580   gtk_combo_filetypes = gtk_combo_box_new_text();
00581 
00582   while (i < NUMBER_OF_COLOR_STYLE)
00583     gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_combo_filetypes), color_style_list[i++][0]);
00584 
00585   gnome_canvas_item_new (GNOME_CANVAS_GROUP(boardRootItem),
00586                       gnome_canvas_widget_get_type (),
00587                       "widget", GTK_WIDGET(gtk_combo_filetypes),
00588                       "x", (double) combo_color_style_x1,
00589                       "y", (double) combo_color_style_y1,
00590                       "width", (double) combo_color_style_width,
00591                       "height", 35.0,
00592                       "anchor", GTK_ANCHOR_NW,
00593                       "size_pixels", FALSE,
00594                       NULL);
00595 
00596   gtk_widget_show(GTK_WIDGET(gtk_combo_filetypes));
00597   gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_combo_filetypes), 0);
00598 
00599   g_signal_connect(G_OBJECT(gtk_combo_filetypes),
00600                  "changed",
00601                  G_CALLBACK(item_event_color_style_selection),
00602                  NULL);
00603 }
00604 
00605 static void tag_style_set(int i, doctype_t *doctype)
00606 {
00607   printf("Setting style %s tag %s\n", doctype->name, doctype->style[i].name);
00608   g_object_set(tag_list[i],
00609               "weight", doctype->style[i].weight,
00610               "font", doctype->style[i].font,
00611               "justification", doctype->style[i].justification,
00612               "indent", doctype->style[i].indent,
00613               "pixels-above-lines", doctype->style[i].pixels_above_lines,
00614               "pixels-below-lines", doctype->style[i].pixels_below_lines,
00615               NULL);
00616 }
00617 
00618 /* Set a new style from the combo box selection
00619  *
00620  */
00621 static void
00622 item_event_style_selection (GtkComboBox *widget,
00623                          void *data)
00624 {
00625   gchar *style_str;
00626   int i;
00627 
00628   style_str = gtk_combo_box_get_active_text((GtkComboBox *)widget);
00629 
00630   printf("item_event_style_selection %s\n", style_str);
00631   /* Search the doctype */
00632   for(i=0; i<NUMBER_OF_DOCTYPE; i++)
00633     {
00634       printf("  trying i=%d  %s\n", i, doctype_list[i]->name);
00635       if(strcmp(doctype_list[i]->name, style_str)==0)
00636        {
00637          /* Change the tag */
00638          int j = 0;
00639 
00640          for(j=0; j<NUMBER_OF_STYLE; j++)
00641            {
00642              tag_style_set(j, doctype_list[i]);
00643            }
00644 
00645          break;
00646        }
00647     }
00648 
00649 }
00650 
00651 
00652 /* Set a new color style from the combo box selection
00653  *
00654  */
00655 static void
00656 item_event_color_style_selection (GtkComboBox *widget,
00657                               void *data)
00658 {
00659   gchar *style_str;
00660   int i;
00661 
00662   style_str = gtk_combo_box_get_active_text((GtkComboBox *)widget);
00663 
00664   printf("item_event_color_style_selection %s\n", style_str);
00665   /* Search the doctype */
00666   for(i=0; i<NUMBER_OF_COLOR_STYLE; i++)
00667     {
00668       printf("  trying i=%d  %s\n", i, color_style_list[i][0]);
00669       if(strcmp(color_style_list[i][0], style_str)==0)
00670        {
00671          int j;
00672          /* Change the color */
00673          for(j=0; j<NUMBER_OF_STYLE; j++)
00674            g_object_set(tag_list[j],
00675                       "foreground",color_style_list[i][j+1],
00676                       NULL);
00677          break;
00678        }
00679     }
00680 
00681 }
00682 
00683 
00684 /* Catch all typing events to apply the proper tags
00685  *
00686  */
00687 static gboolean
00688 key_press_event (GtkWidget *text_view,
00689                GdkEventKey *event)
00690 {
00691   GtkTextIter iter_start, iter_end;
00692   GtkTextBuffer *buffer;
00693 
00694   {
00695     GSList *tags = NULL, *tagp = NULL;
00696 
00697     buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
00698 
00699     gtk_text_buffer_get_iter_at_mark(buffer,
00700                                  &iter_start,
00701                                  gtk_text_buffer_get_insert (buffer));
00702     gtk_text_iter_set_line_offset(&iter_start, 0);
00703 
00704     iter_end = iter_start;
00705     gtk_text_iter_forward_to_line_end(&iter_end);
00706 
00707     tags = gtk_text_iter_get_tags (&iter_start);
00708     printf("length %d\n", g_slist_length(tags));
00709     if(g_slist_length(tags) == 0)
00710       {
00711        gtk_text_iter_backward_char (&iter_end);
00712        tags = gtk_text_iter_get_tags (&iter_end);
00713        gtk_text_iter_forward_char (&iter_end);
00714        printf("2 length %d\n", g_slist_length(tags));
00715       }
00716 
00717     for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
00718       {
00719        GtkTextTag *tag = tagp->data;
00720        gchar *name;
00721        g_object_get (G_OBJECT (tag), "name", &name, NULL);
00722        style_t *style = g_object_get_data (G_OBJECT (tag), "style");
00723 
00724        printf("name=%s  style=%s\n", name, style->name);
00725        set_default_style(buffer, style);
00726        gtk_text_buffer_apply_tag_by_name(buffer,
00727                                      name,
00728                                      &iter_start,
00729                                      &iter_end);
00730       }
00731 
00732     if (tags)
00733       g_slist_free (tags);
00734     else
00735       {
00736        /* Set the default style */
00737        set_default_style(buffer, current_style_default);
00738        gtk_text_buffer_apply_tag_by_name(buffer,
00739                                      current_style_default->name,
00740                                      &iter_start,
00741                                      &iter_end);
00742       }
00743   }
00744 
00745   return FALSE;
00746 }
00747