From 8f2181350bb177589a8c8763062cc501590d053d Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Wed, 12 Sep 2001 21:03:58 +0000 Subject: [PATCH] Implement dynamic stream handlers for gnc_htmls. Factor out some gnucash stream handling to higher-level modules. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5366 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/Makefile.am | 1 + src/gnome-utils/gnc-html.c | 207 ++++++++++++++------------ src/gnome-utils/gnc-html.h | 6 + src/gnome/Makefile.am | 1 + src/gnome/top-level.c | 36 ++++- src/report/report-system/Makefile.am | 16 +- src/report/report-system/gnc-report.c | 71 +++++++++ src/report/report-system/gnc-report.h | 30 ++++ 8 files changed, 268 insertions(+), 100 deletions(-) create mode 100644 src/report/report-system/gnc-report.c create mode 100644 src/report/report-system/gnc-report.h diff --git a/src/Makefile.am b/src/Makefile.am index 13b1dc8d5f..af693bb4e9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,6 +45,7 @@ gnucash_LDADD = \ register/ledger-core/libgncmod-ledger-core.la \ register/register-core/libgncmod-register-core.la \ register/register-gnome/libgncmod-register-gnome.la \ + report/report-system/libgncmod-report-system.la \ import-export/qif-import/libgncmod-qif-import.la \ guile/libgncguile.a \ gnome/libgncgnome.a \ diff --git a/src/gnome-utils/gnc-html.c b/src/gnome-utils/gnc-html.c index 1579409854..bbeaad4b9b 100644 --- a/src/gnome-utils/gnc-html.c +++ b/src/gnome-utils/gnc-html.c @@ -44,7 +44,6 @@ #include "Account.h" #include "Group.h" -#include "file-utils.h" #include "FileDialog.h" #include "dialog-utils.h" #include "window-register.h" @@ -101,15 +100,15 @@ static GHashTable * gnc_html_object_handlers = NULL; * 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; + static char error_404[] = -"

Not found

The specified URL could not be loaded."; +N_("

Not found

The specified URL could not be loaded."); -static char error_start[] = "

Error

There was an error loading the specified URL.

Error message:

"; +static char error_start[] = N_("

Error

There was an error loading the specified URL.

Error message:

"); static char error_end[] = ""; -static char error_report[] = -"

Report error

