r18041 - gnucash/trunk - Merge webkit branch into trunk.

Phil Longstaff plongstaff at code.gnucash.org
Fri Apr 10 21:44:15 EDT 2009


Author: plongstaff
Date: 2009-04-10 21:44:14 -0400 (Fri, 10 Apr 2009)
New Revision: 18041
Trac: http://svn.gnucash.org/trac/changeset/18041

Added:
   gnucash/trunk/src/html/
   gnucash/trunk/src/html/Makefile.am
   gnucash/trunk/src/html/gnc-html-extras.h
   gnucash/trunk/src/html/gnc-html-factory.c
   gnucash/trunk/src/html/gnc-html-factory.h
   gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.c
   gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.h
   gnucash/trunk/src/html/gnc-html-graph-gog-webkit.c
   gnucash/trunk/src/html/gnc-html-graph-gog-webkit.h
   gnucash/trunk/src/html/gnc-html-graph-gog.c
   gnucash/trunk/src/html/gnc-html-graph-gog.h
   gnucash/trunk/src/html/gnc-html-gtkhtml-p.h
   gnucash/trunk/src/html/gnc-html-gtkhtml.c
   gnucash/trunk/src/html/gnc-html-gtkhtml.h
   gnucash/trunk/src/html/gnc-html-history.c
   gnucash/trunk/src/html/gnc-html-history.h
   gnucash/trunk/src/html/gnc-html-p.h
   gnucash/trunk/src/html/gnc-html-webkit-p.h
   gnucash/trunk/src/html/gnc-html-webkit.c
   gnucash/trunk/src/html/gnc-html-webkit.h
   gnucash/trunk/src/html/gnc-html.c
   gnucash/trunk/src/html/gnc-html.h
   gnucash/trunk/src/html/gnc-html.i
   gnucash/trunk/src/html/gncmod-html.c
Removed:
   gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.c
   gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.h
   gnucash/trunk/src/gnome-utils/gnc-html-history.c
   gnucash/trunk/src/gnome-utils/gnc-html-history.h
   gnucash/trunk/src/gnome-utils/gnc-html.c
   gnucash/trunk/src/gnome-utils/gnc-html.h
Modified:
   gnucash/trunk/configure.in
   gnucash/trunk/src/Makefile.am
   gnucash/trunk/src/business/business-gnome/Makefile.am
   gnucash/trunk/src/business/dialog-tax-table/Makefile.am
   gnucash/trunk/src/gnome-utils/Makefile.am
   gnucash/trunk/src/gnome-utils/gnc-gnome-utils.c
   gnucash/trunk/src/gnome-utils/gnc-main-window.c
   gnucash/trunk/src/gnome-utils/gncmod-gnome-utils.c
   gnucash/trunk/src/gnome-utils/gnome-utils.i
   gnucash/trunk/src/gnome/Makefile.am
   gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
   gnucash/trunk/src/gnome/gnc-plugin-page-budget.c
   gnucash/trunk/src/import-export/Makefile.am
   gnucash/trunk/src/import-export/csv/Makefile.am
   gnucash/trunk/src/import-export/hbci/Makefile.am
   gnucash/trunk/src/import-export/hbci/druid-hbci-initial.c
   gnucash/trunk/src/import-export/log-replay/Makefile.am
   gnucash/trunk/src/import-export/ofx/Makefile.am
   gnucash/trunk/src/import-export/qif-import/Makefile.am
   gnucash/trunk/src/report/report-gnome/Makefile.am
   gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
   gnucash/trunk/src/report/report-gnome/window-report.c
   gnucash/trunk/src/report/report-gnome/window-report.h
   gnucash/trunk/src/report/report-system/gnc-report.c
   gnucash/trunk/src/report/report-system/report-system.scm
Log:
Merge webkit branch into trunk.

In order to use the webkit as the html engine, use --enable-webkit on the configure
command.  In SCM files, gnc-html-engine-supports-css can be used to determine whether
the html engine is webkit (supports css) or gtkhtml (doesn't support css).



Modified: gnucash/trunk/configure.in
===================================================================
--- gnucash/trunk/configure.in	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/configure.in	2009-04-11 01:44:14 UTC (rev 18041)
@@ -515,6 +515,26 @@
 AC_SUBST(GCONF_LIBS)
 
 ### --------------------------------------------------------------------------
+### look for webkit
+
+AC_ARG_ENABLE(webkit,
+  [AS_HELP_STRING([--enable-webkit],[build with the webkit HTML engine])],
+  [case "${enableval}" in
+     yes) want_webkit=true ;;
+     no)  want_webkit=false ;;
+     *) want_webkit=false ;;
+   esac],
+   [want_webkit=false])
+if test x${want_webkit} = xtrue
+then
+  PKG_CHECK_MODULES(WEBKIT, webkit-1.0 >= "1.0")
+  AC_DEFINE(WANT_WEBKIT,1,[Use webkit instead of gtkhtml])
+fi
+AM_CONDITIONAL(HTML_USING_WEBKIT, test x${want_webkit} = xtrue)
+AC_SUBST(WEBKIT_CFLAGS)
+AC_SUBST(WEBKIT_LIBS)
+
+### --------------------------------------------------------------------------
 ### LIBXML -- GNOME_XML_LIB is defined by GNOME_XML_CHECK
 
 LIBXML2_REQUIRED=2.5.10
@@ -1511,6 +1531,7 @@
 	  src/gnome-utils/test/Makefile
 	  src/gnome-utils/ui/Makefile
           src/gnome-search/Makefile
+		  src/html/Makefile
           src/import-export/Makefile
           src/import-export/test/Makefile
           src/import-export/qif-import/Makefile

Modified: gnucash/trunk/src/Makefile.am
===================================================================
--- gnucash/trunk/src/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -15,6 +15,7 @@
   tax \
   app-utils \
   gnome-utils \
+  html \
   gnome-search
 
 GUI_SUBDIRS_2 = \

Modified: gnucash/trunk/src/business/business-gnome/Makefile.am
===================================================================
--- gnucash/trunk/src/business/business-gnome/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/business/business-gnome/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -12,6 +12,7 @@
   -I${top_srcdir}/src/gnome \
   -I${top_srcdir}/src/app-utils \
   -I${top_srcdir}/src/gnome-search \
+  -I${top_srcdir}/src/html \
   -I${top_srcdir}/src/report/report-gnome \
   -I${top_srcdir}/src/business/business-core \
   -I${top_srcdir}/src/business/business-ledger \
