Logo Search packages:      
Sourcecode: scigraphica version File versions  Download package

sg_project_file_sax.c

/*  SciGraphica - Scientific graphics and data manipulation
 *  Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gtkextra/gtkextra.h>
#include <parser.h>
#include "sg_project_file_sax.h"
#include "sg.h"
#include "sg_dialogs.h"
#include "sg_layer.h"
#include "sg_dataset.h"

#ifdef WITH_WARNINGS
#warning Temporary Hack to avoid the numerous type mismatches
#warning between CHAR and gchar. All CHAR have been replaced by
#warning XCHAR, which equals gchar in the next typedef. - Rob -
#endif
typedef gchar XCHAR;

typedef enum {
      PARSE_WORKSHEET,
      PARSE_PLOT,
      PARSE_PROJECT,
} SGparseObject;

typedef enum {
      PARSER_IN_WORKSHEET,
      PARSER_IN_PLOT,
      PARSER_IN_PAGE,
      PARSER_IN_LAYER,
      PARSER_IN_FRAME,
      PARSER_IN_CORNER,
      PARSER_IN_AXIS,
      PARSER_IN_TITLE,
      PARSER_IN_VMAJOR,
      PARSER_IN_VMINOR,
      PARSER_IN_HMAJOR,
      PARSER_IN_HMINOR,
      PARSER_IN_MAJOR,
      PARSER_IN_MINOR,
      PARSER_IN_X0,
      PARSER_IN_Y0,
      PARSER_IN_LEGENDS,
      PARSER_IN_DATA,
      PARSER_IN_XLINE,
      PARSER_IN_YLINE,
      PARSER_IN_ZLINE,
      PARSER_IN_POINTS,
        PARSER_IN_CHILD,
        PARSER_IN_PIXMAP,
        PARSER_IN_BG_PIXMAP,
        PARSER_IN_COLOR,
        PARSER_UNKNOWN,
} SGparserState;

typedef struct _sgParseState sgParseState;
struct _sgParseState {
  XCHAR *name;
  GString *content;

  SGparseObject object;

  SGparserState state;
  SGparserState prev_state;

  gint num_layers;

  gint last_worksheet;
  gint last_matrix;
  gint last_plot;
  gint last_dataset;
  gint last_function;
  gint last_expression;

  gboolean in_text;

  SGworksheet *worksheet;
  gint row, col;
  
  SGlayerType layer_type;

  SGplot *plot;
  SGlayer *layer;
  SGdataset *dataset;
  gboolean visible;
  GtkPlotText text;
  GtkPlotCanvasChild child;
  GtkPlotLine line;

  GtkPlotCanvasLine arrow;
  GtkPlotCanvasRectangle rectangle;
  GtkPlotCanvasEllipse ellipse;
  GdkWindow *window;
  GdkImage *image;
  gint px, py;
  gint pwidth, pheight;
  gchar color_str[5];
  gint img_char;
  GdkGC *gc;
  GdkColorContext *cc;

  GtkPlotAxisPos axis;
  gdouble tick_value;

  gulong *pixels;
  gint ncolors;
};

static gint powers[4] = {1, 16, 256, 4096};

static void sgWarning                     (sgParseState *state, 
                                     const char *msg, ...);
static void sgError                       (sgParseState *state, 
                                     const char *msg, ...);
static void sgFatalError                  (sgParseState *state, 
                                     const char *msg, ...);
static void sgStartDocument               (sgParseState *state);
static void sgEndDocument                 (sgParseState *state);
static void sgCharacters                  (sgParseState *state, 
                                     const XCHAR *chars,
                                                 int len); 
static void sgStartElement                (sgParseState *state, 
                                     const XCHAR *name, 
                                     const XCHAR **attrs);
static void sgEndElement                  (sgParseState *state, 
                                     const XCHAR *name); 

static const XCHAR *get_real_name         (const XCHAR *name);
static SGdataset *find_data               (const gchar *name);
static SGdataset *find_function                 (const gchar *name, 
                                     const gchar *exp);


static xmlSAXHandler sgSAXParser = {
  0, /* internal Subset */
  0, /* isStandalone */
  0, /* hasInternalSubset */
  0, /* hasExternalSubset */
  0, /* resolveEntity */
  0, /* getEntity */
  0, /* entityDecl */
  0, /* notationDecl */
  0, /* attributeDecl */
  0, /* elementDecl */
  0, /* unparseEntityDecl */
  0, /* setDocumentLocator */
  (startDocumentSAXFunc)sgStartDocument, /* startDocument */
  (endDocumentSAXFunc)sgEndDocument, /* endDocument */
  (startElementSAXFunc)sgStartElement, /* startElement */
  (endElementSAXFunc)sgEndElement, /* endElement */
  0, /* reference */
  (charactersSAXFunc)sgCharacters, /*characters */
  0, /* ignorableWhitespace */
  0, /* processingInstruction */
  (commentSAXFunc)0, /* comment */
  (warningSAXFunc)sgWarning, /* warning */
  (errorSAXFunc)sgError, /* error */
  (fatalErrorSAXFunc)sgFatalError, /* fatalError */
};

static void  
sgWarning(sgParseState *state, const char *msg, ...)
{
  va_list args;

  va_start(args, msg);
  g_logv("XML", G_LOG_LEVEL_WARNING, msg, args);
  va_end(args);
}

static void  
sgError(sgParseState *state, const char *msg, ...)
{
  va_list args;

  va_start(args, msg);
  g_logv("XML", G_LOG_LEVEL_CRITICAL, msg, args);
  va_end(args);
}

static void  
sgFatalError(sgParseState *state, const char *msg, ...)
{
  va_list args;

  va_start(args, msg);
  g_logv("XML", G_LOG_LEVEL_ERROR, msg, args);
  va_end(args);
}

static void
sgStartDocument(sgParseState *state)
{
  state->name = NULL;
  state->content = g_string_sized_new(128);

  state->state = PARSER_UNKNOWN;
  state->prev_state = PARSER_UNKNOWN;
}

static void
sgEndDocument(sgParseState *state)
{
  GList *list;

  if(state->text.text)
     g_free(state->text.text);

  if(state->text.font)
   g_free(state->text.font);

  if(state->name)
   g_free(state->name);

  if(state->content)
   g_string_free(state->content, TRUE);

  if(state->pixels)
   g_free(state->pixels);

  if(state->last_plot >= 0) 
      last_plot = state->last_plot;
  else
      last_plot = num_plots;

  if(state->last_worksheet >= 0) 
      last_worksheet = state->last_worksheet;
  else
      last_worksheet = num_worksheets;

  if(state->last_matrix >= 0) 
      last_matrix = state->last_matrix;

  if(state->last_dataset >= 0) 
      last_dataset = state->last_dataset;

  if(state->last_function >= 0) 
      last_function = state->last_function;
  else
      last_function = num_functions;

  if(state->last_dataset >= 0) 
      last_expression = state->last_expression;
  else
      last_expression = num_expressions;

  gdk_gc_unref(state->gc);
  gdk_color_context_free(state->cc);
  gdk_window_unref(state->window);

  list = worksheets;
  while (list && list->data)
  {   
      sg_worksheet_update_exp_all(SG_WORKSHEET(list->data));
      list = list->next;
  }
  list = plots;
  while(list){
    GList *aux;

    aux = SG_PLOT(list->data)->layers;
    while(aux){
      sg_layer_refresh_datasets(SG_LAYER(aux->data));
      aux = aux->next;
    }
    gtk_plot_canvas_paint(GTK_PLOT_CANVAS(SG_PLOT(list->data)->real_canvas));
    gtk_plot_canvas_refresh(GTK_PLOT_CANVAS(SG_PLOT(list->data)->real_canvas));
    list = list->next;
  }
}

static void
sgCharacters(sgParseState *state, const XCHAR *chars, int len)
{
  gint i, n;

  if(state->state == PARSER_IN_PIXMAP || state->state == PARSER_IN_BG_PIXMAP){
     GdkColor color; 
     gint index;

     for(i = 0; i < len; i++){

       if((chars[i] >= '0' && chars[i] <= '9')||(chars[i] >= 'A' && chars[i] <= 'F')){
         state->color_str[state->img_char++] = chars[i];

         if(state->img_char == 4){
           gchar *s;

           state->img_char = 0;
       
           s = state->color_str;
           index = 0;
           for(n = 0; n < 4; n++){
             gint value;
             if(*s <= '9') 
               value = *s - '0';
             else
               value = *s - 'A' + 10;
         
             index += powers[3 - n] * value; 
             s++;
           } 

           color.pixel = state->pixels[index];
           gdk_image_put_pixel(state->image, state->px, state->py, color.pixel);

           state->px++;
           if(state->px == state->pwidth){
              state->py++;
              state->px = 0;
           }
         }
       }
     }
  }
  else
  {
    for(i = 0; i < len; i++){
      g_string_append_c(state->content, chars[i]);    
    }
  }
}