An error occurred while running the report."; - static char * extract_machine_name(const gchar * path) { @@ -422,10 +421,11 @@ gnc_html_http_request_cb(const gchar * uri, int completed_ok, gtk_html_write(GTK_HTML(html->html), handle, body, body_len); } else { - gtk_html_write(GTK_HTML(html->html), handle, - error_start, strlen(error_start)); - gtk_html_write(GTK_HTML(html->html), handle, - body, body_len); + char *data; + + data = _(error_start); + gtk_html_write(GTK_HTML(html->html), handle, data, strlen (data)); + gtk_html_write(GTK_HTML(html->html), handle, body, body_len); gtk_html_write(GTK_HTML(html->html), handle, error_end, strlen(error_end)); gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK); @@ -457,8 +457,11 @@ gnc_html_http_request_cb(const gchar * uri, int completed_ok, } /* request failed... body is the ghttp error text. */ else { + char *data; + + data = _(error_start); gtk_html_write(GTK_HTML(html->html), (GtkHTMLStream *)(current->data), - error_start, strlen(error_start)); + data, strlen(data)); gtk_html_write(GTK_HTML(html->html), (GtkHTMLStream *)(current->data), body, body_len); gtk_html_write(GTK_HTML(html->html), (GtkHTMLStream *)(current->data), @@ -469,7 +472,7 @@ gnc_html_http_request_cb(const gchar * uri, int completed_ok, } g_list_free(handles); } - + gnc_unset_busy_cursor (html->html); } @@ -523,26 +526,36 @@ gnc_html_load_to_stream(gnc_html * html, GtkHTMLStream * handle, 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); + + if(ok) { + fdata = fdata ? fdata : g_strdup (""); + gtk_html_write(GTK_HTML(html->html), handle, fdata, strlen (fdata)); + gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK); + } + else { + fdata = fdata ? fdata : g_strdup (_(error_404)); + 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) { + gtk_html_jump_to_anchor(GTK_HTML(html->html), label); + } + + return; + } + } + switch(type) { - case URL_TYPE_HELP: - case URL_TYPE_FILE: - fsize = gncReadFile(location, &fdata); - if(fsize > 0) { - gtk_html_write(GTK_HTML(html->html), handle, fdata, fsize); - gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK); - } - else { - gtk_html_write(GTK_HTML(html->html), handle, error_404, - strlen(error_404)); - gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_ERROR); - } - g_free(fdata); - if(label) { - gtk_html_jump_to_anchor(GTK_HTML(html->html), label); - } - break; - case URL_TYPE_SECURE: if(!https_allowed()) { gnc_error_dialog(_("Secure HTTP access is disabled.\n" @@ -550,7 +563,7 @@ gnc_html_load_to_stream(gnc_html * html, GtkHTMLStream * handle, "the Preferences dialog.")); break; } - + case URL_TYPE_HTTP: if(!http_allowed()) { gnc_error_dialog(_("Network HTTP access is disabled.\n" @@ -562,58 +575,16 @@ gnc_html_load_to_stream(gnc_html * html, GtkHTMLStream * handle, gnc_html_start_request(html, fullurl, handle); } break; - - case URL_TYPE_REPORT: - run_report = gh_eval_str("gnc:report-run"); - if(!strncmp("id=", location, 3)) { - /* get the report ID */ - sscanf(location+3, "%d", &id); - - /* get the HTML text */ - scmtext = gh_call1(run_report, gh_int2scm(id)); - if(scmtext == SCM_BOOL_F) { - gtk_html_write(GTK_HTML(html->html), handle, - error_report, strlen(error_report)); - } - else { - fdata = gh_scm2newstr(scmtext, &fsize); - if(fdata) { - gtk_html_write(GTK_HTML(html->html), handle, fdata, fsize); - TRACE ("%s", fdata); - free(fdata); - fdata = NULL; - fsize = 0; - if(label) { - gtk_html_jump_to_anchor(GTK_HTML(html->html), label); - } - } - else { - gtk_html_write(GTK_HTML(html->html), handle, error_404, - strlen(error_404)); - PWARN("report HTML generator failed."); - } - } - } - - gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_OK); - break; - - case URL_TYPE_REGISTER: - case URL_TYPE_ACCTTREE: - case URL_TYPE_OPTIONS: - case URL_TYPE_SCHEME: - case URL_TYPE_FTP: default: PWARN("load_to_stream for inappropriate type\n" "\turl = '%s#%s'\n", location ? location : "(null)", label ? label : "(null)"); - gtk_html_write(GTK_HTML(html->html), handle, error_404, - strlen(error_404)); + fdata = _(error_404); + gtk_html_write(GTK_HTML(html->html), handle, fdata, strlen (fdata)); gtk_html_end(GTK_HTML(html->html), handle, GTK_HTML_STREAM_ERROR); break; - } } @@ -1396,9 +1367,16 @@ gnc_html_get_widget(gnc_html * html) { 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); } @@ -1407,22 +1385,29 @@ gnc_html_unregister_object_handler(const char * classid) { gchar * keyptr=NULL; gchar * valptr=NULL; - g_hash_table_lookup_extended(gnc_html_object_handlers, - classid, - (gpointer *)&keyptr, - (gpointer *)&valptr); - if(keyptr) { - g_free(keyptr); - g_hash_table_remove(gnc_html_object_handlers, classid); - } + if (!g_hash_table_lookup_extended(gnc_html_object_handlers, + classid, + (gpointer *)&keyptr, + (gpointer *)&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); } @@ -1431,16 +1416,54 @@ gnc_html_unregister_action_handler(const char * actionid) { gchar * keyptr=NULL; gchar * valptr=NULL; - g_hash_table_lookup_extended(gnc_html_action_handlers, - actionid, - (gpointer *)&keyptr, - (gpointer *)&valptr); - if(keyptr) { - g_free(keyptr); - g_hash_table_remove(gnc_html_action_handlers, actionid); - } + g_return_if_fail (actionid != NULL); + + if (!g_hash_table_lookup_extended(gnc_html_action_handlers, + actionid, + (gpointer *)&keyptr, + (gpointer *)&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) +{ + URLType *key; + + g_return_if_fail (url_type >= 0); + + if(!gnc_html_stream_handlers) { + gnc_html_stream_handlers = g_hash_table_new(g_int_hash, g_int_equal); + } + + gnc_html_unregister_stream_handler (url_type); + if (!hand) + return; + + key = g_new (URLType, 1); + *key = url_type; + + g_hash_table_insert (gnc_html_stream_handlers, key, hand); +} + +void +gnc_html_unregister_stream_handler(URLType url_type) +{ + gpointer keyptr; + gpointer valptr; + + if (!g_hash_table_lookup_extended(gnc_html_stream_handlers, + &url_type, + &keyptr, + &valptr)) + return; + + g_hash_table_remove (gnc_html_stream_handlers, &url_type); + g_free (keyptr); +} /******************************************************************** * gnc_html_encode_string diff --git a/src/gnome-utils/gnc-html.h b/src/gnome-utils/gnc-html.h index f882c25a75..6608ecd132 100644 --- a/src/gnome-utils/gnc-html.h +++ b/src/gnome-utils/gnc-html.h @@ -57,6 +57,7 @@ typedef int (* 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); gnc_html * gnc_html_new(void); void gnc_html_destroy(gnc_html * html); @@ -83,6 +84,11 @@ 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); + /* default action handlers for GET and POST methods. 'generic_post' * is the trivial application/x-www-form-urlencoded submit, * multipart-post is a multipart/form-data submit. */ diff --git a/src/gnome/Makefile.am b/src/gnome/Makefile.am index 3133ffe64b..0810fc8207 100644 --- a/src/gnome/Makefile.am +++ b/src/gnome/Makefile.am @@ -112,6 +112,7 @@ INCLUDES = \ -I${top_srcdir}/src/register/ledger-core \ -I${top_srcdir}/src/register/register-core \ -I${top_srcdir}/src/register/register-gnome \ + -I${top_srcdir}/src/report/report-system \ -I${top_srcdir}/src/import-export/qif-import \ ${GNOME_INCLUDEDIR} \ ${GUILE_INCS} diff --git a/src/gnome/top-level.c b/src/gnome/top-level.c index b4d64f36e6..da291faec5 100644 --- a/src/gnome/top-level.c +++ b/src/gnome/top-level.c @@ -31,7 +31,7 @@ #ifdef GTKHTML_HAVE_GCONF #include #endif - +#include #include #include "AccWindow.h" @@ -44,6 +44,7 @@ #include "dialog-account.h" #include "dialog-transfer.h" #include "dialog-utils.h" +#include "file-utils.h" #include "global-options.h" #include "gnc-component-manager.h" #include "gnc-engine-util.h" @@ -53,7 +54,9 @@ #ifdef USE_GUPPI #include "gnc-html-guppi.h" #endif +#include "gnc-html.h" #include "gnc-gpg.h" +#include "gnc-report.h" #include "gnc-ui.h" #include "gw-gnc.h" #include "gnucash-color.h" @@ -70,7 +73,6 @@ #include "window-acct-tree.h" #include "window-report.h" -#include /** PROTOTYPES ******************************************************/ static void gnc_configure_date_format_cb(gpointer); @@ -169,7 +171,28 @@ gnc_set_remaining_argv(int len, const char **rest) gh_define(gnc_scheme_remaining_var, toput); } - + +static gboolean +gnc_html_file_stream_handler (const char *location, char ** data) +{ + return (gncReadFile (location, data) > 0); +} + +static gboolean +gnc_html_report_stream_handler (const char *location, char ** data) +{ + gboolean ok; + + ok = gnc_run_report_id_string (location, data); + + if (!ok) + *data = g_strdup (_("