@@ -22,8 +23,6 @@
   -I${top_srcdir}/src/libqof/qof \
   ${GNOME_CFLAGS} \
   ${GLADE_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
-  ${GDK_PIXBUF_CFLAGS} \
   ${GLIB_CFLAGS} \
   ${GUILE_INCS}
 
@@ -76,6 +75,7 @@
   ${top_builddir}/src/gnome-search/libgncmod-gnome-search.la \
   ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
   ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/src/html/libgncmod-html.la \
   ${top_builddir}/src/engine/libgncmod-engine.la \
   ${top_builddir}/src/core-utils/libgnc-core-utils.la \
   ${top_builddir}/src/gnc-module/libgnc-module.la \

Modified: gnucash/trunk/src/business/dialog-tax-table/Makefile.am
===================================================================
--- gnucash/trunk/src/business/dialog-tax-table/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/business/dialog-tax-table/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -11,8 +11,6 @@
   -I${top_srcdir}/src/libqof/qof \
   ${GNOME_CFLAGS} \
   ${GLADE_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
-  ${GDK_PIXBUF_CFLAGS} \
   ${GLIB_CFLAGS} \
   ${GUILE_INCS}
 

Modified: gnucash/trunk/src/gnome/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -12,13 +12,15 @@
   ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
   ${top_builddir}/src/backend/xml/libgnc-backend-xml-utils.la \
   ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/src/html/libgncmod-html.la \
   ${top_builddir}/src/engine/libgncmod-engine.la \
   ${top_builddir}/src/core-utils/libgnc-core-utils.la \
   ${top_builddir}/src/libqof/qof/libgnc-qof.la \
   ${GLADE_LIBS} \
   ${GUILE_LIBS} \
   ${GNOME_LIBS} \
-  ${GLIB_LIBS}
+  ${GLIB_LIBS} \
+  ${QOF_LIBS}
 
 libgnc_gnome_la_SOURCES = \
   swig-gnome.c \
@@ -112,6 +114,7 @@
   -I${top_srcdir}/src/backend/xml \
   -I${top_srcdir}/src/gnome-utils \
   -I${top_srcdir}/src/gnome-search \
+  -I${top_srcdir}/src/html \
   -I${top_srcdir}/src/register/ledger-core \
   -I${top_srcdir}/src/register/register-core \
   -I${top_srcdir}/src/register/register-gnome \
@@ -121,8 +124,7 @@
   -I${top_srcdir}/src/libqof/qof \
   ${GUILE_INCS} \
   ${GNOME_CFLAGS} \
-  ${GDK_PIXBUF_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
+  ${GNOME_PRINT_CFLAGS} \
   ${GLADE_CFLAGS} \
   $(GLIB_CFLAGS)
 

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -52,7 +52,6 @@
 #include "gnc-gconf-utils.h"
 #include "gnc-gnome-utils.h"
 #include "gnc-gobject-utils.h"
-#include "gnc-html.h"
 #include "gnc-icons.h"
 #include "gnc-plugin-account-tree.h"
 #include "gnc-session.h"

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-budget.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-budget.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-budget.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -45,7 +45,6 @@
 #include "dialog-options.h"
 #include "dialog-utils.h"
 #include "gnc-gnome-utils.h"
-#include "gnc-html.h"
 #include "gnc-icons.h"
 #include "gnc-plugin-page-budget.h"
 #include "gnc-plugin-budget.h"

Modified: gnucash/trunk/src/gnome-utils/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome-utils/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -18,9 +18,9 @@
   ${GLADE_CFLAGS} \
   ${GTK_CFLAGS} \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
+  ${GNOME_PRINT_CFLAGS} \
   ${GUILE_INCS} \
-  ${GOFFICE_CFLAGS}
+  ${QOF_CFLAGS} 
 
 libgncmod_gnome_utils_la_SOURCES = \
   QuickFill.c \
@@ -63,9 +63,6 @@
   gnc-general-select.c \
   gnc-gnome-utils.c \
   gnc-gui-query.c \
-  gnc-html-graph-gog.c \
-  gnc-html-history.c \
-  gnc-html.c \
   gnc-icons.c \
   gnc-main-window.c \
   gnc-menu-extensions.c \
@@ -134,9 +131,6 @@
   gnc-general-select.h \
   gnc-gnome-utils.h \
   gnc-gui-query.h \
-  gnc-html-graph-gog.h \
-  gnc-html-history.h \
-  gnc-html.h \
   gnc-icons.h \
   gnc-main-window.h \
   gnc-menu-extensions.h \
@@ -186,14 +180,11 @@
   $(top_builddir)/lib/libc/libc-missing.la \
   ${top_builddir}/src/libqof/qof/libgnc-qof.la \
   ${GNOME_LIBS} \
-  ${GTKHTML_LIBS} \
-  ${GUILE_LIBS} \
-  ${GDK_PIXBUF_LIBS} \
+  ${GNOME_PRINT_LIBS} \
   ${GLADE_LIBS} \
   ${GUILE_LIBS} \
   ${GLIB_LIBS} \
   ${DB_LIBS} \
-  ${GOFFICE_LIBS} \
   ${REGEX_LIBS} \
   ${LIBXML2_LIBS}
 
@@ -202,7 +193,7 @@
 endif
 
 if BUILDING_FROM_SVN
-swig-gnome-utils.c: gnome-utils.i gnc-html.h \
+swig-gnome-utils.c: gnome-utils.i \
                     ${top_srcdir}/src/base-typemaps.i
 	$(SWIG) -guile $(SWIG_ARGS) -Linkage module \
 	-I${top_srcdir}/src -o $@ $<
@@ -220,11 +211,6 @@
   ${gncmod_DATA} \
   ${gncscm_DATA}
 
-if !GTKHTML_USES_GTKPRINT
-  AM_CPPFLAGS += ${GNOME_PRINT_CFLAGS}
-  libgncmod_gnome_utils_la_LIBADD += ${GNOME_PRINT_LIBS}
-endif
-
 ## We borrow guile's convention and use @-...-@ as the substitution
 ## brackets here, instead of the usual @... at .  This prevents autoconf
 ## from substituting the values directly into the left-hand sides of

Modified: gnucash/trunk/src/gnome-utils/gnc-gnome-utils.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-gnome-utils.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-gnome-utils.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -32,12 +32,12 @@
 #endif
 #include <libxml/xmlIO.h>
 
-#include "gnc-html-graph-gog.h"
+//#include "gnc-html-graph-gog.h"
 
 #include "druid-gconf-setup.h"
 #include "gnc-gconf-utils.h"
 #include "gnc-gnome-utils.h"
-#include "gnc-html.h"
+//#include "gnc-html.h"
 #include "gnc-engine.h"
 #include "gnc-path.h"
 #include "gnc-ui.h"

Deleted: gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,835 +0,0 @@
-/********************************************************************
- * gnc-html-graph-gog.c -- GNC/HTML Graphing support via GOG        *
- *                                                                  *
- * Copyright (C) 2005 Joshua Sled <jsled at asynchronous.org>          *
- *                                                                  *
- * 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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- ********************************************************************/
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-embedded.h>
-#include <string.h>
-
-#include "gnc-ui-util.h"
-#include "gnc-html-graph-gog.h"
-#include "gnc-html.h"
-#include "gnc-engine.h"
-#include <goffice/goffice.h>
-#include <goffice/graph/gog-chart.h>
-#include <goffice/graph/gog-graph.h>
-#include <goffice/graph/gog-object.h>
-#if defined(HAVE_GOFFICE_0_5)
-#    include <goffice/graph/gog-renderer.h>
-#elif defined(GOFFICE_WITH_CAIRO)
-#    include <goffice/graph/gog-renderer-cairo.h>
-#else
-#    include <goffice/graph/gog-renderer-pixbuf.h>
-#endif
-#ifndef GTKHTML_USES_GTKPRINT
-#    include <goffice/graph/gog-renderer-gnome-print.h>
-#endif
-#include <goffice/graph/gog-style.h>
-#include <goffice/graph/gog-styled-object.h>
-#include <goffice/graph/gog-plot.h>
-#include <goffice/graph/gog-series.h>
-#include <goffice/utils/go-color.h>
-#include <goffice/utils/go-marker.h>
-#include <goffice/graph/gog-data-set.h>
-#include <goffice/data/go-data-simple.h>
-#include <goffice/app/go-plugin.h>
-#include <goffice/app/go-plugin-loader-module.h>
-
-/**
- * TODO:
- * - scatter-plot marker selection
- * - series-color, piecharts (hard, not really supported by GOG)
- *   and scatters (or drop feature)
- * - title-string freeing (fixmes)
- * - general graph cleanup
- **/
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "gnc.gui.html.graph.gog"
-
-static int handle_piechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer d);
-static int handle_barchart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer d);
-static int handle_linechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer d);
-static int handle_scatter(gnc_html * html, GtkHTMLEmbedded * eb, gpointer d);
-
-#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
-
-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, GtkHTMLEmbedded * 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, GtkHTMLEmbedded * eb);
-static void set_chart_axis_labels(GogObject *chart, const char *x_axis_label, const char* y_axis_label);
-static void gtkhtml_pre_3_10_1_bug_workaround(GtkHTMLEmbedded *eb);
-
-void
-gnc_html_graph_gog_init(void)
-{
-
-  g_debug( "init gog graphing" );
-  
-  libgoffice_init();
-  
-  /* Initialize plugins manager */
-  go_plugins_init (NULL, NULL, NULL, NULL, TRUE, GO_PLUGIN_LOADER_MODULE_TYPE);
-
-  gnc_html_register_object_handler( "gnc-guppi-pie", handle_piechart );
-  gnc_html_register_object_handler( "gnc-guppi-bar", handle_barchart );
-  gnc_html_register_object_handler( "gnc-guppi-scatter", handle_scatter );
-  gnc_html_register_object_handler( "gnc-guppi-line", handle_linechart );
-}
-
-static double * 
-read_doubles(const char * string, int nvalues)
-{
-  int    n;
-  gchar *next;
-  double * retval = g_new0(double, nvalues);
-
-  // guile is going to (puts ...) the elements of the double array
-  // together. In non-POSIX locales, that will be in a format that
-  // the locale-specific sscanf will not be able to parse.
-  gnc_push_locale("C");
-  {
-    for (n=0; n<nvalues; n++) {
-      retval[n] = strtod(string, &next);
-      string = next;
-     }
-  }
-  gnc_pop_locale();
-
-  return retval;
-}
-
-static char ** 
-read_strings(const char * string, int nvalues)
-{
-  int n;
-  int choffset=0;
-  int accum = 0;
-  char ** retval = g_new0(char *, nvalues);
-  char thischar;
-  const char * inptr = string;
-  int escaped = FALSE;
-
-  for (n=0; n < nvalues; n++) {
-    retval[n] = g_new0(char, strlen(string+accum)+1);
-    retval[n][0] = 0;
-    choffset = 0;
-    while ((thischar = *inptr) != 0) {
-      if (thischar == '\\') {
-        escaped = TRUE;
-        inptr++;
-      }
-      else if ((thischar != ' ') || escaped) {
-        retval[n][choffset] = thischar;
-        retval[n][choffset+1] = 0;    
-        choffset++;
-        escaped = FALSE;
-        inptr++;
-      }
-      else {
-        /* an unescaped space */
-        escaped = FALSE;
-        inptr++;
-        break;
-      }
-    }
-    accum += choffset;
-    /* printf("retval[%d] = '%s'\n", n, retval[n]); */
-  }
-  
-  return retval;  
-}
-
-static void
-add_pixbuf_graph_widget( GtkHTMLEmbedded *eb, GogObject *graph )
-{
-  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;
-
-  // 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));
-
-#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);
-}
-
-static gboolean
-create_basic_plot_elements(const char *plot_type_name,
-                           GogObject **out_graph,
-                           GogObject **out_chart,
-                           GogPlot **out_plot)
-{
-  *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;
-}
-
-static void
-set_chart_titles_from_hash(GogObject *chart, GtkHTMLEmbedded * eb)
-{
-  set_chart_titles(chart,
-                   (const char *)g_hash_table_lookup(eb->params, "title"), 
-                   (const char *)g_hash_table_lookup(eb->params, "subtitle"));
-}
-
-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);
-}
-
-static void
-set_chart_axis_labels_from_hash(GogObject *chart, GtkHTMLEmbedded * eb)
-{
-  set_chart_axis_labels(chart,
-                        (const char *)g_hash_table_lookup(eb->params, "x_axis_label"),
-                        (const char *)g_hash_table_lookup(eb->params, "y_axis_label"));
-}
-
-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);
-  }
-
-  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);
-  }
-}
-
-static void
-gtkhtml_pre_3_10_1_bug_workaround(GtkHTMLEmbedded *eb)
-{
-  /* HACK ALERT! Compensate for bug in gtkhtml < 3.10.1
-     Gtkhtml set the width parameter twice (=width, =height), so both,
-     width (==height) and height (<1) were incorrect. */
-  if (eb->height < 1)
-  {
-      eb->height = eb->width;  /* only squares here :( */
-  }
-}
-
-/*
- * Handle the following parameters:
- * title: text
- * subtitle: text
- * datasize: (length data), sscanf( .., %d, (int)&datasize )
- * data: (foreach (lambda (datum) (push datum) (push " ")) data)
- * colors: string; space-seperated?
- * labels: string; space-seperated?
- * slice_urls_[123]: ?
- * legend_urls_[123]: ?
- */
-static gboolean
-handle_piechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer unused)
-{
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GOData *labelData, *sliceData;
-  int datasize;
-  double *data = NULL;
-  char **labels = NULL, **colors = NULL;
-
-  gtkhtml_pre_3_10_1_bug_workaround(eb);
-
-  // parse data from the text-ized params.
-  {
-    char *datasizeStr, *dataStr, *labelsStr, *colorStr;
-
-    datasizeStr = g_hash_table_lookup(eb->params, "datasize");
-    dataStr = g_hash_table_lookup(eb->params, "data" );
-    labelsStr = g_hash_table_lookup(eb->params, "labels");
-    colorStr = g_hash_table_lookup(eb->params, "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 );
-  }
-
-  if (!create_basic_plot_elements("GogPiePlot", &graph, &chart, &plot))
-  {
-    return FALSE;
-  }
-  gog_object_add_by_name(chart, "Legend", NULL);
-
-  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);
-
-  add_pixbuf_graph_widget (eb, graph);
-
-  return TRUE;
-}
-
-/**
- * data_rows:int
- * data_cols:int
- * data:doubles[], data_rows*data_cols
- * x_axis_label:string
- * y_axis_label:string
- * row_labels:string[]
- * col_labels:string[]
- * col_colors:string[]
- * rotate_row_labels:boolean
- * stacked:boolean
- **/
-static gboolean
-handle_barchart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer unused)
-{
-  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.
-
-  gtkhtml_pre_3_10_1_bug_workaround (eb);
-
-  // parse data from the text-ized params
-  // series => bars [gnc:cols]
-  // series-elements => segments [gnc:rows]
-  {
-    char *data_rows_str, *data_cols_str, *data_str, *col_labels_str, *row_labels_str;
-    char *col_colors_str, *rotate_row_labels_str = NULL, *stacked_str = NULL;
-
-    data_rows_str         = g_hash_table_lookup (eb->params, "data_rows");
-    data_cols_str         = g_hash_table_lookup (eb->params, "data_cols");
-    data_str              = g_hash_table_lookup (eb->params, "data" );
-    row_labels_str        = g_hash_table_lookup (eb->params, "row_labels");
-    col_labels_str        = g_hash_table_lookup (eb->params, "col_labels");
-    col_colors_str        = g_hash_table_lookup (eb->params, "col_colors");
-    rotate_row_labels_str = g_hash_table_lookup (eb->params, "rotate_row_labels");
-    stacked_str           = g_hash_table_lookup (eb->params, "stacked");
-
-    rotate_row_labels     = (gboolean) atoi (rotate_row_labels_str);
-    stacked               = (gboolean) atoi (stacked_str);
-
-#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));
-
-  add_pixbuf_graph_widget (eb, graph);
-
-  g_debug("barchart rendered.");
-  return TRUE;
-}
-
-
-/**
- * data_rows:int
- * data_cols:int
- * data:doubles[], data_rows*data_cols
- * x_axis_label:string
- * y_axis_label:string
- * row_labels:string[]
- * col_labels:string[]
- * col_colors:string[]
- * rotate_row_labels:boolean
- * stacked:boolean
- * markers:boolean
- * major_grid:boolean
- * minor_grid:boolean
- **/
-static gboolean
-handle_linechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer unused)
-{
-  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";
-
-  gtkhtml_pre_3_10_1_bug_workaround (eb);
-
-  // parse data from the text-ized params
-  // series => lines [gnc:cols]
-  // series-elements => segments [gnc:rows]
-  {
-    char *data_rows_str, *data_cols_str, *data_str, *col_labels_str, *row_labels_str;
-    char *col_colors_str, *rotate_row_labels_str = NULL, *stacked_str = NULL, *markers_str = NULL;
-    char *major_grid_str = NULL, *minor_grid_str = NULL;
-
-    data_rows_str         = g_hash_table_lookup (eb->params, "data_rows");
-    data_cols_str         = g_hash_table_lookup (eb->params, "data_cols");
-    data_str              = g_hash_table_lookup (eb->params, "data" );
-    row_labels_str        = g_hash_table_lookup (eb->params, "row_labels");
-    col_labels_str        = g_hash_table_lookup (eb->params, "col_labels");
-    col_colors_str        = g_hash_table_lookup (eb->params, "col_colors");
-    rotate_row_labels_str = g_hash_table_lookup (eb->params, "rotate_row_labels");
-    stacked_str           = g_hash_table_lookup (eb->params, "stacked");
-    markers_str           = g_hash_table_lookup (eb->params, "markers");
-    major_grid_str        = g_hash_table_lookup (eb->params, "major_grid");
-    minor_grid_str        = g_hash_table_lookup (eb->params, "minor_grid");
-
-    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);
-
-#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));
-
-  add_pixbuf_graph_widget (eb, graph);
-
-  g_debug("linechart rendered.");
-  return TRUE;
-}
-
-
-static gboolean
-handle_scatter(gnc_html * html, GtkHTMLEmbedded * eb, gpointer unused)
-{
-  GogObject *graph, *chart;
-  GogPlot *plot;
-  GogSeries *series;
-  GOData *sliceData;
-  GogStyle *style;
-  int datasize;
-  double *xData, *yData;
-  gchar *marker_str, *color_str;
-  gboolean fill = FALSE;
-
-  gtkhtml_pre_3_10_1_bug_workaround(eb);
-
-  {
-    char *datasizeStr, *xDataStr, *yDataStr;
-
-    datasizeStr = g_hash_table_lookup( eb->params, "datasize" );
-    datasize = atoi( datasizeStr );
-
-    xDataStr = g_hash_table_lookup( eb->params, "x_data" );
-    xData = read_doubles( xDataStr, datasize );
-
-    yDataStr = g_hash_table_lookup( eb->params, "y_data" );
-    yData = read_doubles( yDataStr, datasize );
-
-    marker_str = g_hash_table_lookup(eb->params, "marker");
-    color_str = g_hash_table_lookup(eb->params, "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));
-
-  add_pixbuf_graph_widget (eb, graph);
-
-  return TRUE;
-}
-
-#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);
-}
-
-#else /* !GTKHTML_USES_GTKPRINT */
-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 /* GTKHTML_USES_GTKPRINT */

Deleted: gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.h	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html-graph-gog.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,6 +0,0 @@
-#ifndef GNC_HTML_GRAPH_GOG_H
-#define GNC_HTML_GRAPH_GOG_H 1
-
-void gnc_html_graph_gog_init(void);
-
-#endif /* GNC_HTML_GRAPH_GOG_H */

Deleted: gnucash/trunk/src/gnome-utils/gnc-html-history.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html-history.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html-history.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,277 +0,0 @@
-/********************************************************************
- * gnc-html-history.c -- keep a HTML history                        * 
- * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
- *                                                                  *
- * 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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- ********************************************************************/
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include "gnc-html-history.h"
-
-struct _gnc_html_history {
-  GList * nodes;
-  GList * current_node; 
-  GList * last_node;
-
-  /* call this whenever a node is destroyed */
-  gnc_html_history_destroy_cb destroy_cb;
-  gpointer                    destroy_cb_data;
-};
-
-/********************************************************************
- * gnc_html_history_new
- ********************************************************************/
-
-gnc_html_history * 
-gnc_html_history_new(void) {
-  gnc_html_history * hist = g_new0(gnc_html_history, 1);
-  hist->nodes         = NULL;
-  hist->current_node  = NULL;
-  hist->last_node     = NULL;
-  return hist;
-}
-
-
-
-/********************************************************************
- * gnc_html_history_destroy
- ********************************************************************/
-
-void
-gnc_html_history_destroy(gnc_html_history * hist) {
-  GList * n;
-
-  for(n = hist->nodes; n ; n=n->next) {
-    if(hist->destroy_cb) {
-      (hist->destroy_cb)((gnc_html_history_node *)n->data,
-                         hist->destroy_cb_data);
-    }
-    gnc_html_history_node_destroy((gnc_html_history_node *)n->data);
-  }
-  g_list_free(hist->nodes);
-
-  hist->nodes         = NULL;
-  hist->current_node  = NULL;
-  hist->last_node     = NULL;
-  g_free(hist);
-}
-
-/********************************************************************
- * gnc_html_history_set_node_destroy_cb
- ********************************************************************/
-
-void
-gnc_html_history_set_node_destroy_cb(gnc_html_history * hist, 
-                                     gnc_html_history_destroy_cb cb,
-                                     gpointer cb_data) {
-  hist->destroy_cb = cb;
-  hist->destroy_cb_data = cb_data;
-}
-
-static int 
-g_strcmp(char * a, char * b) {
-  if(!a && b) {
-    return 1;
-  }
-  else if(a && !b) {
-    return -1;
-  }
-  else if(!a && !b) {
-    return 0;
-  }
-  else {
-    return strcmp(a, b);
-  }
-  
-}
-
-
-/********************************************************************
- * gnc_html_history_append
- ********************************************************************/
-void 
-gnc_html_history_append(gnc_html_history * hist, 
-                        gnc_html_history_node * node) {
-  GList * n;
-  gnc_html_history_node * hn;
-  
-  if(hist->current_node) {
-    hn = hist->current_node->data;    
-    if((hn->type == node->type) &&
-       !g_strcmp(hn->location, node->location) &&
-       !g_strcmp(hn->label, node->label)) {      
-      if(hist->destroy_cb) {
-        (hist->destroy_cb)(hn, hist->destroy_cb_data);
-      }
-      gnc_html_history_node_destroy(node);
-      return;
-    }
-    
-    /* blow away the history after this point, if there is one */
-    for(n=hist->current_node->next; n; n=n->next) {
-      if(hist->destroy_cb) {
-        (hist->destroy_cb)((gnc_html_history_node *)n->data,
-                           hist->destroy_cb_data);
-      }
-      gnc_html_history_node_destroy((gnc_html_history_node *)n->data); 
-    }
-    g_list_free(hist->current_node->next);
-    hist->current_node->next = NULL;
-    hist->last_node = hist->current_node;
-  }
-  
-  n = g_list_alloc();
-  n->data = (gpointer) node;
-  n->next = NULL;
-  n->prev = NULL;
-
-  if(hist->nodes && hist->last_node) {
-    n->prev               = hist->last_node;  /* back pointer */ 
-    hist->last_node->next = n;                /* add n to the list */ 
-    hist->last_node       = n;                /* n is last */ 
-    hist->current_node    = n;
-  }
-  else {
-    /* this is the first entry in the list */
-    if(hist->nodes) {
-      g_print ("???? hist->nodes non-NULL, but no last_node \n");
-    }
-    hist->nodes        = n;
-    hist->last_node    = n;
-    hist->current_node = n;
-  }  
-}
-
-
-/********************************************************************
- * gnc_html_history_get_current
- ********************************************************************/
-
-gnc_html_history_node * 
-gnc_html_history_get_current(gnc_html_history * hist) {
-  if(!hist || !(hist->current_node)) return NULL;
-
-  return hist->current_node->data;
-}
-
-
-/********************************************************************
- * gnc_html_history_forward
- ********************************************************************/
-
-gnc_html_history_node *
-gnc_html_history_forward(gnc_html_history * hist) {
-  if(!hist || !(hist->current_node)) {
-    return NULL;
-  }
-  
-  if(hist->current_node->next) {
-    hist->current_node = hist->current_node->next;
-  }
-
-  return hist->current_node->data;
-}
-
-
-/********************************************************************
- * gnc_html_history_back
- ********************************************************************/
-
-gnc_html_history_node *
-gnc_html_history_back(gnc_html_history * hist) {
-
-  if(!hist || !(hist->current_node)) {
-    return NULL;
-  }
-  
-  if(hist->current_node->prev) {
-    hist->current_node = hist->current_node->prev;
-  }
-  
-  return hist->current_node->data;
-}
-
-
-/********************************************************************
- * gnc_html_history_back_p
- * is it possible to go back?
- ********************************************************************/
-
-int
-gnc_html_history_back_p(gnc_html_history * hist) {
-  if(hist && hist->current_node && hist->current_node->prev) {
-    return TRUE;
-  }
-  else {
-    return FALSE;
-  }
-}
-
-
-/********************************************************************
- * gnc_html_history_forward_p
- * is it possible to go forward?
- ********************************************************************/
-
-int
-gnc_html_history_forward_p(gnc_html_history * hist) {
-  if(hist && hist->current_node && hist->current_node->next) {
-    return TRUE;
-  }
-  else {
-    return FALSE;
-  }
-}
-
-
-/********************************************************************
- * gnc_html_history_node_new
- ********************************************************************/
-
-gnc_html_history_node *
-gnc_html_history_node_new(URLType type, const gchar * location, 
-                          const gchar * label) {
-  gnc_html_history_node * rv = g_new0(gnc_html_history_node, 1);
-  
-  rv->type      = type;
-  rv->location  = g_strdup(location);
-  rv->label     = g_strdup(label);
-  return rv;
-}
-
-
-/********************************************************************
- * gnc_html_history_node_destroy
- ********************************************************************/
-
-void
-gnc_html_history_node_destroy(gnc_html_history_node * node) {
-  
-  /* free the url resources and cached text */
-  g_free(node->location);
-  g_free(node->label);
-
-  node->location = NULL;
-  node->label    = NULL; 
-
-  g_free(node);
-}

Deleted: gnucash/trunk/src/gnome-utils/gnc-html-history.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html-history.h	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html-history.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,64 +0,0 @@
-/********************************************************************
- * gnc-html-history.h -- keep a HTML history                        * 
- * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
- *                                                                  *
- * 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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- ********************************************************************/
-
-#ifndef GNC_HTML_HISTORY_H
-#define GNC_HTML_HISTORY_H
-
-typedef struct _gnc_html_history_node gnc_html_history_node;
-typedef struct _gnc_html_history gnc_html_history;
-
-#include "gnc-html.h"
-
-struct _gnc_html_history_node {
-  URLType type;
-  gchar   * location;
-  gchar   * label;  
-};
-
-typedef void (* gnc_html_history_destroy_cb)(gnc_html_history_node * n,
-                                             gpointer user_data);
-
-gnc_html_history      * gnc_html_history_new(void);
-void                    gnc_html_history_destroy(gnc_html_history * hist);
-
-void                    gnc_html_history_append(gnc_html_history * h,
-                                                gnc_html_history_node * n);
-gnc_html_history_node * gnc_html_history_get_current(gnc_html_history * h);
-gnc_html_history_node * gnc_html_history_forward(gnc_html_history * h);
-gnc_html_history_node * gnc_html_history_back(gnc_html_history * h);
-int                     gnc_html_history_forward_p(gnc_html_history * h);
-int                     gnc_html_history_back_p(gnc_html_history * h);
-void  gnc_html_history_set_node_destroy_cb(gnc_html_history * h,
-                                           gnc_html_history_destroy_cb cb,
-                                           gpointer cb_data);
-
-gnc_html_history_node * gnc_html_history_node_new(URLType type,
-                                                  const gchar * location, 
-                                                  const gchar * label);
-
-void                    gnc_html_history_node_destroy(gnc_html_history_node * 
-                                                      node);
-
-
-#endif
-
-

Deleted: gnucash/trunk/src/gnome-utils/gnc-html.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,1576 +0,0 @@
-/********************************************************************
- * gnc-html.c -- display HTML with some special gnucash tags.       *
- *                                                                  *
- * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
- * Copyright (C) 2001 Linas Vepstas <linas at linas.org>               *
- *                                                                  *
- * 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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- ********************************************************************/
-
-// libgtkhtml docs:
-// http://www.fifi.org/doc/libgtkhtml-dev/html/
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <regex.h>
-#include <libguile.h>
-
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-embedded.h>
-
-#include "Account.h"
-#include "print-session.h"
-#include "gnc-engine.h"
-#include "gnc-gui-query.h"
-#include "gnc-html.h"
-#include "gnc-html-history.h"
-#include "gnc-html-graph-gog.h"
-#include "gnc-ui.h"
-#include "gnc-ui-util.h"
-
-struct gnc_html_struct {
-  GtkWidget   * window;            /* window this html goes into */
-  GtkWidget   * container;         /* parent of the gtkhtml widget */
-  GtkWidget   * html;              /* gtkhtml widget itself */
-  gchar       * current_link;      /* link under mouse pointer */
-
-  URLType     base_type;           /* base of URL (path - filename) */
-  gchar       * base_location;
-
-    //gnc_http    * http;              /* handles HTTP requests */ 
-  GHashTable  * request_info;      /* hash uri to GList of GtkHTMLStream * */
-
-  /* callbacks */
-  GncHTMLUrltypeCB  urltype_cb;     /* is this type OK for this instance? */
-  GncHTMLLoadCB     load_cb;
-  GncHTMLFlyoverCB  flyover_cb;
-  GncHTMLButtonCB   button_cb;
-  
-  gpointer          flyover_cb_data;
-  gpointer          load_cb_data;
-  gpointer          button_cb_data;
-  
-  gnc_html_history * history; 
-};
-
-
-/* indicates the debugging module that this .o belongs to.  */
-static QofLogModule log_module = GNC_MOD_HTML;
-
-/* hashes for URLType -> protocol and protocol -> URLType */
-static GHashTable * gnc_html_type_to_proto_hash = NULL;
-static GHashTable * gnc_html_proto_to_type_hash = NULL;
-
-/* hashes an HTML <object classid="ID"> classid to a handler function */
-static GHashTable * gnc_html_object_handlers = NULL;
-
-/* hashes an action name from a FORM definition to a handler function.
- * <form method=METHOD action=gnc-action:ACTION-NAME?ACTION-ARGS> 
- * action-args is what gets passed to the handler. */
-static GHashTable * gnc_html_action_handlers = NULL;
-
-/* hashes handlers for loading different URLType data */
-static GHashTable * gnc_html_stream_handlers = NULL;
-
-/* hashes handlers for handling different URLType data */
-static GHashTable * gnc_html_url_handlers = NULL;
-
-static char error_404_format[] =
-"<html><body><h3>%s</h3><p>%s</body></html>";
-static char error_404_title[] = N_("Not found");
-static char error_404_body[] = 
-N_("The specified URL could not be loaded.");
-
-
-static char * 
-extract_machine_name(const gchar * path)
-{
-  char       machine_rexp[] = "^(//[^/]*)/*(.*)?$";
-  regex_t    compiled_m;
-  regmatch_t match[4];
-  char       * machine=NULL;
-
-  if(!path) return NULL;
-  
-  regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
-  
-  /* step 1: split the machine name away from the path
-   * components */
-  if(!regexec(&compiled_m, path, 4, match, 0)) {
-    /* $1 is the machine name */ 
-    if(match[1].rm_so != -1) {
-      machine = g_strndup(path+match[1].rm_so, 
-                          match[1].rm_eo - match[1].rm_so);
-    } 
-  }
-  return machine;
-}
-
-
-/* Register the URLType if it doesn't already exist.
- * Returns TRUE if successful, FALSE if the type already exists.
- */
-gboolean
-gnc_html_register_urltype (URLType type, const char *protocol)
-{
-  if (!gnc_html_type_to_proto_hash) {
-    gnc_html_type_to_proto_hash = g_hash_table_new (g_str_hash, g_str_equal);
-    gnc_html_proto_to_type_hash = g_hash_table_new (g_str_hash, g_str_equal);
-  }
-  if (!protocol) return FALSE;
-  if (g_hash_table_lookup (gnc_html_type_to_proto_hash, type))
-    return FALSE;
-
-  g_hash_table_insert (gnc_html_type_to_proto_hash, type, (gpointer)protocol);
-  if (*protocol)
-    g_hash_table_insert (gnc_html_proto_to_type_hash, (gpointer)protocol, type);
-
-  return TRUE;
-}
-
-/********************************************************************
- * gnc_html_parse_url
- * this takes a URL and determines the protocol type, location, and
- * possible anchor name from the URL.
- ********************************************************************/
-
-URLType
-gnc_html_parse_url(gnc_html * html, const gchar * url, 
-                   char ** url_location, char ** url_label)
-{
-  char        uri_rexp[] = "^(([^:][^:]+):)?([^#]+)?(#(.*))?$";
-  regex_t     compiled;
-  regmatch_t  match[6];
-  char        * protocol=NULL, * path=NULL, * label=NULL;
-  int         found_protocol=0, found_path=0, found_label=0; 
-  URLType     retval;   
-
-  DEBUG("parsing %s, base_location %s",
-        url ? url : "(null)",
-        html ? (html->base_location ? html->base_location
-                : "(null base_location)")
-        : "(null html)");
-  regcomp(&compiled, uri_rexp, REG_EXTENDED);
-
-  if(!regexec(&compiled, url, 6, match, 0)) {
-    if(match[2].rm_so != -1) {
-      protocol = g_new0(char, match[2].rm_eo - match[2].rm_so + 1);
-      strncpy(protocol, url + match[2].rm_so, 
-              match[2].rm_eo - match[2].rm_so);
-      protocol[match[2].rm_eo - match[2].rm_so] = 0;
-      found_protocol = 1;      
-    }
-    if(match[3].rm_so != -1) {
-      path = g_new0(char, match[3].rm_eo - match[3].rm_so + 1);
-      strncpy(path, url+match[3].rm_so, 
-              match[3].rm_eo - match[3].rm_so);
-      path[match[3].rm_eo - match[3].rm_so] = 0;
-      found_path = 1;
-    }
-    if(match[5].rm_so != -1) {
-      label = g_new0(char, match[5].rm_eo - match[5].rm_so + 1);
-      strncpy(label, url+match[5].rm_so, 
-              match[5].rm_eo - match[5].rm_so);
-      label[match[5].rm_eo - match[5].rm_so] = 0;
-      found_label = 1;
-    }
-  }
-
-  regfree(&compiled);
-
-  if(found_protocol) {
-    retval = g_hash_table_lookup (gnc_html_proto_to_type_hash, protocol);
-    if (!retval) {
-      PWARN("unhandled URL type for '%s'", url ? url : "(null)");
-      retval = URL_TYPE_OTHER;
-    }
-  }
-  else if(found_label && !found_path) {
-    retval = URL_TYPE_JUMP;
-  }
-  else {
-    if(html) {
-      retval = html->base_type;
-    }
-    else {
-      retval = URL_TYPE_FILE;
-    }
-  }
-  
-  g_free(protocol);
- 
-  if (!safe_strcmp (retval, URL_TYPE_FILE)) {
-    if(!found_protocol && path && html && html->base_location) {
-      if (g_path_is_absolute(path)) {
-        *url_location = g_strdup(path);
-      }
-      else {
-        *url_location =
-          g_build_filename(html->base_location, path, (gchar*)NULL);
-      }
-      g_free(path);
-    }
-    else {
-      *url_location = g_strdup(path);
-      g_free(path);
-    }
-
-  } else if (!safe_strcmp (retval, URL_TYPE_JUMP)) {
-    *url_location = NULL;
-    g_free(path);
-
-  } else {
-    /* case URL_TYPE_OTHER: */
-
-    if(!found_protocol && path && html && html->base_location) {
-      if (g_path_is_absolute(path)) {
-        *url_location =
-          g_build_filename(extract_machine_name(html->base_location),
-                           path, (gchar*)NULL);
-      }
-      else {
-        *url_location =
-          g_build_filename(html->base_location, path, (gchar*)NULL);
-      }
-      g_free(path);
-    }
-    else {
-      *url_location = g_strdup(path);
-      g_free(path);
-    }
-  }
-  
-  *url_label = label;
-  return retval;
-}
-
-
-static char * 
-extract_base_name(URLType type, const gchar * path)
-{
-  char       machine_rexp[] = "^(//[^/]*)/*(/.*)?$";
-  char       path_rexp[] = "^/*(.*)/+([^/]*)$";
-  regex_t    compiled_m, compiled_p;
-  regmatch_t match[4];
-  char       * machine=NULL, * location = NULL, * base=NULL;
-  char       * basename=NULL;
-
-  DEBUG(" ");
-  if(!path) return NULL;
-  
-  regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
-  regcomp(&compiled_p, path_rexp, REG_EXTENDED);
-
-  if (!safe_strcmp (type, URL_TYPE_HTTP) ||
-      !safe_strcmp (type, URL_TYPE_SECURE) ||
-      !safe_strcmp (type, URL_TYPE_FTP)) {
-
-    /* step 1: split the machine name away from the path
-     * components */
-    if(!regexec(&compiled_m, path, 4, match, 0)) {
-      /* $1 is the machine name */ 
-      if(match[1].rm_so != -1) {
-        machine = g_strndup(path+match[1].rm_so, 
-                            match[1].rm_eo - match[1].rm_so);
-      } 
-      /* $2 is the path */
-      if(match[2].rm_so != -1) {
-        location = g_strndup(path+match[2].rm_so, 
-                             match[2].rm_eo - match[2].rm_so);
-      }
-    }  
-
-  } else {
-    location = g_strdup(path);
-  }
-  /* step 2: split up the path into prefix and file components */ 
-  if(location) {
-    if(!regexec(&compiled_p, location, 4, match, 0)) {
-      if(match[1].rm_so != -1) {
-        base = g_strndup(location+match[1].rm_so, 
-                         match[1].rm_eo - match[1].rm_so);
-      }
-      else {
-        base = NULL;
-      }
-    }
-  }
-  
-  regfree(&compiled_m);
-  regfree(&compiled_p);
-  
-  if(machine) {
-    if(base && (strlen(base) > 0)) {
-      basename = g_strconcat(machine, "/", base, "/", NULL);
-    }
-    else {
-      basename = g_strconcat(machine, "/", NULL);
-    }
-  }
-  else {
-    if(base && (strlen(base) > 0)) {
-      basename = g_strdup(base);
-    }
-    else {
-      basename = NULL;
-    }
-  }
-
-  g_free(machine);
-  g_free(base);
-  g_free(location);
-  return basename;
-}
-
-void
-gnc_html_initialize (void)
-{
-  int i;
-  static struct {
-    URLType	type;
-    char *	protocol;
-  } types[] = {
-    { URL_TYPE_FILE, "file" },
-    { URL_TYPE_JUMP, "" },
-    { URL_TYPE_HTTP, "http" },
-    { URL_TYPE_FTP, "ftp" },
-    { URL_TYPE_SECURE, "https" },
-    { URL_TYPE_REGISTER, "gnc-register" },
-    { URL_TYPE_ACCTTREE, "gnc-acct-tree" },
-    { URL_TYPE_REPORT, "gnc-report" },
-    { URL_TYPE_OPTIONS, "gnc-options" },
-    { URL_TYPE_SCHEME, "gnc-scm" },
-    { URL_TYPE_HELP, "gnc-help" },
-    { URL_TYPE_XMLDATA, "gnc-xml" },
-    { URL_TYPE_PRICE, "gnc-price" },
-    { URL_TYPE_BUDGET, "gnc-budget" },
-    { URL_TYPE_OTHER, "" },
-    { NULL, NULL }};
-
-  for (i = 0; types[i].type; i++)
-    gnc_html_register_urltype (types[i].type, types[i].protocol);
-
-  // initialize graphing support
-  gnc_html_graph_gog_init();
-}
-
-
-char  *
-gnc_build_url (URLType type, const gchar * location, const gchar * label)
-{
-  char * type_name;
-
-  DEBUG(" ");
-  type_name = g_hash_table_lookup (gnc_html_type_to_proto_hash, type);
-  if (!type_name)
-    type_name = "";
-
-  if(label) {
-    return g_strdup_printf("%s%s%s#%s", type_name, (*type_name ? ":" : ""),
-                           (location ? location : ""),
-                           label ? label : "");
-  }
-  else {
-    return g_strdup_printf("%s%s%s", type_name, (*type_name ? ":" : ""),
-                           (location ? location : ""));
-  }
-}
-
-static gboolean
-http_allowed()
-{
-  return TRUE;
-}
-
-static gboolean
-https_allowed()
-{
-  return TRUE;
-}
-
-/************************************************************
- * gnc_html_start_request: starts the gnc-http object working on an
- * http/https request.
- ************************************************************/
-static void 
-gnc_html_start_request(gnc_html * html, gchar * uri, GtkHTMLStream * handle)
-{
-  GList * handles = NULL;
-  gint  need_request = FALSE;
-
-  /* we want to make a list of handles to fill with this URI.
-   * multiple handles with the same URI will all get filled when the
-   * request comes in. */
-  DEBUG("requesting %s", uri);
-  handles = g_hash_table_lookup(html->request_info, uri);
-  if(!handles) {
-    need_request = TRUE;
-  }
-
-  handles = g_list_append(handles, handle);
-  g_hash_table_insert(html->request_info, uri, handles);
-  
-  if(need_request) {
-      g_critical("we've not supported network requests for years");
-  }
-}
-
-
-/********************************************************************
- * gnc_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(gnc_html * html, GtkHTMLStream * handle,
-                        URLType type, const gchar * location, 
-                        const gchar * label)
-{
-  char * fdata = NULL;
-  int fdata_len = 0;
-
-  DEBUG("type %s, location %s, label %s", type ? type : "(null)",
-	location ? location : "(null)", label ? label : "(null)");
-  if(!html) {
-    return;
-  }
-
-  if (gnc_html_stream_handlers) {
-    GncHTMLStreamCB stream_handler;
-
-    stream_handler = g_hash_table_lookup (gnc_html_stream_handlers, type);
-    if (stream_handler) {
-      gboolean ok = stream_handler (location, &fdata, &fdata_len);
-
-      if(ok) {
-        fdata = fdata ? fdata : g_strdup ("");
-        gtk_html_write(GTK_HTML(html->html), handle, fdata, fdata_len);
-        gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK);      
-      }
-      else {
-        fdata = fdata ? fdata : 
-	  g_strdup_printf (error_404_format, 
-			   _(error_404_title), _(error_404_body));
-        gtk_html_write(GTK_HTML(html->html), handle, fdata, strlen (fdata));
-        gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_ERROR);
-      }
-
-      g_free(fdata);
-
-      if(label) {
-	while (gtk_events_pending ())
-	  gtk_main_iteration ();
-        gtk_html_jump_to_anchor(GTK_HTML(html->html), label);
-      }
-
-      return;
-    }
-  }
-
-  do {
-    if (!safe_strcmp (type, URL_TYPE_SECURE) ||
-	!safe_strcmp (type, URL_TYPE_HTTP)) {
-
-      if (!safe_strcmp (type, URL_TYPE_SECURE)) {
-	if(!https_allowed()) {
-	  gnc_error_dialog( html->window,
-                            _("Secure HTTP access is disabled. "
-                              "You can enable it in the Network section of "
-                              "the Preferences dialog."));
-	  break;
-	}
-      }
-
-      if(!http_allowed()) {
-	gnc_error_dialog( html->window,
-                          _("Network HTTP access is disabled. "
-                            "You can enable it in the Network section of "
-                            "the Preferences dialog."));
-      } else {
-	char *fullurl;
-      
-	fullurl = gnc_build_url(type, location, label);
-	gnc_html_start_request(html, fullurl, handle);
-      }
-
-    } else {
-      PWARN("load_to_stream for inappropriate type\n"
-	    "\turl = '%s#%s'\n",
-	    location ? location : "(null)",
-	    label ? label : "(null)");
-      fdata = g_strdup_printf (error_404_format, 
-			       _(error_404_title), _(error_404_body));
-      gtk_html_write(GTK_HTML(html->html), handle, fdata, strlen (fdata));
-      gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_ERROR);
-      g_free (fdata);
-    }
-
-  } while (FALSE);
-
-}
-
-
-/********************************************************************
- * gnc_html_link_clicked_cb - called when user left-clicks on html
- * anchor. 
- ********************************************************************/
-
-static void 
-gnc_html_link_clicked_cb(GtkHTML * html, const gchar * url, gpointer data)
-{
-  URLType   type;
-  char      * location = NULL;
-  char      * label = NULL;
-  gnc_html  * gnchtml = (gnc_html *)data;
-
-  DEBUG("Clicked %s", url);
-  type = gnc_html_parse_url(gnchtml, url, &location, &label);
-  gnc_html_show_url(gnchtml, type, location, label, 0);
-  g_free(location);
-  g_free(label);
-}
-
-
-/********************************************************************
- * gnc_html_url_requested_cb - called when a URL needs to be 
- * loaded within the loading of a page (embedded image).
- ********************************************************************/
-
-static void 
-gnc_html_url_requested_cb(GtkHTML * html, char * url,
-                          GtkHTMLStream * handle, gpointer data)
-{
-  URLType       type;
-  char          * location=NULL;
-  char          * label=NULL;
-  gnc_html      * gnchtml = (gnc_html *)data;
-
-  DEBUG("requesting %s", url);
-  type = gnc_html_parse_url(gnchtml, url, &location, &label);
-  gnc_html_load_to_stream(gnchtml, handle, type, location, label);
-  g_free(location);
-  g_free(label);
-}
-
-
-/********************************************************************
- * gnc_html_object_requested_cb - called when an applet needs to be
- * loaded.  
- ********************************************************************/
-
-static gboolean
-gnc_html_object_requested_cb(GtkHTML * html, GtkHTMLEmbedded * eb,
-                             gpointer data)
-{
-  gnc_html  * gnchtml = data; 
-  GncHTMLObjectCB h;
-
-  DEBUG(" ");
-  if(!eb || !(eb->classid) || !gnc_html_object_handlers) return FALSE;
-  
-  h = g_hash_table_lookup(gnc_html_object_handlers, eb->classid);
-  if(h) {
-    return h(gnchtml, eb, data);
-  }
-  else {
-    return FALSE;
-  }
-}
-
-
-/********************************************************************
- * gnc_html_on_url_cb - called when user rolls over html anchor
- ********************************************************************/
-
-static void 
-gnc_html_on_url_cb(GtkHTML * html, const gchar * url, gpointer data)
-{
-  gnc_html * gnchtml = (gnc_html *) data;
-
-  DEBUG("Rollover %s", url ? url : "(null)");
-  g_free(gnchtml->current_link);
-  gnchtml->current_link = g_strdup(url);
-  if(gnchtml->flyover_cb) {
-    (gnchtml->flyover_cb)(gnchtml, url, gnchtml->flyover_cb_data);
-  }
-}
-
-
-/********************************************************************
- * gnc_html_set_base_cb 
- ********************************************************************/
-
-static void 
-gnc_html_set_base_cb(GtkHTML * gtkhtml, const gchar * base, 
-                     gpointer data)
-{
-  gnc_html * html = (gnc_html *)data;
-  URLType  type;
-  char     * location = NULL;
-  char     * label = NULL;
-
-  DEBUG("Setting base location to %s", base);
-  type = gnc_html_parse_url(html, base, &location, &label);
-
-  g_free(html->base_location);
-  g_free(label);
-
-  html->base_type     = type;
-  html->base_location = location;
-}
-
-
-/********************************************************************
- * gnc_html_button_press_cb
- * mouse button callback (if any)
- ********************************************************************/
-
-static int
-gnc_html_button_press_cb(GtkWidget * widg, GdkEventButton * event,
-                         gpointer user_data)
-{
-  gnc_html * html = user_data;
-
-  DEBUG("Button Press");
-  if(html->button_cb) {
-    (html->button_cb)(html, event, html->button_cb_data);
-    return TRUE;
-  }
-  else {
-    return FALSE;
-  }
-}
-
-
-/********************************************************************
- * gnc_html_pack/unpack_form_data
- * convert an encoded arg string to/from a name-value hash table
- ********************************************************************/
-
-GHashTable *
-gnc_html_unpack_form_data(const char * encoding)
-{
-  GHashTable * rv;
-
-  DEBUG(" ");
-  rv = g_hash_table_new(g_str_hash, g_str_equal);
-  gnc_html_merge_form_data(rv, encoding);
-  return rv;
-}
-
-void
-gnc_html_merge_form_data(GHashTable * rv, const char * encoding)
-{
-  char * next_pair = NULL; 
-  char * name  = NULL;
-  char * value = NULL;
-  char * extr_name  = NULL;
-  char * extr_value = NULL;
-  
-  DEBUG(" ");
-  if(!encoding) {
-    return;
-  }
-  next_pair = g_strdup(encoding);
-
-  while(next_pair) {
-    name = next_pair;
-    if((value = strchr(name, '=')) != NULL) {
-      extr_name = g_strndup(name, value-name);
-      next_pair = strchr(value, '&');
-      if(next_pair) {
-        extr_value = g_strndup(value+1, next_pair-value-1);
-        next_pair++;
-      }
-      else {
-        extr_value = g_strdup(value+1);
-      }
-      
-      g_hash_table_insert(rv, 
-                          gnc_html_decode_string(extr_name),
-                          gnc_html_decode_string(extr_value));
-      g_free(extr_name);
-      g_free(extr_value);
-    }
-    else {
-      next_pair = NULL;
-    }
-  }
-}
-
-static gboolean
-free_form_data_helper(gpointer k, gpointer v, gpointer user)
-{
-  DEBUG(" ");
-  g_free(k);
-  g_free(v);
-  return TRUE;
-}
-
-void 
-gnc_html_free_form_data(GHashTable * d)
-{
-  DEBUG(" ");
-  g_hash_table_foreach_remove(d, free_form_data_helper, NULL);
-  g_hash_table_destroy(d);
-}
-
-static void
-pack_form_data_helper(gpointer key, gpointer val, 
-                      gpointer user_data)
-{
-  char * old_str = *(char **)user_data;
-  char * enc_key = gnc_html_encode_string((char *)key);
-  char * enc_val = gnc_html_encode_string((char *)val);
-  char * new_str = NULL;
-
-  DEBUG(" ");
-  if(old_str) {
-    new_str = g_strconcat(old_str, "&", enc_key, "=", enc_val, NULL);
-  }
-  else {
-    new_str = g_strconcat(enc_key, "=", enc_val, NULL);
-  }
-  *(char **)user_data = new_str;
-  g_free(old_str);
-}
-
-char *
-gnc_html_pack_form_data(GHashTable * form_data)
-{
-  char * encoded = NULL;
-  DEBUG(" ");
-  g_hash_table_foreach(form_data, pack_form_data_helper, &encoded);
-  return encoded;
-}
-
-
-/********************************************************************
- * gnc_html_button_submit_cb
- * form submission callback
- ********************************************************************/
-
-static int
-gnc_html_submit_cb(GtkHTML * html, const gchar * method, 
-                   const gchar * action, const gchar * encoded_form_data,
-                   gpointer user_data)
-{
-  gnc_html * gnchtml = user_data;
-  char     * location = NULL;
-  char     * new_loc = NULL;
-  char     * label = NULL;
-  GHashTable * form_data;
-  URLType  type;
-
-  DEBUG(" ");
-  form_data = gnc_html_unpack_form_data(encoded_form_data);
-  type = gnc_html_parse_url(gnchtml, action, &location, &label);
-
-  g_critical("form submission hasn't been supported in years.");
-  
-  g_free(location);
-  g_free(label);
-  g_free(new_loc);
-  gnc_html_free_form_data(form_data);
-  return TRUE;
-}
-
-
-/********************************************************************
- * gnc_html_open_scm
- * insert some scheme-generated HTML
- ********************************************************************/
-
-static void
-gnc_html_open_scm(gnc_html * html, const gchar * location,
-                  const gchar * label, int newwin)
-{
-  PINFO("location='%s'", location ? location : "(null)");
-}
-
-
-/********************************************************************
- * gnc_html_show_data
- * display some HTML that the creator of the gnc-html got from 
- * somewhere. 
- ********************************************************************/
-
-void
-gnc_html_show_data(gnc_html * html, const char * data, 
-                   int datalen)
-{
-  GtkHTMLStream * handle;
-
-  DEBUG("datalen %d, data %20.20s", datalen, data);
-  handle = gtk_html_begin(GTK_HTML(html->html));
-  gtk_html_write(GTK_HTML(html->html), handle, data, datalen);
-  gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK);  
-}
-
-
-/********************************************************************
- * gnc_html_show_url 
- * 
- * open a URL.  This is called when the user clicks a link or 
- * for the creator of the gnc_html window to explicitly request 
- * a URL. 
- ********************************************************************/
-
-void 
-gnc_html_show_url(gnc_html * html, URLType type, 
-                  const gchar * location, const gchar * label,
-                  gboolean new_window_hint)
-{
-  GncHTMLUrlCB url_handler;
-  GtkHTMLStream * handle;
-  gboolean new_window;
-
-  DEBUG(" ");
-  if (!html) return;
-  if (!location) return;
-
-  /* make sure it's OK to show this URL type in this window */
-  if(new_window_hint == 0) {
-    if (html->urltype_cb)
-      new_window = !((html->urltype_cb)(type));
-    else
-      new_window = FALSE;
-  }
-  else {
-    new_window = TRUE;
-  }
-
-  if(!new_window) {
-    gnc_html_cancel(html);
-  }
-
-  if (gnc_html_url_handlers)
-    url_handler = g_hash_table_lookup (gnc_html_url_handlers, type);
-  else
-    url_handler = NULL;
-
-  if (url_handler)
-  {
-    GNCURLResult result;
-    gboolean ok;
-
-    result.load_to_stream = FALSE;
-    result.url_type = type;
-    result.location = NULL;
-    result.label = NULL;
-    result.base_type = URL_TYPE_FILE;
-    result.base_location = NULL;
-    result.error_message = NULL;
-
-    ok = url_handler (location, label, new_window, &result);
-    if (!ok)
-    {
-      if (result.error_message)
-        gnc_error_dialog( html->window, "%s", result.error_message);
-      else
-	/* %s is a URL (some location somewhere). */
-        gnc_error_dialog( html->window, _("There was an error accessing %s."), location);
-
-      if (html->load_cb)
-        html->load_cb (html, result.url_type,
-                       location, label,
-                       html->load_cb_data);
-    }
-    else if (result.load_to_stream)
-    {
-      gnc_html_history_node *hnode;
-      const char *new_location;
-      const char *new_label;
-      GtkHTMLStream * stream;
-
-      new_location = result.location ? result.location : location;
-      new_label = result.label ? result.label : label;
-      hnode = gnc_html_history_node_new (result.url_type,
-                                         new_location, new_label);
-
-      gnc_html_history_append (html->history, hnode);
-
-      g_free (html->base_location);
-      html->base_type = result.base_type;
-      html->base_location =
-	    g_strdup (extract_base_name(result.base_type, new_location));
-      DEBUG("resetting base location to %s",
-	    html->base_location ? html->base_location : "(null)");
-
-      stream = gtk_html_begin (GTK_HTML(html->html));
-      gnc_html_load_to_stream (html, stream, result.url_type,
-                               new_location, new_label);
-
-      if (html->load_cb)
-        html->load_cb (html, result.url_type,
-                       new_location, new_label,
-                       html->load_cb_data);
-    }
-
-    g_free (result.location);
-    g_free (result.label);
-    g_free (result.base_location);
-    g_free (result.error_message);
-
-    return;
-  }
-
-  if (!safe_strcmp (type, URL_TYPE_SCHEME)) {
-    gnc_html_open_scm(html, location, label, new_window);
-
-  } else if (!safe_strcmp (type, URL_TYPE_JUMP)) {
-    gtk_html_jump_to_anchor(GTK_HTML(html->html), label);
-
-  } else if (!safe_strcmp (type, URL_TYPE_SECURE) ||
-	     !safe_strcmp (type, URL_TYPE_HTTP) ||
-	     !safe_strcmp (type, URL_TYPE_FILE)) {
-
-    do {
-      if (!safe_strcmp (type, URL_TYPE_SECURE)) {
-	if(!https_allowed()) {
-	  gnc_error_dialog( html->window,
-                            _("Secure HTTP access is disabled. "
-                              "You can enable it in the Network section of "
-                              "the Preferences dialog."));
-	  break;
-	}
-      }
-
-      if (safe_strcmp (type, URL_TYPE_FILE)) {
-	if(!http_allowed()) {
-	  gnc_error_dialog( html->window,
-                            _("Network HTTP access is disabled. "
-                              "You can enable it in the Network section of "
-                              "the Preferences dialog."));
-	  break;
-	}
-      }
-
-      html->base_type     = type;
-      
-      if(html->base_location) g_free(html->base_location);
-      html->base_location = extract_base_name(type, location);
-
-      /* FIXME : handle new_window = 1 */
-      gnc_html_history_append(html->history,
-			      gnc_html_history_node_new(type, location, label));
-      handle = gtk_html_begin(GTK_HTML(html->html));
-      gnc_html_load_to_stream(html, handle, type, location, label);
-
-    } while (FALSE);
-
-  } else {
-    PERR ("URLType %s not supported.", type);
-  }
-
-  if(html->load_cb) {
-    (html->load_cb)(html, type, location, label, html->load_cb_data);
-  }
-}
-
-
-/********************************************************************
- * gnc_html_reload
- * reload the current page 
- ********************************************************************/
-
-void
-gnc_html_reload(gnc_html * html)
-{
-  gnc_html_history_node * n;
-
-  DEBUG(" ");
-  n = gnc_html_history_get_current(html->history);
-  if(n) {
-    gnc_html_show_url(html, n->type, n->location, n->label, 0);
-  }
-}
-
-
-/********************************************************************
- * gnc_html_new
- * create and set up a new gtkhtml widget.
- ********************************************************************/
-
-gnc_html * 
-gnc_html_new( GtkWindow *parent )
-{
-  gnc_html * retval = g_new0(gnc_html, 1);
-
-  ENTER("parent %p", parent);
-  
-  retval->window    = GTK_WIDGET(parent);
-  retval->container = gtk_scrolled_window_new(NULL, NULL);
-  retval->html      = gtk_html_new();
-
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(retval->container),
-                                 GTK_POLICY_AUTOMATIC,
-                                 GTK_POLICY_AUTOMATIC);
-
-  gtk_container_add(GTK_CONTAINER(retval->container), 
-                    GTK_WIDGET(retval->html));
-
-  retval->request_info = g_hash_table_new(g_str_hash, g_str_equal);
-  //retval->http         = gnc_http_new();
-  retval->history      = gnc_html_history_new();
-
-#ifdef HAVE_GTK_2_10
-  g_object_ref_sink(retval->container);
-#else
-  g_object_ref (retval->container);
-  gtk_object_sink (GTK_OBJECT (retval->container));
-#endif
-
-  /* signals */
-  g_signal_connect(retval->html, "url_requested",
-		   G_CALLBACK(gnc_html_url_requested_cb),
-		   retval);
-  
-  g_signal_connect(retval->html, "on_url",
-		   G_CALLBACK(gnc_html_on_url_cb),
-		   retval);
-  
-  g_signal_connect(retval->html, "set_base",
-		   G_CALLBACK(gnc_html_set_base_cb),
-		   retval);
-  
-  g_signal_connect(retval->html, "link_clicked",
-		   G_CALLBACK(gnc_html_link_clicked_cb),
-		   retval);
-  
-  g_signal_connect (retval->html, "object_requested",
-		    G_CALLBACK (gnc_html_object_requested_cb), 
-		    retval);
-
-  g_signal_connect (retval->html, "button_press_event",
-		    G_CALLBACK (gnc_html_button_press_cb), 
-		    retval);
-
-  g_signal_connect (retval->html, "submit", 
-		    G_CALLBACK(gnc_html_submit_cb),
-		    retval);
-  
-  gtk_html_load_empty(GTK_HTML(retval->html));
-
-  LEAVE("retval %p", retval);
-  
-  return retval;
-}
-
-
-/********************************************************************
- * gnc_html_cancel
- * cancel any outstanding HTML fetch requests. 
- ********************************************************************/
-
-static gboolean
-html_cancel_helper(gpointer key, gpointer value, gpointer user_data)
-{
-  g_free(key);
-  g_list_free((GList *)value);
-  return TRUE;
-}
-
-void
-gnc_html_cancel(gnc_html * html)
-{
-  /* remove our own references to requests */ 
-    //gnc_http_cancel_requests(html->http);
-  
-  g_hash_table_foreach_remove(html->request_info, html_cancel_helper, NULL);
-}
-
-
-/********************************************************************
- * gnc_html_destroy
- * destroy the struct
- ********************************************************************/
-
-void
-gnc_html_destroy(gnc_html * html)
-{
-
-  if(!html) return;
-
-  /* cancel any outstanding HTTP requests */
-  gnc_html_cancel(html);
-  
-  gnc_html_history_destroy(html->history);
-
-  gtk_widget_destroy(html->container);
-  g_object_unref(html->container);
-
-  g_free(html->current_link);
-  g_free(html->base_location);
-
-  html->window        = NULL;
-  html->container     = NULL;
-  html->html          = NULL;
-  html->history       = NULL;
-  html->current_link  = NULL;
-  html->base_location = NULL;
-
-  g_free(html);
-}
-
-void
-gnc_html_set_urltype_cb(gnc_html * html, GncHTMLUrltypeCB urltype_cb)
-{
-  html->urltype_cb = urltype_cb;
-}
-
-void
-gnc_html_set_load_cb(gnc_html * html, GncHTMLLoadCB load_cb,
-                     gpointer data)
-{
-  html->load_cb = load_cb;
-  html->load_cb_data = data;
-}
-
-void
-gnc_html_set_flyover_cb(gnc_html * html, GncHTMLFlyoverCB flyover_cb,
-                        gpointer data)
-{
-  html->flyover_cb       = flyover_cb;
-  html->flyover_cb_data  = data;
-}
-
-void
-gnc_html_set_button_cb(gnc_html * html, GncHTMLButtonCB button_cb,
-                        gpointer data)
-{
-  html->button_cb       = button_cb;
-  html->button_cb_data  = data;
-}
-
-void
-gnc_html_copy(gnc_html *html)
-{
-  g_return_if_fail(html);
-
-  gtk_html_copy(GTK_HTML(html->html));
-}
-
-/**************************************************************
- * gnc_html_export : wrapper around the builtin function in gtkhtml
- **************************************************************/
-
-static gboolean 
-raw_html_receiver (gpointer     engine,
-                   const gchar *data,
-                   size_t        len,
-                   gpointer     user_data)
-{
-  FILE *fh = (FILE *) user_data;
-  size_t written;
-
-  do {
-    written = fwrite (data, 1, len, fh);
-    len -= written;
-  } while (len > 0);
-  return TRUE;
-}
-
-gboolean
-gnc_html_export(gnc_html * html, const char *filepath)
-{
-  FILE *fh;
-
-  g_return_val_if_fail (html != NULL, FALSE);
-  g_return_val_if_fail (filepath != NULL, FALSE);
-
-  fh = g_fopen (filepath, "w");
-  if (!fh)
-    return FALSE;
-
-  gtk_html_save (GTK_HTML(html->html), GINT_TO_POINTER(raw_html_receiver), fh);
-
-  fclose (fh);
-
-  return TRUE;
-}
-
-static GtkHTML *
-gnc_html_get_top_html (GtkHTML *html)
-{
-  while (html->iframe_parent)
-    html = GTK_HTML (html->iframe_parent);
-
-  return html;
-}
-
-#ifdef GTKHTML_USES_GTKPRINT
-#ifndef HAVE_GTKHTML_3_16
-static void
-draw_page_cb(GtkPrintOperation *operation, GtkPrintContext *context,
-             gint page_nr, gpointer user_data)
-{
-    gnc_html *html = user_data;
-
-    gtk_html_print_page((GtkHTML*) html->html, context);
-}
-#endif
-
-void
-gnc_html_print(gnc_html *html)
-{
-    GtkPrintOperation *print;
-    GtkPrintOperationResult res;
-
-    print = gtk_print_operation_new();
-
-    gnc_print_operation_init(print);
-    gtk_print_operation_set_use_full_page(print, FALSE);
-    gtk_print_operation_set_unit(print, GTK_UNIT_POINTS);
-
-#ifdef HAVE_GTKHTML_3_16
-    res = gtk_html_print_operation_run((GtkHTML*) html->html, print,
-                                       GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
-                                       GTK_WINDOW(html->window), NULL, NULL,
-                                       NULL, NULL, NULL, NULL);
-#else
-    gtk_print_operation_set_n_pages(print, 1);
-    g_signal_connect(print, "draw_page", G_CALLBACK(draw_page_cb), html);
-    res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
-                                  GTK_WINDOW(html->window), NULL);
-#endif
-
-    if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
-        gnc_print_operation_save_print_settings(print);
-
-    g_object_unref(print);
-}
-
-#else /* !GTKHTML_USES_GTKPRINT */
-void
-gnc_html_print(gnc_html * html)
-{
-  PrintSession *ps;
-  GtkWidget *top_level;
-  PangoFontDescription *fontdesc;
-
-  ps = gnc_print_session_create(FALSE);
-  if (ps == NULL) {
-    /* user cancelled */
-    return;
-  }
-
-  top_level = GTK_WIDGET (gnc_html_get_top_html (GTK_HTML(html->html)));
-
-  if (ps->pango_font_string != NULL) {
-    fontdesc = pango_font_description_from_string(ps->pango_font_string);
-    gtk_widget_modify_font(top_level, fontdesc);
-    pango_font_description_free(fontdesc);
-  }
-
-  gtk_html_print_set_master(GTK_HTML(html->html), ps->job);
-  gtk_html_print(GTK_HTML(html->html), ps->context);
-
-  if (ps->pango_font_string != NULL) {
-    gtk_widget_modify_font(top_level, NULL);
-  }
-
-  gnc_print_session_done(ps);
-}
-#endif /* GTKHTML_USES_GTKPRINT */
-
-gnc_html_history * 
-gnc_html_get_history(gnc_html * html)
-{
-  if (!html) return NULL;
-  return html->history;
-}
-
-
-GtkWidget * 
-gnc_html_get_widget(gnc_html * html)
-{
-  if (!html) return NULL;
-  return html->container;
-}
-
-void
-gnc_html_register_object_handler(const char * classid, 
-                                 GncHTMLObjectCB hand)
-{
-  g_return_if_fail (classid != NULL);
-
-  if(!gnc_html_object_handlers) {
-    gnc_html_object_handlers = g_hash_table_new(g_str_hash, g_str_equal);
-  }
-
-  gnc_html_unregister_object_handler (classid);
-  if (!hand)
-    return;
-
-  g_hash_table_insert(gnc_html_object_handlers, g_strdup(classid), hand);
-}
-
-void
-gnc_html_unregister_object_handler(const char * classid)
-{
-  gchar * keyptr=NULL;
-  gchar * valptr=NULL;
-  gchar ** p_keyptr = &keyptr;
-  gchar ** p_valptr = &valptr;
-
-  if (!g_hash_table_lookup_extended(gnc_html_object_handlers,
-                                    classid, 
-                                    (gpointer *)p_keyptr,
-                                    (gpointer *)p_valptr))
-    return;
-
-  g_hash_table_remove(gnc_html_object_handlers, classid);
-  g_free(keyptr);
-}
-
-void
-gnc_html_register_action_handler(const char * actionid, 
-                                 GncHTMLActionCB hand)
-{
-  g_return_if_fail (actionid != NULL);
-
-  if(!gnc_html_action_handlers) {
-    gnc_html_action_handlers = g_hash_table_new(g_str_hash, g_str_equal);
-  }
-
-  gnc_html_unregister_action_handler (actionid);
-  if (!hand)
-    return;
-
-  g_hash_table_insert(gnc_html_action_handlers, g_strdup(actionid), hand);
-}
-
-void
-gnc_html_unregister_action_handler(const char * actionid)
-{
-  gchar * keyptr=NULL;
-  gchar * valptr=NULL;
-  gchar ** p_keyptr = &keyptr;
-  gchar ** p_valptr = &valptr;
-
-  g_return_if_fail (actionid != NULL);
-
-  if (!g_hash_table_lookup_extended(gnc_html_action_handlers,
-                                    actionid, 
-                                    (gpointer *)p_keyptr, 
-                                    (gpointer *)p_valptr))
-    return;
-
-  g_hash_table_remove(gnc_html_action_handlers, actionid);
-  g_free(keyptr);
-}
-
-void
-gnc_html_register_stream_handler(URLType url_type, GncHTMLStreamCB hand)
-{
-  g_return_if_fail (url_type != NULL && *url_type != '\0');
-
-  if(!gnc_html_stream_handlers) {
-    gnc_html_stream_handlers = g_hash_table_new(g_str_hash, g_str_equal);
-  }
-
-  gnc_html_unregister_stream_handler (url_type);
-  if (!hand)
-    return;
-
-  g_hash_table_insert (gnc_html_stream_handlers, url_type, hand);
-}
-
-void
-gnc_html_unregister_stream_handler(URLType url_type)
-{
-  g_hash_table_remove (gnc_html_stream_handlers, url_type);
-}
-
-void
-gnc_html_register_url_handler (URLType url_type, GncHTMLUrlCB hand)
-{
-  g_return_if_fail (url_type != NULL && *url_type != '\0');
-
-  if(!gnc_html_url_handlers)
-{
-    gnc_html_url_handlers = g_hash_table_new (g_str_hash, g_str_equal);
-  }
-
-  gnc_html_unregister_url_handler (url_type);
-  if (!hand)
-    return;
-
-  g_hash_table_insert (gnc_html_url_handlers, url_type, hand);
-}
-
-void
-gnc_html_unregister_url_handler (URLType url_type)
-{
-  g_hash_table_remove (gnc_html_url_handlers, url_type);
-}
-
-/********************************************************************
- * gnc_html_encode_string
- * RFC 1738 encoding of string for submission with an HTML form.
- * GPL code lifted from gtkhtml.  copyright notice: 
- * 
- * Copyright (C) 1997 Martin Jones (mjones at kde.org)
- * Copyright (C) 1997 Torben Weis (weis at kde.org)
- * Copyright (C) 1999 Helix Code, Inc.
- ********************************************************************/
-
-char *
-gnc_html_encode_string(const char * str)
-{
-  static gchar *safe = "$-._!*(),"; /* RFC 1738 */
-  unsigned pos      = 0;
-  GString *encoded  = g_string_new ("");
-  gchar buffer[5], *ptr;
-  guchar c;
-  
-  if(!str) return NULL;
-
-  while(pos < strlen(str)) {
-    c = (unsigned char) str[pos];
-    
-    if ((( c >= 'A') && ( c <= 'Z')) ||
-        (( c >= 'a') && ( c <= 'z')) ||
-        (( c >= '0') && ( c <= '9')) ||
-        (strchr(safe, c))) {
-      encoded = g_string_append_c (encoded, c);
-    }
-    else if ( c == ' ' ) {
-      encoded = g_string_append_c (encoded, '+');
-    }
-    else if ( c == '\n' ) {
-      encoded = g_string_append (encoded, "%0D%0A");
-    }
-    else if ( c != '\r' ) {
-      sprintf( buffer, "%%%02X", (int)c );
-      encoded = g_string_append (encoded, buffer);
-    }
-    pos++;
-  }
-  
-  ptr = encoded->str;
-  
-  g_string_free (encoded, FALSE);
-  
-  return (char *)ptr;  
-}
-
-
-char *
-gnc_html_decode_string(const char * str)
-{
-  static gchar * safe = "$-._!*(),"; /* RFC 1738 */
-  GString * decoded  = g_string_new ("");
-  const gchar   * ptr;
-  guchar  c;
-  guint   hexval;
-  ptr = str;
-  
-  if(!str) return NULL;
-
-  while(*ptr) {
-    c = (unsigned char) *ptr;
-    if ((( c >= 'A') && ( c <= 'Z')) ||
-        (( c >= 'a') && ( c <= 'z')) ||
-        (( c >= '0') && ( c <= '9')) ||
-        (strchr(safe, c))) {
-      decoded = g_string_append_c (decoded, c);
-    }
-    else if ( c == '+' ) {
-      decoded = g_string_append_c (decoded, ' ');
-    }
-    else if (!strncmp(ptr, "%0D0A", 5)) {
-      decoded = g_string_append (decoded, "\n");
-      ptr += 4;
-    }
-    else if(c == '%') {
-      ptr++;
-      if (1 == sscanf(ptr, "%02X", &hexval))
-	decoded = g_string_append_c(decoded, (char)hexval);
-      else
-	decoded = g_string_append_c(decoded, ' ');
-      ptr++;
-    }
-    ptr++;
-  }
-  ptr = decoded->str;
-  g_string_free (decoded, FALSE);  
-
-  return (char *)ptr;  
-}
-
-/********************************************************************
- * escape/unescape_newlines : very simple string encoding for GPG
- * ASCII-armored text.
- ********************************************************************/
-
-char * 
-gnc_html_unescape_newlines(const gchar * in)
-{
-  const char * ip = in;
-  char    * cstr = NULL;
-  GString * rv = g_string_new("");
-
-  for(ip=in; *ip; ip++) {
-    if((*ip == '\\') && (*(ip+1)=='n')) {
-      g_string_append(rv, "\n");
-      ip++; 
-    }
-    else {
-      g_string_append_c(rv, *ip);
-    }
-  }
-
-  g_string_append_c(rv, 0);
-  cstr = rv->str;
-  g_string_free(rv, FALSE);
-  return cstr;
-}
-
-char * 
-gnc_html_escape_newlines(const gchar * in)
-{
-  char *out;
-  const char * ip   = in;
-  GString * escaped = g_string_new("");
-
-  for(ip=in; *ip; ip++) {
-    if(*ip == '\012') {
-      g_string_append(escaped, "\\n");
-    }
-    else {
-      g_string_append_c(escaped, *ip);      
-    }
-  }
-  g_string_append_c(escaped, 0);
-  out = escaped->str;
-  g_string_free(escaped, FALSE);
-  return out;
-}