static void
sgStartElement(sgParseState *state, const XCHAR *real_name, const XCHAR **attrs)
{
  SGplot *plot = state->plot;
  GtkPlot *real_plot = NULL;
  GtkPlotCanvas *canvas = NULL;
  GtkSheet *sheet = NULL;
  const XCHAR **aux = attrs;
  const XCHAR *child = NULL, *value = NULL;
  const XCHAR *name;

  name = get_real_name(real_name);

/*
  fprintf(stderr,"%s\n", name);
*/

  if(state->plot) {
    canvas = GTK_PLOT_CANVAS(state->plot->real_canvas);
  }

  if(state->worksheet) {
    sheet = GTK_SHEET(state->worksheet->sheet);
  }

  state->name = g_strdup(real_name);
  state->content = g_string_truncate(state->content, 0);

  if(state->layer) real_plot = GTK_PLOT(state->layer->real_plot);

  if(strcmp(name, "Environment") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "LastWorksheet") == 0) 
                               state->last_worksheet = atoi(value);
        if(strcmp(child, "LastMatrix") == 0) 
                               state->last_matrix = atoi(value);
        if(strcmp(child, "LastPlot") == 0) 
                               state->last_plot = atoi(value);
        if(strcmp(child, "LastDataset") == 0) 
                               state->last_dataset = atoi(value);
        if(strcmp(child, "LastFunction") == 0) 
                               state->last_function = atoi(value);
        if(strcmp(child, "LastExpression") == 0) 
                               state->last_expression = atoi(value);
     }
  }

  if(strcmp(name, "Worksheet") == 0){
     state->prev_state = state->state;
     state->state = PARSER_IN_WORKSHEET;

     state->row = 0;
     state->col = 0;

     state->plot = NULL;
     state->layer = NULL;

     if(state->object == PARSE_PROJECT){
         state->worksheet = sg_project_new_worksheet();
         sheet = GTK_SHEET(state->worksheet->sheet);
     }
  }

  if(strcmp(name, "Matrix") == 0){
     state->prev_state = state->state;
     state->state = PARSER_IN_WORKSHEET;

     state->row = 0;
     state->col = 0;

     state->plot = NULL;
     state->layer = NULL;

     if(state->object == PARSE_PROJECT){
         state->worksheet = sg_project_new_matrix();
         sheet = GTK_SHEET(state->worksheet->sheet);
     }
  }

  if(strcmp(name, "Range") == 0 && state->state == PARSER_IN_WORKSHEET){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Xmin") == 0) state->worksheet->xmin = atof(value);
        if(strcmp(child, "Xmax") == 0) state->worksheet->xmax = atof(value);
        if(strcmp(child, "Ymin") == 0) state->worksheet->ymin = atof(value);
        if(strcmp(child, "Ymax") == 0) state->worksheet->ymax = atof(value);
     }
  }

  if(strcmp(name, "MatrixFormat") == 0 && state->state == PARSER_IN_WORKSHEET){
     SGcolumntype type = SG_TYPE_NUMBER;
     SGcolumnformat format = SG_FORMAT_DECIMAL;
     SGcolumninternal internal = SG_INTERNAL_DOUBLE;
     gint precision = 3;
     gchar *exp = NULL;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Exp") == 0) exp = (gchar *)value;
        if(strcmp(child, "Internal") == 0) internal = (SGcolumninternal)atoi(value);
        if(strcmp(child, "Format") == 0) format = (SGcolumnformat)atoi(value);
        if(strcmp(child, "Precision") == 0 ||
           strcmp(child, "Presicion") == 0) precision = atoi(value);
     }

     sg_worksheet_matrix_set_exp(state->worksheet, exp);
     state->worksheet->matrix.type = type;
     state->worksheet->matrix.format = format;
     state->worksheet->matrix.internal = internal;
     state->worksheet->matrix.precision = precision;
  }

  if(state->state == PARSER_IN_WORKSHEET && strcmp(name, "Cell") == 0){
  }

  if(strcmp(name, "Plot") == 0){
     state->prev_state = state->state;
     state->state = PARSER_IN_PLOT;
     state->in_text = FALSE;

     state->worksheet = NULL;
     if(state->object == PARSE_PROJECT){
         state->plot = sg_project_new_plot();
         canvas = GTK_PLOT_CANVAS(state->plot->real_canvas);
     }
  }

  if(strcmp(name, "Function") == 0){
     const gchar *name = NULL;
     const gchar *exp = NULL;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Name") == 0) name = value;
        if(strcmp(child, "Exp") == 0) exp = value;
     }

     if(exp && name){
         SGdataset *dataset;
         dataset = sg_project_new_function((gchar *)exp);
         sg_dataset_set_name(dataset, (gchar *)name);
     }
       
  }

  if(strcmp(name, "Text") == 0){
     state->in_text = TRUE;
  }

  if(strcmp(name, "Child") == 0){
     state->state = PARSER_IN_CHILD;
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "X1") == 0) state->child.rx1 = atof(value);
        if(strcmp(child, "Y1") == 0) state->child.ry1 = atof(value);
        if(strcmp(child, "X2") == 0) state->child.rx2 = atof(value);
        if(strcmp(child, "Y2") == 0) state->child.ry2 = atof(value);
        if(strcmp(child, "Type") == 0) state->child.type = (GtkPlotCanvasType)atoi(value);
        if(strcmp(child, "Flags") == 0) state->child.flags = (GtkPlotCanvasFlag)atoi(value);
     }
  }

  if(strcmp(name, "XPMColor") == 0){
     state->state = PARSER_IN_COLOR;
  }


  if(strcmp(name, "Rectangle") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Fill") == 0) state->rectangle.filled = atoi(value);
        if(strcmp(child, "Border") == 0) state->rectangle.border = (GtkPlotBorderStyle)atoi(value);
        if(strcmp(child, "Shadow") == 0) state->rectangle.shadow_width = atoi(value);
        if(strcmp(child, "R") == 0) state->rectangle.bg.red = atoi(value);
        if(strcmp(child, "G") == 0) state->rectangle.bg.green = atoi(value);
        if(strcmp(child, "B") == 0) state->rectangle.bg.blue = atoi(value);
     }
  }

  if(strcmp(name, "Ellipse") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Fill") == 0) state->ellipse.filled = atoi(value);
        if(strcmp(child, "R") == 0) state->ellipse.bg.red = atoi(value);
        if(strcmp(child, "G") == 0) state->ellipse.bg.green = atoi(value);
        if(strcmp(child, "B") == 0) state->ellipse.bg.blue = atoi(value);
     }
  }

  if(strcmp(name, "Pixels") == 0){
     if(state->state == PARSER_IN_CHILD)
       state->state = PARSER_IN_PIXMAP;
     else
       state->state = PARSER_IN_BG_PIXMAP;
  }

  if(strcmp(name, "Pixmap") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Width") == 0) state->pwidth = atoi(value);
        if(strcmp(child, "Height") == 0) state->pheight = atoi(value);
     }
     state->px = state->py = 0;
     state->img_char = 0;
     state->image = gdk_image_new(GDK_IMAGE_FASTEST, 
                                  gdk_visual_get_system(),
                                  state->pwidth, state->pheight);
  }
 

  if(strcmp(name, "Arrow") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Mask") == 0) state->arrow.arrow_mask = (GtkPlotCanvasArrow)atoi(value);
        if(strcmp(child, "Length") == 0) state->arrow.arrow_length = atoi(value);
        if(strcmp(child, "Width") == 0) state->arrow.arrow_width = atoi(value);
        if(strcmp(child, "Style") == 0) state->arrow.arrow_style = (GtkPlotSymbolStyle)atoi(value);
     }
  }


  if(state->state != PARSER_IN_LAYER && strcmp(name, "Geometry") == 0){
     gint width = 400;
     gint height = 350;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Width") == 0) width = atoi(value); 
        if(strcmp(child, "Height") == 0) height = atoi(value); 
     }

     if(state->state == PARSER_IN_PLOT){
       state->plot->width = width; 
       state->plot->height = height; 
       if(state->plot->is_mapped)
             gtk_window_set_default_size(GTK_WINDOW(plot), width, height);
     }

     if(state->state == PARSER_IN_WORKSHEET){
       state->worksheet->width = width;
       state->worksheet->height = height;
       if(state->worksheet->is_mapped)
            gtk_window_set_default_size(GTK_WINDOW(state->worksheet), width, height);
     }

  }

  if(state->state == PARSER_IN_WORKSHEET && strcmp(name, "Column") == 0){
     gint ncol = 0;
     gint width = 80;
     const gchar *title = NULL;
     SGcolumntype type = SG_TYPE_NONE;
     SGcolumnformat format = SG_FORMAT_DECIMAL;
     SGcolumninternal internal = SG_INTERNAL_DOUBLE;
     gint precision = 3;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Width") == 0) width = atoi(value);
        if(strcmp(child, "No") == 0) ncol = atoi(value);
        if(strcmp(child, "Title") == 0) title = value;
        if(strcmp(child, "Type") == 0) type = (SGcolumntype)atoi(value);
        if(strcmp(child, "Internal") == 0) internal = (SGcolumninternal)atoi(value);
        if(strcmp(child, "Format") == 0) format = (SGcolumnformat)atoi(value);
        if(strcmp(child, "Precision") == 0 ||
           strcmp(child, "Presicion") == 0) precision = atoi(value);
     }
     gtk_sheet_set_column_width(sheet, ncol, width);
     gtk_sheet_set_column_title(sheet, ncol, title);
     gtk_sheet_column_button_add_label(sheet, ncol, title);

     if(type == SG_TYPE_NONE){ /* before 0.7 */
       type = (SGcolumntype)format;
       format = SG_FORMAT_DECIMAL;
     } 

     sg_worksheet_column_set_format(state->worksheet, ncol, type, format, internal, precision);
     state->col = ncol;
  }

  if(state->state == PARSER_IN_WORKSHEET && strcmp(name, "Cell") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Row") == 0) state->row = atoi(value);
        if(strcmp(child, "Col") == 0) state->col = atoi(value);
     }
  }


  if(strcmp(name, "Page") == 0){
     gint width = GTK_PLOT_LETTER_W;
     gint height = GTK_PLOT_LETTER_H;
     gint temp;
     gint orientation = GTK_PLOT_PORTRAIT;
     gint page_size = GTK_PLOT_LETTER;
     gdouble scale = .65;

     state->state = PARSER_IN_PAGE;
     state->in_text = FALSE;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Width") == 0) width = atoi(value); 
        if(strcmp(child, "Height") == 0) height = atoi(value);
        if(strcmp(child, "Orientation") == 0) orientation = atoi(value); 
        if(strcmp(child, "Size") == 0) page_size = atoi(value); 
        if(strcmp(child, "Scale") == 0) scale = atof(value); 
     }
     sg_plot_rescale(plot, scale);

     if (orientation==GTK_PLOT_LANDSCAPE){
         temp=width;
         width=height;
         height=temp;
     }
     sg_plot_set_size(plot, page_size, width, height, orientation);
  }

  if(strcmp(name, "Layer") == 0){
     state->prev_state = state->state;
     state->state = PARSER_IN_LAYER;
     state->in_text = FALSE;
     state->layer_type = SG_LAYER_2D;

     state->num_layers++;

     while(aux && *aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Type") == 0) state->layer_type = (SGlayerType)atoi(value); 
     }
  }

  if(state->layer && strcmp(name, "Autosymbols") == 0){
     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Type") == 0) state->layer->symbol = atoi(value); 
        if(strcmp(child, "Style") == 0) state->layer->symbol_style = atoi(value); 
        if(strcmp(child, "Line") == 0) state->layer->line_style = atoi(value); 
        if(strcmp(child, "Connector") == 0) state->layer->connector = atoi(value); 
     }
  }

  if(state->state == PARSER_IN_LAYER && strcmp(name, "Geometry") == 0){
     GList *list = NULL;
     gdouble x = .175;
     gdouble y = .15;
     gdouble width = .65;
     gdouble height = .45;
     GtkPlotScale xscale = GTK_PLOT_SCALE_LINEAR;
     GtkPlotScale yscale = GTK_PLOT_SCALE_LINEAR;
     gint num_plots = 0;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "X") == 0) x = atof(value); 
        if(strcmp(child, "Y") == 0) y = atof(value); 
        if(strcmp(child, "Width") == 0) width = atof(value); 
        if(strcmp(child, "Height") == 0) height = atof(value); 
        if(strcmp(child, "Xscale") == 0) xscale = (GtkPlotScale)atoi(value); 
        if(strcmp(child, "Yscale") == 0) yscale = (GtkPlotScale)atoi(value); 
     }

