r18005 - gnucash/branches/webkit/src/html - When loading an html string to the webkit html engine, check if there's an <object> tag.

Phil Longstaff plongstaff at cvs.gnucash.org
Sat Mar 28 18:20:08 EDT 2009


Author: plongstaff
Date: 2009-03-28 18:20:08 -0400 (Sat, 28 Mar 2009)
New Revision: 18005
Trac: http://svn.gnucash.org/trac/changeset/18005

Modified:
   gnucash/branches/webkit/src/html/gnc-html-graph-gog-webkit.c
   gnucash/branches/webkit/src/html/gnc-html-graph-gog.c
   gnucash/branches/webkit/src/html/gnc-html-webkit.c
Log:
When loading an html string to the webkit html engine, check if there's an <object> tag.
If so, remove the string between the <object> and </object> markers, and pass that to the
object handler.  The webkit object handlers pick the info out of the various parameters,
use gog to create the graph pixbuf, save that to a file in /tmp, and then replace the
original <object>...</object> with <img src="/tmp/barchart">.  This can then be fed to
webkit and it will load the graph.



Modified: gnucash/branches/webkit/src/html/gnc-html-graph-gog-webkit.c
===================================================================
--- gnucash/branches/webkit/src/html/gnc-html-graph-gog-webkit.c	2009-03-28 19:12:52 UTC (rev 18004)
+++ gnucash/branches/webkit/src/html/gnc-html-graph-gog-webkit.c	2009-03-28 22:20:08 UTC (rev 18005)
@@ -1,6 +1,6 @@
 /********************************************************************
  * gnc-html-graph-gog_webkit.c -- GNC/HTML Graphing support via GOG *
-
+ *                                                                  *
  * Copyright (C) 2005 Joshua Sled <jsled at asynchronous.org>          *
  * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
  *                                                                  *
@@ -29,6 +29,7 @@
 #include <string.h>
 
 #include "gnc-ui-util.h"
+#include "gnc-html-graph-gog.h"
 #include "gnc-html-graph-gog-webkit.h"
 #include "gnc-html.h"
 #include "gnc-engine.h"
@@ -74,23 +75,8 @@
 static int handle_linechart( GncHtml* html, gpointer eb, gpointer d );
 static int handle_scatter( GncHtml* html, gpointer eb, gpointer d );
 
-#if 0
-#ifdef GTKHTML_USES_GTKPRINT
-static void draw_print_cb(GtkHTMLEmbedded *eb, cairo_t *cr, gpointer graph);
-#else
-static void draw_print_cb(GtkHTMLEmbedded *eb, GnomePrintContext *context, gpointer graph);
-#endif
-#endif
-
-static gboolean create_basic_plot_elements(const char *plot_type, GogObject **out_graph, GogObject **out_chart, GogPlot **out_plot);
-
 static double * read_doubles(const char * string, int nvalues);
 
-static void set_chart_titles_from_hash(GogObject *chart, gpointer eb);
-static void set_chart_titles(GogObject *chart, const char *title, const char* sub_title);
-static void set_chart_axis_labels_from_hash(GogObject *chart, gpointer eb);
-static void set_chart_axis_labels(GogObject *chart, const char *x_axis_label, const char* y_axis_label);
-
 void
 gnc_html_graph_gog_webkit_init( void )
 {
@@ -170,141 +156,61 @@
   return retval;  
 }
 
-#if 0
-static void
-add_pixbuf_graph_widget( GtkHTMLEmbedded *eb, GogObject *graph )
+static int
+get_int_value( gchar** str, const gchar* name )
 {
-  GtkWidget *widget;
-#if defined(HAVE_GOFFICE_0_5)
-  GogRenderer *renderer;
-#elif defined(GOFFICE_WITH_CAIRO)
-  GogRendererCairo *cairo_renderer;
-#else
-  GogRendererPixbuf *pixbuf_renderer;
-#endif
-  GdkPixbuf *buf;
-  gboolean update_status;
+	gchar* p;
+	gchar* tag_name;
+	int val = -1;
 
-  // Note that this shouldn't be necessary as per discussion with Jody...
-  // ... but it is because we don't embed in a control which passes the
-  // update requests back to the graph widget, a-la the foo-canvas that
-  // gnumeric uses.  We probably _should_ do something like that, though.
-  gog_object_update (GOG_OBJECT (graph));
+	tag_name = g_strdup_printf( "%s=", name );
+	p = g_strstr_len( *str, -1, tag_name );
+	if( p != NULL ) {
+		val = atoi( p+strlen( tag_name ) );
+		*str = p+strlen( tag_name );
+	}
+	g_free( tag_name );
 
-#if defined(HAVE_GOFFICE_0_5)
-  renderer = GOG_RENDERER (g_object_new (GOG_RENDERER_TYPE,
-					 "model", graph,
-					 NULL));
-  update_status = gog_renderer_update (renderer, eb->width, eb->height);
-  buf = gog_renderer_get_pixbuf (renderer);
-#elif defined(GOFFICE_WITH_CAIRO)
-  cairo_renderer = GOG_RENDERER_CAIRO (g_object_new (GOG_RENDERER_CAIRO_TYPE,
-						     "model", graph,
-						     NULL));
-  update_status = gog_renderer_cairo_update (cairo_renderer,
-					     eb->width, eb->height, 1.0);
-  buf = gog_renderer_cairo_get_pixbuf (cairo_renderer);
-#else
-  pixbuf_renderer = GOG_RENDERER_PIXBUF (g_object_new (GOG_RENDERER_PIXBUF_TYPE,
-						       "model", graph,
-						       NULL));
-  update_status = gog_renderer_pixbuf_update (pixbuf_renderer,
-					      eb->width, eb->height, 1.0);
-  buf = gog_renderer_pixbuf_get (pixbuf_renderer);
-#endif
-
-  widget = gtk_image_new_from_pixbuf (buf);
-  gtk_widget_set_size_request (widget, eb->width, eb->height);
-  gtk_widget_show_all (widget);
-  gtk_container_add (GTK_CONTAINER (eb), widget);
-
-  // blindly copied from gnc-html-guppi.c..
-  gtk_widget_set_size_request (GTK_WIDGET (eb), eb->width, eb->height);
-
-  g_object_set_data_full (G_OBJECT (eb), "graph", graph, g_object_unref);
-  g_signal_connect (G_OBJECT (eb), "draw_print",
-		    G_CALLBACK (draw_print_cb), NULL);
+	return val;
 }
-#endif
 
-static gboolean
-create_basic_plot_elements(const char *plot_type_name,
-                           GogObject **out_graph,
-                           GogObject **out_chart,
-                           GogPlot **out_plot)
+static int
+get_int_param( gchar** str, const gchar* name )
 {
-  *out_graph = g_object_new(GOG_GRAPH_TYPE, NULL);
-  *out_chart = gog_object_add_by_name(*out_graph, "Chart", NULL);
-  *out_plot = gog_plot_new_by_name(plot_type_name);
-  if (!*out_plot)
-  {
-    // FIXME - log betterer; should probably use GError?
-    g_warning("gog: unable to load %s plugin", plot_type_name);
-    return FALSE;
-  }
-  gog_object_add_by_name(*out_chart, "Plot", GOG_OBJECT(*out_plot) );
-  return TRUE;
-}
+	gchar* p;
+	gchar* tag_string;
+	int val = -1;
 
-static void
-set_chart_titles_from_hash(GogObject *chart, gpointer eb)
-{
-  set_chart_titles(chart,
-                   (const char *)gnc_html_get_embedded_param(eb, "title"), 
-                   (const char *)gnc_html_get_embedded_param(eb, "subtitle"));
-}
+	tag_string = g_strdup_printf( "<param name=\"%s\" value=\"", name );
+	p = g_strstr_len( *str, -1, tag_string );
+	if( p != NULL ) {
+		val = atoi( p+strlen( tag_string ) );
+		*str = p+strlen( tag_string );
+	}
+	g_free( tag_string );
 
-static void
-set_chart_titles(GogObject *chart, const char *title, const char* sub_title)
-{
-  gchar *my_sub_title, *total_title;
-  GOData *title_scalar;
-  GogObject *tmp;
-
-  if (sub_title)
-    my_sub_title = g_strdup_printf("%s(%s)", title ? " " : "", sub_title);
-  else
-    my_sub_title = g_strdup("");
-
-  total_title = g_strdup_printf("%s%s", title ? title : "", my_sub_title);
-
-  tmp = gog_object_add_by_name(chart, "Title", NULL);
-  title_scalar = go_data_scalar_str_new(total_title, TRUE);
-  gog_dataset_set_dim(GOG_DATASET(tmp), 0, title_scalar, NULL);
-
-  g_free(my_sub_title);
+	return val;
 }
 
-static void
-set_chart_axis_labels_from_hash(GogObject *chart, gpointer eb)
+static gchar*
+get_string_param( gchar** str, const gchar* name )
 {
-  set_chart_axis_labels(chart,
-                        gnc_html_get_embedded_param(eb, "x_axis_label"),
-                        gnc_html_get_embedded_param(eb, "y_axis_label"));
-}
+	gchar* p;
+	gchar* p_end;
+	gchar* tag_string;
+	gchar* val = NULL;
 
-static void
-set_chart_axis_labels(GogObject *chart, const char *x_axis_label, const char* y_axis_label)
-{
-  if (x_axis_label != NULL)
-  {
-    GogObject *xaxis, *label;
-    GOData *data;
-    xaxis = gog_object_get_child_by_role(chart, gog_object_find_role_by_name(chart, "X-Axis"));
-    label = gog_object_add_by_name(xaxis, "Label", NULL);
-    data = go_data_scalar_str_new(x_axis_label, FALSE);
-    gog_dataset_set_dim(GOG_DATASET(label), 0, data, NULL);
-  }
+	tag_string = g_strdup_printf( "<param name=\"%s\" value=\"", name );
+	p = g_strstr_len( *str, -1, tag_string );
+	if( p != NULL ) {
+		p += strlen( tag_string );
+		p_end = g_strstr_len( p, -1, "\">\n" );
+		val = g_strndup( p, (p_end-p) );
+		*str = p_end+strlen( "\">\n" );
+	}
+	g_free( tag_string );
 
-  if (y_axis_label != NULL)
-  {
-    GogObject *yaxis, *label;
-    GOData *data;
-    yaxis = gog_object_get_child_by_role(chart, gog_object_find_role_by_name(chart, "Y-Axis"));
-    label = gog_object_add_by_name(yaxis, "Label", NULL);
-    data = go_data_scalar_str_new(y_axis_label, FALSE);
-    gog_dataset_set_dim(GOG_DATASET(label), 0, data, NULL);
-  }
+	return val;
 }
 
 /*
@@ -319,58 +225,47 @@
  * legend_urls_[123]: ?
  */
 static gboolean