Deleted: gnucash/trunk/src/gnome-utils/gnc-html.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-html.h	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-html.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -1,171 +0,0 @@
-/********************************************************************
- * gnc-html.h -- display html with gnc special tags                 *
- * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
- *                                                                  *
- * 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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-#ifndef GNC_HTML_H
-#define GNC_HTML_H
-
-#include <gtkhtml/gtkhtml.h>
-
-typedef char * URLType;
-
-#define URL_TYPE_FILE	"file"
-#define URL_TYPE_JUMP	"jump"
-#define URL_TYPE_HTTP	"http"
-#define URL_TYPE_FTP	"ftp"
-#define URL_TYPE_SECURE	"secure"
-#define URL_TYPE_REGISTER	"register"   /* for gnucash register popups */
-#define URL_TYPE_ACCTTREE	"accttree"   /* for account tree windows */
-#define URL_TYPE_REPORT	"report"     /* for gnucash report popups */
-#define URL_TYPE_OPTIONS	"options"    /* for editing report options */ 
-#define URL_TYPE_SCHEME	"scheme"     /* for scheme code evaluation */
-#define URL_TYPE_HELP	"help"       /* for a gnucash help window */
-#define URL_TYPE_XMLDATA	"xmldata"    /* links to gnucash XML data files */ 
-#define URL_TYPE_PRICE	"price"      /* for price editor popups */
-#define URL_TYPE_OTHER	"other"
-#define URL_TYPE_BUDGET "budget"
-
-#include "gnc-html-history.h"
-
-typedef struct gnc_html_struct gnc_html;
-
-/* The result structure of url handlers. Strings should be g_malloc'd
- * by the handler and will be freed by gnc_html. */
-typedef struct
-{
-  /* The following members are used if the handler succeeds (returns TRUE). */
-
-  gboolean load_to_stream; /* If TRUE, the url should be loaded from
-                            * a stream using the rest of the data in
-                            * the struct into the original gnc_html
-                            * object. If FALSE, the handler will
-                            * perform all needed actions itself. */
-
-  URLType url_type;        /* Defaults to original */
-  char * location;         /* If NULL, use original (NULL is default) */
-  char * label;            /* If NULL, use original (NULL is default) */
-
-  URLType base_type;
-  char * base_location;
-
-  /* The following members are used if the handler fails (returns FALSE). */
-  char * error_message;
-} GNCURLResult;
-
-typedef int  (* GncHTMLUrltypeCB)(URLType ut);
-typedef void (* GncHTMLFlyoverCB)(gnc_html * html, const char * url,
-                                  gpointer data);
-typedef void (* GncHTMLLoadCB)(gnc_html * html, URLType type, 
-                               const char * location, const char * label,
-                               gpointer data);
-typedef int  (* GncHTMLButtonCB)(gnc_html * html, GdkEventButton * event,
-                                 gpointer data);
-
-typedef gboolean (* GncHTMLObjectCB)(gnc_html * html, GtkHTMLEmbedded * eb,
-                                 gpointer data); 
-typedef int  (* GncHTMLActionCB)(gnc_html * html, const char * method,
-                                 const char * action, GHashTable * form_data);
-typedef gboolean (* GncHTMLStreamCB)(const char *location, char **data, int *datalen);
-typedef gboolean (* GncHTMLUrlCB)(const char *location, const char *label,
-                                  gboolean new_window, GNCURLResult * result);
-
-gnc_html    * gnc_html_new(GtkWindow *parent);
-void          gnc_html_destroy(gnc_html * html);
-void          gnc_html_show_url(gnc_html * html, 
-                                URLType type,
-                                const char * location, 
-                                const char * label,
-                                gboolean new_window_hint);
-void          gnc_html_show_data(gnc_html * html, 
-                                 const char * data, int datalen);
-void          gnc_html_reload(gnc_html * html);
-void          gnc_html_copy(gnc_html *html);
-gboolean      gnc_html_export(gnc_html * html, const char *file);
-void          gnc_html_print(gnc_html * html);
-void          gnc_html_cancel(gnc_html * html);
-
-char  * gnc_build_url (URLType type, const gchar * location,
-                       const gchar * label);
-
-/* Register a new URLType.
- * returns TRUE if succesful, FALSE if type already exists.
- *
- * protocol should be an empty string if there is no corresponding protocol.
- * if protocol is NULL, this function returns FALSE.
- */
-gboolean      gnc_html_register_urltype (URLType type, const char *protocol);
-
-/* object handlers deal with <object classid="foo"> objects in HTML.
- * the handlers are looked up at object load time. */
-//#if 0
-void          gnc_html_register_object_handler(const char * classid, 
-                                               GncHTMLObjectCB hand);
-//#endif
-void          gnc_html_unregister_object_handler(const char * classid);
-
-/* action handlers deal with submitting forms of the type 
- * <FORM action="gnc-action:action?args">.  Normal get/post http:
- * forms are handled as would be expected, with no callback. */
-void          gnc_html_register_action_handler(const char * action, 
-                                               GncHTMLActionCB hand);
-void          gnc_html_unregister_action_handler(const char * action);
-
-/* stream handlers load data for particular URLTypes. */
-void          gnc_html_register_stream_handler(URLType url_type,
-                                               GncHTMLStreamCB hand);
-void          gnc_html_unregister_stream_handler(URLType url_type);
-
-/* handlers for particular URLTypes. */
-void          gnc_html_register_url_handler(URLType url_type,
-                                            GncHTMLUrlCB hand);
-void          gnc_html_unregister_url_handler(URLType url_type);
-
-URLType       gnc_html_parse_url(gnc_html * html, const gchar * url, 
-                                 char ** url_location, char ** url_label);
-
-/* some string coding/decoding routines */
-char          * gnc_html_encode_string(const char * in);
-char          * gnc_html_decode_string(const char * in);
-char          * gnc_html_escape_newlines(const char * in);
-char          * gnc_html_unescape_newlines(const char * in);
-
-/* utilities for dealing with encoded argument strings for forms */
-char          * gnc_html_pack_form_data(GHashTable * form_data);
-GHashTable    * gnc_html_unpack_form_data(const char * encoding);
-void            gnc_html_merge_form_data(GHashTable * fdata, const char * enc);
-void            gnc_html_free_form_data(GHashTable * fdata);
-
-gnc_html_history * gnc_html_get_history(gnc_html * html);
-GtkWidget   * gnc_html_get_widget(gnc_html * html);
-
-/* setting callbacks */
-void gnc_html_set_urltype_cb(gnc_html * html, GncHTMLUrltypeCB urltype_cb);
-void gnc_html_set_load_cb(gnc_html * html, GncHTMLLoadCB load_cb,
-                          gpointer data);
-void gnc_html_set_flyover_cb(gnc_html * html, GncHTMLFlyoverCB newwin_cb,
-                             gpointer data);
-void gnc_html_set_button_cb(gnc_html * html, GncHTMLButtonCB button_cb,
-                            gpointer data);
-
-/* Initialize the html subsystem */
-void gnc_html_initialize (void);
-
-#endif

Modified: gnucash/trunk/src/gnome-utils/gnc-main-window.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-main-window.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnc-main-window.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -65,7 +65,7 @@
 #include "gnc-main.h"
 #include "gnc-gconf-utils.h"
 // +JSLED
-#include "gnc-html.h"
+//#include "gnc-html.h"
 #include "gnc-autosave.h"
 #ifdef HAVE_GTK_2_10
 #    include "print-session.h"

Modified: gnucash/trunk/src/gnome-utils/gncmod-gnome-utils.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gncmod-gnome-utils.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gncmod-gnome-utils.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -14,7 +14,6 @@
 #include "gnc-module-api.h"
 
 #include "dialog-options.h"
-#include "gnc-html.h"
 #include "qof.h"
 #include "gnc-gui-query.h"
 