/*   This is to fix the bug in gtkplotcanvas in gtkextra-0.99.6 */
     list = canvas->plots;
     while(list){
         num_plots++;
         list = list->next;
     }
 
     if(state->num_layers <= num_plots){
       state->layer = (SGlayer*) g_list_nth_data(plot->layers, 
                                                 state->num_layers - 1);
       real_plot = GTK_PLOT(state->layer->real_plot);
       gtk_plot_move_resize(real_plot, 
                            x, y, width, height);
     }
     else
     {
       state->layer = sg_layer_new(state->layer_type, width, height);
       sg_plot_add_layer(plot, state->layer, x, y);
       real_plot = GTK_PLOT(state->layer->real_plot);
     }

     gtk_plot_set_xscale(real_plot, xscale);
     gtk_plot_set_yscale(real_plot, yscale);
  }

  if(state->state == PARSER_IN_LAYER){
    if(strcmp(name, "Frame") == 0){
      gdouble xfactor = 1.0, yfactor = 1.0, zfactor = 1.0;
      gint titles_offset;

      state->state = PARSER_IN_FRAME;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Titles") == 0) titles_offset = atoi(value); 
        if(strcmp(child, "Xfactor") == 0) xfactor = atof(value); 
        if(strcmp(child, "Yfactor") == 0) yfactor = atof(value); 
        if(strcmp(child, "Zfactor") == 0) zfactor = atof(value); 
      }

      if(GTK_IS_PLOT3D(real_plot)){
        GTK_PLOT3D(real_plot)->titles_offset = titles_offset;
        gtk_plot3d_set_xfactor(GTK_PLOT3D(real_plot), xfactor);
        gtk_plot3d_set_yfactor(GTK_PLOT3D(real_plot), yfactor);
        gtk_plot3d_set_xfactor(GTK_PLOT3D(real_plot), xfactor);
      }
    }

    if(strcmp(name, "Corner") == 0){
      gint visible = FALSE;

      state->state = PARSER_IN_CORNER;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) visible = atoi(value); 
      }

      if(GTK_IS_PLOT3D(real_plot))
        gtk_plot3d_corner_set_visible(GTK_PLOT3D(real_plot), visible);
    }

    if(strcmp(name, "Plane") == 0){
      GtkPlotPlane position = GTK_PLOT_PLANE_XY;
      gint visible = TRUE;
      GdkColor color;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Position") == 0) position = (GtkPlotPlane)atoi(value); 
        if(strcmp(child, "Visible") == 0) visible = atoi(value); 
        if(strcmp(child, "R") == 0) color.red = atoi(value); 
        if(strcmp(child, "G") == 0) color.green = atoi(value); 
        if(strcmp(child, "B") == 0) color.blue = atoi(value); 
      }
      gdk_color_alloc(gdk_colormap_get_system(), &color);

      if(GTK_IS_PLOT3D(real_plot)){
        gtk_plot3d_plane_set_color(GTK_PLOT3D(real_plot), position, &color);
        gtk_plot3d_plane_set_visible(GTK_PLOT3D(real_plot), position, visible);
      }
    }

    if(strcmp(name, "Range") == 0){
      gdouble xmin = 0.0;
      gdouble xmax = 1.0;
      gdouble ymin = 0.0;
      gdouble ymax = 1.0;
      gdouble zmin = 0.0;
      gdouble zmax = 1.0;
      gdouble rotation = 0.0;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Xmin") == 0) xmin = atof(value); 
        if(strcmp(child, "Xmax") == 0) xmax = atof(value); 
        if(strcmp(child, "Ymin") == 0) ymin = atof(value); 
        if(strcmp(child, "Ymax") == 0) ymax = atof(value); 
        if(strcmp(child, "Zmin") == 0) zmin = atof(value); 
        if(strcmp(child, "Zmax") == 0) zmax = atof(value); 
        if(strcmp(child, "Rotation") == 0) rotation = atof(value); 
      }

      if(GTK_IS_PLOT_POLAR(real_plot))
        gtk_plot_polar_rotate(GTK_PLOT_POLAR(real_plot), rotation);

      if(GTK_IS_PLOT3D(real_plot)){
        gtk_plot3d_set_xrange(GTK_PLOT3D(real_plot), xmin, xmax);
        gtk_plot3d_set_yrange(GTK_PLOT3D(real_plot), ymin, ymax);
        gtk_plot3d_set_zrange(GTK_PLOT3D(real_plot), zmin, zmax);
      }
      else 
        gtk_plot_set_range(real_plot, xmin, xmax, ymin, ymax);

    }


    if(strcmp(name, "Vmajor") == 0){ 

      state->state = PARSER_IN_VMAJOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) real_plot->bottom->show_major_grid = atoi(value); 
      }

    }

    if(strcmp(name, "Vminor") == 0){ 

      state->state = PARSER_IN_VMINOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) real_plot->bottom->show_minor_grid = atoi(value); 
      }

    }
    if(strcmp(name, "Hmajor") == 0){ 

      state->state = PARSER_IN_HMAJOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) real_plot->left->show_major_grid = atoi(value); 
      }

    }
    if(strcmp(name, "Hminor") == 0){ 

      state->state = PARSER_IN_HMINOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) real_plot->left->show_minor_grid = atoi(value); 
      }
    }

    if(strcmp(name, "X0") == 0){
      gint visible = FALSE;

      state->state = PARSER_IN_X0;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) visible = atoi(value);
      }
      gtk_plot_x0_set_visible(real_plot, visible);
    }

    if(strcmp(name, "Y0") == 0){
      gint visible = FALSE;

      state->state = PARSER_IN_Y0;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) visible = atoi(value);
      }
      gtk_plot_y0_set_visible(real_plot, visible);
    }

    if(strcmp(name, "Xticks") == 0 || strcmp(name, "Yticks") == 0){
      gdouble step = .1;
      gint nminor = 1;
      gboolean limits = FALSE;
      gdouble begin = 0.;
      gdouble end = 0.;
      GtkPlotOrientation orientation = GTK_PLOT_AXIS_X;

      if(strcmp(name, "Xticks") == 0)
        orientation = (GtkPlotOrientation)GTK_ORIENTATION_HORIZONTAL;
      else
        orientation = (GtkPlotOrientation)GTK_ORIENTATION_VERTICAL;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Step") == 0) step = atof(value); 
        if(strcmp(child, "Begin") == 0) begin = atof(value); 
        if(strcmp(child, "End") == 0) end = atof(value); 
        if(strcmp(child, "Nminor") == 0) nminor = atoi(value); 
        if(strcmp(child, "Limits") == 0) limits = atoi(value); 
      }

      gtk_plot_axis_set_ticks(real_plot, orientation, step, nminor);
      if(limits)
         gtk_plot_axis_set_ticks_limits(real_plot, orientation, begin, end);
      else
         gtk_plot_axis_unset_ticks_limits(real_plot, orientation); 
    }
  }

  if(state->state == PARSER_IN_LAYER && strcmp(name, "Side") == 0){
     GtkPlotSide side;
     gint major_mask, minor_mask, label_mask;
     gint title_visible = TRUE;

     state->in_text = FALSE;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Position") == 0) side = (GtkPlotSide)atoi(value); 
        if(strcmp(child, "Major") == 0) major_mask = atoi(value); 
        if(strcmp(child, "Minor") == 0) minor_mask = atoi(value);
        if(strcmp(child, "Labels") == 0) label_mask = atoi(value); 
        if(strcmp(child, "Title") == 0) title_visible = atoi(value); 
     }

     if(GTK_IS_PLOT3D(real_plot)){
       GtkPlotAxis *the_side;
       the_side = gtk_plot3d_get_side(GTK_PLOT3D(real_plot), side);

       the_side->major_mask = major_mask;
       the_side->minor_mask = minor_mask;
       the_side->label_mask = label_mask;
       the_side->title_visible = title_visible;
     }
  }
 
  if(state->state == PARSER_IN_LAYER && strcmp(name, "Axis") == 0){
     gdouble align = 0.;
     gboolean visible = TRUE;
     GtkPlotScale scale = GTK_PLOT_SCALE_LINEAR;
     GtkPlotAxis *the_axis;

     state->state = PARSER_IN_AXIS;
     state->in_text = FALSE;
     state->tick_value = 1.0;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Position") == 0){
           if(strcmp(value, "Top") == 0) state->axis = GTK_PLOT_AXIS_TOP; 
           if(strcmp(value, "Bottom") == 0) state->axis = GTK_PLOT_AXIS_BOTTOM; 
           if(strcmp(value, "Left") == 0) state->axis = GTK_PLOT_AXIS_LEFT; 
           if(strcmp(value, "Right") == 0) state->axis = GTK_PLOT_AXIS_RIGHT; 
        }
        if(strcmp(child, "Visible") == 0) visible = atoi(value);
        if(strcmp(child, "Scale") == 0) scale = (GtkPlotScale)atoi(value);
        if(strcmp(child, "Align") == 0) align = atof(value);
     }
   
     the_axis = gtk_plot_get_axis(real_plot, state->axis); 
     the_axis->scale = scale;
     gtk_plot_axis_set_visible(real_plot, state->axis, visible); 
     switch(state->axis){
       case GTK_PLOT_AXIS_TOP:
           real_plot->top_align = align;
           break;
       case GTK_PLOT_AXIS_BOTTOM:
           real_plot->bottom_align = align;
           break;
       case GTK_PLOT_AXIS_LEFT:
           real_plot->left_align = align;
           break;
       case GTK_PLOT_AXIS_RIGHT:
           real_plot->right_align = align;
           break;
     }
  }

  if(state->state == PARSER_IN_AXIS){
    GtkPlotAxis *the_axis;

    the_axis = gtk_plot_get_axis(real_plot, state->axis);

    if(strcmp(name, "Ticks") == 0){
      gint major_mask = 0;
      gint minor_mask = 0;
      gint length = 0;
      gfloat width = 0.0;
      gdouble step = .1;
      gint nminor = 1;
      gboolean limits = FALSE;
      gdouble begin = 0.;
      gdouble end = 0.;
      GtkPlotOrientation orientation;

      state->in_text = FALSE;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Major") == 0) major_mask = atoi(value); 
         if(strcmp(child, "Minor") == 0) minor_mask = atoi(value); 
         if(strcmp(child, "Length") == 0) length = atoi(value); 
         if(strcmp(child, "Width") == 0) width = atof(value); 
         if(strcmp(child, "Step") == 0) step = atof(value); 
         if(strcmp(child, "Begin") == 0) begin = atof(value); 
         if(strcmp(child, "End") == 0) end = atof(value); 
         if(strcmp(child, "Nminor") == 0) nminor = atoi(value); 
         if(strcmp(child, "Limits") == 0) limits = atoi(value); 
      }

      if(GTK_IS_PLOT3D(real_plot) && state->axis == GTK_PLOT_AXIS_RIGHT) return;

      orientation = the_axis->orientation;

      if(GTK_IS_PLOT3D(real_plot)){
        gtk_plot3d_axis_set_ticks(GTK_PLOT3D(real_plot), orientation, step, nminor);
        gtk_plot3d_axis_set_ticks_length(GTK_PLOT3D(real_plot), orientation, length);
        gtk_plot3d_axis_set_ticks_width(GTK_PLOT3D(real_plot), orientation, width);
      } else {
        gtk_plot_axis_show_ticks(real_plot, state->axis, major_mask, minor_mask);
        gtk_plot_axis_set_ticks(real_plot, orientation, step, nminor);
        gtk_plot_axis_set_ticks_length(real_plot, state->axis, length);
        gtk_plot_axis_set_ticks_width(real_plot, state->axis, width);
      }

      if(limits)
         gtk_plot_axis_set_ticks_limits(real_plot, the_axis->orientation, begin, end);
      else
         gtk_plot_axis_unset_ticks_limits(real_plot, the_axis->orientation); 
    }

    if(strcmp(name, "Title") == 0){
      gboolean visible = FALSE;

      state->state = PARSER_IN_TITLE;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) visible = atoi(value);
      }
      if(visible)
        gtk_plot_axis_show_title(real_plot, state->axis);
      else
        gtk_plot_axis_hide_title(real_plot, state->axis);
    }
   
    if(strcmp(name, "Labels") == 0){
      gint mask = 0;
      gint precision = 2;
      gint offset = 10;
      gint style = 0;
      gchar *prefix = NULL;
      gchar *suffix = NULL;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Mask") == 0) mask = atoi(value);
        if(strcmp(child, "Precision") == 0 ||
           strcmp(child, "Presicion") == 0) precision = atoi(value);
        if(strcmp(child, "Offset") == 0) offset = atoi(value);
        if(strcmp(child, "Style") == 0) style = atoi(value);
        if(strcmp(child, "Prefix") == 0) prefix = g_strdup(value);
        if(strcmp(child, "Suffix") == 0) suffix = g_strdup(value);
      }
      
      the_axis->labels_offset = offset;
      gtk_plot_axis_show_labels(real_plot, state->axis, mask);
      gtk_plot_axis_set_labels_numbers(real_plot, state->axis, 
                                       style, precision);
      if(prefix){
        gtk_plot_axis_set_labels_prefix(real_plot, state->axis, prefix);
        g_free(prefix);
      }
      if(suffix){
        gtk_plot_axis_set_labels_suffix(real_plot, state->axis, suffix);
        g_free(suffix);
      }
    }

    if(strcmp(name, "Minor") == 0){ 
      state->state = PARSER_IN_MINOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) the_axis->show_minor_grid = atoi(value); 
      }
    }

    if(strcmp(name, "Major") == 0){ 
      state->state = PARSER_IN_MAJOR;
      state->in_text = FALSE;

      while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) the_axis->show_major_grid = atoi(value); 
      }
    }

  }

  if(state->state == PARSER_IN_AXIS && strcmp(name, "Ticklabels") == 0){
    gchar *worksheet_name = NULL;
    gint values_column = -1;
    gint labels_column = -1;

    while(aux && *aux){
      child = *aux++;
      value = *aux++;
      if(strcmp(child, "Worksheet") == 0) worksheet_name = g_strdup(value);
      if(strcmp(child, "Labels") == 0) labels_column = atoi(value);
      if(strcmp(child, "Values") == 0) values_column = atoi(value);
    }

    if(worksheet_name){
      SGworksheet *labels_worksheet;

      labels_worksheet = sg_project_get_worksheet(worksheet_name);       

      if(labels_worksheet){ 
        sg_layer_set_tick_labels(state->layer, state->axis, labels_worksheet, 
                                 values_column, labels_column); 
      }

      g_free(worksheet_name);
    }
  }
 
  if(state->state == PARSER_IN_LAYER && strcmp(name, "Legends") == 0){
     gdouble x = 0.6;
     gdouble y = 0.6;
     gint width = 10;
     gint height = 10;
     gboolean visible = TRUE;

     state->state = PARSER_IN_LEGENDS;
     state->in_text = FALSE;

     while(*aux){
        child = *aux++;
        value = *aux++;
        if(strcmp(child, "Visible") == 0) visible = atoi(value);
        if(strcmp(child, "X") == 0) x = atof(value);
        if(strcmp(child, "Y") == 0) y = atof(value);
        if(strcmp(child, "Width") == 0) width = atoi(value);
        if(strcmp(child, "Height") == 0) height = atoi(value);
     }

     if(visible)
       gtk_plot_show_legends(real_plot);  
     else
       gtk_plot_hide_legends(real_plot);  
     gtk_plot_legends_move(real_plot, x, y); 
  } 
  
  if(strcmp(name, "Border") == 0){
    GtkPlotBorderStyle style = GTK_PLOT_BORDER_NONE;
    gint width = 0;
    gint shadow = 3;
    gint space = 2;

    while(*aux){
       child = *aux++;
       value = *aux++;
       if(strcmp(child, "Style") == 0) style = (GtkPlotBorderStyle)atoi(value); 
       if(strcmp(child, "Space") == 0) space = atoi(value); 
       if(strcmp(child, "Line") == 0) width = atoi(value); 
       if(strcmp(child, "Shadow") == 0) shadow = atoi(value); 
    }

    if(state->in_text){
        state->text.border = style; 
        state->text.border_space = space; 
        state->text.border_width = width;
        state->text.shadow_width = shadow; 
    } else {
        gtk_plot_set_legends_border(real_plot, style, shadow);
        real_plot->legends_border_width = width;
    }
  }

  if(strcmp(name, "Dataset") == 0){
    SGdataset *real_data = NULL;
    gboolean show_labels = TRUE, is_python = FALSE;
    gboolean show_gradient = FALSE;
    gboolean fill_area = FALSE;
    gint id = -1;
    GtkPlotConnector connector = GTK_PLOT_CONNECT_NONE;
    SGdataStyle style = SG_STYLE_LPOINTS;
    const gchar *name = NULL;
    const gchar *exp = NULL;

    state->prev_state = state->state;
    state->state = PARSER_IN_DATA;
    state->in_text = FALSE;
    state->visible = TRUE;

    while(aux && *aux){
       child = *aux++;
       value = *aux++;
       if(strcmp(child, "ID") == 0) id = atoi(value); 
       if(strcmp(child, "Type") == 0) style = (SGdataStyle)(atoi(value) - 2);/* before 0.7.2 */
       if(strcmp(child, "Style") == 0) style = (SGdataStyle)atoi(value); 
       if(strcmp(child, "Visible") == 0) state->visible = atoi(value); 
       if(strcmp(child, "Labels") == 0) show_labels = atoi(value); 
       if(strcmp(child, "Connector") == 0) connector = (GtkPlotConnector)atoi(value); 
       if(strcmp(child, "Fill") == 0) fill_area = atoi(value); 
       if(strcmp(child, "Gradient") == 0) show_gradient = atoi(value); 
       if(strcmp(child, "Name") == 0) name = value; 
       if(strcmp(child, "Function") == 0) exp = value;
    }

    if(!exp){
       if(id >= 0){ /* after 0.7.2 */
         real_data = sg_project_dataset_get_by_id(id);
         if(real_data)
           state->dataset = sg_dataset_clone(real_data);
         else 
           state->dataset = sg_project_new_dataset(style);
         state->dataset->id = id; 
       }else{ /* before 0.7.2 */
         real_data = find_data(name);
         if(real_data)
           state->dataset = sg_dataset_clone(real_data);
         else
           state->dataset = sg_project_new_dataset(style);
       }
    }else{
       if(id >= 0){ /* after 0.7.2 */
         real_data = sg_project_function_get_by_id(id);
         if(real_data)
           state->dataset = sg_dataset_clone(real_data);
         else 
           state->dataset = sg_project_new_function((gchar *)exp);
         state->dataset->id = id; 
       }else{ /* before 0.7.2 */
         real_data = find_function(name, exp);
         if(real_data)
           state->dataset = sg_dataset_clone(real_data);
         else
           state->dataset = sg_project_new_function((gchar *)exp);
       }
    }

    gtk_plot_data_show_labels(state->dataset->real_data, show_labels);
    gtk_plot_data_gradient_set_visible(state->dataset->real_data, show_gradient);
    gtk_plot_data_fill_area(state->dataset->real_data, fill_area);
    gtk_plot_data_set_connector(state->dataset->real_data, connector);

    if(name && strlen(name) > 0){
        sg_dataset_set_name(state->dataset, (gchar *)name);
    }
  }  
  
  if(state->state == PARSER_IN_DATA){
    if(strcmp(name, "Surface") == 0){
      GdkColor fg, bg;
      gboolean transparent = FALSE;
      gboolean height_gradient= FALSE;

      fg.red = 0; 
      fg.green = 0; 
      fg.blue = 65535; 
      bg.red = 0; 
      bg.green = 0; 
      bg.blue = 0; 

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Transparent") == 0) transparent = atoi(value); 
         if(strcmp(child, "Gradient") == 0) height_gradient = atoi(value); 
         if(strcmp(child, "FGR") == 0) fg.red = atoi(value); 
         if(strcmp(child, "FGG") == 0) fg.green = atoi(value); 
         if(strcmp(child, "FGB") == 0) fg.blue = atoi(value); 
         if(strcmp(child, "BGR") == 0) bg.red = atoi(value); 
         if(strcmp(child, "BGG") == 0) bg.green = atoi(value); 
         if(strcmp(child, "BGB") == 0) bg.blue = atoi(value); 
      }
      gdk_color_alloc(gdk_colormap_get_system(), &fg);
      gdk_color_alloc(gdk_colormap_get_system(), &bg);

      GTK_PLOT_SURFACE(state->dataset->real_data)->color = fg;
      GTK_PLOT_SURFACE(state->dataset->real_data)->shadow = bg;
      GTK_PLOT_SURFACE(state->dataset->real_data)->transparent = transparent;
      GTK_PLOT_SURFACE(state->dataset->real_data)->height_gradient = height_gradient;
    }

    if(strcmp(name, "Grid") == 0){
      gboolean visible = TRUE;
      GdkColor fg, bg;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Visible") == 0) visible = atoi(value); 
         if(strcmp(child, "FGR") == 0) fg.red = atoi(value); 
         if(strcmp(child, "FGG") == 0) fg.green = atoi(value); 
         if(strcmp(child, "FGB") == 0) fg.blue = atoi(value); 
         if(strcmp(child, "BGR") == 0) bg.red = atoi(value); 
         if(strcmp(child, "BGG") == 0) bg.green = atoi(value); 
         if(strcmp(child, "BGB") == 0) bg.blue = atoi(value); 
      }
      gdk_color_alloc(gdk_colormap_get_system(), &fg);
      gdk_color_alloc(gdk_colormap_get_system(), &bg);

      GTK_PLOT_SURFACE(state->dataset->real_data)->grid_foreground = fg;
      GTK_PLOT_SURFACE(state->dataset->real_data)->grid_background = bg;

      if(GTK_IS_PLOT_SURFACE(state->dataset->real_data))
        GTK_PLOT_SURFACE(state->dataset->real_data)->show_grid = visible;
    }
    if(strcmp(name, "Mesh") == 0){
      gboolean visible = FALSE;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Visible") == 0) visible = atoi(value); 
      }

      if(GTK_IS_PLOT_SURFACE(state->dataset->real_data))
        GTK_PLOT_SURFACE(state->dataset->real_data)->show_mesh = visible;
    }
    if(strcmp(name, "Contour") == 0){
      gboolean visible = TRUE;
      gboolean project = TRUE;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Visible") == 0) visible = atoi(value); 
         if(strcmp(child, "Project") == 0) project = atoi(value); 
      }

      if(GTK_IS_PLOT_CSURFACE(state->dataset->real_data)){
        GTK_PLOT_CSURFACE(state->dataset->real_data)->lines_visible = visible;
        GTK_PLOT_CSURFACE(state->dataset->real_data)->project_xy = project;
      }
    }
    if(strcmp(name, "Legend") == 0){
      gboolean visible = TRUE;
      gint precision = 3;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Visible") == 0) visible = atoi(value); 
         if(strcmp(child, "Precision") == 0) precision = atoi(value); 
      }

      if(!visible)
        gtk_plot_data_hide_legend(state->dataset->real_data);
      state->dataset->real_data->legends_precision = precision;
    }

    if(strcmp(name, "Datasheet") == 0){
      gchar *name = NULL;
      gint x = -1;
      gint y = -1;
      gint z = -1;
      gint a = -1;
      gint dx = -1;
      gint dy = -1;
      gint dz = -1;
      gint da = -1;
      gint labels = -1;
      SGworksheet *datasheet = NULL;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Name") == 0) name = g_strdup(value); 
         if(strcmp(child, "X") == 0) x = atoi(value); 
         if(strcmp(child, "Y") == 0) y = atoi(value); 
         if(strcmp(child, "Z") == 0) z = atoi(value); 
         if(strcmp(child, "A") == 0) a = atoi(value); 
         if(strcmp(child, "DX") == 0) dx = atoi(value); 
         if(strcmp(child, "DY") == 0) dy = atoi(value); 
         if(strcmp(child, "DZ") == 0) dz = atoi(value); 
         if(strcmp(child, "DA") == 0) da = atoi(value); 
         if(strcmp(child, "Labels") == 0) labels = atoi(value); 
      }

      datasheet = sg_project_get_worksheet((gchar *)name);
      sg_dataset_set_name(state->dataset, name);
      if(datasheet){
        if(datasheet->mode == SG_MODE_MATRIX)
          sg_dataset_set_matrix(state->dataset, datasheet);
        else
          sg_dataset_set_worksheet(state->dataset, datasheet,
                             x, y, z, a, dx, dy, dz, da, labels);
      }
    }

    if(strcmp(name, "Expressionsdata") == 0){
      const gchar *name = NULL;
      gchar *p_exp[9];
      gint i;
     
      for(i = 0; i < 9; i++) p_exp[i] = NULL;
 
      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Name") == 0) name = value; 
         if(strcmp(child, "X") == 0) 
            p_exp[0] = g_strdup((gchar *)value); 
         if(strcmp(child, "Y") == 0) 
            p_exp[1] = g_strdup((gchar *)value);
         if(strcmp(child, "Z") == 0) 
            p_exp[2] = g_strdup((gchar *)value); 
         if(strcmp(child, "A") == 0) 
            p_exp[3] = g_strdup((gchar *)value);
         if(strcmp(child, "DX") == 0) 
            p_exp[4] = g_strdup((gchar *)value);
         if(strcmp(child, "DY") == 0) 
            p_exp[5] = g_strdup((gchar *)value);
         if(strcmp(child, "DZ") == 0) 
            p_exp[6] = g_strdup((gchar *)value);
         if(strcmp(child, "DA") == 0) 
            p_exp[7] = g_strdup((gchar *)value);
         if(strcmp(child, "Labels") == 0) 
            p_exp[8] = g_strdup(value);
      }

      sg_dataset_set_python(state->dataset, p_exp);
    }

    if(strcmp(name, "Xline") == 0){

      state->state = PARSER_IN_XLINE;
      state->in_text = FALSE;

    }

    if(strcmp(name, "Yline") == 0){

      state->state = PARSER_IN_YLINE;
      state->in_text = FALSE;

    }

    if(strcmp(name, "Zline") == 0){

      state->state = PARSER_IN_ZLINE;
      state->in_text = FALSE;

    }

    if(strcmp(name, "Gradient") == 0){
      GdkColor color_min, color_max;
      gdouble min, max;
      gint nlevels, nsublevels = 0, mask;

      while(*aux){
         child = *aux++;
         value = *aux++;
         if(strcmp(child, "Mask") == 0) mask = atoi(value); 
         if(strcmp(child, "Min") == 0) min = atof(value); 
         if(strcmp(child, "Max") == 0) max = atof(value); 
         if(strcmp(child, "Nlevels") == 0) nlevels = atoi(value); 
         if(strcmp(child, "Nsublevels") == 0) nsublevels = atoi(value); 
         if(strcmp(child, "Rmin") == 0) color_min.red = atoi(value); 
         if(strcmp(child, "Gmin") == 0) color_min.green = atoi(value); 
         if(strcmp(child, "Bmin") == 0) color_min.blue = atoi(value); 
         if(strcmp(child, "Rmax") == 0) color_max.red = atoi(value); 
         if(strcmp(child, "Gmax") == 0) color_max.green = atoi(value); 
         if(strcmp(child, "Bmax") == 0) color_max.blue = atoi(value); 
      }
      gdk_color_alloc(gdk_colormap_get_system(), &color_min);
      gdk_color_alloc(gdk_colormap_get_system(), &color_max);

      state->dataset->real_data->gradient_mask = mask;
      gtk_plot_data_set_gradient_colors(state->dataset->real_data, 
                                        &color_min, &color_max);
      gtk_plot_data_set_gradient(state->dataset->real_data, min, max, nlevels, nsublevels);

    }

  }

  if(state->state == PARSER_IN_DATA && strcmp(name, "Points") == 0){
    gint nx = 0, ny = 0;

    state->state = PARSER_IN_POINTS;
    state->in_text = FALSE;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "NX") == 0) nx = atoi(value); 
       if(strcmp(child, "NY") == 0) ny = atoi(value); 
    }

    if(GTK_IS_PLOT_SURFACE(state->dataset->real_data)){
        GTK_PLOT_SURFACE(state->dataset->real_data)->nx = nx;
        GTK_PLOT_SURFACE(state->dataset->real_data)->ny = ny;
    }

  }

  if(state->object == PARSE_PLOT && state->state == PARSER_IN_POINTS && strcmp(name, "Point") == 0){
    gdouble x = 0.;
    gdouble y = 0.;
    gdouble z = 0.;
    gdouble a = 0.;
    gdouble dx = 0.;
    gdouble dy = 0.;
    gdouble dz = 0.;
    gdouble da = 0.;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "X") == 0) x = atof(value); 
       if(strcmp(child, "Y") == 0) y = atof(value); 
       if(strcmp(child, "Z") == 0) z = atof(value); 
       if(strcmp(child, "A") == 0) a = atof(value); 
       if(strcmp(child, "DX") == 0) dx = atof(value); 
       if(strcmp(child, "DY") == 0) dy = atof(value); 
       if(strcmp(child, "DZ") == 0) dz = atof(value); 
       if(strcmp(child, "DA") == 0) da = atof(value); 
    }
    sg_dataset_add_point(state->dataset, &x, &y, &z, &a, &dx, &dy, &dz, &da, NULL);
  }

  if(state->state == PARSER_IN_DATA && strcmp(name, "Xerrbars") == 0){
    gboolean visible = FALSE;
    gint width = 0;
    gint caps = 0;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Visible") == 0) visible = atoi(value); 
       if(strcmp(child, "Width") == 0) width = atoi(value); 
       if(strcmp(child, "Caps") == 0) caps = atoi(value); 
    }

    if(visible)
       gtk_plot_data_show_xerrbars(state->dataset->real_data);
    state->dataset->real_data->xerrbar_width = width;
    state->dataset->real_data->xerrbar_caps = caps;
  }

  if(state->state == PARSER_IN_DATA && strcmp(name, "Yerrbars") == 0){
    gboolean visible = FALSE;
    gint width = 0;
    gint caps = 0;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Visible") == 0) visible = atoi(value); 
       if(strcmp(child, "Width") == 0) width = atoi(value); 
       if(strcmp(child, "Caps") == 0) caps = atoi(value); 
    }

    if(visible)
       gtk_plot_data_show_yerrbars(state->dataset->real_data);
    state->dataset->real_data->yerrbar_width = width;
    state->dataset->real_data->yerrbar_caps = caps;
  }

  if(state->state == PARSER_IN_DATA && strcmp(name, "Zerrbars") == 0){
    gboolean visible = FALSE;
    gint width = 0;
    gint caps = 0;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Visible") == 0) visible = atoi(value); 
       if(strcmp(child, "Width") == 0) width = atoi(value); 
       if(strcmp(child, "Caps") == 0) caps = atoi(value); 
    }

    if(visible)
       gtk_plot_data_show_zerrbars(state->dataset->real_data);
    state->dataset->real_data->zerrbar_width = width;
    state->dataset->real_data->zerrbar_caps = caps;
  }


  if(state->state == PARSER_IN_DATA && strcmp(name, "Datalabels") == 0){
    gboolean visible = FALSE;
    gint offset = 6;

    state->in_text = FALSE;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Visible") == 0) visible = atoi(value); 
       if(strcmp(child, "Offset") == 0) offset = atoi(value); 
    }

    gtk_plot_data_show_labels(state->dataset->real_data, visible);
    state->dataset->real_data->labels_offset = offset;
  }


  if(state->state == PARSER_IN_DATA && strcmp(name, "Label") == 0){
    const gchar *text = NULL;
    gint npoint = 0;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Text") == 0) text = value; 
       if(strcmp(child, "Point") == 0) npoint = atoi(value); 
    }

    if(npoint < state->dataset->real_data->num_points)
       state->dataset->real_data->labels[npoint] = g_strdup(text);
  }