-handle_piechart( GncHtml* html, gpointer eb, gpointer unused )
+handle_piechart( GncHtml* html, gpointer eb, gpointer d )
 {
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GOData *labelData, *sliceData;
-  int datasize;
-  double *data = NULL;
-  char **labels = NULL, **colors = NULL;
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlPieChartInfo pieChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* filename;
 
-  // parse data from the text-ized params.
-  {
-    const char *datasizeStr, *dataStr, *labelsStr, *colorStr;
+	pieChartInfo.width = get_int_value( &object_info, "width" );
+	pieChartInfo.height = get_int_value( &object_info, "height" );
+	pieChartInfo.title = get_string_param( &object_info, "title" );
+	pieChartInfo.subtitle = get_string_param( &object_info, "subtitle" );
+	pieChartInfo.datasize = get_int_param( &object_info, "datasize" );
+	temp_str = get_string_param( &object_info, "data" );
+	if( temp_str != NULL ) {
+		pieChartInfo.data = read_doubles( temp_str, pieChartInfo.datasize );
+	}
+	temp_str = get_string_param( &object_info, "colors" );
+	if( temp_str != NULL ) {
+		pieChartInfo.colors = read_strings( temp_str, pieChartInfo.datasize );
+		g_free( temp_str );
+	}
+	temp_str = get_string_param( &object_info, "labels" );
+	if( temp_str != NULL ) {
+		pieChartInfo.labels = read_strings( temp_str, pieChartInfo.datasize );
+		g_free( temp_str );
+	}
 
-    datasizeStr = gnc_html_get_embedded_param(eb, "datasize");
-    dataStr = gnc_html_get_embedded_param(eb, "data" );
-    labelsStr = gnc_html_get_embedded_param(eb, "labels");
-    colorStr = gnc_html_get_embedded_param(eb, "colors");
-    g_return_val_if_fail( datasizeStr != NULL
-                          && dataStr != NULL
-                          && labelsStr != NULL
-                          && colorStr != NULL, FALSE );
-    datasize = atoi( datasizeStr );
-    data = read_doubles( dataStr, datasize );
-    labels = read_strings( labelsStr, datasize );
-    colors = read_strings( colorStr, datasize );
-  }
+	pixbuf = gnc_html_graph_gog_create_piechart( &pieChartInfo );
+	if( pieChartInfo.title != NULL ) g_free( (gchar*)pieChartInfo.title );
+	if( pieChartInfo.subtitle != NULL ) g_free( (gchar*)pieChartInfo.subtitle );
 
-  if (!create_basic_plot_elements("GogPiePlot", &graph, &chart, &plot))
-  {
-    return FALSE;
-  }
-  gog_object_add_by_name(chart, "Legend", NULL);
+	filename = "/tmp/piechart.png";
+	gdk_pixbuf_savev( pixbuf, filename, "png", NULL, NULL, NULL );
+	*pResult = g_strdup_printf( "<img src=\"%s\" alt=\"Cannot display piechart\"/>", filename );
 
-  GOG_STYLED_OBJECT(graph)->style->outline.width = 5;
-  GOG_STYLED_OBJECT(graph)->style->outline.color = RGBA_BLACK;
-
-  series = gog_plot_new_series(plot);
-  labelData = go_data_vector_str_new((char const * const *)labels, datasize, NULL);
-  gog_series_set_dim(series, 0, labelData, NULL);
-  go_data_emit_changed(GO_DATA(labelData));
-
-  sliceData = go_data_vector_val_new(data, datasize, NULL);
-  gog_series_set_dim(series, 1, sliceData, NULL);
-  go_data_emit_changed(GO_DATA(sliceData));
-
-  // fixme: colors
-  set_chart_titles_from_hash(chart, eb);
-
-//FIXME  add_pixbuf_graph_widget (eb, graph);
-
-  return TRUE;
+	g_debug("piechart rendered.");
+	return TRUE;
 }
 
 /**
@@ -386,125 +281,59 @@
  * stacked:boolean
  **/
 static gboolean