@@ -77,7 +76,6 @@
   /* Initialize the options-ui database */
   if (refcount == 0) {
     gnc_options_ui_initialize ();
-    gnc_html_initialize ();
 
     /* register the druid pieces */
     gnc_druid_gnome_register();

Modified: gnucash/trunk/src/gnome-utils/gnome-utils.i
===================================================================
--- gnucash/trunk/src/gnome-utils/gnome-utils.i	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/gnome-utils/gnome-utils.i	2009-04-11 01:44:14 UTC (rev 18041)
@@ -3,6 +3,7 @@
 /* Includes the header in the wrapper code */
 #include <config.h>
 #include <gtk/gtk.h>
+#include <glib-object.h>
 #include <dialog-options.h>
 #include <dialog-utils.h>
 #include <druid-utils.h>
@@ -11,7 +12,6 @@
 #include <gnc-file.h>
 #include <gnc-gnome-utils.h>
 #include <gnc-gui-query.h>
-#include <gnc-html.h>
 #include <gnc-main-window.h>
 #include <gnc-window.h>
 #include <gnc-menu-extensions.h>
@@ -24,10 +24,6 @@
 
 %import "base-typemaps.i"
 
-/* Parse the header file to generate wrappers */
-%include "gnc-html.h"
-
-
 GNCOptionWin * gnc_options_dialog_new(gchar *title);
 void gnc_options_dialog_destroy(GNCOptionWin * win);
 void gnc_options_dialog_build_contents(GNCOptionWin *propertybox,
@@ -56,30 +52,3 @@
 void gnc_window_show_progress (const char *message, double percentage);
 
 gboolean gnucash_ui_is_running(void);
-
-%init {
-  {
-    char tmp[100];
-
-#define SET_ENUM(e) snprintf(tmp, 100, "(set! %s (%s))", (e), (e));  \
-    scm_c_eval_string(tmp);
-
-    SET_ENUM("URL-TYPE-FILE");
-    SET_ENUM("URL-TYPE-JUMP");
-    SET_ENUM("URL-TYPE-HTTP");
-    SET_ENUM("URL-TYPE-FTP");
-    SET_ENUM("URL-TYPE-SECURE");
-    SET_ENUM("URL-TYPE-REGISTER");
-    SET_ENUM("URL-TYPE-ACCTTREE");
-    SET_ENUM("URL-TYPE-REPORT");
-    SET_ENUM("URL-TYPE-OPTIONS");
-    SET_ENUM("URL-TYPE-SCHEME");
-    SET_ENUM("URL-TYPE-HELP");
-    SET_ENUM("URL-TYPE-XMLDATA");
-    SET_ENUM("URL-TYPE-PRICE");
-    SET_ENUM("URL-TYPE-OTHER");
-
-#undefine SET_ENUM
-  }
-
-}


Property changes on: gnucash/trunk/src/html
___________________________________________________________________
Added: svn:ignore
   + Makefile
Makefile.in
*.lo
.deps
.libs
.scm-links
gnucash
swig-gnc-html.c



Added: gnucash/trunk/src/html/Makefile.am
===================================================================
--- gnucash/trunk/src/html/Makefile.am	                        (rev 0)
+++ gnucash/trunk/src/html/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,110 @@
+#SUBDIRS = . test
+SUBDIRS = .
+
+pkglib_LTLIBRARIES = libgncmod-html.la
+
+AM_CPPFLAGS = \
+  -I${top_srcdir}/src/core-utils \
+  -I${top_srcdir}/src/gnc-module \
+  -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/gnome-utils \
+  -I${top_srcdir}/src/app-utils \
+  -I${top_srcdir}/src \
+  -I${top_builddir}/src \
+  -I${top_srcdir}/lib/libc \
+  ${QOF_CFLAGS} \
+  ${GLIB_CFLAGS} \
+  ${GTK_CFLAGS} \
+  ${GNOME_CFLAGS} \
+  ${GOFFICE_CFLAGS}
+
+libgncmod_html_la_SOURCES = \
+  gncmod-html.c \
+  gnc-html.c \
+  gnc-html-history.c \
+  gnc-html-graph-gog.c \
+  gnc-html-factory.c \
+  swig-gnc-html.c
+
+gncincludedir = ${GNC_INCLUDE_DIR}
+gncinclude_HEADERS = \
+  gnc-html-graph-gog.h \
+  gnc-html-history.h \
+  gnc-html.h \
+  gnc-html-factory.h
+
+libgncmod_html_la_LDFLAGS = -avoid-version
+
+libgncmod_html_la_LIBADD = \
+  ${top_builddir}/src/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/src/gnc-module/libgnc-module.la \
+  ${top_builddir}/src/engine/libgncmod-engine.la \
+  ${top_builddir}/src/calculation/libgncmod-calculation.la \
+  ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
+  $(top_builddir)/lib/libc/libc-missing.la \
+  ${GNOME_LIBS} \
+  ${GDK_PIXBUF_LIBS} \
+  ${GLIB_LIBS} \
+  ${DB_LIBS} \
+  ${QOF_LIBS} \
+  ${GOFFICE_LIBS} \
+  ${GUILE_LIBS} \
+  ${REGEX_LIBS}
+
+if HTML_USING_WEBKIT
+AM_CPPFLAGS += ${WEBKIT_CFLAGS}
+libgncmod_html_la_SOURCES += \
+  gnc-html-webkit.c \
+  gnc-html-graph-gog-webkit.c
+libgncmod_html_la_LIBADD += \
+  ${WEBKIT_LIBS}
+else
+AM_CPPFLAGS += ${GTKHTML_CFLAGS}
+libgncmod_html_la_SOURCES += \
+  gnc-html-gtkhtml.c \
+  gnc-html-graph-gog-gtkhtml.c
+libgncmod_html_la_LIBADD += \
+  ${GTKHTML_LIBS}
+
+if !GTKHTML_USES_GTKPRINT
+  AM_CPPFLAGS += ${GNOME_PRINT_CFLAGS}
+  libgncmod_html_la_LIBADD += ${GNOME_PRINT_LIBS}
+endif
+
+endif
+
+if BUILDING_FROM_SVN
+swig-gnc-html.c: gnc-html.i gnc-html.h \
+                    ${top_srcdir}/src/base-typemaps.i
+	$(SWIG) -guile $(SWIG_ARGS) -Linkage module \
+	-I${top_srcdir}/src -o $@ $<
+endif
+
+EXTRA_DIST = \
+  gnc-svninfo.h \
+  gnc-html.i
+
+if !GTKHTML_USES_GTKPRINT
+  AM_CPPFLAGS += ${GNOME_PRINT_CFLAGS}
+  libgncmod_html_la_LIBADD += ${GNOME_PRINT_LIBS}
+endif
+
+CLEANFILES = $(BUILT_SOURCES) gnucash
+MAINTAINERCLEANFILES = swig-html.c
+
+# FIXME: Symlinking directories only works on non-win32.
+if !PLATFORM_WIN32
+#
+# I hate inconsistent standards. Autotools puts help files into
+# ${datadir}/gnome/help/${program} while the gnome2 libraries expect
+# them in ${pkgdatadir}/gnome/help/${program}.
+#
+install-data-hook:
+	$(LN_S) -f ../gnome ${DESTDIR}${pkgdatadir}
+
+uninstall-hook:
+	rm -f ${DESTDIR}${pkgdatadir}/gnome
+endif
+
+INCLUDES = -DG_LOG_DOMAIN=\"gnc.html\"

Added: gnucash/trunk/src/html/gnc-html-extras.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-extras.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-extras.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,52 @@
+/********************************************************************
+ * gnc-html-extras.h -- display html with gnc special tags          *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_EXTRAS_H
+#define GNC_HTML_EXTRAS_H
+
+// This file is needed so that these definitions can be separately included in the
+// gnc-html.i file.  The full gnc-html.h file can't be parsed because of the new
+// use of GObject
+
+typedef gchar* URLType;
+
+#define URL_TYPE_FILE	"file"
+#define URL_TYPE_JUMP	"jump"
+#define URL_TYPE_HTTP	"http"
+#define URL_TYPE_FTP	"ftp"
+#define URL_TYPE_SECURE	"secure"
+#define URL_TYPE_REGISTER	"register"   /* for gnucash register popups */
+#define URL_TYPE_ACCTTREE	"accttree"   /* for account tree windows */
+#define URL_TYPE_REPORT	"report"     /* for gnucash report popups */
+#define URL_TYPE_OPTIONS	"options"    /* for editing report options */ 
+#define URL_TYPE_SCHEME	"scheme"     /* for scheme code evaluation */
+#define URL_TYPE_HELP	"help"       /* for a gnucash help window */
+#define URL_TYPE_XMLDATA	"xmldata"    /* links to gnucash XML data files */ 
+#define URL_TYPE_PRICE	"price"      /* for price editor popups */
+#define URL_TYPE_OTHER	"other"
+#define URL_TYPE_BUDGET "budget"
+
+gchar* gnc_build_url( URLType type, const gchar* location, const gchar* label );
+
+gboolean gnc_html_engine_supports_css( void );
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-factory.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-factory.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-factory.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,56 @@
+/********************************************************************
+ * gnc-html_factory.c -- Factory to create HTML component           *
+ *                                                                  *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "gnc-html.h"
+#include "gnc-html-gtkhtml.h"
+#include "gnc-html-webkit.h"
+#include "qoflog.h"
+#include "gnc-engine.h"
+
+#include "gnc-html-factory.h"
+
+/* indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_HTML;
+
+GncHtml* gnc_html_factory_create_html( void )
+{
+#ifdef WANT_WEBKIT
+	return gnc_html_webkit_new();
+#else
+	return gnc_html_gtkhtml_new();
+#endif
+}
+
+gboolean
+gnc_html_engine_supports_css( void )
+{
+#ifdef WANT_WEBKIT
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}

Added: gnucash/trunk/src/html/gnc-html-factory.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-factory.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-factory.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,30 @@
+/********************************************************************
+ * gnc-html-factory.h -- display html with gnc special tags         *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_FACTORY_H
+#define GNC_HTML_FACTORY_H
+
+#include "gnc-html.h"
+
+GncHtml* gnc_html_factory_create_html( void );
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,515 @@
+/********************************************************************
+ * gnc-html-graph-gog.c -- GNC/HTML Graphing support via GOG        *
+ *                                                                  *
+ * Copyright (C) 2005 Joshua Sled <jsled at asynchronous.org>          *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-embedded.h>
+#include <string.h>
+
+#include "gnc-ui-util.h"
+#include "gnc-html-graph-gog.h"
+#include "gnc-html-graph-gog-gtkhtml.h"
+#include "gnc-html.h"
+#include "gnc-engine.h"
+#include <goffice/goffice.h>
+#include <goffice/graph/gog-chart.h>
+#include <goffice/graph/gog-graph.h>
+#include <goffice/graph/gog-object.h>
+#if defined(HAVE_GOFFICE_0_5)
+#    include <goffice/graph/gog-renderer.h>
+#elif defined(GOFFICE_WITH_CAIRO)
+#    include <goffice/graph/gog-renderer-cairo.h>
+#else
+#    include <goffice/graph/gog-renderer-pixbuf.h>
+#endif
+#ifndef GTKHTML_USES_GTKPRINT
+#    include <goffice/graph/gog-renderer-gnome-print.h>
+#endif
+#include <goffice/graph/gog-style.h>
+#include <goffice/graph/gog-styled-object.h>
+#include <goffice/graph/gog-plot.h>
+#include <goffice/graph/gog-series.h>
+#include <goffice/utils/go-color.h>
+#include <goffice/utils/go-marker.h>
+#include <goffice/graph/gog-data-set.h>
+#include <goffice/data/go-data-simple.h>
+#include <goffice/app/go-plugin.h>
+#include <goffice/app/go-plugin-loader-module.h>
+
+/**
+ * TODO:
+ * - scatter-plot marker selection
+ * - series-color, piecharts (hard, not really supported by GOG)
+ *   and scatters (or drop feature)
+ * - title-string freeing (fixmes)
+ * - general graph cleanup
+ **/
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "gnc.html.graph.gog.gtkhtml"
+
+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 );
+
+#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
+
+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_gtkhtml_init( void )
+{
+  gnc_html_graph_gog_init();
+
+  gnc_html_register_object_handler( "gnc-guppi-pie", handle_piechart );
+  gnc_html_register_object_handler( "gnc-guppi-bar", handle_barchart );
+  gnc_html_register_object_handler( "gnc-guppi-scatter", handle_scatter );
+  gnc_html_register_object_handler( "gnc-guppi-line", handle_linechart );
+}
+
+static double * 
+read_doubles(const char * string, int nvalues)
+{
+  int    n;
+  gchar *next;
+  double * retval = g_new0(double, nvalues);
+
+  // guile is going to (puts ...) the elements of the double array
+  // together. In non-POSIX locales, that will be in a format that
+  // the locale-specific sscanf will not be able to parse.
+  gnc_push_locale("C");
+  {
+    for (n=0; n<nvalues; n++) {
+      retval[n] = strtod(string, &next);
+      string = next;
+     }
+  }
+  gnc_pop_locale();
+
+  return retval;
+}
+
+static char ** 
+read_strings(const char * string, int nvalues)
+{
+  int n;
+  int choffset=0;
+  int accum = 0;
+  char ** retval = g_new0(char *, nvalues);
+  char thischar;
+  const char * inptr = string;
+  int escaped = FALSE;
+
+  for (n=0; n < nvalues; n++) {
+    retval[n] = g_new0(char, strlen(string+accum)+1);
+    retval[n][0] = 0;
+    choffset = 0;
+    while ((thischar = *inptr) != 0) {
+      if (thischar == '\\') {
+        escaped = TRUE;
+        inptr++;
+      }
+      else if ((thischar != ' ') || escaped) {
+        retval[n][choffset] = thischar;
+        retval[n][choffset+1] = 0;    
+        choffset++;
+        escaped = FALSE;
+        inptr++;
+      }
+      else {
+        /* an unescaped space */
+        escaped = FALSE;
+        inptr++;
+        break;
+      }
+    }
+    accum += choffset;
+    /* printf("retval[%d] = '%s'\n", n, retval[n]); */
+  }
+  
+  return retval;  
+}
+
+static void
+add_pixbuf_graph_widget( GtkHTMLEmbedded *eb, GdkPixbuf* buf )
+{
+  GtkWidget *widget;
+  gboolean update_status;
+  GogGraph *graph = GOG_GRAPH(g_object_get_data( G_OBJECT(buf), "graph" ));
+
+  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);
+}
+
+static gboolean
+create_basic_plot_elements(const char *plot_type_name,
+                           GogObject **out_graph,
+                           GogObject **out_chart,
+                           GogPlot **out_plot)
+{
+  *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;
+}
+
+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"));
+}
+
+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);
+}
+
+static void
+set_chart_axis_labels_from_hash(GogObject *chart, gpointer eb)
+{
+  set_chart_axis_labels(chart,
+                        gnc_html_get_embedded_param(eb, "x_axis_label"),
+                        gnc_html_get_embedded_param(eb, "y_axis_label"));
+}
+
+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);
+  }
+
+  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);
+  }
+}
+
+/*
+ * Handle the following parameters:
+ * title: text
+ * subtitle: text
+ * datasize: (length data), sscanf( .., %d, (int)&datasize )
+ * data: (foreach (lambda (datum) (push datum) (push " ")) data)
+ * colors: string; space-seperated?
+ * labels: string; space-seperated?
+ * slice_urls_[123]: ?
+ * legend_urls_[123]: ?
+ */
+static gboolean
+handle_piechart( GncHtml* html, gpointer eb, gpointer unused )
+{
+  GncHtmlPieChartInfo pieChartInfo;
+
+  // parse data from the text-ized params.
+  {
+    const char *datasizeStr, *dataStr, *labelsStr, *colorStr;
+
+    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 );
+    pieChartInfo.datasize = atoi( datasizeStr );
+    pieChartInfo.data = read_doubles( dataStr, pieChartInfo.datasize );
+    pieChartInfo.labels = read_strings( labelsStr, pieChartInfo.datasize );
+    pieChartInfo.colors = read_strings( colorStr, pieChartInfo.datasize );
+  }
+
+  pieChartInfo.title = (const char *)gnc_html_get_embedded_param(eb, "title"); 
+  pieChartInfo.subtitle = (const char *)gnc_html_get_embedded_param(eb, "subtitle");
+  pieChartInfo.width = ((GtkHTMLEmbedded*)eb)->width;
+  pieChartInfo.height = ((GtkHTMLEmbedded*)eb)->height;
+
+  add_pixbuf_graph_widget( eb, gnc_html_graph_gog_create_piechart( &pieChartInfo ) );
+
+  return TRUE;
+}
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ **/
+static gboolean
+handle_barchart( GncHtml* html, gpointer eb, gpointer unused )
+{
+  GncHtmlBarChartInfo barChartInfo;
+
+  // 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;
+
+    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");
+
+    barChartInfo.rotate_row_labels     = (gboolean) atoi (rotate_row_labels_str);
+    barChartInfo.stacked               = (gboolean) atoi (stacked_str);
+
+#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
+    barChartInfo.data_rows = atoi (data_rows_str);
+    barChartInfo.data_cols = atoi (data_cols_str);
+    barChartInfo.data = read_doubles (data_str, barChartInfo.data_rows*barChartInfo.data_cols);
+    barChartInfo.row_labels = read_strings (row_labels_str, barChartInfo.data_rows);
+    barChartInfo.col_labels = read_strings (col_labels_str, barChartInfo.data_cols);
+    barChartInfo.col_colors = read_strings (col_colors_str, barChartInfo.data_cols);
+  }
+
+  barChartInfo.title = (const char *)gnc_html_get_embedded_param(eb, "title"); 
+  barChartInfo.subtitle = (const char *)gnc_html_get_embedded_param(eb, "subtitle");
+  barChartInfo.width = ((GtkHTMLEmbedded*)eb)->width;
+  barChartInfo.height = ((GtkHTMLEmbedded*)eb)->height;
+  barChartInfo.x_axis_label = gnc_html_get_embedded_param(eb, "x_axis_label"),
+  barChartInfo.y_axis_label = gnc_html_get_embedded_param(eb, "y_axis_label");
+
+  add_pixbuf_graph_widget( eb, gnc_html_graph_gog_create_barchart( &barChartInfo ) );
+
+  g_debug("barchart rendered.");
+  return TRUE;
+}
+
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ * markers:boolean
+ * major_grid:boolean
+ * minor_grid:boolean
+ **/
+static gboolean
+handle_linechart( GncHtml* html, gpointer eb, gpointer unused )
+{
+  GncHtmlLineChartInfo lineChartInfo;
+
+  // 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;
+
+    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");
+
+    lineChartInfo.rotate_row_labels     = (gboolean) atoi (rotate_row_labels_str);
+    lineChartInfo.stacked               = (gboolean) atoi (stacked_str);
+    lineChartInfo.markers               = (gboolean) atoi (markers_str);
+    lineChartInfo.major_grid            = (gboolean) atoi (major_grid_str);
+    lineChartInfo.minor_grid            = (gboolean) atoi (minor_grid_str);
+
+    lineChartInfo.data_rows = atoi (data_rows_str);
+    lineChartInfo.data_cols = atoi (data_cols_str);
+    lineChartInfo.data = read_doubles (data_str, lineChartInfo.data_rows*lineChartInfo.data_cols);
+    lineChartInfo.row_labels = read_strings (row_labels_str, lineChartInfo.data_rows);
+    lineChartInfo.col_labels = read_strings (col_labels_str, lineChartInfo.data_cols);
+    lineChartInfo.col_colors = read_strings (col_colors_str, lineChartInfo.data_cols);
+  }
+
+  lineChartInfo.title = (const char *)gnc_html_get_embedded_param(eb, "title"); 
+  lineChartInfo.subtitle = (const char *)gnc_html_get_embedded_param(eb, "subtitle");
+  lineChartInfo.width = ((GtkHTMLEmbedded*)eb)->width;
+  lineChartInfo.height = ((GtkHTMLEmbedded*)eb)->height;
+  lineChartInfo.x_axis_label = gnc_html_get_embedded_param(eb, "x_axis_label"),
+  lineChartInfo.y_axis_label = gnc_html_get_embedded_param(eb, "y_axis_label");
+
+  add_pixbuf_graph_widget( eb, gnc_html_graph_gog_create_linechart( &lineChartInfo ) );
+
+  g_debug("linechart rendered.");
+  return TRUE;
+}
+
+
+static gboolean
+handle_scatter( GncHtml* html, gpointer eb, gpointer unused )
+{
+  GncHtmlScatterPlotInfo scatterPlotInfo;
+
+  {
+    const char *datasizeStr, *xDataStr, *yDataStr;
+
+    datasizeStr = gnc_html_get_embedded_param( eb, "datasize" );
+    scatterPlotInfo.datasize = atoi( datasizeStr );
+
+    xDataStr = gnc_html_get_embedded_param( eb, "x_data" );
+    scatterPlotInfo.xData = read_doubles( xDataStr, scatterPlotInfo.datasize );
+
+    yDataStr = gnc_html_get_embedded_param( eb, "y_data" );
+    scatterPlotInfo.yData = read_doubles( yDataStr, scatterPlotInfo.datasize );
+
+    scatterPlotInfo.marker_str = gnc_html_get_embedded_param(eb, "marker");
+    scatterPlotInfo.color_str = gnc_html_get_embedded_param(eb, "color");
+  }
+
+  scatterPlotInfo.title = (const char *)gnc_html_get_embedded_param(eb, "title"); 
+  scatterPlotInfo.subtitle = (const char *)gnc_html_get_embedded_param(eb, "subtitle");
+  scatterPlotInfo.width = ((GtkHTMLEmbedded*)eb)->width;
+  scatterPlotInfo.height = ((GtkHTMLEmbedded*)eb)->height;
+  scatterPlotInfo.x_axis_label = gnc_html_get_embedded_param(eb, "x_axis_label"),
+  scatterPlotInfo.y_axis_label = gnc_html_get_embedded_param(eb, "y_axis_label");
+
+  add_pixbuf_graph_widget( eb, gnc_html_graph_gog_create_scatterplot( &scatterPlotInfo ) );
+
+  return TRUE;
+}
+
+#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);
+}
+
+#else /* !GTKHTML_USES_GTKPRINT */
+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 /* GTKHTML_USES_GTKPRINT */

Added: gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog-gtkhtml.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,30 @@
+/********************************************************************
+ * gnc-html_graph_gog_gtkhtml.h -- display html with gnc special    *
+ *									tags			                *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_GRAPH_GOG_GTKHTML_H
+#define GNC_HTML_GRAPH_GOG_GTKHTML_H 1
+
+void gnc_html_graph_gog_gtkhtml_init( void );
+
+#endif /* GNC_HTML_GRAPH_GOG_GTKHTML_H */

Added: gnucash/trunk/src/html/gnc-html-graph-gog-webkit.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog-webkit.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog-webkit.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,489 @@
+/********************************************************************
+ * 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>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+#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"
+#include <goffice/goffice.h>
+#include <goffice/graph/gog-chart.h>
+#include <goffice/graph/gog-graph.h>
+#include <goffice/graph/gog-object.h>
+#if defined(HAVE_GOFFICE_0_5)
+#    include <goffice/graph/gog-renderer.h>
+#elif defined(GOFFICE_WITH_CAIRO)
+#    include <goffice/graph/gog-renderer-cairo.h>
+#else
+#    include <goffice/graph/gog-renderer-pixbuf.h>
+#endif
+#ifndef GTKHTML_USES_GTKPRINT
+#    include <goffice/graph/gog-renderer-gnome-print.h>
+#endif
+#include <goffice/graph/gog-style.h>
+#include <goffice/graph/gog-styled-object.h>
+#include <goffice/graph/gog-plot.h>
+#include <goffice/graph/gog-series.h>
+#include <goffice/utils/go-color.h>
+#include <goffice/utils/go-marker.h>
+#include <goffice/graph/gog-data-set.h>
+#include <goffice/data/go-data-simple.h>
+#include <goffice/app/go-plugin.h>
+#include <goffice/app/go-plugin-loader-module.h>
+
+/**
+ * TODO:
+ * - scatter-plot marker selection
+ * - series-color, piecharts (hard, not really supported by GOG)
+ *   and scatters (or drop feature)
+ * - title-string freeing (fixmes)
+ * - general graph cleanup
+ **/
+
+/* indicates the debugging module that this .o belongs to.  */
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "gnc.html.graph.gog.webkit"
+static QofLogModule log_module = GNC_MOD_HTML;
+
+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 double * read_doubles(const char * string, int nvalues);
+
+void
+gnc_html_graph_gog_webkit_init( void )
+{
+  g_debug( "init gog graphing" );
+  
+  libgoffice_init();
+  
+  /* Initialize plugins manager */
+  go_plugins_init( NULL, NULL, NULL, NULL, TRUE, GO_PLUGIN_LOADER_MODULE_TYPE );
+
+  gnc_html_register_object_handler( "gnc-guppi-pie", handle_piechart );
+  gnc_html_register_object_handler( "gnc-guppi-bar", handle_barchart );
+  gnc_html_register_object_handler( "gnc-guppi-scatter", handle_scatter );
+  gnc_html_register_object_handler( "gnc-guppi-line", handle_linechart );
+}
+
+static double * 
+read_doubles(const char * string, int nvalues)
+{
+  int    n;
+  gchar *next;
+  double * retval = g_new0(double, nvalues);
+
+  // guile is going to (puts ...) the elements of the double array
+  // together. In non-POSIX locales, that will be in a format that
+  // the locale-specific sscanf will not be able to parse.
+  gnc_push_locale("C");
+  {
+    for (n=0; n<nvalues; n++) {
+      retval[n] = strtod(string, &next);
+      string = next;
+     }
+  }
+  gnc_pop_locale();
+
+  return retval;
+}
+
+static char ** 
+read_strings(const char * string, int nvalues)
+{
+  int n;
+  int choffset=0;
+  int accum = 0;
+  char ** retval = g_new0(char *, nvalues);
+  char thischar;
+  const char * inptr = string;
+  int escaped = FALSE;
+
+  for (n=0; n < nvalues; n++) {
+    retval[n] = g_new0(char, strlen(string+accum)+1);
+    retval[n][0] = 0;
+    choffset = 0;
+    while ((thischar = *inptr) != 0) {
+      if (thischar == '\\') {
+        escaped = TRUE;
+        inptr++;
+      }
+      else if ((thischar != ' ') || escaped) {
+        retval[n][choffset] = thischar;
+        retval[n][choffset+1] = 0;    
+        choffset++;
+        escaped = FALSE;
+        inptr++;
+      }
+      else {
+        /* an unescaped space */
+        escaped = FALSE;
+        inptr++;
+        break;
+      }
+    }
+    accum += choffset;
+    /* printf("retval[%d] = '%s'\n", n, retval[n]); */
+  }
+  
+  return retval;  
+}
+
+static int
+get_int_value( gchar** str, const gchar* name )
+{
+	gchar* p;
+	gchar* tag_name;
+	int val = -1;
+
+	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 );
+
+	return val;
+}
+
+static int
+get_int_param( gchar** str, const gchar* name )
+{
+	gchar* p;
+	gchar* tag_string;
+	int val = -1;
+
+	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 );
+
+	return val;
+}
+
+static gchar*
+get_string_param( gchar** str, const gchar* name )
+{
+	gchar* p;
+	gchar* p_end;
+	gchar* tag_string;
+	gchar* val = 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 );
+
+	return val;
+}
+
+static gchar*
+convert_pixbuf_to_base64_string( GdkPixbuf* pixbuf )
+{
+	gchar* pixel_buffer;
+	gsize pixel_buffer_size;
+	GError* error = NULL;
+	gchar* base64_buf;
+
+    if( !gdk_pixbuf_save_to_buffer( pixbuf, &pixel_buffer, &pixel_buffer_size, "png",
+									&error, NULL ) ) {
+		PERR( "Unable to save pixbuf to buffer: %s\n", error->message );
+		return NULL;
+	}
+
+	base64_buf = g_base64_encode( pixel_buffer, pixel_buffer_size );
+	g_free( pixel_buffer );
+	return base64_buf;
+}
+
+/*
+ * Handle the following parameters:
+ * title: text
+ * subtitle: text
+ * datasize: (length data), sscanf( .., %d, (int)&datasize )
+ * data: (foreach (lambda (datum) (push datum) (push " ")) data)
+ * colors: string; space-seperated?
+ * labels: string; space-seperated?
+ * slice_urls_[123]: ?
+ * legend_urls_[123]: ?
+ */
+static gboolean
+handle_piechart( GncHtml* html, gpointer eb, gpointer d )
+{
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlPieChartInfo pieChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* base64_buf;
+
+	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 );
+	}
+
+	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 );
+
+	base64_buf = convert_pixbuf_to_base64_string( pixbuf );
+	if( base64_buf == NULL ) {
+		return FALSE;
+	}
+
+	*pResult = g_strdup_printf( "<img src=\"data:image/png;base64,%s \" alt=\"Cannot display piechart\"/>", base64_buf );
+	g_free( base64_buf );
+
+	g_debug("piechart rendered.");
+	return TRUE;
+}
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ **/
+static gboolean
+handle_barchart( GncHtml* html, gpointer eb, gpointer d )
+{
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlBarChartInfo barChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* base64_buf;
+
+	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" );
+
+	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 );
+
+	base64_buf = convert_pixbuf_to_base64_string( pixbuf );
+	if( base64_buf == NULL ) {
+		return FALSE;
+	}
+
+	*pResult = g_strdup_printf( "<img src=\"data:image/png;base64,%s \" alt=\"Cannot display barchart\"/>", base64_buf );
+
+	g_debug("barchart rendered.");
+	return TRUE;
+}
+
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ * markers:boolean
+ * major_grid:boolean
+ * minor_grid:boolean
+ **/
+static gboolean
+handle_linechart( GncHtml* html, gpointer eb, gpointer d )
+{
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlLineChartInfo lineChartInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* base64_buf;
+
+	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" );
+
+	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 );
+
+	base64_buf = convert_pixbuf_to_base64_string( pixbuf );
+	if( base64_buf == NULL ) {
+		return FALSE;
+	}
+
+	*pResult = g_strdup_printf( "<img src=\"data:image/png;base64,%s \" alt=\"Cannot display linechart\"/>", base64_buf );
+
+	g_debug("linechart rendered.");
+	return TRUE;
+}
+
+
+static gboolean
+handle_scatter( GncHtml* html, gpointer eb, gpointer d )
+{
+	gchar* object_info = (gchar*)eb;
+	gchar** pResult = (gchar**)d;
+	GncHtmlScatterPlotInfo scatterPlotInfo;
+	GdkPixbuf* pixbuf;
+	gchar* p;
+	gchar* p_end;
+	gchar* temp_str;
+	gchar* base64_buf;
+
+	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 );
+	}
+
+	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 );
+
+	base64_buf = convert_pixbuf_to_base64_string( pixbuf );
+	if( base64_buf == NULL ) {
+		return FALSE;
+	}
+
+	*pResult = g_strdup_printf( "<img src=\"data:image/png;base64,%s \" alt=\"Cannot display scatterplot\"/>", base64_buf );
+
+	g_debug("scatterplot rendered.");
+	return TRUE;
+}

Added: gnucash/trunk/src/html/gnc-html-graph-gog-webkit.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog-webkit.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog-webkit.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,30 @@
+/********************************************************************
+ * gnc-html_graph_gog_webkit.h -- display html with gnc special     *
+ *									tags			                *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_GRAPH_GOG_WEBKIT_H
+#define GNC_HTML_GRAPH_GOG_WEBKIT_H 1
+
+void gnc_html_graph_gog_webkit_init( void );
+
+#endif /* GNC_HTML_GRAPH_GOG_WEBKIT_H */