/***********************************************************
 * LINES
 ***********************************************************/
  if(strcmp(name, "Line") == 0){
    GtkPlotAxis *the_axis;
    GtkPlotLineStyle style = GTK_PLOT_LINE_NONE;
    gfloat width = 0.0;
    GdkColor color;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Style") == 0) style = (GtkPlotLineStyle)atoi(value); 
       if(strcmp(child, "Width") == 0) width = atof(value); 
       if(strcmp(child, "R") == 0) color.red = atoi(value); 
       if(strcmp(child, "G") == 0) color.green = atoi(value); 
       if(strcmp(child, "B") == 0) color.blue = atoi(value); 
    }
    gdk_color_alloc(gdk_colormap_get_system(), &color);

    switch(state->state){
        case PARSER_IN_AXIS:
          gtk_plot_axis_set_attributes(real_plot, state->axis,
                                       width, &color);
          
        break;
        case PARSER_IN_FRAME:
          if(GTK_IS_PLOT3D(real_plot))
            gtk_plot3d_frame_set_attributes(GTK_PLOT3D(real_plot), style, width, &color);
          break;
        case PARSER_IN_CORNER:
          if(GTK_IS_PLOT3D(real_plot))
            gtk_plot3d_corner_set_attributes(GTK_PLOT3D(real_plot), style, width, &color);
          break;
        case PARSER_IN_VMAJOR:
          gtk_plot_major_vgrid_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_VMINOR:
          gtk_plot_minor_vgrid_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_HMAJOR:
          gtk_plot_major_hgrid_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_HMINOR:
          gtk_plot_minor_hgrid_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_MAJOR:
          the_axis = gtk_plot_get_axis(real_plot, state->axis);
          the_axis->major_grid.line_style = style;
          the_axis->major_grid.line_width = width;
          the_axis->major_grid.color = color;
        break;
        case PARSER_IN_MINOR:
          the_axis = gtk_plot_get_axis(real_plot, state->axis);
          the_axis->minor_grid.line_style = style;
          the_axis->minor_grid.line_width = width;
          the_axis->minor_grid.color = color;
        break;
        case PARSER_IN_X0:
          gtk_plot_x0line_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_Y0:
          gtk_plot_y0line_set_attributes(real_plot, style, width, &color);
        break;
        case PARSER_IN_DATA:
          gtk_plot_data_set_line_attributes(state->dataset->real_data,
                                            style, width, &color);
        break;
        case PARSER_IN_XLINE:
          gtk_plot_data_set_x_attributes(state->dataset->real_data,
                                         style, width, &color);
        break;
        case PARSER_IN_YLINE:
          gtk_plot_data_set_y_attributes(state->dataset->real_data,
                                         style, width, &color);
        break;
        case PARSER_IN_ZLINE:
          gtk_plot_data_set_z_attributes(state->dataset->real_data,
                                         style, width, &color);
        break;
        case PARSER_IN_CHILD:
          state->line.line_style = style; 
          state->line.line_width = width; 
          state->line.color = color; 
        break;
        default:
        break;
    }

  }