-handle_barchart( GncHtml* html, gpointer eb, gpointer unused )
+handle_barchart( GncHtml* html, gpointer eb, gpointer d )
 {
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GogStyle *style;
-  GOData *label_data, *slice_data;
-  int data_rows, data_cols;
-  double *data = NULL;
-  char **col_labels = NULL, **row_labels = NULL, **col_colors = NULL;
-  gboolean rotate_row_labels = FALSE;
-  gboolean stacked = FALSE;
-  char *bar_type = "normal";
-  int bar_overlap = 0 /*percent*/; // seperate bars; no overlap.
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlBarChartInfo barChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* filename;
 
-  // parse data from the text-ized params
-  // series => bars [gnc:cols]
-  // series-elements => segments [gnc:rows]
-  {
-    const char *data_rows_str, *data_cols_str, *data_str, *col_labels_str, *row_labels_str;
-    const char *col_colors_str, *rotate_row_labels_str = NULL, *stacked_str = NULL;
+	barChartInfo.width = get_int_value( &object_info, "width" );
+	barChartInfo.height = get_int_value( &object_info, "height" );
+	barChartInfo.title = get_string_param( &object_info, "title" );
+	barChartInfo.subtitle = get_string_param( &object_info, "subtitle" );
+	barChartInfo.data_rows = get_int_param( &object_info, "data_rows" );
+	barChartInfo.data_cols = get_int_param( &object_info, "data_cols" );
+	temp_str = get_string_param( &object_info, "data" );
+	if( temp_str != NULL ) {
+		barChartInfo.data = read_doubles( temp_str, barChartInfo.data_rows*barChartInfo.data_cols );
+	}
+	barChartInfo.x_axis_label = get_string_param( &object_info, "x_axis_label" );
+	barChartInfo.y_axis_label = get_string_param( &object_info, "y_axis_label" );
+	temp_str = get_string_param( &object_info, "col_colors" );
+	if( temp_str != NULL ) {
+		barChartInfo.col_colors = read_strings( temp_str, barChartInfo.data_cols );
+		g_free( temp_str );
+	}
+	temp_str = get_string_param( &object_info, "row_labels" );
+	if( temp_str != NULL ) {
+		barChartInfo.row_labels = read_strings( temp_str, barChartInfo.data_rows );
+		g_free( temp_str );
+	}
+	temp_str = get_string_param( &object_info, "col_labels" );
+	if( temp_str != NULL ) {
+		barChartInfo.col_labels = read_strings( temp_str, barChartInfo.data_cols );
+		g_free( temp_str );
+	}
+	barChartInfo.rotate_row_labels = get_int_param( &object_info, "rotate_row_labels" );
+	barChartInfo.stacked = get_int_param( &object_info, "stacked" );
 
-    data_rows_str         = gnc_html_get_embedded_param (eb, "data_rows");
-    data_cols_str         = gnc_html_get_embedded_param (eb, "data_cols");
-    data_str              = gnc_html_get_embedded_param (eb, "data" );
-    row_labels_str        = gnc_html_get_embedded_param (eb, "row_labels");
-    col_labels_str        = gnc_html_get_embedded_param (eb, "col_labels");
-    col_colors_str        = gnc_html_get_embedded_param (eb, "col_colors");
-    rotate_row_labels_str = gnc_html_get_embedded_param (eb, "rotate_row_labels");
-    stacked_str           = gnc_html_get_embedded_param (eb, "stacked");
+	pixbuf = gnc_html_graph_gog_create_barchart( &barChartInfo );
+	if( barChartInfo.title != NULL ) g_free( (gchar*)barChartInfo.title );
+	if( barChartInfo.subtitle != NULL ) g_free( (gchar*)barChartInfo.subtitle );
+	if( barChartInfo.x_axis_label != NULL ) g_free( (gchar*)barChartInfo.x_axis_label );
+	if( barChartInfo.y_axis_label != NULL ) g_free( (gchar*)barChartInfo.y_axis_label );
 
-    rotate_row_labels     = (gboolean) atoi (rotate_row_labels_str);
-    stacked               = (gboolean) atoi (stacked_str);
+	filename = "/tmp/barchart.png";
+	gdk_pixbuf_savev( pixbuf, filename, "png", NULL, NULL, NULL );
+	*pResult = g_strdup_printf( "<img src=\"%s\" alt=\"Cannot display barchart\"/>", filename );
 
-#if 0 // too strong at the moment.
-    g_return_val_if_fail (data_rows_str != NULL
-                          && data_cols_str != NULL
-                          && data_str != NULL
-                          && col_labels_str != NULL
-                          && row_labels_str != NULL
-                          && col_colors_str != NULL, FALSE );
-#endif // 0
-    data_rows = atoi (data_rows_str);
-    data_cols = atoi (data_cols_str);
-    data = read_doubles (data_str, data_rows*data_cols);
-    row_labels = read_strings (row_labels_str, data_rows);
-    col_labels = read_strings (col_labels_str, data_cols);
-    col_colors = read_strings (col_colors_str, data_cols);
-  }
-
-  if (!create_basic_plot_elements("GogBarColPlot", &graph, &chart, &plot)) {
-    return FALSE;
-  }
-  gog_object_add_by_name(chart, "Legend", NULL);
-
-  if ( stacked ) {
-    // when stacked, we want the bars on _top_ of eachother.
-    bar_type = "stacked";
-    bar_overlap = 100 /*percent*/;
-  }
-
-  g_object_set (G_OBJECT (plot),
-                //"vary_style_by_element",	TRUE,
-                "type",                         bar_type,
-                "overlap_percentage",           bar_overlap, 
-                NULL);
-  label_data = go_data_vector_str_new ((char const * const *)row_labels, data_rows, NULL);
-  {
-    // foreach row:
-    //   series = row
-    GdkColor color;
-    int i;
-    for (i = 0; i < data_cols; i++) {
-      GError *err = NULL;
-
-      series = gog_plot_new_series (plot);
-      gog_object_set_name (GOG_OBJECT (series), col_labels[i], &err);
-      if (err != NULL)
-      {
-           g_warning("error setting name [%s] on series [%d]: [%s]",
-                     col_labels[i], i, err->message);
-      }
-
-      g_object_ref (label_data);
-      gog_series_set_dim (series, 0, label_data, NULL);
-      go_data_emit_changed (GO_DATA (label_data));
-
-      slice_data = go_data_vector_val_new (data + (i*data_rows), data_rows, NULL);
-      gog_series_set_dim (series, 1, slice_data, NULL);
-      go_data_emit_changed (GO_DATA (slice_data));
-
-      style = gog_styled_object_get_style (GOG_STYLED_OBJECT (series));
-      style->fill.type = GOG_FILL_STYLE_PATTERN;
-      if (gdk_color_parse (col_colors[i], &color)) {
-           style->fill.auto_back = FALSE;
-           go_pattern_set_solid (&style->fill.pattern, GDK_TO_UINT (color));
-      } else {
-           g_warning("cannot parse color [%s]", col_colors[i]);
-      }
-    }
-  }
-
-  if (rotate_row_labels) {
-    GogObject *object = gog_object_get_child_by_role (
-      chart, gog_object_find_role_by_name (chart, "X-Axis"));
-    style = gog_styled_object_get_style (GOG_STYLED_OBJECT (object));
-    gog_style_set_text_angle (style, 90.0);
-  }
-
-  set_chart_titles_from_hash (chart, eb);
-  set_chart_axis_labels_from_hash (chart, eb);
-
-  // we need to do this twice for the barchart... :p
-  gog_object_update (GOG_OBJECT (graph));
-
-//FIXME  add_pixbuf_graph_widget (eb, graph);
-
-  g_debug("barchart rendered.");
-  return TRUE;
+	g_debug("barchart rendered.");
+	return TRUE;
 }
 
 