Added: gnucash/trunk/src/html/gnc-html-graph-gog.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,528 @@
+/********************************************************************
+ * gnc-html-graph-gog.c -- GNC/HTML Graphing support via GOG        *
+ *                                                                  *
+ * Copyright (C) 2005 Joshua Sled <jsled at asynchronous.org>          *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "gnc-html-graph-gog.h"
+#include "gnc-html.h"
+#include "gnc-engine.h"
+#include <goffice/goffice.h>
+#include <goffice/graph/gog-chart.h>
+#include <goffice/graph/gog-graph.h>
+#include <goffice/graph/gog-object.h>
+#if defined(HAVE_GOFFICE_0_5)
+#    include <goffice/graph/gog-renderer.h>
+#elif defined(GOFFICE_WITH_CAIRO)
+#    include <goffice/graph/gog-renderer-cairo.h>
+#else
+#    include <goffice/graph/gog-renderer-pixbuf.h>
+#endif
+#ifndef GTKHTML_USES_GTKPRINT
+#    include <goffice/graph/gog-renderer-gnome-print.h>
+#endif
+#include <goffice/graph/gog-style.h>
+#include <goffice/graph/gog-styled-object.h>
+#include <goffice/graph/gog-plot.h>
+#include <goffice/graph/gog-series.h>
+#include <goffice/utils/go-color.h>
+#include <goffice/utils/go-marker.h>
+#include <goffice/graph/gog-data-set.h>
+#include <goffice/data/go-data-simple.h>
+#include <goffice/app/go-plugin.h>
+#include <goffice/app/go-plugin-loader-module.h>
+
+/**
+ * TODO:
+ * - scatter-plot marker selection
+ * - series-color, piecharts (hard, not really supported by GOG)
+ *   and scatters (or drop feature)
+ * - title-string freeing (fixmes)
+ * - general graph cleanup
+ **/
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "gnc.html.graph.gog"
+
+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);
+static void set_chart_axis_labels(GogObject *chart, const char *x_axis_label, const char* y_axis_label);
+
+void
+gnc_html_graph_gog_init( void )
+{
+	static gboolean initialized = FALSE;
+
+	if( !initialized ) {
+		g_debug( "init gog graphing" );
+
+		libgoffice_init();
+  
+		/* Initialize plugins manager */
+		go_plugins_init( NULL, NULL, NULL, NULL, TRUE, GO_PLUGIN_LOADER_MODULE_TYPE );
+
+		initialized = TRUE;
+	}
+}
+
+static GdkPixbuf*
+create_graph_pixbuf( GogObject *graph, int width, int height )
+{
+#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;
+
+	// 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));
+
+#if defined(HAVE_GOFFICE_0_5)
+	renderer = GOG_RENDERER(g_object_new( GOG_RENDERER_TYPE, "model", graph, NULL ));
+	update_status = gog_renderer_update( renderer, width, 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, width, 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, width, height, 1.0 );
+	buf = gog_renderer_pixbuf_get( pixbuf_renderer );
+#endif
+
+	g_object_set_data_full( G_OBJECT(buf), "graph", graph, g_object_unref );
+	return buf;
+}
+
+static gboolean
+create_basic_plot_elements(const char *plot_type_name,
+                           GogObject **out_graph,
+                           GogObject **out_chart,
+                           GogPlot **out_plot)
+{
+  *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;
+}
+
+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);
+}
+
+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);
+  }
+
+  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);
+  }
+}
+
+/*
+ * Handle the following parameters:
+ * title: text
+ * subtitle: text
+ * datasize: (length data), sscanf( .., %d, (int)&datasize )
+ * data: (foreach (lambda (datum) (push datum) (push " ")) data)
+ * colors: string; space-seperated?
+ * labels: string; space-seperated?
+ * slice_urls_[123]: ?
+ * legend_urls_[123]: ?
+ */
+GdkPixbuf*
+gnc_html_graph_gog_create_piechart( GncHtmlPieChartInfo* info )
+{
+	GogObject *graph, *chart;
+	GogPlot *plot;
+	GogSeries *series;
+	GOData *labelData, *sliceData;
+	GdkPixbuf* pixbuf;
+
+	if( !create_basic_plot_elements( "GogPiePlot", &graph, &chart, &plot ) ) {
+		return NULL;
+	}
+	gog_object_add_by_name( chart, "Legend", NULL );
+
+	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( (gchar const * const *)info->labels, info->datasize, NULL );
+	gog_series_set_dim( series, 0, labelData, NULL );
+	go_data_emit_changed( GO_DATA(labelData) );
+
+	sliceData = go_data_vector_val_new( info->data, info->datasize, NULL );
+	gog_series_set_dim( series, 1, sliceData, NULL );
+	go_data_emit_changed( GO_DATA(sliceData) );
+
+	// fixme: colors
+	set_chart_titles( chart, info->title, info->subtitle );
+
+	pixbuf = create_graph_pixbuf( graph, info->width, info->height );
+
+	return pixbuf;
+}
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ **/
+GdkPixbuf*
+gnc_html_graph_gog_create_barchart( GncHtmlBarChartInfo* info )
+{
+	GogObject *graph, *chart;
+	GogPlot *plot;
+	GogSeries *series;
+	GogStyle *style;
+	GOData *label_data, *slice_data;
+	char *bar_type = "normal";
+	int bar_overlap = 0 /*percent*/; // seperate bars; no overlap.
+	GdkPixbuf* pixbuf;
+
+	if( !create_basic_plot_elements( "GogBarColPlot", &graph, &chart, &plot ) ) {
+		return FALSE;
+	}
+	gog_object_add_by_name( chart, "Legend", NULL );
+
+	if( info->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( (gchar const * const *)info->row_labels, info->data_rows, NULL );
+	{
+		// foreach row:
+		//   series = row
+		GdkColor color;
+		int i;
+		for( i = 0; i < info->data_cols; i++ ) {
+			GError *err = NULL;
+
+			series = gog_plot_new_series( plot );
+			gog_object_set_name( GOG_OBJECT(series), info->col_labels[i], &err );
+			if( err != NULL ) {
+				g_warning( "error setting name [%s] on series [%d]: [%s]",
+							info->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( info->data + (i*info->data_rows), info->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( info->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]", info->col_colors[i] );
+			}
+		}
+	}
+
+	if( info->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( chart, info->title, info->subtitle );
+	set_chart_axis_labels( chart, info->x_axis_label, info->y_axis_label );
+
+	// we need to do this twice for the barchart... :p
+	gog_object_update( GOG_OBJECT(graph) );
+
+	pixbuf = create_graph_pixbuf( graph, info->width, info->height );
+	g_debug( "barchart rendered." );
+
+	return pixbuf;
+}
+
+
+/**
+ * data_rows:int
+ * data_cols:int
+ * data:doubles[], data_rows*data_cols
+ * x_axis_label:string
+ * y_axis_label:string
+ * row_labels:string[]
+ * col_labels:string[]
+ * col_colors:string[]
+ * rotate_row_labels:boolean
+ * stacked:boolean
+ * markers:boolean
+ * major_grid:boolean
+ * minor_grid:boolean
+ **/
+GdkPixbuf*
+gnc_html_graph_gog_create_linechart( GncHtmlLineChartInfo* info )
+{
+	GogObject *graph, *chart;
+	GogPlot *plot;
+	GogSeries *series;
+	GogStyle *style;
+	GOData *label_data, *slice_data;
+	gchar* line_type = "normal";
+	GdkPixbuf* pixbuf;
+
+	if( !create_basic_plot_elements( "GogLinePlot", &graph, &chart, &plot ) ) {
+		return NULL;
+	}
+	gog_object_add_by_name( chart, "Legend", NULL );
+
+	if( info->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", info->markers,
+					NULL);
+	label_data = go_data_vector_str_new( (gchar const * const *)info->row_labels, info->data_rows, NULL );
+	{
+		// foreach row:
+		//   series = row
+		GdkColor color;
+		int i;
+		for( i = 0; i < info->data_cols; i++ ) {
+			GError *err = NULL;
+
+			series = gog_plot_new_series( plot );
+			gog_object_set_name( GOG_OBJECT(series), info->col_labels[i], &err );
+			if( err != NULL ) {
+				g_warning( "error setting name [%s] on series [%d]: [%s]",
+							info->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( info->data + (i* info->data_rows),  info->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( info->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]", info->col_colors[i] );
+			}
+		}
+	}
+
+	if( info->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( info->major_grid ||  info->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( info->major_grid ) {
+			gog_object_add_by_name( GOG_OBJECT(object), "MajorGrid", NULL );
+		}
+		if( info->minor_grid ) {
+			gog_object_add_by_name( GOG_OBJECT (object), "MinorGrid", NULL );
+		}
+	}
+
+	set_chart_titles( chart, info->title, info->subtitle );
+	set_chart_axis_labels( chart, info->x_axis_label, info->y_axis_label );
+
+	// we need to do this twice for the linechart... :p
+	gog_object_update( GOG_OBJECT(graph) );
+
+	pixbuf = create_graph_pixbuf( graph, info->width, info->height );
+	g_debug( "linechart rendered." );
+
+	return pixbuf;
+}
+
+GdkPixbuf*
+gnc_html_graph_gog_create_scatterplot( GncHtmlScatterPlotInfo* info )
+{
+	GogObject *graph, *chart;
+	GogPlot *plot;
+	GogSeries *series;
+	GOData *sliceData;
+	GogStyle *style;
+	gboolean fill = FALSE;
+
+	if( !create_basic_plot_elements( "GogXYPlot", &graph, &chart, &plot ) ) {
+		return NULL;
+	}
+
+	series = gog_plot_new_series( plot );
+	style = gog_styled_object_get_style( GOG_STYLED_OBJECT(series) );
+
+	sliceData = go_data_vector_val_new( info->xData, info->datasize, NULL );
+	gog_series_set_dim( series, 0, sliceData, NULL );
+	go_data_emit_changed( GO_DATA(sliceData) );
+
+	sliceData = go_data_vector_val_new( info->yData, info->datasize, NULL );
+	gog_series_set_dim( series, 1, sliceData, NULL );
+	go_data_emit_changed( GO_DATA(sliceData) );
+
+	/* set marker shape */
+	if( info->marker_str != NULL ) {
+		GOMarkerShape shape;
+
+		if( g_str_has_prefix( info->marker_str, "filled ") ) {
+			fill = TRUE;
+			info->marker_str += 7;
+		}
+		shape = go_marker_shape_from_str( info->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]", info->marker_str );
+		}
+	}
+
+	/* set marker and line colors */
+	if( info->color_str != NULL ) {
+		GdkColor color;
+		if( gdk_color_parse( info->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]", info->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( chart, info->title, info->subtitle );
+	set_chart_axis_labels( chart, info->x_axis_label, info->y_axis_label );
+
+	// And twice for the scatter, too... :p
+	gog_object_update( GOG_OBJECT(graph) );
+
+	return create_graph_pixbuf( graph, info->width, info->height );
+}

Added: gnucash/trunk/src/html/gnc-html-graph-gog.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-graph-gog.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-graph-gog.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,96 @@
+/********************************************************************
+ * gnc-html_graph_gog.h -- display html with gnc special            *
+ *									tags			                *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_GRAPH_GOG_H
+#define GNC_HTML_GRAPH_GOG_H 1
+
+typedef struct {
+    gint width;
+	gint height;
+	const gchar* title;
+	const gchar* subtitle;
+	gint datasize;
+	gdouble* data;
+	gchar** labels;
+	gchar** colors;
+} GncHtmlPieChartInfo;
+
+typedef struct {
+    gint width;
+	gint height;
+	const gchar* title;
+	const gchar* subtitle;
+	gint data_rows;
+	gint data_cols;
+	gdouble* data;
+	gchar** col_labels;
+	gchar** row_labels;
+	gchar** col_colors;
+	const gchar* x_axis_label;
+	const gchar* y_axis_label;
+	gboolean rotate_row_labels;
+	gboolean stacked;
+} GncHtmlBarChartInfo;
+
+typedef struct {
+    gint width;
+	gint height;
+	const gchar* title;
+	const gchar* subtitle;
+	gint data_rows;
+	gint data_cols;
+	gdouble* data;
+	gchar** col_labels;
+	gchar** row_labels;
+	gchar** col_colors;
+	gboolean rotate_row_labels;
+	gboolean stacked;
+	gboolean markers;
+	gboolean major_grid;
+	gboolean minor_grid;
+	const gchar* x_axis_label;
+	const gchar* y_axis_label;
+} GncHtmlLineChartInfo;
+
+typedef struct {
+    gint width;
+	gint height;
+	const gchar* title;
+	const gchar* subtitle;
+	const gchar* x_axis_label;
+	const gchar* y_axis_label;
+	gint datasize;
+	gdouble* xData;
+	gdouble* yData;
+	const gchar* marker_str;
+	const gchar* color_str;
+} GncHtmlScatterPlotInfo;
+
+void gnc_html_graph_gog_init( void );
+GdkPixbuf* gnc_html_graph_gog_create_piechart( GncHtmlPieChartInfo* info );
+GdkPixbuf* gnc_html_graph_gog_create_barchart( GncHtmlBarChartInfo* info );
+GdkPixbuf* gnc_html_graph_gog_create_linechart( GncHtmlLineChartInfo* info );
+GdkPixbuf* gnc_html_graph_gog_create_scatterplot( GncHtmlScatterPlotInfo* info );
+
+#endif /* GNC_HTML_GRAPH_GOG_H */

Added: gnucash/trunk/src/html/gnc-html-gtkhtml-p.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-gtkhtml-p.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-gtkhtml-p.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,34 @@
+/********************************************************************
+ * gnc-html-gtkhtml-p.h -- display html with gnc special tags       *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_GTKHTML_P_H
+#define GNC_HTML_GTKHTML_P_H
+
+#include "gnc-html-p.h"
+
+struct _GncHtmlGtkhtmlPrivate {
+	struct _GncHtmlPrivate base;
+
+	GtkWidget* html;				/* gtkhtml widget itself */
+};
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-gtkhtml.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-gtkhtml.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-gtkhtml.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,932 @@
+/********************************************************************
+ * gnc-html-gtkhtml.c -- display HTML with some special gnucash     *
+ *                       tags.                                      *
+ *                                                                  *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2001 Linas Vepstas <linas at linas.org>               *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+// libgtkhtml docs:
+// http://www.fifi.org/doc/libgtkhtml-dev/html/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <regex.h>
+#include <libguile.h>
+
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-embedded.h>
+
+#include "Account.h"
+#include "print-session.h"
+#include "gnc-engine.h"
+#include "gnc-gui-query.h"
+#include "gnc-html.h"
+#include "gnc-html-gtkhtml.h"
+#include "gnc-html-history.h"
+#include "gnc-html-graph-gog-gtkhtml.h"
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+
+G_DEFINE_TYPE(GncHtmlGtkhtml, gnc_html_gtkhtml, GNC_TYPE_HTML )
+
+static void gnc_html_gtkhtml_dispose( GObject* obj );
+static void gnc_html_gtkhtml_finalize( GObject* obj );
+static void gnc_html_gtkhtml_class_init( GncHtmlGtkhtmlClass* klass );
+static void gnc_html_gtkhtml_init( GncHtmlGtkhtml* gs );
+
+//#define GNC_HTML_GTKHTML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_HTML_GTKHTML, GncHtmlGtkhtmlPrivate))
+#define GNC_HTML_GTKHTML_GET_PRIVATE(o) (GNC_HTML_GTKHTML(o)->priv)
+
+#include "gnc-html-gtkhtml-p.h"
+
+/* indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_HTML;
+
+/* hashes for URLType -> protocol and protocol -> URLType */
+//extern GHashTable* gnc_html_type_to_proto_hash;
+extern GHashTable* gnc_html_proto_to_type_hash;
+
+/* hashes an HTML <object classid="ID"> classid to a handler function */
+extern GHashTable* gnc_html_object_handlers;
+
+/* hashes handlers for loading different URLType data */
+extern GHashTable* gnc_html_stream_handlers;
+
+/* hashes handlers for handling different URLType data */
+extern GHashTable* gnc_html_url_handlers;
+
+static char error_404_format[] = "<html><body><h3>%s</h3><p>%s</body></html>";
+static char error_404_title[] = N_("Not found");
+static char error_404_body[] = N_("The specified URL could not be loaded.");
+
+static void gtkhtml_pre_3_10_1_bug_workaround( GtkHTMLEmbedded* eb );
+static void gnc_html_url_requested_cb( GtkHTML* html, gchar* url,
+                          GtkHTMLStream* handle, gpointer data );
+static void gnc_html_on_url_cb( GtkHTML* html, const gchar* url, gpointer data );
+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 );
+static gboolean gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
+                             gpointer data );
+static int gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
+                         gpointer user_data );
+static void impl_gtkhtml_show_url( GncHtml* self, URLType type,
+                  const gchar* location, const gchar* label,
+                  gboolean new_window_hint );
+static void impl_gtkhtml_show_data( GncHtml* self, const gchar* data, int datalen );
+static void impl_gtkhtml_reload( GncHtml* self );
+static void impl_gtkhtml_copy_to_clipboard( GncHtml* self );
+static gboolean impl_gtkhtml_export_to_file( GncHtml* self, const gchar* filepath );
+static void impl_gtkhtml_print( GncHtml* self );
+static void impl_gtkhtml_cancel( GncHtml* self );
+static void impl_gtkhtml_set_parent( GncHtml* self, GtkWindow* parent );
+
+static void
+gnc_html_gtkhtml_init( GncHtmlGtkhtml* self )
+{
+	GncHtmlGtkhtmlPrivate* priv;
+	GncHtmlGtkhtmlPrivate* new_priv;
+
+	new_priv = g_realloc( GNC_HTML(self)->priv, sizeof(GncHtmlGtkhtmlPrivate) );
+	priv = self->priv = new_priv;
+
+	priv->html = gtk_html_new();
+	gtk_container_add( GTK_CONTAINER(priv->base.container),
+						GTK_WIDGET(priv->html) );
+
+#ifdef HAVE_GTK_2_10
+	g_object_ref_sink( priv->base.container );
+#else
+	g_object_ref( priv->base.container );
+	gtk_object_sink( GTK_OBJECT(priv->base.container) );
+#endif
+
+	/* signals */
+	g_signal_connect( priv->html, "url_requested",
+					G_CALLBACK(gnc_html_url_requested_cb),
+					self);
+
+	g_signal_connect( priv->html, "on_url",
+				   G_CALLBACK(gnc_html_on_url_cb),
+				   self );
+
+	g_signal_connect( priv->html, "set_base",
+		   G_CALLBACK(gnc_html_set_base_cb),
+		   self);
+
+	g_signal_connect(priv->html, "link_clicked",
+		   G_CALLBACK(gnc_html_link_clicked_cb),
+		   self);
+
+	g_signal_connect (priv->html, "object_requested",
+		    G_CALLBACK (gnc_html_object_requested_cb),
+		    self);
+
+	g_signal_connect (priv->html, "button_press_event",
+		    G_CALLBACK (gnc_html_button_press_cb),
+		    self);
+
+	gtk_html_load_empty(GTK_HTML(priv->html));
+
+	LEAVE("retval %p", self);
+}
+
+static void
+gnc_html_gtkhtml_class_init( GncHtmlGtkhtmlClass* klass )
+{
+	GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+	GncHtmlClass* html_class = GNC_HTML_CLASS(klass);
+
+	gobject_class->dispose = gnc_html_gtkhtml_dispose;
+	gobject_class->finalize = gnc_html_gtkhtml_finalize;
+
+	html_class->show_url = impl_gtkhtml_show_url;
+	html_class->show_data = impl_gtkhtml_show_data;
+	html_class->reload = impl_gtkhtml_reload;
+	html_class->copy_to_clipboard = impl_gtkhtml_copy_to_clipboard;
+	html_class->export_to_file = impl_gtkhtml_export_to_file;
+	html_class->print = impl_gtkhtml_print;
+	html_class->cancel = impl_gtkhtml_cancel;
+	html_class->set_parent = impl_gtkhtml_set_parent;
+
+	// Initialize graphing support
+	gnc_html_graph_gog_gtkhtml_init();
+}
+
+static void
+gnc_html_gtkhtml_dispose( GObject* obj )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(obj);
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	if( priv->html != NULL ) {
+		g_object_unref( G_OBJECT(priv->html) );
+		priv->html = NULL;
+	}
+
+	G_OBJECT_CLASS(gnc_html_gtkhtml_parent_class)->dispose( obj );
+}
+
+static void
+gnc_html_gtkhtml_finalize( GObject* obj )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(obj);
+
+//	if( self->priv != NULL ) {
+//		g_free( self->priv );
+		self->priv = NULL;
+//	}
+
+	G_OBJECT_CLASS(gnc_html_gtkhtml_parent_class)->finalize( obj );
+}
+
+/*****************************************************************************/
+
+static char*
+extract_base_name(URLType type, const gchar* path)
+{
+	gchar       machine_rexp[] = "^(//[^/]*)/*(/.*)?$";
+	gchar       path_rexp[] = "^/*(.*)/+([^/]*)$";
+	regex_t    compiled_m, compiled_p;
+	regmatch_t match[4];
+	gchar       * machine=NULL, * location = NULL, * base=NULL;
+	gchar       * basename=NULL;
+
+	DEBUG(" ");
+	if(!path) return NULL;
+
+	regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
+	regcomp(&compiled_p, path_rexp, REG_EXTENDED);
+
+	if (!safe_strcmp (type, URL_TYPE_HTTP) ||
+			!safe_strcmp (type, URL_TYPE_SECURE) ||
+			!safe_strcmp (type, URL_TYPE_FTP)) {
+
+		/* step 1: split the machine name away from the path
+		 * components */
+		if(!regexec(&compiled_m, path, 4, match, 0)) {
+			/* $1 is the machine name */
+			if(match[1].rm_so != -1) {
+				machine = g_strndup(path+match[1].rm_so,
+                            match[1].rm_eo - match[1].rm_so);
+			}
+			/* $2 is the path */
+			if(match[2].rm_so != -1) {
+				location = g_strndup(path+match[2].rm_so,
+                             match[2].rm_eo - match[2].rm_so);
+			}
+		}
+
+	} else {
+		location = g_strdup(path);
+	}
+	/* step 2: split up the path into prefix and file components */
+	if(location) {
+		if(!regexec(&compiled_p, location, 4, match, 0)) {
+			if(match[1].rm_so != -1) {
+				base = g_strndup(location+match[1].rm_so,
+                         match[1].rm_eo - match[1].rm_so);
+			} else {
+				base = NULL;
+			}
+		}
+	}
+
+	regfree(&compiled_m);
+	regfree(&compiled_p);
+
+	if(machine) {
+		if(base && (strlen(base) > 0)) {
+			basename = g_strconcat(machine, "/", base, "/", NULL);
+		} else {
+			basename = g_strconcat(machine, "/", NULL);
+		}
+	} else {
+		if(base && (strlen(base) > 0)) {
+			basename = g_strdup(base);
+		} else {
+			basename = NULL;
+		}
+	}
+
+	g_free(machine);
+	g_free(base);
+	g_free(location);
+	return basename;
+}
+
+static gboolean
+http_allowed()
+{
+	return TRUE;
+}
+
+static gboolean
+https_allowed()
+{
+	return TRUE;
+}
+
+/************************************************************
+ * gnc_html_start_request: starts the gnc-http object working on an
+ * http/https request.
+ ************************************************************/
+static void
+gnc_html_start_request( GncHtmlGtkhtml* self, gchar * uri, GtkHTMLStream * handle )
+{
+	GList * handles = NULL;
+	gint  need_request = FALSE;
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	/* we want to make a list of handles to fill with this URI.
+	 * multiple handles with the same URI will all get filled when the
+	 * request comes in. */
+	DEBUG("requesting %s", uri);
+	handles = g_hash_table_lookup( priv->base.request_info, uri );
+	if( handles == NULL ) {
+		need_request = TRUE;
+	}
+
+	handles = g_list_append( handles, handle );
+	g_hash_table_insert( priv->base.request_info, uri, handles );
+
+	if( need_request ) {
+		g_critical("we've not supported network requests for years");
+	}
+}
+
+/********************************************************************
+ * gnc_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( GncHtmlGtkhtml* self, GtkHTMLStream* handle,
+                        URLType type, const gchar* location,
+                        const gchar* label )
+{
+	gchar* fdata = NULL;
+	int fdata_len = 0;
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	DEBUG( "type %s, location %s, label %s", type ? type : "(null)",
+			location ? location : "(null)", label ? label : "(null)");
+
+	g_return_if_fail( self != NULL );
+
+	if( gnc_html_stream_handlers != NULL ) {
+		GncHTMLStreamCB stream_handler;
+
+		stream_handler = g_hash_table_lookup( gnc_html_stream_handlers, type );
+		if( stream_handler ) {
+			gboolean ok = stream_handler( location, &fdata, &fdata_len );
+
+			if( ok ) {
+				fdata = fdata ? fdata : g_strdup( "" );
+				gtk_html_write( GTK_HTML(priv->html), handle, fdata, fdata_len );
+				gtk_html_end( GTK_HTML(priv->html), handle, GTK_HTML_STREAM_OK );
+			} else {
+				fdata = fdata ? fdata :
+							g_strdup_printf( error_404_format,
+							_(error_404_title), _(error_404_body) );
+				gtk_html_write( GTK_HTML(priv->html), handle, fdata, strlen(fdata) );
+				gtk_html_end( GTK_HTML(priv->html), handle, GTK_HTML_STREAM_ERROR );
+			}
+
+			g_free( fdata );
+
+			if( label ) {
+				while( gtk_events_pending() ) {
+					gtk_main_iteration();
+				}
+				gtk_html_jump_to_anchor( GTK_HTML(priv->html), label );
+			}
+
+			return;
+		}
+	}
+
+	do {
+		if( !safe_strcmp( type, URL_TYPE_SECURE ) ||
+			!safe_strcmp( type, URL_TYPE_HTTP ) ) {
+
+			if( !safe_strcmp( type, URL_TYPE_SECURE ) ) {
+				if( !https_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+                            _("Secure HTTP access is disabled. "
+                              "You can enable it in the Network section of "
+                              "the Preferences dialog."));
+					break;
+				}
+			}
+
+			if( !http_allowed() ) {
+				gnc_error_dialog( priv->base.parent,
+                          _("Network HTTP access is disabled. "
+                            "You can enable it in the Network section of "
+                            "the Preferences dialog."));
+			} else {
+				char *fullurl;
+
+				fullurl = gnc_build_url( type, location, label );
+				gnc_html_start_request( self, fullurl, handle );
+			}
+
+		} else {
+			PWARN( "load_to_stream for inappropriate type\n"
+					"\turl = '%s#%s'\n",
+					location ? location : "(null)",
+					label ? label : "(null)" );
+			fdata = g_strdup_printf( error_404_format,
+								_(error_404_title), _(error_404_body) );
+			gtk_html_write( GTK_HTML(priv->html), handle, fdata, strlen (fdata) );
+			gtk_html_end( GTK_HTML(priv->html), handle, GTK_HTML_STREAM_ERROR );
+			g_free( fdata );
+		}
+
+	} while( FALSE );
+}
+
+/********************************************************************
+ * gnc_html_link_clicked_cb - called when user left-clicks on html
+ * anchor.
+ ********************************************************************/
+
+static void
+gnc_html_link_clicked_cb( GtkHTML* html, const gchar* url, gpointer data )
+{
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(data);
+
+	DEBUG("Clicked %s", url);
+	type = gnc_html_parse_url( GNC_HTML(self), url, &location, &label );
+	gnc_html_show_url( GNC_HTML(self), type, location, label, 0 );
+	g_free( location );
+	g_free( label );
+}
+
+
+/********************************************************************
+ * gnc_html_url_requested_cb - called when a URL needs to be
+ * loaded within the loading of a page (embedded image).
+ ********************************************************************/
+
+static void
+gnc_html_url_requested_cb( GtkHTML* html, gchar* url,
+                          GtkHTMLStream* handle, gpointer data )
+{
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(data);
+
+	DEBUG( "requesting %s", url );
+	type = gnc_html_parse_url( GNC_HTML(self), url, &location, &label );
+	gnc_html_load_to_stream( self, handle, type, location, label );
+	g_free( location );
+	g_free( label );
+}
+
+
+/********************************************************************
+ * gnc_html_object_requested_cb - called when an applet needs to be
+ * loaded.
+ ********************************************************************/
+
+static gboolean
+gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
+                             gpointer data )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(data);
+	GncHTMLObjectCB h;
+
+	DEBUG( " " );
+	if( !eb || !(eb->classid) || !gnc_html_object_handlers ) return FALSE;
+
+	gtkhtml_pre_3_10_1_bug_workaround( eb );
+	h = g_hash_table_lookup( gnc_html_object_handlers, eb->classid );
+	if( h ) {
+		return h( GNC_HTML(self), eb, data );
+	} else {
+		return FALSE;
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_on_url_cb - called when user rolls over html anchor
+ ********************************************************************/
+
+static void
+gnc_html_on_url_cb( GtkHTML* html, const gchar* url, gpointer data )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(data);
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	DEBUG( "Rollover %s", url ? url : "(null)" );
+	g_free( priv->base.current_link );
+	priv->base.current_link = g_strdup( url );
+	if( priv->base.flyover_cb ) {
+		(priv->base.flyover_cb)( GNC_HTML(self), url, priv->base.flyover_cb_data );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_set_base_cb
+ ********************************************************************/
+
+static void
+gnc_html_set_base_cb( GtkHTML* gtkhtml, const gchar* base,
+                     gpointer data )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(data);
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+
+	DEBUG( "Setting base location to %s", base );
+	type = gnc_html_parse_url( GNC_HTML(self), base, &location, &label );
+
+	g_free( priv->base.base_location );
+	g_free( label );
+
+	priv->base.base_type = type;
+	priv->base.base_location = location;
+}
+
+
+/********************************************************************
+ * gnc_html_button_press_cb
+ * mouse button callback (if any)
+ ********************************************************************/
+
+static int
+gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
+                         gpointer user_data )
+{
+	GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(user_data);
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	DEBUG( "Button Press" );
+	if( priv->base.button_cb != NULL ) {
+		(priv->base.button_cb)( GNC_HTML(self), event, priv->base.button_cb_data );
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/********************************************************************
+ * gnc_html_open_scm
+ * insert some scheme-generated HTML
+ ********************************************************************/
+
+static void
+gnc_html_open_scm( GncHtmlGtkhtml* self, const gchar * location,
+                  const gchar * label, int newwin )
+{
+	PINFO("location='%s'", location ? location : "(null)");
+}
+
+
+/********************************************************************
+ * gnc_html_show_data
+ * display some HTML that the creator of the gnc-html got from
+ * somewhere.
+ ********************************************************************/
+
+static void
+impl_gtkhtml_show_data( GncHtml* self, const char * data, int datalen )
+{
+	GtkHTMLStream * handle;
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	DEBUG( "datalen %d, data %20.20s", datalen, data );
+	handle = gtk_html_begin( GTK_HTML(priv->html) );
+	gtk_html_write( GTK_HTML(priv->html), handle, data, datalen );
+	gtk_html_end( GTK_HTML(priv->html), handle, GTK_HTML_STREAM_OK );
+}
+
+/********************************************************************
+ * gnc_html_show_url
+ *
+ * open a URL.  This is called when the user clicks a link or
+ * for the creator of the gnc_html window to explicitly request
+ * a URL.
+ ********************************************************************/
+
+static void
+impl_gtkhtml_show_url( GncHtml* self, URLType type,
+                  const gchar* location, const gchar* label,
+                  gboolean new_window_hint )
+{
+	GncHTMLUrlCB url_handler;
+	GtkHTMLStream * handle;
+	gboolean new_window;
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	DEBUG(" ");
+
+	if( self == NULL ) return;
+	if( location == NULL ) return;
+
+	/* make sure it's OK to show this URL type in this window */
+	if( new_window_hint == 0 ) {
+		if( priv->base.urltype_cb ) {
+			new_window = !((priv->base.urltype_cb)( type ));
+		} else {
+			new_window = FALSE;
+		}
+	} else {
+		new_window = TRUE;
+	}
+
+	if( !new_window ) {
+		gnc_html_cancel( GNC_HTML(self) );
+	}
+
+	if( gnc_html_url_handlers ) {
+		url_handler = g_hash_table_lookup( gnc_html_url_handlers, type );
+	} else {
+		url_handler = NULL;
+	}
+
+	if( url_handler ) {
+		GNCURLResult result;
+		gboolean ok;
+
+		result.load_to_stream = FALSE;
+		result.url_type = type;
+		result.location = NULL;
+		result.label = NULL;
+		result.base_type = URL_TYPE_FILE;
+		result.base_location = NULL;
+		result.error_message = NULL;
+
+		ok = url_handler( location, label, new_window, &result );
+		if( !ok ) {
+			if( result.error_message ) {
+			  gnc_error_dialog( priv->base.parent, "%s", result.error_message );
+			} else {
+				/* %s is a URL (some location somewhere). */
+				gnc_error_dialog( priv->base.parent, _("There was an error accessing %s."), location );
+			}
+
+			if( priv->base.load_cb ) {
+				priv->base.load_cb( GNC_HTML(self), result.url_type,
+								location, label, priv->base.load_cb_data );
+			}
+		} else if( result.load_to_stream ) {
+			gnc_html_history_node *hnode;
+			const char *new_location;
+			const char *new_label;
+			GtkHTMLStream * stream;
+
+			new_location = result.location ? result.location : location;
+			new_label = result.label ? result.label : label;
+			hnode = gnc_html_history_node_new( result.url_type, new_location, new_label );
+
+			gnc_html_history_append( priv->base.history, hnode );
+
+			g_free( priv->base.base_location );
+			priv->base.base_type = result.base_type;
+			priv->base.base_location =
+					g_strdup( extract_base_name( result.base_type, new_location ) );
+			DEBUG( "resetting base location to %s",
+					priv->base.base_location ? priv->base.base_location : "(null)" );
+
+			stream = gtk_html_begin( GTK_HTML(priv->html) );
+			gnc_html_load_to_stream( GNC_HTML_GTKHTML(self), stream, result.url_type,
+									new_location, new_label );
+
+			if( priv->base.load_cb != NULL ) {
+				priv->base.load_cb( GNC_HTML(self), result.url_type,
+								new_location, new_label, priv->base.load_cb_data );
+			}
+		}
+
+		g_free( result.location );
+		g_free( result.label );
+		g_free( result.base_location );
+		g_free( result.error_message );
+
+		return;
+	}
+
+	if( safe_strcmp( type, URL_TYPE_SCHEME ) == 0 ) {
+		gnc_html_open_scm( GNC_HTML_GTKHTML(self), location, label, new_window );
+
+	} else if( safe_strcmp( type, URL_TYPE_JUMP ) == 0 ) {
+		gtk_html_jump_to_anchor( GTK_HTML(priv->html), label );
+
+	} else if( safe_strcmp( type, URL_TYPE_SECURE ) == 0 ||
+				safe_strcmp( type, URL_TYPE_HTTP ) == 0 ||
+				safe_strcmp( type, URL_TYPE_FILE ) == 0 ) {
+
+		do {
+			if( safe_strcmp( type, URL_TYPE_SECURE ) == 0 ) {
+				if( !https_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+									_("Secure HTTP access is disabled. "
+									"You can enable it in the Network section of "
+									"the Preferences dialog.") );
+					break;
+				}
+			}
+
+			if( safe_strcmp( type, URL_TYPE_HTTP ) == 0 ) {
+				if( !http_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+									_("Network HTTP access is disabled. "
+									"You can enable it in the Network section of "
+									"the Preferences dialog.") );
+					break;
+				}
+			}
+
+			priv->base.base_type = type;
+
+			if( priv->base.base_location != NULL ) g_free( priv->base.base_location );
+			priv->base.base_location = extract_base_name( type, location );
+
+			/* FIXME : handle new_window = 1 */
+			gnc_html_history_append( priv->base.history,
+								gnc_html_history_node_new( type, location, label ) );
+			handle = gtk_html_begin( GTK_HTML(priv->html) );
+			gnc_html_load_to_stream( GNC_HTML_GTKHTML(self), handle, type, location, label );
+
+		} while( FALSE );
+
+	} else {
+		PERR( "URLType %s not supported.", type );
+	}
+
+	if( priv->base.load_cb != NULL ) {
+		(priv->base.load_cb)( GNC_HTML(self), type, location, label, priv->base.load_cb_data );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_reload
+ * reload the current page
+ ********************************************************************/
+
+static void
+impl_gtkhtml_reload( GncHtml* self )
+{
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	gnc_html_history_node * n;
+
+	DEBUG(" ");
+	n = gnc_html_history_get_current( priv->base.history );
+	if( n != NULL ) {
+		gnc_html_show_url( self, n->type, n->location, n->label, 0 );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_gtkhtml_new
+ * create and set up a new gtkhtml widget.
+ ********************************************************************/
+
+GncHtml*
+gnc_html_gtkhtml_new( void )
+{
+	GncHtmlGtkhtml* self = g_object_new( GNC_TYPE_HTML_GTKHTML, NULL );
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+
+	return GNC_HTML(self);
+}
+
+/********************************************************************
+ * gnc_html_cancel
+ * cancel any outstanding HTML fetch requests.
+ ********************************************************************/
+
+static gboolean
+gtkhtml_cancel_helper(gpointer key, gpointer value, gpointer user_data)
+{
+	g_free(key);
+	g_list_free((GList *)value);
+	return TRUE;
+}
+
+static void
+impl_gtkhtml_cancel( GncHtml* self )
+{
+	GncHtmlGtkhtmlPrivate* priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	/* remove our own references to requests */
+	//gnc_http_cancel_requests( priv->http );
+
+	g_hash_table_foreach_remove( priv->base.request_info, gtkhtml_cancel_helper, NULL );
+}
+
+static void
+impl_gtkhtml_copy_to_clipboard( GncHtml* self )
+{
+	GncHtmlGtkhtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+
+	priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	gtk_html_copy( GTK_HTML(priv->html) );
+}
+
+/**************************************************************
+ * gnc_html_export_to_file : wrapper around the builtin function in gtkhtml
+ **************************************************************/
+
+static gboolean
+raw_html_receiver( gpointer engine,
+                   const gchar* data,
+                   size_t len,
+                   gpointer user_data )
+{
+	FILE *fh = (FILE *) user_data;
+	size_t written;
+
+	do {
+		written = fwrite (data, 1, len, fh);
+		len -= written;
+	} while (len > 0);
+	return TRUE;
+}
+
+static gboolean
+impl_gtkhtml_export_to_file( GncHtml* self, const char *filepath )
+{
+	FILE *fh;
+	GncHtmlGtkhtmlPrivate* priv;
+
+	g_return_val_if_fail( self != NULL, FALSE );
+	g_return_val_if_fail( filepath != NULL, FALSE );
+
+	priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	fh = g_fopen( filepath, "w" );
+	if( fh == 0 )
+		return FALSE;
+
+	gtk_html_save( GTK_HTML(priv->html), GINT_TO_POINTER(raw_html_receiver), fh );
+	fclose (fh);
+
+	return TRUE;
+}
+
+#ifdef GTKHTML_USES_GTKPRINT
+static void
+draw_page_cb(GtkPrintOperation *operation, GtkPrintContext *context,
+             gint page_nr, gpointer user_data)
+{
+    GncHtmlGtkhtml* self = GNC_HTML_GTKHTML(user_data);
+	GncHtmlGtkhtmlPrivate* priv;
+
+	priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+    gtk_html_print_page( GTK_HTML(priv->html), context );
+}
+
+static void
+impl_gtkhtml_print( GncHtml* self )
+{
+    GtkPrintOperation *print;
+    GtkPrintOperationResult res;
+	GncHtmlGtkhtmlPrivate* priv;
+
+	priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+    print = gtk_print_operation_new();
+
+    gnc_print_operation_init(print);
+    gtk_print_operation_set_use_full_page(print, FALSE);
+    gtk_print_operation_set_unit(print, GTK_UNIT_POINTS);
+    gtk_print_operation_set_n_pages(print, 1);
+    g_signal_connect(print, "draw_page", G_CALLBACK(draw_page_cb), self);
+
+    res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+                                  GTK_WINDOW(priv->base.parent), NULL);
+
+    if( res == GTK_PRINT_OPERATION_RESULT_APPLY ) {
+        gnc_print_operation_save_print_settings( print );
+	}
+
+    g_object_unref(print);
+}
+
+#else /* !GTKHTML_USES_GTKPRINT */
+void
+gnc_html_print( GncHtml* html )
+{
+	PrintSession *ps;
+
+	ps = gnc_print_session_create( FALSE );
+	if( ps == NULL ) {
+		/* user cancelled */
+		return;
+	}
+
+	gtk_html_print( GTK_HTML(html->html), ps->context );
+	gnc_print_session_done( ps );
+}
+#endif /* GTKHTML_USES_GTKPRINT */
+
+static void
+impl_gtkhtml_set_parent( GncHtml* self, GtkWindow* parent )
+{
+	GncHtmlGtkhtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+
+	priv = GNC_HTML_GTKHTML_GET_PRIVATE(self);
+	priv->base.parent = GTK_WIDGET(parent);
+}
+
+const gchar*
+gnc_html_get_embedded_param( gpointer eb, const gchar* param_name )
+{
+	GtkHTMLEmbedded* gtk_eb = (GtkHTMLEmbedded*)eb;
+
+	return (const gchar *)g_hash_table_lookup(gtk_eb->params, param_name);
+}
+
+static void
+gtkhtml_pre_3_10_1_bug_workaround(GtkHTMLEmbedded *eb)
+{
+	/* HACK ALERT! Compensate for bug in gtkhtml < 3.10.1
+		Gtkhtml set the width parameter twice (=width, =height), so both,
+		width (==height) and height (<1) were incorrect. */
+	if( eb->height < 1 ) {
+		eb->height = eb->width;  /* only squares here :( */
+	}
+}

Added: gnucash/trunk/src/html/gnc-html-gtkhtml.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-gtkhtml.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-gtkhtml.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,59 @@
+/********************************************************************
+ * gnc-html-gtkhtml.h -- display html with gnc special tags         *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_GTKHTML_H
+#define GNC_HTML_GTKHTML_H
+
+#include <glib-object.h>
+#include "gnc-html.h"
+
+G_BEGIN_DECLS
+
+#define GNC_TYPE_HTML_GTKHTML       (gnc_html_gtkhtml_get_type())
+#define GNC_HTML_GTKHTML(o)         (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_HTML_GTKHTML, GncHtmlGtkhtml))
+#define GNC_HTML_GTKHTML_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_HTML_GTKHTML, GncHtmlGtkhtmlClass))
+#define GNC_IS_HTML_GTKHTML(o)      (G_TYPE_CHECK_INSTANCE_TYPE((o), GNC_TYPE_HTML_GTKHTML))
+#define GNC_IS_HTML_GTKHTML_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE((k), GNC_TYPE_HTML_GTKHTML))
+#define GNC_HTML_GTKHTML_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS((o), GNC_TYPE_HTML_GTKHTML, GncHtmlGtkhtmlClass))
+
+typedef struct _GncHtmlGtkhtml GncHtmlGtkhtml;
+typedef struct _GncHtmlGtkhtmlClass GncHtmlGtkhtmlClass;
+typedef struct _GncHtmlGtkhtmlPrivate GncHtmlGtkhtmlPrivate;
+
+struct _GncHtmlGtkhtml {
+	GncHtml parent_instance;
+
+	/*< private >*/
+	GncHtmlGtkhtmlPrivate* priv;
+};
+
+struct _GncHtmlGtkhtmlClass {
+	GncHtmlClass parent_class;
+};
+
+GType gnc_html_gtkhtml_get_type( void );
+
+GncHtml* gnc_html_gtkhtml_new( void );
+
+G_END_DECLS
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-history.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-history.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-history.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,277 @@
+/********************************************************************
+ * gnc-html-history.c -- keep a HTML history                        * 
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "gnc-html-history.h"
+
+struct _gnc_html_history {
+  GList * nodes;
+  GList * current_node; 
+  GList * last_node;
+
+  /* call this whenever a node is destroyed */
+  gnc_html_history_destroy_cb destroy_cb;
+  gpointer                    destroy_cb_data;
+};
+
+/********************************************************************
+ * gnc_html_history_new
+ ********************************************************************/
+
+gnc_html_history * 
+gnc_html_history_new(void) {
+  gnc_html_history * hist = g_new0(gnc_html_history, 1);
+  hist->nodes         = NULL;
+  hist->current_node  = NULL;
+  hist->last_node     = NULL;
+  return hist;
+}
+
+
+
+/********************************************************************
+ * gnc_html_history_destroy
+ ********************************************************************/
+
+void
+gnc_html_history_destroy(gnc_html_history * hist) {
+  GList * n;
+
+  for(n = hist->nodes; n ; n=n->next) {
+    if(hist->destroy_cb) {
+      (hist->destroy_cb)((gnc_html_history_node *)n->data,
+                         hist->destroy_cb_data);
+    }
+    gnc_html_history_node_destroy((gnc_html_history_node *)n->data);
+  }
+  g_list_free(hist->nodes);
+
+  hist->nodes         = NULL;
+  hist->current_node  = NULL;
+  hist->last_node     = NULL;
+  g_free(hist);
+}
+
+/********************************************************************
+ * gnc_html_history_set_node_destroy_cb
+ ********************************************************************/
+
+void
+gnc_html_history_set_node_destroy_cb(gnc_html_history * hist, 
+                                     gnc_html_history_destroy_cb cb,
+                                     gpointer cb_data) {
+  hist->destroy_cb = cb;
+  hist->destroy_cb_data = cb_data;
+}
+
+static int 
+g_strcmp(char * a, char * b) {
+  if(!a && b) {
+    return 1;
+  }
+  else if(a && !b) {
+    return -1;
+  }
+  else if(!a && !b) {
+    return 0;
+  }
+  else {
+    return strcmp(a, b);
+  }
+  
+}
+
+
+/********************************************************************
+ * gnc_html_history_append
+ ********************************************************************/
+void 
+gnc_html_history_append(gnc_html_history * hist, 
+                        gnc_html_history_node * node) {
+  GList * n;
+  gnc_html_history_node * hn;
+  
+  if(hist->current_node) {
+    hn = hist->current_node->data;    
+    if((hn->type == node->type) &&
+       !g_strcmp(hn->location, node->location) &&
+       !g_strcmp(hn->label, node->label)) {      
+      if(hist->destroy_cb) {
+        (hist->destroy_cb)(hn, hist->destroy_cb_data);
+      }
+      gnc_html_history_node_destroy(node);
+      return;
+    }
+    
+    /* blow away the history after this point, if there is one */
+    for(n=hist->current_node->next; n; n=n->next) {
+      if(hist->destroy_cb) {
+        (hist->destroy_cb)((gnc_html_history_node *)n->data,
+                           hist->destroy_cb_data);
+      }
+      gnc_html_history_node_destroy((gnc_html_history_node *)n->data); 
+    }
+    g_list_free(hist->current_node->next);
+    hist->current_node->next = NULL;
+    hist->last_node = hist->current_node;
+  }
+  
+  n = g_list_alloc();
+  n->data = (gpointer) node;
+  n->next = NULL;
+  n->prev = NULL;
+
+  if(hist->nodes && hist->last_node) {
+    n->prev               = hist->last_node;  /* back pointer */ 
+    hist->last_node->next = n;                /* add n to the list */ 
+    hist->last_node       = n;                /* n is last */ 
+    hist->current_node    = n;
+  }
+  else {
+    /* this is the first entry in the list */
+    if(hist->nodes) {
+      g_print ("???? hist->nodes non-NULL, but no last_node \n");
+    }
+    hist->nodes        = n;
+    hist->last_node    = n;
+    hist->current_node = n;
+  }  
+}
+
+
+/********************************************************************
+ * gnc_html_history_get_current
+ ********************************************************************/
+
+gnc_html_history_node * 
+gnc_html_history_get_current(gnc_html_history * hist) {
+  if(!hist || !(hist->current_node)) return NULL;
+
+  return hist->current_node->data;
+}
+
+
+/********************************************************************
+ * gnc_html_history_forward
+ ********************************************************************/
+
+gnc_html_history_node *
+gnc_html_history_forward(gnc_html_history * hist) {
+  if(!hist || !(hist->current_node)) {
+    return NULL;
+  }
+  
+  if(hist->current_node->next) {
+    hist->current_node = hist->current_node->next;
+  }
+
+  return hist->current_node->data;
+}
+
+
+/********************************************************************
+ * gnc_html_history_back
+ ********************************************************************/
+
+gnc_html_history_node *
+gnc_html_history_back(gnc_html_history * hist) {
+
+  if(!hist || !(hist->current_node)) {
+    return NULL;
+  }
+  
+  if(hist->current_node->prev) {
+    hist->current_node = hist->current_node->prev;
+  }
+  
+  return hist->current_node->data;
+}
+
+
+/********************************************************************
+ * gnc_html_history_back_p
+ * is it possible to go back?
+ ********************************************************************/
+
+int
+gnc_html_history_back_p(gnc_html_history * hist) {
+  if(hist && hist->current_node && hist->current_node->prev) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+
+/********************************************************************
+ * gnc_html_history_forward_p
+ * is it possible to go forward?
+ ********************************************************************/
+
+int
+gnc_html_history_forward_p(gnc_html_history * hist) {
+  if(hist && hist->current_node && hist->current_node->next) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+
+/********************************************************************
+ * gnc_html_history_node_new
+ ********************************************************************/
+
+gnc_html_history_node *
+gnc_html_history_node_new(URLType type, const gchar * location, 
+                          const gchar * label) {
+  gnc_html_history_node * rv = g_new0(gnc_html_history_node, 1);
+  
+  rv->type      = type;
+  rv->location  = g_strdup(location);
+  rv->label     = g_strdup(label);
+  return rv;
+}
+
+
+/********************************************************************
+ * gnc_html_history_node_destroy
+ ********************************************************************/
+
+void
+gnc_html_history_node_destroy(gnc_html_history_node * node) {
+  
+  /* free the url resources and cached text */
+  g_free(node->location);
+  g_free(node->label);
+
+  node->location = NULL;
+  node->label    = NULL; 
+
+  g_free(node);
+}

Added: gnucash/trunk/src/html/gnc-html-history.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-history.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-history.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,64 @@
+/********************************************************************
+ * gnc-html-history.h -- keep a HTML history                        * 
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#ifndef GNC_HTML_HISTORY_H
+#define GNC_HTML_HISTORY_H
+
+typedef struct _gnc_html_history_node gnc_html_history_node;
+typedef struct _gnc_html_history gnc_html_history;
+
+#include "gnc-html.h"
+
+struct _gnc_html_history_node {
+  URLType type;
+  gchar   * location;
+  gchar   * label;  
+};
+
+typedef void (* gnc_html_history_destroy_cb)(gnc_html_history_node * n,
+                                             gpointer user_data);
+
+gnc_html_history      * gnc_html_history_new(void);
+void                    gnc_html_history_destroy(gnc_html_history * hist);
+
+void                    gnc_html_history_append(gnc_html_history * h,
+                                                gnc_html_history_node * n);
+gnc_html_history_node * gnc_html_history_get_current(gnc_html_history * h);
+gnc_html_history_node * gnc_html_history_forward(gnc_html_history * h);
+gnc_html_history_node * gnc_html_history_back(gnc_html_history * h);
+int                     gnc_html_history_forward_p(gnc_html_history * h);
+int                     gnc_html_history_back_p(gnc_html_history * h);
+void  gnc_html_history_set_node_destroy_cb(gnc_html_history * h,
+                                           gnc_html_history_destroy_cb cb,
+                                           gpointer cb_data);
+
+gnc_html_history_node * gnc_html_history_node_new(URLType type,
+                                                  const gchar * location, 
+                                                  const gchar * label);
+
+void                    gnc_html_history_node_destroy(gnc_html_history_node * 
+                                                      node);
+
+
+#endif
+
+

Added: gnucash/trunk/src/html/gnc-html-p.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-p.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-p.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,49 @@
+/********************************************************************
+ * gnc-html-p.h -- display html with gnc special tags               *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_P_H
+#define GNC_HTML_P_H
+
+struct _GncHtmlPrivate {
+	GtkWidget* parent;				/* window this html goes into */
+	GtkWidget* container;			/* parent of the gtkhtml widget */
+	gchar* current_link;			/* link under mouse pointer */
+
+	URLType base_type;				/* base of URL (path - filename) */
+	gchar* base_location;
+
+	GHashTable* request_info;		/* hash uri to GList of GtkHTMLStream * */
+
+	/* callbacks */
+	GncHTMLUrltypeCB urltype_cb;	/* is this type OK for this instance? */
+	GncHTMLLoadCB load_cb;
+	GncHTMLFlyoverCB flyover_cb;
+	GncHTMLButtonCB button_cb;
+
+	gpointer flyover_cb_data;
+	gpointer load_cb_data;
+	gpointer button_cb_data;
+
+	gnc_html_history * history;
+};
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-webkit-p.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-webkit-p.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-webkit-p.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,35 @@
+/********************************************************************
+ * gnc-html-webkit-p.h -- display html with gnc special tags        *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_WEBKIT_P_H
+#define GNC_HTML_WEBKIT_P_H
+
+#include "gnc-html-p.h"
+
+struct _GncHtmlWebkitPrivate {
+	struct _GncHtmlPrivate base;
+
+	WebKitWebView* web_view;				/* webkit widget itself */
+	gchar* html_string;						/* html string being displayed */
+};
+
+#endif

Added: gnucash/trunk/src/html/gnc-html-webkit.c
===================================================================
--- gnucash/trunk/src/html/gnc-html-webkit.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-webkit.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,930 @@
+/********************************************************************
+ * gnc-html_webkit.c -- display HTML with some special gnucash tags.*
+ *                                                                  *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2001 Linas Vepstas <linas at linas.org>               *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <regex.h>
+#include <libguile.h>
+#include <dlfcn.h>
+
+#include <webkit/webkit.h>
+
+#include "Account.h"
+#include "gnc-gui-query.h"
+#include "gnc-engine.h"
+#include "gnc-html.h"
+#include "gnc-html-webkit.h"
+#include "gnc-html-history.h"
+#include "gnc-html-graph-gog-webkit.h"
+
+G_DEFINE_TYPE(GncHtmlWebkit, gnc_html_webkit, GNC_TYPE_HTML )
+
+static void gnc_html_webkit_dispose( GObject* obj );
+static void gnc_html_webkit_finalize( GObject* obj );
+static void gnc_html_webkit_class_init( GncHtmlWebkitClass* klass );
+static void gnc_html_webkit_init( GncHtmlWebkit* gs );
+
+#define GNC_HTML_WEBKIT_GET_PRIVATE(o) (GNC_HTML_WEBKIT(o)->priv)
+
+#include "gnc-html-webkit-p.h"
+
+/* indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_HTML;
+
+/* hashes for URLType -> protocol and protocol -> URLType */
+//extern GHashTable* gnc_html_type_to_proto_hash;
+extern GHashTable* gnc_html_proto_to_type_hash;
+
+/* hashes an HTML <object classid="ID"> classid to a handler function */
+extern GHashTable* gnc_html_object_handlers;
+
+/* hashes handlers for loading different URLType data */
+extern GHashTable* gnc_html_stream_handlers;
+
+/* hashes handlers for handling different URLType data */
+extern GHashTable* gnc_html_url_handlers;
+
+static char error_404_format[] = "<html><body><h3>%s</h3><p>%s</body></html>";
+static char error_404_title[] = N_("Not found");
+static char error_404_body[] = N_("The specified URL could not be loaded.");
+
+static void webkit_navigation_requested_cb( WebKitWebView* web_view, GObject* arg1,
+												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 );
+static gboolean gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
+                             gpointer data );
+#endif
+static int gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
+                         gpointer user_data );
+static void impl_webkit_show_url( GncHtml* self, URLType type,
+                  const gchar* location, const gchar* label,
+                  gboolean new_window_hint );
+static void impl_webkit_show_data( GncHtml* self, const gchar* data, int datalen );
+static void impl_webkit_reload( GncHtml* self );
+static void impl_webkit_copy_to_clipboard( GncHtml* self );
+static gboolean impl_webkit_export_to_file( GncHtml* self, const gchar* filepath );
+static void impl_webkit_print( GncHtml* self );
+static void impl_webkit_cancel( GncHtml* self );
+static void impl_webkit_set_parent( GncHtml* self, GtkWindow* parent );
+
+static void
+gnc_html_webkit_init( GncHtmlWebkit* self )
+{
+	GncHtmlWebkitPrivate* priv;
+	GncHtmlWebkitPrivate* new_priv;
+
+	new_priv = g_realloc( GNC_HTML(self)->priv, sizeof(GncHtmlWebkitPrivate) );
+	priv = self->priv = new_priv;
+	GNC_HTML(self)->priv = (GncHtmlPrivate*)priv;
+
+	priv->html_string = NULL;
+	priv->web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+
+	gtk_container_add( GTK_CONTAINER(priv->base.container),
+						GTK_WIDGET(priv->web_view) );
+
+#ifdef HAVE_GTK_2_10
+	g_object_ref_sink( priv->base.container );
+#else
+	g_object_ref( priv->base.container );
+	gtk_object_sink( GTK_OBJECT(priv->base.container) );
+#endif
+
+	/* signals */
+	g_signal_connect( priv->web_view, "navigation-requested",
+					G_CALLBACK(webkit_navigation_requested_cb),
+					self);
+
+	g_signal_connect( priv->web_view, "hovering-over-link",
+				   G_CALLBACK(webkit_on_url_cb),
+				   self );
+
+#if 0
+	g_signal_connect( priv->html, "set_base",
+		   G_CALLBACK(gnc_html_set_base_cb),
+		   self);
+
+	g_signal_connect(priv->html, "link_clicked",
+		   G_CALLBACK(gnc_html_link_clicked_cb),
+		   self);
+
+	g_signal_connect (priv->html, "object_requested",
+		    G_CALLBACK (gnc_html_object_requested_cb),
+		    self);
+
+	g_signal_connect (priv->html, "button_press_event",
+		    G_CALLBACK (gnc_html_button_press_cb),
+		    self);
+
+	g_signal_connect (priv->html, "submit",
+		    G_CALLBACK(gnc_html_submit_cb),
+		    self);
+#endif
+
+	LEAVE("retval %p", self);
+}
+
+static void
+gnc_html_webkit_class_init( GncHtmlWebkitClass* klass )
+{
+	GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+	GncHtmlClass* html_class = GNC_HTML_CLASS(klass);
+
+	gobject_class->dispose = gnc_html_webkit_dispose;
+	gobject_class->finalize = gnc_html_webkit_finalize;
+
+	html_class->show_url = impl_webkit_show_url;
+	html_class->show_data = impl_webkit_show_data;
+	html_class->reload = impl_webkit_reload;
+	html_class->copy_to_clipboard = impl_webkit_copy_to_clipboard;
+	html_class->export_to_file = impl_webkit_export_to_file;
+	html_class->print = impl_webkit_print;
+	html_class->cancel = impl_webkit_cancel;
+	html_class->set_parent = impl_webkit_set_parent;
+
+	// Initialize graphing support
+	gnc_html_graph_gog_webkit_init();
+}
+
+static void
+gnc_html_webkit_dispose( GObject* obj )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(obj);
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	if( priv->web_view != NULL ) {
+		gtk_container_remove( GTK_CONTAINER(priv->base.container),
+						GTK_WIDGET(priv->web_view) );
+		g_object_unref( G_OBJECT(priv->web_view) );
+		priv->web_view = NULL;
+	}
+
+	G_OBJECT_CLASS(gnc_html_webkit_parent_class)->dispose( obj );
+}
+
+static void
+gnc_html_webkit_finalize( GObject* obj )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(obj);
+
+//	if( self->priv != NULL ) {
+//		g_free( self->priv );
+		self->priv = NULL;
+//	}
+
+	G_OBJECT_CLASS(gnc_html_webkit_parent_class)->finalize( obj );
+}
+
+/*****************************************************************************/
+
+static char*
+extract_base_name(URLType type, const gchar* path)
+{
+	gchar       machine_rexp[] = "^(//[^/]*)/*(/.*)?$";
+	gchar       path_rexp[] = "^/*(.*)/+([^/]*)$";
+	regex_t    compiled_m, compiled_p;
+	regmatch_t match[4];
+	gchar       * machine=NULL, * location = NULL, * base=NULL;
+	gchar       * basename=NULL;
+
+	DEBUG(" ");
+	if(!path) return NULL;
+
+	regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
+	regcomp(&compiled_p, path_rexp, REG_EXTENDED);
+
+	if (!safe_strcmp (type, URL_TYPE_HTTP) ||
+			!safe_strcmp (type, URL_TYPE_SECURE) ||
+			!safe_strcmp (type, URL_TYPE_FTP)) {
+
+		/* step 1: split the machine name away from the path
+		 * components */
+		if(!regexec(&compiled_m, path, 4, match, 0)) {
+			/* $1 is the machine name */
+			if(match[1].rm_so != -1) {
+				machine = g_strndup(path+match[1].rm_so,
+                            match[1].rm_eo - match[1].rm_so);
+			}
+			/* $2 is the path */
+			if(match[2].rm_so != -1) {
+				location = g_strndup(path+match[2].rm_so,
+                             match[2].rm_eo - match[2].rm_so);
+			}
+		}
+
+	} else {
+		location = g_strdup(path);
+	}
+	/* step 2: split up the path into prefix and file components */
+	if(location) {
+		if(!regexec(&compiled_p, location, 4, match, 0)) {
+			if(match[1].rm_so != -1) {
+				base = g_strndup(location+match[1].rm_so,
+                         match[1].rm_eo - match[1].rm_so);
+			} else {
+				base = NULL;
+			}
+		}
+	}
+
+	regfree(&compiled_m);
+	regfree(&compiled_p);
+
+	if(machine) {
+		if(base && (strlen(base) > 0)) {
+			basename = g_strconcat(machine, "/", base, "/", NULL);
+		} else {
+			basename = g_strconcat(machine, "/", NULL);
+		}
+	} else {
+		if(base && (strlen(base) > 0)) {
+			basename = g_strdup(base);
+		} else {
+			basename = NULL;
+		}
+	}
+
+	g_free(machine);
+	g_free(base);
+	g_free(location);
+	return basename;
+}
+
+static gboolean
+http_allowed()
+{
+	return TRUE;
+}
+
+static gboolean
+https_allowed()
+{
+	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;
+}
+
+/********************************************************************
+ * 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
+load_to_stream( GncHtmlWebkit* self, URLType type,
+				const gchar* location, const gchar* label )
+{
+	gchar* fdata = NULL;
+	int fdata_len = 0;
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	DEBUG( "type %s, location %s, label %s", type ? type : "(null)",
+			location ? location : "(null)", label ? label : "(null)");
+
+	g_return_if_fail( self != NULL );
+
+	if( gnc_html_stream_handlers != NULL ) {
+		GncHTMLStreamCB stream_handler;
+
+		stream_handler = g_hash_table_lookup( gnc_html_stream_handlers, type );
+		if( stream_handler ) {
+			gboolean ok = stream_handler( location, &fdata, &fdata_len );
+
+			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;
+				}
+
+				// Save a copy for export purposes
+				if( priv->html_string != NULL ) {
+					g_free( priv->html_string );
+				}
+				priv->html_string = g_strdup( fdata );
+				webkit_web_view_load_html_string( priv->web_view, fdata, "base-uri" );
+			} else {
+				fdata = fdata ? fdata :
+							g_strdup_printf( error_404_format,
+							_(error_404_title), _(error_404_body) );
+				webkit_web_view_load_html_string( priv->web_view, fdata, "base-uri" );
+			}
+
+			g_free( fdata );
+
+			if( label ) {
+				while( gtk_events_pending() ) {
+					gtk_main_iteration();
+				}
+//				gtk_html_jump_to_anchor( GTK_HTML(priv->html), label );
+				g_assert( FALSE );
+			}
+
+			return;
+		}
+	}
+
+	do {
+		if( !safe_strcmp( type, URL_TYPE_SECURE ) ||
+			!safe_strcmp( type, URL_TYPE_HTTP ) ) {
+
+			if( !safe_strcmp( type, URL_TYPE_SECURE ) ) {
+				if( !https_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+                            _("Secure HTTP access is disabled. "
+                              "You can enable it in the Network section of "
+                              "the Preferences dialog."));
+					break;
+				}
+			}
+
+			if( !http_allowed() ) {
+				gnc_error_dialog( priv->base.parent,
+                          _("Network HTTP access is disabled. "
+                            "You can enable it in the Network section of "
+                            "the Preferences dialog."));
+			} else {
+				char *fullurl;
+
+				fullurl = gnc_build_url( type, location, label );
+			}
+
+		} else {
+			PWARN( "load_to_stream for inappropriate type\n"
+					"\turl = '%s#%s'\n",
+					location ? location : "(null)",
+					label ? label : "(null)" );
+			fdata = g_strdup_printf( error_404_format,
+								_(error_404_title), _(error_404_body) );
+			webkit_web_view_load_html_string( priv->web_view, fdata, "base-uri" );
+			g_free( fdata );
+		}
+
+	} while( FALSE );
+}
+
+#if 0
+/********************************************************************
+ * gnc_html_link_clicked_cb - called when user left-clicks on html
+ * anchor.
+ ********************************************************************/
+
+static void
+gnc_html_link_clicked_cb( GtkHTML* html, const gchar* url, gpointer data )
+{
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(data);
+
+	DEBUG("Clicked %s", url);
+	type = gnc_html_parse_url( GNC_HTML(self), url, &location, &label );
+	gnc_html_show_url( GNC_HTML(self), type, location, label, 0 );
+	g_free( location );
+	g_free( label );
+}
+#endif
+
+/********************************************************************
+ * webkit_navigation_requested_cb - called when a URL needs to be
+ * loaded within the loading of a page (embedded image).
+ ********************************************************************/
+
+static void
+webkit_navigation_requested_cb( WebKitWebView* web_view, GObject* arg1,
+												GObject* arg2, gpointer data )
+{
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(data);
+	WebKitNetworkRequest* req = WEBKIT_NETWORK_REQUEST(arg2);
+	const gchar* url = webkit_network_request_get_uri( req );
+
+	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 );
+//	load_to_stream( self, type, location, label );
+	g_free( location );
+	g_free( label );
+}
+
+#if 0
+/********************************************************************
+ * gnc_html_object_requested_cb - called when an applet needs to be
+ * loaded.
+ ********************************************************************/
+
+static gboolean
+gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
+                             gpointer data )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(data);
+	GncHTMLObjectCB h;
+
+	DEBUG( " " );
+	if( !eb || !(eb->classid) || !gnc_html_object_handlers ) return FALSE;
+
+	h = g_hash_table_lookup( gnc_html_object_handlers, eb->classid );
+	if( h ) {
+		return h( GNC_HTML(self), eb, data );
+	} else {
+		return FALSE;
+	}
+}
+#endif
+
+/********************************************************************
+ * webkit_on_url_cb - called when user rolls over html anchor
+ ********************************************************************/
+
+static void
+webkit_on_url_cb( WebKitWebView* web_view, gchar* title, gchar* url, gpointer data )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(data);
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	DEBUG( "Rollover %s", url ? url : "(null)" );
+	g_free( priv->base.current_link );
+	priv->base.current_link = g_strdup( url );
+	if( priv->base.flyover_cb ) {
+		(priv->base.flyover_cb)( GNC_HTML(self), url, priv->base.flyover_cb_data );
+	}
+}
+
+#if 0
+/********************************************************************
+ * gnc_html_set_base_cb
+ ********************************************************************/
+
+static void
+gnc_html_set_base_cb( GtkHTML* gtkhtml, const gchar* base,
+                     gpointer data )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(data);
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	URLType type;
+	gchar* location = NULL;
+	gchar* label = NULL;
+
+	DEBUG( "Setting base location to %s", base );
+	type = gnc_html_parse_url( GNC_HTML(self), base, &location, &label );
+
+	g_free( priv->base.base_location );
+	g_free( label );
+
+	priv->base.base_type = type;
+	priv->base.base_location = location;
+}
+#endif
+
+/********************************************************************
+ * gnc_html_button_press_cb
+ * mouse button callback (if any)
+ ********************************************************************/
+
+static int
+gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
+                         gpointer user_data )
+{
+	GncHtmlWebkit* self = GNC_HTML_WEBKIT(user_data);
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	DEBUG( "Button Press" );
+	if( priv->base.button_cb != NULL ) {
+		(priv->base.button_cb)( GNC_HTML(self), event, priv->base.button_cb_data );
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/********************************************************************
+ * gnc_html_open_scm
+ * insert some scheme-generated HTML
+ ********************************************************************/
+
+static void
+gnc_html_open_scm( GncHtmlWebkit* self, const gchar * location,
+                  const gchar * label, int newwin )
+{
+	PINFO("location='%s'", location ? location : "(null)");
+}
+
+
+/********************************************************************
+ * gnc_html_show_data
+ * display some HTML that the creator of the gnc-html got from
+ * somewhere.
+ ********************************************************************/
+
+static void
+impl_webkit_show_data( GncHtml* self, const gchar* data, int datalen )
+{
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+
+	DEBUG( "datalen %d, data %20.20s", datalen, data );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	webkit_web_view_load_html_string( priv->web_view, data, "base-uri" );
+}
+
+/********************************************************************
+ * gnc_html_show_url
+ *
+ * open a URL.  This is called when the user clicks a link or
+ * for the creator of the gnc_html window to explicitly request
+ * a URL.
+ ********************************************************************/
+
+static void
+impl_webkit_show_url( GncHtml* self, URLType type,
+                  const gchar* location, const gchar* label,
+                  gboolean new_window_hint )
+{
+	GncHTMLUrlCB url_handler;
+	gboolean new_window;
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+	g_return_if_fail( location != NULL );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	/* make sure it's OK to show this URL type in this window */
+	if( new_window_hint == 0 ) {
+		if( priv->base.urltype_cb ) {
+			new_window = !((priv->base.urltype_cb)( type ));
+		} else {
+			new_window = FALSE;
+		}
+	} else {
+		new_window = TRUE;
+	}
+
+	if( !new_window ) {
+		gnc_html_cancel( GNC_HTML(self) );
+	}
+
+	if( gnc_html_url_handlers ) {
+		url_handler = g_hash_table_lookup( gnc_html_url_handlers, type );
+	} else {
+		url_handler = NULL;
+	}
+
+	if( url_handler ) {
+		GNCURLResult result;
+		gboolean ok;
+
+		result.load_to_stream = FALSE;
+		result.url_type = type;
+		result.location = NULL;
+		result.label = NULL;
+		result.base_type = URL_TYPE_FILE;
+		result.base_location = NULL;
+		result.error_message = NULL;
+
+		ok = url_handler( location, label, new_window, &result );
+		if( !ok ) {
+			if( result.error_message ) {
+			  gnc_error_dialog( priv->base.parent, "%s", result.error_message );
+			} else {
+				/* %s is a URL (some location somewhere). */
+				gnc_error_dialog( priv->base.parent, _("There was an error accessing %s."), location );
+			}
+
+			if( priv->base.load_cb ) {
+				priv->base.load_cb( GNC_HTML(self), result.url_type,
+								location, label, priv->base.load_cb_data );
+			}
+		} else if( result.load_to_stream ) {
+			gnc_html_history_node *hnode;
+			const char *new_location;
+			const char *new_label;
+
+			new_location = result.location ? result.location : location;
+			new_label = result.label ? result.label : label;
+			hnode = gnc_html_history_node_new( result.url_type, new_location, new_label );
+
+			gnc_html_history_append( priv->base.history, hnode );
+
+			g_free( priv->base.base_location );
+			priv->base.base_type = result.base_type;
+			priv->base.base_location =
+					g_strdup( extract_base_name( result.base_type, new_location ) );
+			DEBUG( "resetting base location to %s",
+					priv->base.base_location ? priv->base.base_location : "(null)" );
+
+			load_to_stream( GNC_HTML_WEBKIT(self), result.url_type,
+									new_location, new_label );
+
+			if( priv->base.load_cb != NULL ) {
+				priv->base.load_cb( GNC_HTML(self), result.url_type,
+								new_location, new_label, priv->base.load_cb_data );
+			}
+		}
+
+		g_free( result.location );
+		g_free( result.label );
+		g_free( result.base_location );
+		g_free( result.error_message );
+
+		return;
+	}
+
+	if( safe_strcmp( type, URL_TYPE_SCHEME ) == 0 ) {
+		gnc_html_open_scm( GNC_HTML_WEBKIT(self), location, label, new_window );
+
+	} else if( safe_strcmp( type, URL_TYPE_JUMP ) == 0 ) {
+//		gtk_html_jump_to_anchor( GTK_HTML(priv->html), label );
+		g_assert( FALSE );
+
+	} else if( safe_strcmp( type, URL_TYPE_SECURE ) == 0 ||
+				safe_strcmp( type, URL_TYPE_HTTP ) == 0 ||
+				safe_strcmp( type, URL_TYPE_FILE ) == 0 ) {
+
+		do {
+			if( safe_strcmp( type, URL_TYPE_SECURE ) == 0 ) {
+				if( !https_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+									_("Secure HTTP access is disabled. "
+									"You can enable it in the Network section of "
+									"the Preferences dialog.") );
+					break;
+				}
+			}
+
+			if( safe_strcmp( type, URL_TYPE_HTTP ) == 0 ) {
+				if( !http_allowed() ) {
+					gnc_error_dialog( priv->base.parent,
+									_("Network HTTP access is disabled. "
+									"You can enable it in the Network section of "
+									"the Preferences dialog.") );
+					break;
+				}
+			}
+
+			priv->base.base_type = type;
+
+			if( priv->base.base_location != NULL ) g_free( priv->base.base_location );
+			priv->base.base_location = extract_base_name( type, location );
+
+			/* FIXME : handle new_window = 1 */
+			gnc_html_history_append( priv->base.history,
+								gnc_html_history_node_new( type, location, label ) );
+			load_to_stream( GNC_HTML_WEBKIT(self), type, location, label );
+
+		} while( FALSE );
+
+	} else {
+		PERR( "URLType %s not supported.", type );
+	}
+
+	if( priv->base.load_cb != NULL ) {
+		(priv->base.load_cb)( GNC_HTML(self), type, location, label, priv->base.load_cb_data );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_reload
+ * reload the current page
+ ********************************************************************/
+
+static void
+impl_webkit_reload( GncHtml* self )
+{
+	gnc_html_history_node * n;
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	n = gnc_html_history_get_current( priv->base.history );
+	if( n != NULL ) {
+		gnc_html_show_url( self, n->type, n->location, n->label, 0 );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_new
+ * create and set up a new webkit widget.
+ ********************************************************************/
+
+GncHtml*
+gnc_html_webkit_new( void )
+{
+	GncHtmlWebkit* self = g_object_new( GNC_TYPE_HTML_WEBKIT, NULL );
+	GncHtmlWebkitPrivate* priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	return GNC_HTML(self);
+}
+
+/********************************************************************
+ * gnc_html_cancel
+ * cancel any outstanding HTML fetch requests.
+ ********************************************************************/
+
+static gboolean
+webkit_cancel_helper(gpointer key, gpointer value, gpointer user_data)
+{
+	g_free(key);
+	g_list_free((GList *)value);
+	return TRUE;
+}
+
+static void
+impl_webkit_cancel( GncHtml* self )
+{
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+
+	/* remove our own references to requests */
+	//gnc_http_cancel_requests( priv->http );
+
+	g_hash_table_foreach_remove( priv->base.request_info, webkit_cancel_helper, NULL );
+}
+
+static void
+impl_webkit_copy_to_clipboard( GncHtml* self )
+{
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	if( webkit_web_view_can_copy_clipboard( priv->web_view ) ) {
+		webkit_web_view_copy_clipboard( priv->web_view );
+	}
+}
+
+/**************************************************************
+ * gnc_html_export_to_file : wrapper around the builtin function in webkit
+ **************************************************************/
+static gboolean
+impl_webkit_export_to_file( GncHtml* self, const char *filepath )
+{
+	FILE *fh;
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_val_if_fail( self != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_HTML_WEBKIT(self), FALSE );
+	g_return_val_if_fail( filepath != NULL, FALSE );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	if( priv->html_string == NULL ) {
+		return FALSE;
+	}
+	fh = g_fopen( filepath, "w" );
+	if( fh != NULL ) {
+		gint written;
+		gint len = strlen( priv->html_string );
+
+		written = fwrite( priv->html_string, 1, len, fh );
+		fclose (fh);
+
+		if( written != len ) {
+			return FALSE;
+		}
+
+		return TRUE;
+	} else {
+		return FALSE;
+	} 
+}
+
+static void
+impl_webkit_print( GncHtml* self )
+{
+	GncHtmlWebkitPrivate* priv;
+//	static void (*webkit_web_frame_print)( WebKitWebFrame* frame ) = NULL;
+	WebKitWebFrame* frame;
+	extern void webkit_web_frame_print( WebKitWebFrame* frame );
+
+	/*  HACK ALERT
+	 *
+	 * The api to print isn't exported, but exists and works, so let's dig for it.
+	 */
+#if 0
+	if( webkit_web_frame_print == NULL ) {
+		void* handle = dlopen( "/usr/lib/libwebkit-1.0.so", RTLD_LAZY );
+		webkit_web_frame_print = dlsym( handle, "webkit_web_frame_print" );
+		dlclose( handle );
+	}
+#endif
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	frame = webkit_web_view_get_main_frame( priv->web_view );
+	webkit_web_frame_print( frame );
+}
+
+static void
+impl_webkit_set_parent( GncHtml* self, GtkWindow* parent )
+{
+	GncHtmlWebkitPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
+
+	priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
+	priv->base.parent = GTK_WIDGET(parent);
+}

Added: gnucash/trunk/src/html/gnc-html-webkit.h
===================================================================
--- gnucash/trunk/src/html/gnc-html-webkit.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html-webkit.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,59 @@
+/********************************************************************
+ * gnc-html-webkit.h -- display html with gnc special tags          *
+ * Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>        *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_WEBKIT_H
+#define GNC_HTML_WEBKIT_H
+
+#include <glib-object.h>
+#include "gnc-html.h"
+
+G_BEGIN_DECLS
+
+#define GNC_TYPE_HTML_WEBKIT       (gnc_html_webkit_get_type())
+#define GNC_HTML_WEBKIT(o)         (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_HTML_WEBKIT, GncHtmlWebkit))
+#define GNC_HTML_WEBKIT_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_HTML_WEBKIT, GncHtmlWebkitClass))
+#define GNC_IS_HTML_WEBKIT(o)      (G_TYPE_CHECK_INSTANCE_TYPE((o), GNC_TYPE_HTML_WEBKIT))
+#define GNC_IS_HTML_WEBKIT_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE((k), GNC_TYPE_HTML_WEBKIT))
+#define GNC_HTML_WEBKIT_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS((o), GNC_TYPE_HTML_WEBKIT, GncHtmlWebkitClass))
+
+typedef struct _GncHtmlWebkit GncHtmlWebkit;
+typedef struct _GncHtmlWebkitClass GncHtmlWebkitClass;
+typedef struct _GncHtmlWebkitPrivate GncHtmlWebkitPrivate;
+
+struct _GncHtmlWebkit {
+	GncHtml parent_instance;
+
+	/*< private >*/
+	GncHtmlWebkitPrivate* priv;
+};
+
+struct _GncHtmlWebkitClass {
+	GncHtmlClass parent_class;
+};
+
+GType gnc_html_webkit_get_type( void );
+
+GncHtml* gnc_html_webkit_new( void );
+
+G_END_DECLS
+
+#endif

Added: gnucash/trunk/src/html/gnc-html.c
===================================================================
--- gnucash/trunk/src/html/gnc-html.c	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,800 @@
+/********************************************************************
+ * gnc-html.c -- display HTML with some special gnucash tags.       *
+ *                                                                  *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ * Copyright (C) 2001 Linas Vepstas <linas at linas.org>               *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+// libgtkhtml docs:
+// http://www.fifi.org/doc/libgtkhtml-dev/html/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <regex.h>
+#include <libguile.h>
+
+#include "Account.h"
+#include "print-session.h"
+#include "gnc-engine.h"
+#include "gnc-html.h"
+#include "gnc-html-history.h"
+
+/* indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_HTML;
+
+/* hashes for URLType -> protocol and protocol -> URLType */
+static GHashTable * gnc_html_type_to_proto_hash = NULL;
+GHashTable * gnc_html_proto_to_type_hash = NULL;
+
+/* hashes an HTML <object classid="ID"> classid to a handler function */
+GHashTable* gnc_html_object_handlers = NULL;
+
+/* hashes handlers for loading different URLType data */
+GHashTable* gnc_html_stream_handlers = NULL;
+
+/* hashes handlers for handling different URLType data */
+GHashTable* gnc_html_url_handlers = NULL;
+
+/* hashes an HTML <object classid="ID"> classid to a handler function */
+extern GHashTable* gnc_html_object_handlers;
+
+static char error_404_format[] =
+"<html><body><h3>%s</h3><p>%s</body></html>";
+static char error_404_title[] = N_("Not found");
+static char error_404_body[] =
+N_("The specified URL could not be loaded.");
+
+G_DEFINE_ABSTRACT_TYPE(GncHtml, gnc_html, GTK_TYPE_BIN)
+
+static void gnc_html_class_init( GncHtmlClass* klass );
+static void gnc_html_dispose( GObject* obj );
+static void gnc_html_finalize( GObject* obj );
+
+//#define GNC_HTML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_HTML, GncHtmlPrivate))
+#define GNC_HTML_GET_PRIVATE(o) (GNC_HTML(o)->priv)
+
+#include "gnc-html-p.h"
+
+static void
+gnc_html_class_init( GncHtmlClass* klass )
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+	gobject_class->dispose = gnc_html_dispose;
+	gobject_class->finalize = gnc_html_finalize;
+
+	klass->show_url = NULL;
+	klass->show_data = NULL;
+	klass->reload = NULL;
+	klass->copy_to_clipboard = NULL;
+	klass->export_to_file = NULL;
+	klass->print = NULL;
+	klass->cancel = NULL;
+	klass->parse_url = NULL;
+	klass->set_parent = NULL;
+}
+
+static void
+gnc_html_init( GncHtml* self )
+{
+	GncHtmlPrivate* priv;
+	priv = self->priv = g_new0( GncHtmlPrivate, 1 );
+
+	priv->container = gtk_scrolled_window_new( NULL, NULL );
+	gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(priv->container),
+									GTK_POLICY_AUTOMATIC,
+									GTK_POLICY_AUTOMATIC );
+	priv->request_info = g_hash_table_new( g_str_hash, g_str_equal );
+	priv->history = gnc_html_history_new();
+}
+
+static void
+gnc_html_dispose( GObject* obj )
+{
+	GncHtml* self = GNC_HTML(obj);
+	GncHtmlPrivate* priv = GNC_HTML_GET_PRIVATE(self);
+
+	if( priv->container != NULL ) {
+		gtk_widget_destroy( GTK_WIDGET(priv->container) );
+		g_object_unref( G_OBJECT(priv->container) );
+		priv->container = NULL;
+	}
+	if( priv->request_info != NULL ) {
+		g_hash_table_destroy( priv->request_info );
+		priv->request_info = NULL;
+	}
+	if( priv->history != NULL ) {
+		gnc_html_history_destroy( priv->history );
+		priv->history = NULL;
+	}
+
+	G_OBJECT_CLASS(gnc_html_parent_class)->dispose( obj );
+}
+
+static void
+gnc_html_finalize( GObject* obj )
+{
+	GncHtml* self = GNC_HTML(obj);
+
+	if( self->priv != NULL ) {
+		g_free( self->priv );
+		self->priv = NULL;
+	}
+
+	G_OBJECT_CLASS(gnc_html_parent_class)->finalize( obj );
+}
+
+/***********************************************************************************/
+
+static char*
+extract_machine_name( const gchar* path )
+{
+	gchar machine_rexp[] = "^(//[^/]*)/*(.*)?$";
+	regex_t compiled_m;
+	regmatch_t match[4];
+	gchar* machine = NULL;
+
+	if( path == NULL ) return NULL;
+
+	regcomp( &compiled_m, machine_rexp, REG_EXTENDED );
+
+	/* step 1: split the machine name away from the path
+	 * components */
+	if( !regexec( &compiled_m, path, 4, match, 0 ) ) {
+		/* $1 is the machine name */
+		if( match[1].rm_so != -1 ) {
+			machine = g_strndup( path+match[1].rm_so, match[1].rm_eo - match[1].rm_so );
+		}
+	}
+	return machine;
+}
+
+/********************************************************************
+ * gnc_html_parse_url
+ * this takes a URL and determines the protocol type, location, and
+ * possible anchor name from the URL.
+ ********************************************************************/
+
+URLType
+gnc_html_parse_url( GncHtml* self, const gchar* url,
+					gchar** url_location, gchar** url_label )
+{
+	gchar uri_rexp[] = "^(([^:][^:]+):)?([^#]+)?(#(.*))?$";
+	regex_t compiled;
+	regmatch_t match[6];
+	gchar* protocol = NULL;
+	gchar* path = NULL;
+	gchar* label = NULL;
+	gboolean found_protocol = FALSE;
+	gboolean found_path = FALSE;
+	gboolean found_label = FALSE;
+	URLType retval;
+	GncHtmlPrivate* priv = GNC_HTML_GET_PRIVATE(self);
+
+	g_return_val_if_fail( self != NULL, NULL );
+	g_return_val_if_fail( GNC_IS_HTML(self), NULL );
+
+	DEBUG( "parsing %s, base_location %s",
+			url ? url : "(null)",
+			self ? (priv->base_location ? priv->base_location
+										: "(null base_location)")
+				: "(null html)");
+
+	regcomp( &compiled, uri_rexp, REG_EXTENDED );
+
+	if( !regexec( &compiled, url, 6, match, 0 ) ) {
+		if( match[2].rm_so != -1 ) {
+			protocol = g_new0( gchar, match[2].rm_eo - match[2].rm_so + 1 );
+			strncpy( protocol, url + match[2].rm_so, match[2].rm_eo - match[2].rm_so );
+			protocol[match[2].rm_eo - match[2].rm_so] = 0;
+			found_protocol = TRUE;
+		}
+		if( match[3].rm_so != -1 ) {
+			path = g_new0( gchar, match[3].rm_eo - match[3].rm_so + 1 );
+			strncpy( path, url+match[3].rm_so, match[3].rm_eo - match[3].rm_so );
+			path[match[3].rm_eo - match[3].rm_so] = 0;
+			found_path = TRUE;
+		}
+		if( match[5].rm_so != -1 ) {
+			label = g_new0( gchar, match[5].rm_eo - match[5].rm_so + 1 );
+			strncpy( label, url+match[5].rm_so, match[5].rm_eo - match[5].rm_so );
+			label[match[5].rm_eo - match[5].rm_so] = 0;
+			found_label = TRUE;
+		}
+	}
+
+	regfree( &compiled );
+
+	if( found_protocol ) {
+		retval = g_hash_table_lookup( gnc_html_proto_to_type_hash, protocol );
+		if( retval == NULL ) {
+			PWARN( "unhandled URL type for '%s'", url ? url : "(null)" );
+			retval = URL_TYPE_OTHER;
+		}
+	} else if( found_label && !found_path ) {
+		retval = URL_TYPE_JUMP;
+	} else {
+		if( self ) {
+			retval = priv->base_type;
+		} else {
+			retval = URL_TYPE_FILE;
+		}
+	}
+
+	g_free( protocol );
+
+	if( !safe_strcmp( retval, URL_TYPE_FILE ) ) {
+		if( !found_protocol && path && self && priv->base_location ) {
+			if( g_path_is_absolute( path ) ) {
+				*url_location = g_strdup( path );
+			} else {
+				*url_location = g_build_filename( priv->base_location, path, (gchar*)NULL );
+			}
+			g_free( path );
+		} else {
+			*url_location = g_strdup( path );
+			g_free( path );
+		}
+
+	} else if( !safe_strcmp( retval, URL_TYPE_JUMP ) ) {
+		*url_location = NULL;
+		g_free( path );
+
+	} else {
+		/* case URL_TYPE_OTHER: */
+
+		if( !found_protocol && path && self && priv->base_location ) {
+			if( g_path_is_absolute( path ) ) {
+				*url_location = g_build_filename( extract_machine_name( priv->base_location ),
+                           path, (gchar*)NULL );
+			} else {
+				*url_location = g_build_filename( priv->base_location, path, (gchar*)NULL );
+			}
+			g_free( path );
+		} else {
+			*url_location = g_strdup( path );
+			g_free( path );
+		}
+	}
+
+	*url_label = label;
+	return retval;
+}
+
+/********************************************************************
+ * gnc_html_show_data
+ * display some HTML that the creator of the gnc-html got from
+ * somewhere.
+ ********************************************************************/
+
+void
+gnc_html_show_data( GncHtml* self, const gchar* data, int datalen )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->show_data != NULL ) {
+		GNC_HTML_GET_CLASS(self)->show_data( self, data, datalen );
+	} else {
+		DEBUG( "'show_data' not implemented" );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_show_url
+ *
+ * open a URL.  This is called when the user clicks a link or
+ * for the creator of the gnc_html window to explicitly request
+ * a URL.
+ ********************************************************************/
+
+void
+gnc_html_show_url( GncHtml* self, URLType type,
+                  const gchar* location, const gchar* label,
+                  gboolean new_window_hint )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->show_url != NULL ) {
+		GNC_HTML_GET_CLASS(self)->show_url( self, type, location, label, new_window_hint );
+	} else {
+		DEBUG( "'show_url' not implemented" );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_reload
+ * reload the current page
+ ********************************************************************/
+
+void
+gnc_html_reload( GncHtml* self )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->reload != NULL ) {
+		GNC_HTML_GET_CLASS(self)->reload( self );
+	} else {
+		DEBUG( "'reload' not implemented" );
+	}
+}
+
+/********************************************************************
+ * gnc_html_cancel
+ * cancel any outstanding HTML fetch requests.
+ ********************************************************************/
+
+void
+gnc_html_cancel( GncHtml* self )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->cancel != NULL ) {
+		GNC_HTML_GET_CLASS(self)->cancel( self );
+	} else {
+		DEBUG( "'cancel' not implemented" );
+	}
+}
+
+
+/********************************************************************
+ * gnc_html_destroy
+ * destroy the struct
+ ********************************************************************/
+
+void
+gnc_html_destroy( GncHtml* self )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	g_object_unref( G_OBJECT(self) );
+}
+
+void
+gnc_html_set_urltype_cb( GncHtml* self, GncHTMLUrltypeCB urltype_cb )
+{
+	GncHtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	priv = GNC_HTML_GET_PRIVATE(self);
+	priv->urltype_cb = urltype_cb;
+}
+
+void
+gnc_html_set_load_cb( GncHtml* self, GncHTMLLoadCB load_cb, gpointer data )
+{
+	GncHtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	priv = GNC_HTML_GET_PRIVATE(self);
+	priv->load_cb = load_cb;
+	priv->load_cb_data = data;
+}
+
+void
+gnc_html_set_flyover_cb( GncHtml* self, GncHTMLFlyoverCB flyover_cb, gpointer data )
+{
+	GncHtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	priv = GNC_HTML_GET_PRIVATE(self);
+	priv->flyover_cb = flyover_cb;
+	priv->flyover_cb_data = data;
+}
+
+void
+gnc_html_set_button_cb( GncHtml* self, GncHTMLButtonCB button_cb, gpointer data )
+{
+	GncHtmlPrivate* priv;
+
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	priv = GNC_HTML_GET_PRIVATE(self);
+	priv->button_cb = button_cb;
+	priv->button_cb_data = data;
+}
+
+void
+gnc_html_copy_to_clipboard( GncHtml* self )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->copy_to_clipboard != NULL ) {
+		GNC_HTML_GET_CLASS(self)->copy_to_clipboard( self );
+	} else {
+		DEBUG( "'copy_to_clipboard' not implemented" );
+	}
+}
+
+/**************************************************************
+ * gnc_html_export_to_file : wrapper around the builtin function in gtkhtml
+ **************************************************************/
+
+gboolean
+gnc_html_export_to_file( GncHtml* self, const gchar* filepath )
+{
+	g_return_val_if_fail( self != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_HTML(self), FALSE );
+
+	if( GNC_HTML_GET_CLASS(self)->export_to_file != NULL ) {
+		return GNC_HTML_GET_CLASS(self)->export_to_file( self, filepath );
+	} else {
+		DEBUG( "'export_to_file' not implemented" );
+		return FALSE;
+	}
+}
+
+void
+gnc_html_print( GncHtml* self )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->print != NULL ) {
+		GNC_HTML_GET_CLASS(self)->print( self );
+	} else {
+		DEBUG( "'print' not implemented" );
+	}
+}
+
+gnc_html_history *
+gnc_html_get_history( GncHtml* self )
+{
+	g_return_val_if_fail( self != NULL, NULL );
+	g_return_val_if_fail( GNC_IS_HTML(self), NULL );
+
+	return GNC_HTML_GET_PRIVATE(self)->history;
+}
+
+
+GtkWidget *
+gnc_html_get_widget( GncHtml* self )
+{
+	g_return_val_if_fail( self != NULL, NULL );
+	g_return_val_if_fail( GNC_IS_HTML(self), NULL );
+
+	return GNC_HTML_GET_PRIVATE(self)->container;
+}
+
+void
+gnc_html_set_parent( GncHtml* self, GtkWindow* parent )
+{
+	g_return_if_fail( self != NULL );
+	g_return_if_fail( GNC_IS_HTML(self) );
+
+	if( GNC_HTML_GET_CLASS(self)->set_parent != NULL ) {
+		GNC_HTML_GET_CLASS(self)->set_parent( self, parent );
+	} else {
+		DEBUG( "'set_parent' not implemented" );
+	}
+}
+
+/* Register the URLType if it doesn't already exist.
+ * Returns TRUE if successful, FALSE if the type already exists.
+ */
+gboolean
+gnc_html_register_urltype( URLType type, const char *protocol )
+{
+  if (!gnc_html_type_to_proto_hash) {
+    gnc_html_type_to_proto_hash = g_hash_table_new (g_str_hash, g_str_equal);
+    gnc_html_proto_to_type_hash = g_hash_table_new (g_str_hash, g_str_equal);
+  }
+  if (!protocol) return FALSE;
+  if (g_hash_table_lookup (gnc_html_type_to_proto_hash, type))
+    return FALSE;
+
+  g_hash_table_insert (gnc_html_type_to_proto_hash, type, (gpointer)protocol);
+  if (*protocol)
+    g_hash_table_insert (gnc_html_proto_to_type_hash, (gpointer)protocol, type);
+
+  return TRUE;
+}
+
+void
+gnc_html_initialize( void )
+{
+  int i;
+  static struct {
+    URLType	type;
+    char *	protocol;
+  } types[] = {
+    { URL_TYPE_FILE, "file" },
+    { URL_TYPE_JUMP, "" },
+    { URL_TYPE_HTTP, "http" },
+    { URL_TYPE_FTP, "ftp" },
+    { URL_TYPE_SECURE, "https" },
+    { URL_TYPE_REGISTER, "gnc-register" },
+    { URL_TYPE_ACCTTREE, "gnc-acct-tree" },
+    { URL_TYPE_REPORT, "gnc-report" },
+    { URL_TYPE_OPTIONS, "gnc-options" },
+    { URL_TYPE_SCHEME, "gnc-scm" },
+    { URL_TYPE_HELP, "gnc-help" },
+    { URL_TYPE_XMLDATA, "gnc-xml" },
+    { URL_TYPE_PRICE, "gnc-price" },
+    { URL_TYPE_BUDGET, "gnc-budget" },
+    { URL_TYPE_OTHER, "" },
+    { NULL, NULL }};
+
+  for (i = 0; types[i].type; i++)
+    gnc_html_register_urltype (types[i].type, types[i].protocol);
+}
+
+char  *
+gnc_build_url (URLType type, const gchar * location, const gchar * label)
+{
+  char * type_name;
+
+  DEBUG(" ");
+  type_name = g_hash_table_lookup (gnc_html_type_to_proto_hash, type);
+  if (!type_name)
+    type_name = "";
+
+  if(label) {
+    return g_strdup_printf("%s%s%s#%s", type_name, (*type_name ? ":" : ""),
+                           (location ? location : ""),
+                           label ? label : "");
+  }
+  else {
+    return g_strdup_printf("%s%s%s", type_name, (*type_name ? ":" : ""),
+                           (location ? location : ""));
+  }
+}
+
+/********************************************************************
+ * gnc_html_encode_string
+ * RFC 1738 encoding of string for submission with an HTML form.
+ * GPL code lifted from gtkhtml.  copyright notice:
+ *
+ * Copyright (C) 1997 Martin Jones (mjones at kde.org)
+ * Copyright (C) 1997 Torben Weis (weis at kde.org)
+ * Copyright (C) 1999 Helix Code, Inc.
+ ********************************************************************/
+
+char *
+gnc_html_encode_string(const char * str)
+{
+  static gchar *safe = "$-._!*(),"; /* RFC 1738 */
+  unsigned pos      = 0;
+  GString *encoded  = g_string_new ("");
+  gchar buffer[5], *ptr;
+  guchar c;
+
+  if(!str) return NULL;
+
+  while(pos < strlen(str)) {
+    c = (unsigned char) str[pos];
+
+    if ((( c >= 'A') && ( c <= 'Z')) ||
+        (( c >= 'a') && ( c <= 'z')) ||
+        (( c >= '0') && ( c <= '9')) ||
+        (strchr(safe, c))) {
+      encoded = g_string_append_c (encoded, c);
+    }
+    else if ( c == ' ' ) {
+      encoded = g_string_append_c (encoded, '+');
+    }
+    else if ( c == '\n' ) {
+      encoded = g_string_append (encoded, "%0D%0A");
+    }
+    else if ( c != '\r' ) {
+      sprintf( buffer, "%%%02X", (int)c );
+      encoded = g_string_append (encoded, buffer);
+    }
+    pos++;
+  }
+
+  ptr = encoded->str;
+
+  g_string_free (encoded, FALSE);
+
+  return (char *)ptr;
+}
+
+
+char *
+gnc_html_decode_string(const char * str)
+{
+  static gchar * safe = "$-._!*(),"; /* RFC 1738 */
+  GString * decoded  = g_string_new ("");
+  const gchar   * ptr;
+  guchar  c;
+  guint   hexval;
+  ptr = str;
+
+  if(!str) return NULL;
+
+  while(*ptr) {
+    c = (unsigned char) *ptr;
+    if ((( c >= 'A') && ( c <= 'Z')) ||
+        (( c >= 'a') && ( c <= 'z')) ||
+        (( c >= '0') && ( c <= '9')) ||
+        (strchr(safe, c))) {
+      decoded = g_string_append_c (decoded, c);
+    }
+    else if ( c == '+' ) {
+      decoded = g_string_append_c (decoded, ' ');
+    }
+    else if (!strncmp(ptr, "%0D0A", 5)) {
+      decoded = g_string_append (decoded, "\n");
+      ptr += 4;
+    }
+    else if(c == '%') {
+      ptr++;
+      if (1 == sscanf(ptr, "%02X", &hexval))
+	decoded = g_string_append_c(decoded, (char)hexval);
+      else
+	decoded = g_string_append_c(decoded, ' ');
+      ptr++;
+    }
+    ptr++;
+  }
+  ptr = decoded->str;
+  g_string_free (decoded, FALSE);
+
+  return (char *)ptr;
+}
+
+/********************************************************************
+ * escape/unescape_newlines : very simple string encoding for GPG
+ * ASCII-armored text.
+ ********************************************************************/
+
+char *
+gnc_html_unescape_newlines(const gchar * in)
+{
+  const char * ip = in;
+  char    * cstr = NULL;
+  GString * rv = g_string_new("");
+
+  for(ip=in; *ip; ip++) {
+    if((*ip == '\\') && (*(ip+1)=='n')) {
+      g_string_append(rv, "\n");
+      ip++;
+    }
+    else {
+      g_string_append_c(rv, *ip);
+    }
+  }
+
+  g_string_append_c(rv, 0);
+  cstr = rv->str;
+  g_string_free(rv, FALSE);
+  return cstr;
+}
+
+char *
+gnc_html_escape_newlines(const gchar * in)
+{
+  char *out;
+  const char * ip   = in;
+  GString * escaped = g_string_new("");
+
+  for(ip=in; *ip; ip++) {
+    if(*ip == '\012') {
+      g_string_append(escaped, "\\n");
+    }
+    else {
+      g_string_append_c(escaped, *ip);
+    }
+  }
+  g_string_append_c(escaped, 0);
+  out = escaped->str;
+  g_string_free(escaped, FALSE);
+  return out;
+}
+
+void
+gnc_html_register_object_handler( const char * classid,
+                                 GncHTMLObjectCB hand )
+{
+	g_return_if_fail( classid != NULL );
+
+	if( gnc_html_object_handlers == NULL ) {
+		gnc_html_object_handlers = g_hash_table_new( g_str_hash, g_str_equal );
+	}
+
+	gnc_html_unregister_object_handler( classid );
+	if( hand != NULL ) {
+		g_hash_table_insert( gnc_html_object_handlers, g_strdup( classid ), hand );
+	}
+}
+
+void
+gnc_html_unregister_object_handler( const gchar* classid )
+{
+	gchar* keyptr = NULL;
+	gchar* valptr = NULL;
+	gchar** p_keyptr = &keyptr;
+	gchar** p_valptr = &valptr;
+
+	if( g_hash_table_lookup_extended( gnc_html_object_handlers,
+											 classid,
+											(gpointer *)p_keyptr,
+											(gpointer *)p_valptr) ) {
+		g_hash_table_remove( gnc_html_object_handlers, classid );
+		g_free( keyptr );
+	}
+}
+
+void
+gnc_html_register_stream_handler( URLType url_type, GncHTMLStreamCB hand )
+{
+	g_return_if_fail( url_type != NULL && *url_type != '\0' );
+
+	if( gnc_html_stream_handlers == NULL ) {
+		gnc_html_stream_handlers = g_hash_table_new( g_str_hash, g_str_equal );
+	}
+
+	gnc_html_unregister_stream_handler( url_type );
+	if( hand != NULL ) {
+		g_hash_table_insert( gnc_html_stream_handlers, url_type, hand );
+	}
+}
+
+void
+gnc_html_unregister_stream_handler( URLType url_type )
+{
+	g_hash_table_remove( gnc_html_stream_handlers, url_type );
+}
+
+void
+gnc_html_register_url_handler( URLType url_type, GncHTMLUrlCB hand )
+{
+	g_return_if_fail( url_type != NULL && *url_type != '\0' );
+
+	if( gnc_html_url_handlers == NULL ) {
+		gnc_html_url_handlers = g_hash_table_new( g_str_hash, g_str_equal );
+	}
+
+	gnc_html_unregister_url_handler( url_type );
+	if( hand != NULL ) {
+		g_hash_table_insert( gnc_html_url_handlers, url_type, hand );
+	}
+}
+
+void
+gnc_html_unregister_url_handler( URLType url_type )
+{
+	g_hash_table_remove( gnc_html_url_handlers, url_type );
+}