/***********************************************************
 * SYMBOLS 
 ***********************************************************/
  if(strcmp(name, "Symbol") == 0){
    GtkPlotSymbolType type = GTK_PLOT_SYMBOL_NONE;
    GtkPlotSymbolStyle style = GTK_PLOT_SYMBOL_EMPTY;
    gint size = 0;
    gfloat width = 0.0;
    gint arrow_width = 0;
    gint arrow_length = 12;
    GtkPlotSymbolStyle arrow_style = GTK_PLOT_SYMBOL_EMPTY;
    gint arrow_centered = TRUE;
    gdouble bar_width = 0.05;
    gdouble scale = 1.0;
    GdkColor color, border;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Type") == 0) type = (GtkPlotSymbolType)atoi(value); 
       if(strcmp(child, "Style") == 0) style = (GtkPlotSymbolStyle)atoi(value); 
       if(strcmp(child, "Size") == 0) size = atoi(value); 
       if(strcmp(child, "Width") == 0) width = atof(value); 
       if(strcmp(child, "ArrowStyle") == 0) arrow_style = (GtkPlotSymbolStyle)atoi(value); 
       if(strcmp(child, "ArrowLength") == 0) arrow_length = atoi(value); 
       if(strcmp(child, "ArrowWidth") == 0) arrow_width = atoi(value); 
       if(strcmp(child, "Center") == 0) arrow_centered = atoi(value);
       if(strcmp(child, "BarWidth") == 0) bar_width = atof(value); 
       if(strcmp(child, "Scale") == 0) scale = atof(value); 
       if(strcmp(child, "R") == 0) border.red = color.red = atoi(value); 
       if(strcmp(child, "G") == 0) border.green = color.green = atoi(value); 
       if(strcmp(child, "B") == 0) border.blue = color.blue = atoi(value); 
       if(strcmp(child, "BorderR") == 0) border.red = atoi(value); 
       if(strcmp(child, "BorderG") == 0) border.green = atoi(value); 
       if(strcmp(child, "BorderB") == 0) border.blue = atoi(value); 
    }
    gdk_color_alloc(gdk_colormap_get_system(), &color);
    gdk_color_alloc(gdk_colormap_get_system(), &border);

    gtk_plot_data_set_symbol(state->dataset->real_data,
                             type, style, size, width, &color, &border);
    gtk_plot_data_set_a_scale(state->dataset->real_data, scale);

    if(GTK_IS_PLOT_FLUX(state->dataset->real_data)){
       GTK_PLOT_FLUX(state->dataset->real_data)->arrow_style = arrow_style;
       GTK_PLOT_FLUX(state->dataset->real_data)->arrow_length = arrow_length;
       GTK_PLOT_FLUX(state->dataset->real_data)->arrow_width = arrow_width;
       GTK_PLOT_FLUX(state->dataset->real_data)->centered = arrow_centered;
    }
    if(GTK_IS_PLOT_BAR(state->dataset->real_data))
         GTK_PLOT_BAR(state->dataset->real_data)->width = bar_width;
  }