@@ -524,298 +353,103 @@
  * minor_grid:boolean
  **/
 static gboolean
-handle_linechart( GncHtml* html, gpointer eb, gpointer unused )
+handle_linechart( GncHtml* html, gpointer eb, gpointer d )
 {
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GogStyle *style;
-  GOData *label_data, *slice_data;
-  int data_rows, data_cols;
-  double *data = NULL;
-  char **col_labels = NULL, **row_labels = NULL, **col_colors = NULL;
-  gboolean rotate_row_labels = FALSE;
-  gboolean stacked = FALSE;
-  gboolean markers = FALSE;
-  gboolean major_grid = FALSE;
-  gboolean minor_grid = FALSE;
-  char *line_type = "normal";
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlLineChartInfo lineChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* filename;
 
-  // parse data from the text-ized params
-  // series => lines [gnc:cols]
-  // series-elements => segments [gnc:rows]
-  {
-    const char *data_rows_str, *data_cols_str, *data_str, *col_labels_str, *row_labels_str;
-    const char *col_colors_str, *rotate_row_labels_str = NULL, *stacked_str = NULL, *markers_str = NULL;
-    const char *major_grid_str = NULL, *minor_grid_str = NULL;
+	lineChartInfo.width = get_int_value( &object_info, "width" );
+	lineChartInfo.height = get_int_value( &object_info, "height" );
+	lineChartInfo.title = get_string_param( &object_info, "title" );
+	lineChartInfo.subtitle = get_string_param( &object_info, "subtitle" );
+	lineChartInfo.data_rows = get_int_param( &object_info, "data_rows" );
+	lineChartInfo.data_cols = get_int_param( &object_info, "data_cols" );
+	temp_str = get_string_param( &object_info, "data" );
+	if( temp_str != NULL ) {
+		lineChartInfo.data = read_doubles( temp_str, lineChartInfo.data_rows*lineChartInfo.data_cols );
+	}
+	lineChartInfo.x_axis_label = get_string_param( &object_info, "x_axis_label" );
+	lineChartInfo.y_axis_label = get_string_param( &object_info, "y_axis_label" );
+	temp_str = get_string_param( &object_info, "col_colors" );
+	if( temp_str != NULL ) {
+		lineChartInfo.col_colors = read_strings( temp_str, lineChartInfo.data_cols );
+		g_free( temp_str );
+	}
+	temp_str = get_string_param( &object_info, "row_labels" );
+	if( temp_str != NULL ) {
+		lineChartInfo.row_labels = read_strings( temp_str, lineChartInfo.data_rows );
+		g_free( temp_str );
+	}
+	temp_str = get_string_param( &object_info, "col_labels" );
+	if( temp_str != NULL ) {
+		lineChartInfo.col_labels = read_strings( temp_str, lineChartInfo.data_cols );
+		g_free( temp_str );
+	}
+	lineChartInfo.rotate_row_labels = get_int_param( &object_info, "rotate_row_labels" );
+	lineChartInfo.stacked = get_int_param( &object_info, "stacked" );
+	lineChartInfo.markers = get_int_param( &object_info, "markers" );
+	lineChartInfo.major_grid = get_int_param( &object_info, "major_grid" );
+	lineChartInfo.minor_grid = get_int_param( &object_info, "minor_grid" );
 
-    data_rows_str         = gnc_html_get_embedded_param (eb, "data_rows");
-    data_cols_str         = gnc_html_get_embedded_param (eb, "data_cols");
-    data_str              = gnc_html_get_embedded_param (eb, "data" );
-    row_labels_str        = gnc_html_get_embedded_param (eb, "row_labels");
-    col_labels_str        = gnc_html_get_embedded_param (eb, "col_labels");
-    col_colors_str        = gnc_html_get_embedded_param (eb, "col_colors");
-    rotate_row_labels_str = gnc_html_get_embedded_param (eb, "rotate_row_labels");
-    stacked_str           = gnc_html_get_embedded_param (eb, "stacked");
-    markers_str           = gnc_html_get_embedded_param (eb, "markers");
-    major_grid_str        = gnc_html_get_embedded_param (eb, "major_grid");
-    minor_grid_str        = gnc_html_get_embedded_param (eb, "minor_grid");
+	pixbuf = gnc_html_graph_gog_create_linechart( &lineChartInfo );
+	if( lineChartInfo.title != NULL ) g_free( (gchar*)lineChartInfo.title );
+	if( lineChartInfo.subtitle != NULL ) g_free( (gchar*)lineChartInfo.subtitle );
+	if( lineChartInfo.x_axis_label != NULL ) g_free( (gchar*)lineChartInfo.x_axis_label );
+	if( lineChartInfo.y_axis_label != NULL ) g_free( (gchar*)lineChartInfo.y_axis_label );
 
-    rotate_row_labels     = (gboolean) atoi (rotate_row_labels_str);
-    stacked               = (gboolean) atoi (stacked_str);
-    markers               = (gboolean) atoi (markers_str);
-    major_grid            = (gboolean) atoi (major_grid_str);
-    minor_grid            = (gboolean) atoi (minor_grid_str);
+	filename = "/tmp/linechart.png";
+	gdk_pixbuf_savev( pixbuf, filename, "png", NULL, NULL, NULL );
+	*pResult = g_strdup_printf( "<img src=\"%s\" alt=\"Cannot display linechart\"/>", filename );
 
-#if 0 // too strong at the moment.
-    g_return_val_if_fail (data_rows_str != NULL
-                          && data_cols_str != NULL
-                          && data_str != NULL
-                          && col_labels_str != NULL
-                          && row_labels_str != NULL
-                          && col_colors_str != NULL, FALSE );
-#endif // 0
-
-    data_rows = atoi (data_rows_str);
-    data_cols = atoi (data_cols_str);
-    data = read_doubles (data_str, data_rows*data_cols);
-    row_labels = read_strings (row_labels_str, data_rows);
-    col_labels = read_strings (col_labels_str, data_cols);
-    col_colors = read_strings (col_colors_str, data_cols);
-  }
-
-  if (!create_basic_plot_elements("GogLinePlot", &graph, &chart, &plot)) {
-    return FALSE;
-  }
-  gog_object_add_by_name(chart, "Legend", NULL);
-
-  if ( stacked ) {
-    // when stacked, we want the lines on _top_ of eachother.
-    line_type = "stacked";
-  }
-
-  g_object_set (G_OBJECT (plot),
-                //"vary_style_by_element",	TRUE,
-                "type",                         line_type,
-                "default-style-has-markers",	markers,
-                NULL);
-  label_data = go_data_vector_str_new ((char const * const *)row_labels, data_rows, NULL);
-  {
-    // foreach row:
-    //   series = row
-    GdkColor color;
-    int i;
-    for (i = 0; i < data_cols; i++) {
-      GError *err = NULL;
-
-      series = gog_plot_new_series (plot);
-      gog_object_set_name (GOG_OBJECT (series), col_labels[i], &err);
-      if (err != NULL)
-      {
-           g_warning("error setting name [%s] on series [%d]: [%s]",
-                     col_labels[i], i, err->message);
-      }
-
-      g_object_ref (label_data);
-      gog_series_set_dim (series, 0, label_data, NULL);
-      go_data_emit_changed (GO_DATA (label_data));
-
-      slice_data = go_data_vector_val_new (data + (i*data_rows), data_rows, NULL);
-      gog_series_set_dim (series, 1, slice_data, NULL);
-      go_data_emit_changed (GO_DATA (slice_data));
-
-      style = gog_styled_object_get_style (GOG_STYLED_OBJECT (series));
-      style->fill.type = GOG_FILL_STYLE_PATTERN;
-      if (gdk_color_parse (col_colors[i], &color)) {
-           style->fill.auto_back = FALSE;
-           go_pattern_set_solid (&style->fill.pattern, GDK_TO_UINT (color));
-      } else {
-           g_warning("cannot parse color [%s]", col_colors[i]);
-      }
-    }
-  }
-
-  if (rotate_row_labels) {
-    GogObject *object = gog_object_get_child_by_role (
-      chart, gog_object_find_role_by_name (chart, "X-Axis"));
-    style = gog_styled_object_get_style (GOG_STYLED_OBJECT (object));
-    gog_style_set_text_angle (style, 90.0);
-  }
-
-  if (major_grid || minor_grid) {
-    GogObject *object;
-    gog_object_add_by_name(chart,"Grid", NULL);
-    object = gog_object_get_child_by_role (chart, gog_object_find_role_by_name (chart, "Y-Axis"));
-    if (major_grid)
-      gog_object_add_by_name (GOG_OBJECT (object),"MajorGrid", NULL);
-    if (minor_grid)
-      gog_object_add_by_name (GOG_OBJECT (object),"MinorGrid", NULL);
-  }
-
-  set_chart_titles_from_hash (chart, eb);
-  set_chart_axis_labels_from_hash (chart, eb);
-
-  // we need to do this twice for the linechart... :p
-  gog_object_update (GOG_OBJECT (graph));
-
-//FIXME  add_pixbuf_graph_widget (eb, graph);
-
-  g_debug("linechart rendered.");
-  return TRUE;
+	g_debug("linechart rendered.");
+	return TRUE;
 }
 
 
 static gboolean