Added: gnucash/trunk/src/html/gnc-html.h
===================================================================
--- gnucash/trunk/src/html/gnc-html.h	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,268 @@
+/********************************************************************
+ * gnc-html.h -- display html with gnc special tags                 *
+ * Copyright (C) 2000 Bill Gribble <grib at billgribble.com>           *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_HTML_H
+#define GNC_HTML_H
+
+/**
+ * A GncHtml object is an abstract base for an html engine used to display reports and
+ * charts in gnucash.  It must be overridden to create specific objects using specific
+ * html engines (e.g. gtkhtml, webkit).
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GNC_TYPE_HTML         (gnc_html_get_type())
+#define GNC_HTML(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_HTML, GncHtml))
+#define GNC_HTML_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_HTML, GncHtmlClass))
+#define GNC_IS_HTML(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GNC_TYPE_HTML))
+#define GNC_IS_HTML_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((o), GNC_TYPE_HTML))
+#define GNC_HTML_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GNC_TYPE_HTML, GncHtmlClass))
+
+GType gnc_html_get_type(void);
+
+typedef struct _GncHtml GncHtml;
+typedef struct _GncHtmlClass GncHtmlClass;
+typedef struct _GncHtmlPrivate GncHtmlPrivate;
+
+#include "gnc-html-extras.h"
+
+/* The result structure of url handlers. Strings should be g_malloc'd
+ * by the handler and will be freed by gnc_html. */
+typedef struct
+{
+	/* The following members are used if the handler succeeds (returns TRUE). */
+
+	gboolean load_to_stream; /* If TRUE, the url should be loaded from
+                            * a stream using the rest of the data in
+                            * the struct into the original gnc_html
+                            * object. If FALSE, the handler will
+                            * perform all needed actions itself. */
+
+	URLType url_type;        /* Defaults to original */
+	gchar* location;         /* If NULL, use original (NULL is default) */
+	gchar* label;            /* If NULL, use original (NULL is default) */
+
+	URLType base_type;
+	gchar* base_location;
+
+	/* The following members are used if the handler fails (returns FALSE). */
+	gchar* error_message;
+} GNCURLResult;
+
+typedef gboolean (* GncHTMLObjectCB)(GncHtml* html, gpointer eb,
+                                 gpointer data); 
+typedef gboolean (* GncHTMLStreamCB)(const gchar* location, gchar** data, int* datalen);
+typedef gboolean (* GncHTMLUrlCB)(const gchar* location, const gchar* label,
+                                  gboolean new_window, GNCURLResult* result);
+
+/**
+ * Registers a new URLType.
+ * returns TRUE if succesful, FALSE if type already exists.
+ *
+ * @param type New URL type
+ * @param prococol Protocol - should be an empty string if there is no corresponding protocol.
+ * @return TRUE if successful, FALSE if type already exists or protocol is NULL.
+ */
+gboolean gnc_html_register_urltype( URLType type, const gchar* protocol );
+
+/**
+ * Initializes the html subsystem
+ */
+void gnc_html_initialize( void );
+
+gchar* gnc_html_encode_string( const gchar* in );
+gchar* gnc_html_decode_string( const gchar* in );
+gchar* gnc_html_escape_newlines( const gchar* in );
+gchar* gnc_html_unescape_newlines( const gchar* in );
+
+/* object handlers deal with <object classid="foo"> objects in HTML.
+ * the handlers are looked up at object load time. */
+void gnc_html_register_object_handler( const gchar* classid, GncHTMLObjectCB hand );
+void gnc_html_unregister_object_handler( const gchar* classid );
+
+/* stream handlers load data for particular URLTypes. */
+void gnc_html_register_stream_handler( URLType url_type, GncHTMLStreamCB hand );
+void gnc_html_unregister_stream_handler( URLType url_type );
+
+/* handlers for particular URLTypes. */
+void gnc_html_register_url_handler( URLType url_type, GncHTMLUrlCB hand );
+void gnc_html_unregister_url_handler( URLType url_type );
+
+#include "gnc-html-history.h"
+
+typedef int  (* GncHTMLUrltypeCB)(URLType ut);
+typedef void (* GncHTMLFlyoverCB)(GncHtml* html, const gchar* url,
+                                  gpointer data);
+typedef void (* GncHTMLLoadCB)(GncHtml* html, URLType type, 
+                               const gchar* location, const gchar* label,
+                               gpointer data);
+typedef int  (* GncHTMLButtonCB)(GncHtml* html, GdkEventButton* event,
+                                 gpointer data);
+
+struct _GncHtmlClass
+{
+	GtkBinClass parent_class;
+
+	/* Methods */
+	void (*show_url)( GncHtml* html, 
+                      URLType type,
+                      const gchar* location, 
+                      const gchar* label,
+                      gboolean new_window_hint );
+	void (*show_data)( GncHtml* html, const gchar* data, int datalen );
+	void (*reload)( GncHtml* html );
+	void (*copy_to_clipboard)( GncHtml* html );
+	gboolean (*export_to_file)( GncHtml* html, const gchar* file );
+	void (*print)( GncHtml* html );
+	void (*cancel)( GncHtml* html );
+	URLType (*parse_url)( GncHtml* html, const gchar* url, 
+                          gchar** url_location, gchar** url_label );
+	void (*set_parent)( GncHtml* html, GtkWindow* parent );
+};
+
+struct _GncHtml
+{
+	GtkBin parent_instance;
+
+	/*< private >*/
+	GncHtmlPrivate* priv;
+};
+
+/**
+ * Destroys a GncHtml object.
+ *
+ * @param html GncHtml object to destroy
+ */
+void gnc_html_destroy( GncHtml* html );
+
+/**
+ * Displays a URL in a GncHtml object.
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_show_url( GncHtml* html, URLType type, const gchar* location, 
+						const gchar* label, gboolean new_window_hint );
+
+/**
+ * Displays an HTML string in a GncHtml object.
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_show_data( GncHtml* html, const gchar* data, int datalen );
+
+/**
+ * Reloads the current GncHtml object.
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_reload( GncHtml* html );
+
+/**
+ * Copies the html to the clipboard
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_copy_to_clipboard( GncHtml* html );
+
+/**
+ * Exports the html to an external file.
+ *
+ * @param html GncHtml object
+ * @param filename External file name
+ * @param TRUE if successful, FALSE if unsuccessful
+ */
+gboolean gnc_html_export_to_file( GncHtml* html, const gchar* filename );
+
+/**
+ * Prints the report.
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_print( GncHtml* html );
+
+/**
+ * Cancels the current operation
+ *
+ * @param html GncHtml object
+ */
+void gnc_html_cancel( GncHtml* html );
+
+/**
+ * Parses a URL into URI and label
+ *
+ * @param html GncHtml object
+ * @param url URL
+ * @param url_location Pointer where to store address of string containing main URI
+ * @param url_label Pointer where to store address of string containing label
+ */
+URLType gnc_html_parse_url( GncHtml* html, const gchar* url, 
+							gchar** url_location, gchar** url_label );
+
+/**
+ * Returns the history for this html engine
+ *
+ * @param html GncHtml object
+ * @return History
+ */
+gnc_html_history* gnc_html_get_history( GncHtml* html );
+
+/**
+ * Returns the main widget for this html engine
+ *
+ * @param html GncHtml object
+ * @return Main widget
+ */
+GtkWidget* gnc_html_get_widget( GncHtml* html );
+
+/**
+ * Sets the parent window for this html engine.  The engine will be embedded in this parent.
+ *
+ * @param html GncHtml object
+ * @param parent Parent window
+ */
+void gnc_html_set_parent( GncHtml* html, GtkWindow* parent );
+
+/* setting callbacks */
+void gnc_html_set_urltype_cb( GncHtml* html, GncHTMLUrltypeCB urltype_cb );
+void gnc_html_set_load_cb( GncHtml* html, GncHTMLLoadCB load_cb, gpointer data );
+void gnc_html_set_flyover_cb( GncHtml* html, GncHTMLFlyoverCB newwin_cb, gpointer data );
+void gnc_html_set_button_cb( GncHtml* html, GncHTMLButtonCB button_cb, gpointer data );
+
+/* object handlers deal with <object classid="foo"> objects in HTML.
+ * the handlers are looked up at object load time. */
+void gnc_html_register_object_handler( const gchar* classid, GncHTMLObjectCB hand );
+void gnc_html_unregister_object_handler( const gchar* classid );
+
+/* stream handlers load data for particular URLTypes. */
+void gnc_html_register_stream_handler( URLType url_type, GncHTMLStreamCB hand );
+void gnc_html_unregister_stream_handler( URLType url_type );
+
+/* handlers for particular URLTypes. */
+void gnc_html_register_url_handler( URLType url_type, GncHTMLUrlCB hand );
+void gnc_html_unregister_url_handler( URLType url_type );
+
+const gchar* gnc_html_get_embedded_param( gpointer eb, const gchar* param_name );
+
+#endif