/***********************************************************
 * TEXT 
 ***********************************************************/
  if(strcmp(name, "Text") == 0){
    gdouble x = 0.;
    gdouble y = 0.;
    gint angle = 0;
    GtkJustification justification = GTK_JUSTIFY_FILL;
    gboolean transparent = TRUE;

    state->in_text = TRUE;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "X") == 0) x = atof(value); 
       if(strcmp(child, "Y") == 0) y = atof(value); 
       if(strcmp(child, "Angle") == 0) angle = atoi(value); 
       if(strcmp(child, "Justification") == 0) justification = (GtkJustification)atoi(value); 
       if(strcmp(child, "Transparent") == 0) transparent = atoi(value); 
    }

    state->text.x = x;
    state->text.y = y;
    state->text.angle = angle;
    state->text.justification = justification;
    state->text.transparent = transparent;
  }

  if(strcmp(name, "Foreground") == 0){
    GdkColor color;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "R") == 0) color.red = atoi(value); 
       if(strcmp(child, "G") == 0) color.green = atoi(value); 
       if(strcmp(child, "B") == 0) color.blue = atoi(value); 
    }
    gdk_color_alloc(gdk_colormap_get_system(), &color);

    if(state->in_text) state->text.fg = color;
    
  }

  if(strcmp(name, "Background") == 0){
    GdkColor color;
    gint transparent = TRUE;
 
    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "R") == 0) color.red = atoi(value); 
       if(strcmp(child, "G") == 0) color.green = atoi(value); 
       if(strcmp(child, "B") == 0) color.blue = atoi(value); 
       if(strcmp(child, "Transparent") == 0) transparent = atoi(value); 
    }
    gdk_color_alloc(gdk_colormap_get_system(), &color);

    if(state->in_text) 
       state->text.bg = color;
    else
      switch(state->state){
       case PARSER_IN_PAGE:
       case PARSER_IN_PLOT:
          GTK_PLOT_CANVAS(state->plot->real_canvas)->background = color;
          break;
       case PARSER_IN_LAYER:
          GTK_PLOT(state->layer->real_plot)->background = color;
          gtk_plot_set_transparent(GTK_PLOT(state->layer->real_plot), transparent);
          break;
      }
  }
 
  if(strcmp(name, "Font") == 0){
    const gchar *name = NULL; 
    gint height = 12;

    while(*aux){
       child = *aux++;
       value = *aux++;

       if(strcmp(child, "Name") == 0) name = value; 
       if(strcmp(child, "Height") == 0) height = atoi(value); 
    }

    if(state->text.font)
      g_free(state->text.font);

    state->text.font = g_strdup(name);
    state->text.height = height;
  }
 

}