-handle_scatter( GncHtml* html, gpointer eb, gpointer unused )
+handle_scatter( GncHtml* html, gpointer eb, gpointer d )
 {
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GOData *sliceData;
-  GogStyle *style;
-  int datasize;
-  double *xData, *yData;
-  const gchar *marker_str, *color_str;
-  gboolean fill = FALSE;
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlScatterPlotInfo scatterPlotInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* filename;
 
-  {
-    const char *datasizeStr, *xDataStr, *yDataStr;
+	scatterPlotInfo.width = get_int_value( &object_info, "width" );
+	scatterPlotInfo.height = get_int_value( &object_info, "height" );
+	scatterPlotInfo.title = get_string_param( &object_info, "title" );
+	scatterPlotInfo.subtitle = get_string_param( &object_info, "subtitle" );
+	scatterPlotInfo.x_axis_label = get_string_param( &object_info, "x_axis_label" );
+	scatterPlotInfo.y_axis_label = get_string_param( &object_info, "y_axis_label" );
+	scatterPlotInfo.marker_str = get_string_param( &object_info, "marker" );
+	scatterPlotInfo.color_str = get_string_param( &object_info, "color" );
+	scatterPlotInfo.datasize = get_int_param( &object_info, "datasize" );
+	temp_str = get_string_param( &object_info, "x_data" );
+	if( temp_str != NULL ) {
+		scatterPlotInfo.xData = read_doubles( temp_str, scatterPlotInfo.datasize );
+	}
+	temp_str = get_string_param( &object_info, "y_data" );
+	if( temp_str != NULL ) {
+		scatterPlotInfo.yData = read_doubles( temp_str, scatterPlotInfo.datasize );
+	}
 
-    datasizeStr = gnc_html_get_embedded_param( eb, "datasize" );
-    datasize = atoi( datasizeStr );
+	pixbuf = gnc_html_graph_gog_create_scatterplot( &scatterPlotInfo );
+	if( scatterPlotInfo.title != NULL ) g_free( (gchar*)scatterPlotInfo.title );
+	if( scatterPlotInfo.subtitle != NULL ) g_free( (gchar*)scatterPlotInfo.subtitle );
 
-    xDataStr = gnc_html_get_embedded_param( eb, "x_data" );
-    xData = read_doubles( xDataStr, datasize );
+	filename = "/tmp/scatterplot.png";
+	gdk_pixbuf_savev( pixbuf, filename, "png", NULL, NULL, NULL );
+	*pResult = g_strdup_printf( "<img src=\"%s\" alt=\"Cannot display scatterplot\"/>", filename );
 
-    yDataStr = gnc_html_get_embedded_param( eb, "y_data" );
-    yData = read_doubles( yDataStr, datasize );
-
-    marker_str = gnc_html_get_embedded_param(eb, "marker");
-    color_str = gnc_html_get_embedded_param(eb, "color");
-  }
-
-  if (!create_basic_plot_elements("GogXYPlot", &graph, &chart, &plot))
-  {
-    return FALSE;
-  }
-
-  series = gog_plot_new_series( plot );
-  style = gog_styled_object_get_style(GOG_STYLED_OBJECT(series));
-
-  sliceData = go_data_vector_val_new( xData, datasize, NULL );
-  gog_series_set_dim( series, 0, sliceData, NULL );
-  go_data_emit_changed (GO_DATA (sliceData));
-
-  sliceData = go_data_vector_val_new( yData, datasize, NULL );
-  gog_series_set_dim( series, 1, sliceData, NULL );
-  go_data_emit_changed (GO_DATA (sliceData));
-
-  /* set marker shape */
-  if (marker_str) {
-    GOMarkerShape shape;
-
-    if (g_str_has_prefix(marker_str, "filled ")) {
-      fill = TRUE;
-      marker_str += 7;
-    }
-    shape = go_marker_shape_from_str(marker_str);
-    if (shape != GO_MARKER_NONE) {
-      style->marker.auto_shape = FALSE;
-      go_marker_set_shape(style->marker.mark, shape);
-    } else {
-      g_warning("cannot parse marker shape [%s]", marker_str);
-    }
-  }
-
-  /* set marker and line colors */
-  if (color_str) {
-    GdkColor color;
-    if (gdk_color_parse(color_str, &color)) {
-      style->marker.auto_outline_color = FALSE;
-      go_marker_set_outline_color(style->marker.mark, GDK_TO_UINT(color));
-      style->line.auto_color = FALSE;
-      style->line.color = GDK_TO_UINT(color);
-    } else {
-      g_warning("cannot parse color [%s]", color_str);
-    }
-  }
-
-  /* set marker fill colors */
-  if (fill) {
-    style->marker.auto_fill_color = style->marker.auto_outline_color;
-    go_marker_set_fill_color(style->marker.mark,
-                             go_marker_get_outline_color(style->marker.mark));
-  } else {
-    GogStyle *chart_style =
-      gog_styled_object_get_style(GOG_STYLED_OBJECT(chart));
-
-    if (chart_style->fill.type == GOG_FILL_STYLE_PATTERN
-        && chart_style->fill.pattern.pattern == GO_PATTERN_SOLID) {
-      style->marker.auto_fill_color = FALSE;
-      go_marker_set_fill_color(style->marker.mark,
-                               chart_style->fill.pattern.back);
-    } else if (chart_style->fill.type == GOG_FILL_STYLE_PATTERN
-               && chart_style->fill.pattern.pattern
-               == GO_PATTERN_FOREGROUND_SOLID) {
-      style->marker.auto_fill_color = FALSE;
-      go_marker_set_fill_color(style->marker.mark,
-                               chart_style->fill.pattern.fore);
-    } else {
-      g_warning("fill color of markers can only be set like a solid fill "
-                "pattern of the chart");
-    }
-  }
-
-  set_chart_titles_from_hash(chart, eb);
-  set_chart_axis_labels_from_hash(chart, eb);
-
-  // And twice for the scatter, too... :p
-  gog_object_update(GOG_OBJECT(graph));
-
-//FIXME  add_pixbuf_graph_widget (eb, graph);
-
-  return TRUE;
+	g_debug("scatterplot rendered.");
+	return TRUE;
 }