Added: gnucash/trunk/src/html/gnc-html.i
===================================================================
--- gnucash/trunk/src/html/gnc-html.i	                        (rev 0)
+++ gnucash/trunk/src/html/gnc-html.i	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,51 @@
+%module sw_gnc_html
+%{
+/* Includes the header in the wrapper code */
+#include <config.h>
+#include <gtk/gtk.h>
+#include <glib-object.h>
+#include <dialog-options.h>
+#include <dialog-utils.h>
+#include <druid-utils.h>
+#include <gnc-amount-edit.h>
+#include <gnc-date-edit.h>
+#include <gnc-file.h>
+#include <gnc-gnome-utils.h>
+#include <gnc-gui-query.h>
+#include <gnc-html.h>
+
+SCM scm_init_sw_gnc_html_module(void);
+%}
+
+%import "base-typemaps.i"
+
+/* Parse the header file to generate wrappers */
+%include "gnc-html-extras.h"
+
+
+%init {
+  {
+    char tmp[100];
+
+#define SET_ENUM(e) snprintf(tmp, 100, "(set! %s (%s))", (e), (e));  \
+    scm_c_eval_string(tmp);
+
+    SET_ENUM("URL-TYPE-FILE");
+    SET_ENUM("URL-TYPE-JUMP");
+    SET_ENUM("URL-TYPE-HTTP");
+    SET_ENUM("URL-TYPE-FTP");
+    SET_ENUM("URL-TYPE-SECURE");
+    SET_ENUM("URL-TYPE-REGISTER");
+    SET_ENUM("URL-TYPE-ACCTTREE");
+    SET_ENUM("URL-TYPE-REPORT");
+    SET_ENUM("URL-TYPE-OPTIONS");
+    SET_ENUM("URL-TYPE-SCHEME");
+    SET_ENUM("URL-TYPE-HELP");
+    SET_ENUM("URL-TYPE-XMLDATA");
+    SET_ENUM("URL-TYPE-PRICE");
+    SET_ENUM("URL-TYPE-OTHER");
+
+#undefine SET_ENUM
+  }
+
+}