static void
sgEndElement(sgParseState *state, const XCHAR *real_name)
{
  SGworksheet *worksheet = state->worksheet;
  GtkSheet *sheet = NULL;
  GdkPixmap *pixmap = NULL;
  const XCHAR *name;

  name = get_real_name(real_name);

  if(worksheet) sheet = GTK_SHEET(worksheet->sheet);
  
  if(strcmp(name, "Worksheet") == 0 || strcmp(name, "Matrix") == 0){
     SGworksheet *worksheet;
     gint nrows, ncols;
     gint i;

     state->prev_state = state->state;
     state->state = PARSER_UNKNOWN;
     state->layer = NULL;

     worksheet = state->worksheet;
     ncols = gtk_sheet_get_columns_count(GTK_SHEET(worksheet->sheet));
     nrows = gtk_sheet_get_rows_count(GTK_SHEET(worksheet->sheet));

  }

  if(strcmp(name, "MaxRow") == 0)
     sg_worksheet_add_rows(state->worksheet,
                           atoi(state->content->str)-sheet->maxrow);

  if(strcmp(name, "MaxCol") == 0)
     sg_worksheet_add_columns(state->worksheet,
                              atoi(state->content->str)-sheet->maxcol);

  if(state->state == PARSER_IN_WORKSHEET && strcmp(name, "Name") == 0){
     sg_worksheet_rename(state->worksheet, state->content->str);
  }

  if(strcmp(name, "Begin") == 0)
     sg_worksheet_set_begin(state->worksheet, atoi(state->content->str));

  if(strcmp(name, "End") == 0)
    sg_worksheet_set_end(state->worksheet, atoi(state->content->str));

  if(strcmp(name, "Content") == 0)
     sg_worksheet_cell_set(state->worksheet, state->row, state->col,
                           state->content->str, FALSE, FALSE);
  if(strcmp(name, "Formula") == 0)
      sg_worksheet_cell_set(state->worksheet, state->row, state->col,
                                 state->content->str, TRUE,FALSE);

  if(strcmp(name, "ColFormula") == 0 && strlen(state->content->str)>0)
  {
       sg_worksheet_column_set_exp(state->worksheet, state->col,
                                   g_strdup(state->content->str));
  }

  if(state->state == PARSER_IN_PLOT && strcmp(name, "Name") == 0){
     sg_plot_rename(state->plot, state->content->str); 
  }

  /* This is to fix a bug: tag Page closed in the wrong place */
  if(state->state == PARSER_IN_PAGE && strcmp(name, "Name") == 0){
     sg_plot_rename(state->plot, state->content->str); 
     state->state = PARSER_IN_PLOT;
  }

  if(strcmp(name, "Plot") == 0){
     state->prev_state = state->state;
     state->state = PARSER_UNKNOWN;
     state->num_layers = 0;
  }

  if(strcmp(name, "Page") == 0){
     state->state = PARSER_IN_PLOT;
  }

  if(strcmp(name, "Child") == 0){
     GtkPlotCanvas *canvas;
     GtkPlotCanvasChild *child = NULL;

     state->state = PARSER_IN_PLOT;

     canvas = GTK_PLOT_CANVAS(state->plot->real_canvas);
     
     switch(state->child.type){
       case GTK_PLOT_CANVAS_TEXT: 
         return;
       case GTK_PLOT_CANVAS_LINE: 
         child = gtk_plot_canvas_put_line(canvas,
                                          state->child.rx1, state->child.ry1,
                                          state->child.rx2, state->child.ry2,
                                          state->line.line_style,
                                          state->line.line_width,
                                          &state->line.color,
                                          state->arrow.arrow_mask);
         break;
       case GTK_PLOT_CANVAS_RECTANGLE: 
         child = gtk_plot_canvas_put_rectangle(canvas,
                                          state->child.rx1, state->child.ry1,
                                          state->child.rx2, state->child.ry2,
                                          state->line.line_style,
                                          state->line.line_width,
                                          &state->line.color,
                                          &state->rectangle.bg,
                                          state->rectangle.border,
                                          state->rectangle.filled);
         break;
       case GTK_PLOT_CANVAS_ELLIPSE: 
         child = gtk_plot_canvas_put_ellipse(canvas,
                                          state->child.rx1, state->child.ry1,
                                          state->child.rx2, state->child.ry2,
                                          state->line.line_style,
                                          state->line.line_width,
                                          &state->line.color,
                                          &state->ellipse.bg,
                                          state->ellipse.filled);
         break;
       case GTK_PLOT_CANVAS_PIXMAP: 
         pixmap = gdk_pixmap_new(state->window, state->pwidth, state->pheight, -1); 
         gdk_draw_image(pixmap, state->gc, state->image, 0, 0, 0, 0,
                        state->pwidth, state->pheight);

         child = gtk_plot_canvas_put_pixmap(canvas, pixmap,
                                            state->child.rx1, state->child.ry1);
         gtk_plot_canvas_child_move_resize(canvas,
                                           child,
                                           state->child.rx1, state->child.ry1,
                                           state->child.rx2, state->child.ry2);
         gdk_image_destroy(state->image);
         state->image = NULL;
         state->img_char = 0;
         break;
       default:
         gtk_plot_canvas_put_child(canvas, 
                                   child, 
                                   child->rx1, child->ry1, 
                                   child->rx2, child->ry2);
     }

  }

  if(strcmp(name, "Layer") == 0){
     state->prev_state = state->state;
     state->state = PARSER_IN_PLOT;
  }

  if(strcmp(name, "Pixels") == 0){
     if(state->state == PARSER_IN_PIXMAP)
        state->state = PARSER_IN_CHILD;
     if(state->state == PARSER_IN_BG_PIXMAP)
        state->state = PARSER_IN_LAYER;
  }
     
  if(strcmp(name, "BGpixmap") == 0){
     pixmap = gdk_pixmap_new(state->window, state->pwidth, state->pheight, -1); 
     gdk_draw_image(pixmap, state->gc, state->image, 0, 0, 0, 0,
                    state->pwidth, state->pheight);

     gtk_plot_set_background_pixmap(GTK_PLOT(state->layer->real_plot), pixmap);
     gdk_image_destroy(state->image);
     state->image = NULL;
     state->img_char = 0;
  }
 
  if(strcmp(name, "Vmajor") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Vminor") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Hmajor") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Hminor") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "X0") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Y0") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Axis") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Ticks") == 0){
     state->state = PARSER_IN_AXIS;
  }

  if(strcmp(name, "Title") == 0){
     state->state = PARSER_IN_AXIS;
  }

  if(strcmp(name, "Labels") == 0){
     state->state = PARSER_IN_AXIS;
  }

  if(strcmp(name, "Major") == 0){
     state->state = PARSER_IN_AXIS;
  }

  if(strcmp(name, "Minor") == 0){
     state->state = PARSER_IN_AXIS;
  }

  if(strcmp(name, "Legends") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Frame") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Corner") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Side") == 0){
     state->state = PARSER_IN_LAYER;
  }

  if(strcmp(name, "Legend") == 0 && state->state == PARSER_IN_DATA){
     gtk_plot_data_set_legend(state->dataset->real_data, state->content->str); 
  }

  if(strcmp(name, "String") == 0 && state->in_text){
     state->text.text = g_strdup(state->content->str);
  }

  if(strcmp(name, "Pixmap") == 0){
     gint i;

     state->state = PARSER_IN_CHILD;
     if(state->pixels) g_free(state->pixels);
     state->pixels = g_new0(gulong, 1);
     state->ncolors = 0;
  }

  if(strcmp(name, "XPMColor") == 0){
     GdkColor color;
     gchar color_str[17];
     gint i;

     g_snprintf(color_str, 17, "#%s", state->content->str);

     gdk_color_parse(color_str, &color);
/*
     printf("%s %d %d %d\n",color_str,color.red,color.green,color.blue);
*/
     gdk_color_alloc(gdk_colormap_get_system(), &color);

     state->pixels = (gulong *)g_realloc(state->pixels, (state->ncolors+1)*sizeof(gulong)); 
     state->pixels[state->ncolors] = color.pixel;

/*
     printf("%d %d\n",state->ncolors,color.pixel);
*/
     state->ncolors++;
  }


  if(strcmp(name, "Text") == 0){
     GtkPlotCanvasChild *child = NULL;

     switch(state->state){
       case PARSER_IN_PLOT:
       case PARSER_IN_CHILD:
         child = gtk_plot_canvas_put_text(GTK_PLOT_CANVAS(state->plot->real_canvas),
                          state->text.x,
                          state->text.y,
                          state->text.font,
                          state->text.height,
                          state->text.angle,
                          &state->text.fg,
                          &state->text.bg,
                          state->text.transparent,
                          state->text.justification,
                          state->text.text);
         gtk_plot_text_set_border((GtkPlotText *)child->data,
                          state->text.border,
                          state->text.border_space,
                          state->text.border_width,
                          state->text.shadow_width);
         break;
       case PARSER_IN_LEGENDS:
         gtk_plot_legends_set_attributes(GTK_PLOT(state->layer->real_plot),
                                 state->text.font,
                                 state->text.height,
                                 &state->text.fg,
                                 &state->text.bg);
         break;
       case PARSER_IN_AXIS:
         gtk_plot_axis_set_labels_attributes(GTK_PLOT(state->layer->real_plot),
                                             state->axis,
                                     state->text.font,
                                     state->text.height,
                                     state->text.angle,
                                     &state->text.fg,
                                     &state->text.bg,
                                             state->text.transparent,
                                             state->text.justification);

         break;
       case PARSER_IN_TITLE:
         gtk_plot_axis_move_title(GTK_PLOT(state->layer->real_plot),
                                state->axis,
                                state->text.angle,
                                  state->text.x, state->text.y);
         gtk_plot_axis_title_set_attributes(GTK_PLOT(state->layer->real_plot),
                                            state->axis,
                                    state->text.font,
                                    state->text.height,
                                    state->text.angle,
                                    &state->text.fg,
                                    &state->text.bg,
                                            state->text.transparent,
                                            state->text.justification);
         if(state->text.text && strlen(state->text.text) > 0){
           gtk_plot_axis_set_title(GTK_PLOT(state->layer->real_plot),
                                   state->axis,
                                   state->text.text);
         }
         break;
       case PARSER_IN_DATA:
         gtk_plot_data_labels_set_attributes(state->dataset->real_data,
                                     state->text.font,
                                     state->text.height,
                                     state->text.angle,
                                     &state->text.fg,
                                     &state->text.bg);
         break;
       default:
         break;
     }

     state->in_text = FALSE;

     if(state->text.text)
        g_free(state->text.text);
     state->text.text = NULL;
     if(state->text.font)
        g_free(state->text.font);
     state->text.font = NULL;
     return;
  }

  if(strcmp(name, "Dataset") == 0){
     if(state->prev_state == PARSER_IN_LAYER){
       sg_layer_add_dataset(state->layer, state->dataset);
       if(!state->visible) gtk_widget_hide(GTK_WIDGET(state->dataset->real_data));
       state->prev_state = state->state;
       state->state = PARSER_IN_LAYER;
     }else
       state->state = state->prev_state;
  }

  if(strcmp(name, "Points") == 0){
     state->state = PARSER_IN_DATA;
  }

  if(strcmp(name, "Datalabels") == 0){
     state->state = PARSER_IN_DATA;
  }

  if(strcmp(name, "Xline") == 0){
     state->state = PARSER_IN_DATA;
  }

  if(strcmp(name, "Yline") == 0){
     state->state = PARSER_IN_DATA;
  }

  if(strcmp(name, "Zline") == 0){
     state->state = PARSER_IN_DATA;
  }

  g_free(state->name);
  state->name = NULL;
}