-
-#if 0
-#ifdef GTKHTML_USES_GTKPRINT
-static void
-draw_print_cb(GtkHTMLEmbedded *eb, cairo_t *cr, gpointer unused)
-{
-  GogGraph *graph = GOG_GRAPH(g_object_get_data(G_OBJECT(eb), "graph"));
-#    ifdef HAVE_GOFFICE_0_5
-  GogRenderer *rend = g_object_new(GOG_RENDERER_TYPE, "model", graph, NULL);
-#    else
-  GogRendererCairo *rend = g_object_new(GOG_RENDERER_CAIRO_TYPE, "model", graph,
-                                        "cairo", cr, "is-vector", TRUE, NULL);
-#    endif
-
-  /* assuming pixel size is 0.5, cf. gtkhtml/src/htmlprinter.c */
-  cairo_scale(cr, 0.5, 0.5);
-
-  cairo_translate(cr, 0, -eb->height);
-
-#    ifdef HAVE_GOFFICE_0_5
-  gog_renderer_render_to_cairo(rend, cr, eb->width, eb->height);
-#    else
-  gog_renderer_cairo_update(rend, eb->width, eb->height, 1.0);
-#    endif
-  g_object_unref(rend);
-}
-#endif
-
-#else /* !GTKHTML_USES_GTKPRINT */
-#if 0
-static void
-draw_print_cb(GtkHTMLEmbedded *eb, GnomePrintContext *context, gpointer unused)
-{
-  GogGraph *graph = GOG_GRAPH (g_object_get_data (G_OBJECT (eb), "graph"));
-
-  /* assuming pixel size is 0.5, cf. gtkhtml/src/htmlprinter.c */
-  gnome_print_scale (context, 0.5, 0.5);
-
-  gnome_print_translate (context, 0, eb->height);
-  gog_graph_print_to_gnome_print (graph, context, eb->width, eb->height);
-}
-#endif
-#endif /* GTKHTML_USES_GTKPRINT */