Report error

" + "

An error occurred while running the report.

" + "")); + + return ok; +} + /* ============================================================== */ /* These gnucash_ui_init and gnucash_ui functions are just hacks to get @@ -311,6 +334,13 @@ gnucash_ui_init(void) gnucash_style_init(); gnucash_color_init(); + gnc_html_register_stream_handler (URL_TYPE_HELP, + gnc_html_file_stream_handler); + gnc_html_register_stream_handler (URL_TYPE_FILE, + gnc_html_file_stream_handler); + gnc_html_register_stream_handler (URL_TYPE_REPORT, + gnc_html_report_stream_handler); + /* initialize gnome MDI and set up application window defaults */ app = gnc_main_window_new(); /* Run the ui startup hooks. */ diff --git a/src/report/report-system/Makefile.am b/src/report/report-system/Makefile.am index fc8fb2b6d5..769e49b0f8 100644 --- a/src/report/report-system/Makefile.am +++ b/src/report/report-system/Makefile.am @@ -2,16 +2,24 @@ SUBDIRS = . test pkglib_LTLIBRARIES = libgncmod-report-system.la -libgncmod_report_system_la_SOURCES = gncmod-report-system.c +libgncmod_report_system_la_SOURCES = \ + gncmod-report-system.c \ + gnc-report.c + +noinst_HEADERS = \ + gnc-report.h + libgncmod_report_system_la_LDFLAGS = -module libgncmod_report_system_la_LIBADD = \ -L../../gnc-module -L../../gnc-module/.libs -lgncmodule \ - ${GLIB_LIBS} ${GUILE_LIBS} + ${GLIB_LIBS} \ + ${GUILE_LIBS} INCLUDES = \ -I${top_srcdir}/src/gnc-module \ - ${GLIB_CFLAGS} + ${GLIB_CFLAGS} \ + ${GUILE_INCS} .scm-links: rm -f gnucash report @@ -43,5 +51,3 @@ gncscm_DATA = \ EXTRA_DIST = ${gncscmmod_DATA} ${gncscm_DATA} CLEANFILES += gnucash report .scm-links - - diff --git a/src/report/report-system/gnc-report.c b/src/report/report-system/gnc-report.c new file mode 100644 index 0000000000..9d44868265 --- /dev/null +++ b/src/report/report-system/gnc-report.c @@ -0,0 +1,71 @@ +/******************************************************************** + * gnc-report.c -- C functions for reports. * + * * + * Copyright (C) 2001 Linux Developers Group * + * * + * 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 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "gnc-report.h" + +gboolean +gnc_run_report (int report_id, char ** data) +{ + char *free_data; + SCM run_report; + SCM scm_text; + + g_return_val_if_fail (data != NULL, FALSE); + *data = NULL; + + run_report = gh_eval_str ("gnc:report-run"); + + scm_text = gh_call1 (run_report, gh_int2scm (report_id)); + if (!gh_string_p (scm_text)) + return FALSE; + + free_data = gh_scm2newstr (scm_text, NULL); + *data = g_strdup (free_data); + if (free_data) free (free_data); + + return TRUE; +} + +gboolean +gnc_run_report_id_string (const char * id_string, char **data) +{ + int report_id; + + g_return_val_if_fail (id_string != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + *data = NULL; + + if (strncmp ("id=", id_string, 3) != 0) + return FALSE; + + if (sscanf (id_string + 3, "%d", &report_id) != 1) + return FALSE; + + return gnc_run_report (report_id, data); +} diff --git a/src/report/report-system/gnc-report.h b/src/report/report-system/gnc-report.h new file mode 100644 index 0000000000..ef52528008 --- /dev/null +++ b/src/report/report-system/gnc-report.h @@ -0,0 +1,30 @@ +/******************************************************************** + * gnc-report.h -- C functions for reports. * + * * + * Copyright (C) 2001 Linux Developers Group * + * * + * 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 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#ifndef GNC_REPORT_H +#define GNC_REPORT_H + +gboolean gnc_run_report (int report_id, char ** data); +gboolean gnc_run_report_id_string (const char * id_string, char **data); + +#endif