Added: gnucash/trunk/src/html/gncmod-html.c
===================================================================
--- gnucash/trunk/src/html/gncmod-html.c	                        (rev 0)
+++ gnucash/trunk/src/html/gncmod-html.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -0,0 +1,82 @@
+/*********************************************************************
+ * gncmod-html.c
+ * module definition/initialization for the html utilities
+ *
+ * Copyright (c) 2001 Linux Developers Group, Inc.
+ *********************************************************************/
+
+#include "config.h"
+
+#include <gmodule.h>
+#include <libguile.h>
+#include <gtk/gtk.h>
+
+#include "gnc-module.h"
+#include "gnc-module-api.h"
+
+#include "gnc-html.h"
+#include "qof.h"
+
+GNC_MODULE_API_DECL(libgncmod_html)
+
+/* version of the gnc module system interface we require */
+int libgncmod_html_gnc_module_system_interface = 0;
+
+/* module versioning uses libtool semantics. */
+int libgncmod_html_gnc_module_current  = 0;
+int libgncmod_html_gnc_module_revision = 0;
+int libgncmod_html_gnc_module_age      = 0;
+
+
+char *
+libgncmod_html_gnc_module_path( void )
+{
+	return g_strdup( "gnucash/html" );
+}
+
+char *
+libgncmod_html_gnc_module_description( void )
+{
+	return g_strdup( "Utilities for using HTML with GnuCash" );
+}
+
+static void
+lmod( char* mn )
+{
+	char* form = g_strdup_printf( "(use-modules %s)\n", mn );
+	scm_c_eval_string( form );
+	g_free( form );
+}
+
+extern SCM scm_init_sw_gnc_html_module( void );
+
+int
+libgncmod_html_gnc_module_init( int refcount )
+{
+	/* load the engine (we depend on it) */
+	if( !gnc_module_load( "gnucash/engine", 0 ) ) {
+		return FALSE;
+	}
+
+	/* load the calculation module (we depend on it) */
+	if( !gnc_module_load( "gnucash/calculation", 0 ) ) {
+		return FALSE;
+	}
+
+	if( !gnc_module_load( "gnucash/app-utils", 0 ) ) {
+		return FALSE;
+	}
+
+	scm_init_sw_gnc_html_module();
+	gnc_html_initialize();
+	lmod( "(sw_gnc_html)" );
+//	lmod( "(gnucash gnc_html)" );
+
+	return TRUE;
+}
+
+int
+libgncmod_html_gnc_module_end( int refcount )
+{
+	return TRUE;
+}

Modified: gnucash/trunk/src/import-export/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -68,8 +68,6 @@
   -I${top_srcdir}/src/gnome-utils \
   -I${top_srcdir}/src/libqof/qof \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
-  ${GDK_PIXBUF_CFLAGS} \
   ${GLADE_CFLAGS} \
   ${GUILE_INCS} \
   ${GLIB_CFLAGS}

Modified: gnucash/trunk/src/import-export/csv/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/csv/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/csv/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -43,7 +43,6 @@
   -I${top_srcdir}/lib/libc \
   -I${top_srcdir}/lib \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
   ${GLADE_CFLAGS} \
   ${GUILE_INCS} \
   ${GLIB_CFLAGS} \

Modified: gnucash/trunk/src/import-export/hbci/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/hbci/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/hbci/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -74,7 +74,6 @@
   -I${top_srcdir}/src/libqof/qof \
   ${GUILE_INCS} \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
   ${GLADE_CFLAGS} \
   ${GLIB_CFLAGS} \
   ${AQBANKING_CFLAGS}

Modified: gnucash/trunk/src/import-export/hbci/druid-hbci-initial.c
===================================================================
--- gnucash/trunk/src/import-export/hbci/druid-hbci-initial.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/hbci/druid-hbci-initial.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -45,7 +45,7 @@
 #include "druid-utils.h"
 #include "gnc-ui-util.h"
 #include "gnc-ui.h"
-#include "gnc-html.h"
+//#include "gnc-html.h"
 //#include "import-account-matcher.h"
 #include "gnc-component-manager.h"
 #include "gnc-session.h"

Modified: gnucash/trunk/src/import-export/log-replay/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/log-replay/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/log-replay/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -21,7 +21,8 @@
   ${top_builddir}/src/gnc-module/libgnc-module.la \
   ${top_builddir}/src/libqof/qof/libgnc-qof.la \
   ${GTK_LIBS} \
-  ${GLIB_LIBS}
+  ${GLIB_LIBS} \
+  ${QOF_LIBS}
 
 AM_CPPFLAGS = \
   -I${top_srcdir}/src \
@@ -34,7 +35,6 @@
   -I${top_srcdir}/src/import-export \
   -I${top_srcdir}/src/libqof/qof \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
   ${GLADE_CFLAGS} \
   ${GUILE_INCS} \
   ${GLIB_CFLAGS}

Modified: gnucash/trunk/src/import-export/ofx/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/ofx/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/ofx/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -35,7 +35,6 @@
   -I${top_srcdir}/src/import-export \
   -I${top_srcdir}/src/libqof/qof \
   ${GNOME_CFLAGS} \
-  ${GTKHTML_CFLAGS} \
   ${GLADE_CFLAGS} \
   ${GUILE_INCS} \
   ${GLIB_CFLAGS} \

Modified: gnucash/trunk/src/import-export/qif-import/Makefile.am
===================================================================
--- gnucash/trunk/src/import-export/qif-import/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/import-export/qif-import/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -65,9 +65,7 @@
   ${GUILE_INCS} \
   ${GLIB_CFLAGS} \
   ${GLADE_CFLAGS} \
-  ${GNOME_CFLAGS} \
-  ${GDK_PIXBUF_CFLAGS} \
-  ${GTKHTML_CFLAGS}
+  ${GNOME_CFLAGS} 
 
 uidir = $(GNC_UI_DIR)
 ui_DATA = \

Modified: gnucash/trunk/src/report/report-gnome/Makefile.am
===================================================================
--- gnucash/trunk/src/report/report-gnome/Makefile.am	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-gnome/Makefile.am	2009-04-11 01:44:14 UTC (rev 18041)
@@ -11,11 +11,11 @@
   -I${top_srcdir}/src/app-utils \
   -I${top_srcdir}/src/gnome-utils \
   -I${top_srcdir}/src/gnome \
+  -I${top_srcdir}/src/html \
   -I${top_srcdir}/src/report/report-system \
   -I${top_srcdir}/src/libqof/qof \
   ${GLADE_CFLAGS} \
   ${GUILE_INCS} \
-  ${GTKHTML_CFLAGS} \
   ${GNOME_CFLAGS} \
   ${GLIB_CFLAGS}
 
@@ -44,6 +44,7 @@
   ${top_builddir}/src/engine/libgncmod-engine.la \
   ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
   ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/src/html/libgncmod-html.la \
   ${top_builddir}/src/report/report-system/libgncmod-report-system.la \
   ${top_builddir}/src/libqof/qof/libgnc-qof.la \
   ${GLADE_LIBS} \

Modified: gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
===================================================================
--- gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -53,6 +53,7 @@
 #include "gnc-gnome-utils.h"
 #include "gnc-html-history.h"
 #include "gnc-html.h"
+#include "gnc-html-factory.h"
 #include "gnc-file.h"
 #include "gnc-plugin.h"
 #include "gnc-plugin-page-report.h"
@@ -112,7 +113,8 @@
         gboolean	reloading;
 
         /// the gnc_html abstraction this PluginPage contains
-        gnc_html *html;
+//        gnc_html *html;
+        GncHtml *html;
 
         /// the container the above HTML widget is in.
         GtkContainer *container;
@@ -138,7 +140,8 @@
 static gboolean gnc_plugin_page_report_finish_pending (GncPluginPage *page);
 
 static int gnc_plugin_page_report_check_urltype(URLType t);
-static void gnc_plugin_page_report_load_cb(gnc_html * html, URLType type,
+//static void gnc_plugin_page_report_load_cb(gnc_html * html, URLType type,
+static void gnc_plugin_page_report_load_cb(GncHtml * html, URLType type,
                                       const gchar * location, const gchar * label,
                                       gpointer data);
 static void gnc_plugin_page_report_expose_event_cb(GtkWidget *unused, GdkEventExpose *unused1, gpointer data);
@@ -324,7 +327,9 @@
         priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
 
         topLvl = GTK_WINDOW(gnc_ui_get_toplevel());
-        priv->html = gnc_html_new( topLvl );
+//        priv->html = gnc_html_new( topLvl );
+	priv->html = gnc_html_factory_create_html();
+		gnc_html_set_parent( priv->html, topLvl );
 
         gnc_html_history_set_node_destroy_cb(gnc_html_get_history(priv->html),
                                              gnc_plugin_page_report_history_destroy_cb,
@@ -357,6 +362,7 @@
 
         gnc_window_set_progressbar_window( GNC_WINDOW(page->window) );
         gnc_html_show_url(priv->html, type, url_location, url_label, 0);
+		g_free(url_location);
         gnc_window_set_progressbar_window( NULL );
 
         g_signal_connect(priv->container, "expose_event",
@@ -427,7 +433,8 @@
  * called after a report is loaded into the gnc_html widget 
  ********************************************************************/
 static void 
-gnc_plugin_page_report_load_cb(gnc_html * html, URLType type, 
+//gnc_plugin_page_report_load_cb(gnc_html * html, URLType type, 
+gnc_plugin_page_report_load_cb(GncHtml * html, URLType type, 
                                const gchar * location, const gchar * label, 
                                gpointer data)
 {
@@ -1428,7 +1435,7 @@
                 result = (res != SCM_BOOL_F);
         }
         else
-                result = gnc_html_export (priv->html, filepath);
+                result = gnc_html_export_to_file (priv->html, filepath);
 
         if (!result)
         {
@@ -1485,7 +1492,7 @@
         GncPluginPageReportPrivate *priv;
 
         priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
-        gnc_html_copy(priv->html);
+        gnc_html_copy_to_clipboard(priv->html);
 }
 
 /********************************************************************

Modified: gnucash/trunk/src/report/report-gnome/window-report.c
===================================================================
--- gnucash/trunk/src/report/report-gnome/window-report.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-gnome/window-report.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -40,6 +40,7 @@
 #include "gnc-report.h"
 #include "gnc-ui.h"
 #include "option-util.h"
+#include "gnc-html.h"
 #include "window-report.h"
 #include "guile-mappings.h"
 

Modified: gnucash/trunk/src/report/report-gnome/window-report.h
===================================================================
--- gnucash/trunk/src/report/report-gnome/window-report.h	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-gnome/window-report.h	2009-04-11 01:44:14 UTC (rev 18041)
@@ -25,7 +25,7 @@
 
 #include <libguile.h>
 
-#include "gnc-html.h"
+//#include "gnc-html.h"
 #include "qof.h"
   
 typedef struct gnc_report_window_s gnc_report_window;

Modified: gnucash/trunk/src/report/report-system/gnc-report.c
===================================================================
--- gnucash/trunk/src/report/report-system/gnc-report.c	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-system/gnc-report.c	2009-04-11 01:44:14 UTC (rev 18041)
@@ -144,6 +144,7 @@
 
   str = g_strdup_printf("(gnc:report-run %d)", report_id);
   scm_text = gfec_eval_string(str, error_handler);
+  g_free(str);
 
   if (scm_text == SCM_UNDEFINED || !SCM_STRINGP (scm_text))
     return FALSE;

Modified: gnucash/trunk/src/report/report-system/report-system.scm
===================================================================
--- gnucash/trunk/src/report/report-system/report-system.scm	2009-04-11 00:53:14 UTC (rev 18040)
+++ gnucash/trunk/src/report/report-system/report-system.scm	2009-04-11 01:44:14 UTC (rev 18041)
@@ -17,7 +17,8 @@
 
 (gnc:module-load "gnucash/engine" 0)
 (gnc:module-load "gnucash/app-utils" 0)
-(gnc:module-load "gnucash/gnome-utils" 0) ; for the html routines
+(gnc:module-load "gnucash/html" 0)
+(gnc:module-load "gnucash/gnome-utils" 0)
 
 ;; commodity-utilities.scm
 (export gnc:get-match-commodity-splits)



More information about the gnucash-changes mailing list