Modified: gnucash/branches/webkit/src/html/gnc-html-graph-gog.c
===================================================================
--- gnucash/branches/webkit/src/html/gnc-html-graph-gog.c	2009-03-28 19:12:52 UTC (rev 18004)
+++ gnucash/branches/webkit/src/html/gnc-html-graph-gog.c	2009-03-28 22:20:08 UTC (rev 18005)
@@ -67,11 +67,6 @@
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "gnc.html.graph.gog"
 
-static int handle_piechart( GncHtml* html, gpointer eb, gpointer d );
-static int handle_barchart( GncHtml* html, gpointer eb, gpointer d );
-static int handle_linechart( GncHtml* html, gpointer eb, gpointer d );
-static int handle_scatter( GncHtml* html, gpointer eb, gpointer d );
-
 static gboolean create_basic_plot_elements(const char *plot_type, GogObject **out_graph, GogObject **out_chart, GogPlot **out_plot);
 
 static void set_chart_titles(GogObject *chart, const char *title, const char* sub_title);

Modified: gnucash/branches/webkit/src/html/gnc-html-webkit.c
===================================================================
--- gnucash/branches/webkit/src/html/gnc-html-webkit.c	2009-03-28 19:12:52 UTC (rev 18004)
+++ gnucash/branches/webkit/src/html/gnc-html-webkit.c	2009-03-28 22:20:08 UTC (rev 18005)
@@ -92,6 +92,7 @@
 												GObject* arg2, gpointer data );
 static void webkit_on_url_cb( WebKitWebView* web_view, gchar* title, gchar* url,
 							gpointer data );