gboolean  
sg_project_file_import_xml(gchar *file, SGworksheet *worksheet, SGplot *plot)
{
  FILE *ftest;
  sgParseState state;
  GdkWindowAttr attributes;
  gint attributes_mask;
  gint i;

  state.worksheet = worksheet;
  state.plot = plot;
  state.layer = NULL;
  state.dataset = NULL;
  state.image = NULL;

  state.text.font = NULL;
  state.text.text = NULL;
  state.text.height = 12;

  state.in_text = FALSE;
  state.last_worksheet = -1;
  state.last_matrix = 0;
  state.last_plot = -1;
  state.last_dataset = -1;
  state.last_function = -1;
  state.last_expression = -1;

  state.color_str[4] = '\0';

  state.num_layers = 0;

  state.object = PARSE_PROJECT;
  if(worksheet) state.object = PARSE_WORKSHEET;
  if(plot) state.object = PARSE_PLOT;

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.title = NULL;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gdk_visual_get_system ();
  attributes.colormap = gdk_colormap_get_system ();
  attributes.event_mask = 0;
  attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
  
  state.window = gdk_window_new (NULL, &attributes, attributes_mask);

  state.gc = gdk_gc_new(state.window);
  state.cc = gdk_color_context_new(attributes.visual, attributes.colormap);

  state.ncolors = 0;
  state.pixels = g_new0(gulong, 1);

  xmlSubstituteEntitiesDefault(TRUE);

  ftest = fopen(file, "r");
  if (!ftest){
         sg_message_dialog("File not found!", 1);
         gdk_gc_unref(state.gc);
         gdk_color_context_free(state.cc);
         g_free(state.pixels);
         return FALSE;
  }
  fclose(ftest);

  if(xmlSAXUserParseFile(&sgSAXParser, &state, sg_project_autosave_check(file)) < 0) {
       sg_message_dialog("Document not well formed!", 1);
       gdk_gc_unref(state.gc);
       gdk_color_context_free(state.cc);
       g_free(state.pixels);
       return FALSE;
  }

  return TRUE;
}

static const XCHAR *
get_real_name(const XCHAR *name)
{
  const XCHAR *real_name = name;

  while(real_name && real_name != '\0'){
    if(*real_name++ == ':') return real_name;
  }

  return name;
} 

static SGdataset * 
find_function(const gchar *name, const gchar *exp)
{
  GList *list;
  SGdataset *dataset = NULL;

  list = functions;
  while(list)
  {
    SGdataset *aux;

    aux = (SGdataset *)list->data;
    if(strcmp(aux->real_data->name, name) == 0 &&
       strcmp(aux->exp, exp) == 0){
            dataset = aux;
            break;
    }

    list = list->next;
  }

  return dataset;
} 

static SGdataset * 
find_data(const gchar *name)
{
  GList *list;
  SGdataset *dataset = NULL;

  list = functions;
  while(list)
  {
    SGdataset *aux;

    aux = (SGdataset *)list->data;
    if(strcmp(aux->real_data->name, name) == 0){
            dataset = aux;
            break;
    }

    list = list->next;
  }

  return dataset;
} 

Generated by  Doxygen 1.6.0   Back to index