+static gchar* handle_embedded_object( GncHtmlWebkit* self, gchar* html_str );
 #if 0
 static void gnc_html_set_base_cb( GtkHTML* gtkhtml, const gchar* base, gpointer data );
 static void gnc_html_link_clicked_cb( GtkHTML* html, const gchar* url, gpointer data );
@@ -312,15 +313,63 @@
 	return TRUE;
 }
 
+static gchar*
+handle_embedded_object( GncHtmlWebkit* self, gchar* html_str )
+{
+	// Find the <object> tag and get the classid from it.  This will provide the correct
+	// object callback handler.  Pass the <object> entity text to the handler.  What should
+	// come back is embedded image information.
+	gchar* object_tag;
+	gchar* end_object_tag;
+	gchar* object_contents;
+	gchar* html_str_start;
+	gchar* html_str_middle;
+	gchar* html_str_result;
+	gchar* classid;
+	gchar* classid_end;
+	gchar* object_classid;
+	GncHTMLObjectCB h;
+
+	object_tag = g_strstr_len( html_str, -1, "<object classid=" );
+	if( object_tag == NULL ) {
+		//  Hmmm... no object tag
+		return html_str;
+	}
+	classid = object_tag+strlen( "<object classid=" )+1;
+	classid_end = g_strstr_len( classid, -1, "\"" );
+	object_classid = g_strndup( classid, (classid_end-classid) );
+	end_object_tag = g_strstr_len( object_tag, -1, "</object>" );
+	if( end_object_tag == NULL ) {
+		//  Hmmm... no object end tag
+		return html_str;
+	}
+	end_object_tag += strlen( "</object>" );
+	object_contents = g_strndup( object_tag, (end_object_tag-object_tag) );
+
+	h = g_hash_table_lookup( gnc_html_object_handlers, object_classid );
+	if( h != NULL ) {
+		(void)h( GNC_HTML(self), object_contents, &html_str_middle );
+	} else {
+		html_str_middle = g_strdup_printf( "No handler found for classid \"%s\"", object_classid );
+	}
+
+	html_str_start = g_strndup( html_str, (object_tag-html_str) );
+	html_str_result = g_strdup_printf( "%s%s%s", html_str_start, html_str_middle, end_object_tag );
+	
+	g_free( html_str_start );
+	g_free( html_str_middle );
+	return html_str_result;
+}
+
 /********************************************************************
- * gnc_html_load_to_stream : actually do the work of loading the HTML
+ * load_to_stream : actually do the work of loading the HTML
  * or binary data referenced by a URL and feeding it into the GtkHTML
  * widget.
  ********************************************************************/
 
 static void
-gnc_html_load_to_stream( GncHtmlWebkit* self, URLType type,
-						const gchar* location, const gchar* label )
+load_to_stream( GncHtmlWebkit* self, URLType type,
+				const gchar* location, const gchar* label )
 {
 	gchar* fdata = NULL;
 	int fdata_len = 0;
@@ -340,6 +389,16 @@
 
 			if( ok ) {
 				fdata = fdata ? fdata : g_strdup( "" );
+
+				// Until webkitgtk supports download requests, look for "<object classid="
+				// indicating the beginning of an embedded graph.  If found, handle it
+				if( g_strstr_len( fdata, -1, "<object classid=" ) != NULL ) {
+					gchar* new_fdata;
+					new_fdata = handle_embedded_object( self, fdata );
+					g_free( fdata );
+					fdata = new_fdata;
+				}
+
 				webkit_web_view_load_html_string( priv->web_view, fdata, "base-uri" );
 			} else {
 				fdata = fdata ? fdata :
@@ -442,7 +501,7 @@
 	DEBUG( "requesting %s", url );
 	type = gnc_html_parse_url( GNC_HTML(self), url, &location, &label );
 	gnc_html_show_url( GNC_HTML(self), type, location, label, 0 );
-//	gnc_html_load_to_stream( self, type, location, label );
+//	load_to_stream( self, type, location, label );
 	g_free( location );
 	g_free( label );
 }
@@ -683,7 +742,7 @@
 			DEBUG( "resetting base location to %s",
 					priv->base.base_location ? priv->base.base_location : "(null)" );
 
-			gnc_html_load_to_stream( GNC_HTML_WEBKIT(self), result.url_type,
+			load_to_stream( GNC_HTML_WEBKIT(self), result.url_type,
 									new_location, new_label );
 
 			if( priv->base.load_cb != NULL ) {
@@ -740,7 +799,7 @@
 			/* FIXME : handle new_window = 1 */
 			gnc_html_history_append( priv->base.history,
 								gnc_html_history_node_new( type, location, label ) );
-			gnc_html_load_to_stream( GNC_HTML_WEBKIT(self), type, location, label );
+			load_to_stream( GNC_HTML_WEBKIT(self), type, location, label );
 
 		} while( FALSE );
 



More information about the gnucash-changes mailing list