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
This commit is contained in:
Dave Peticolas 2001-09-12 21:03:58 +00:00
parent cc2479bdff
commit 8f2181350b
8 changed files with 268 additions and 100 deletions

View File

@ -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 \

View File

@ -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[] =
"<html><body><h3>Not found</h3><p>The specified URL could not be loaded.</body></html>";
N_("<html><body><h3>Not found</h3><p>The specified URL could not be loaded.</body></html>");
static char error_start[] = "<html><body><h3>Error</h3><p>There was an error loading the specified URL. <p>Error message: <p> ";
static char error_start[] = N_("<html><body><h3>Error</h3><p>There was an error loading the specified URL. <p>Error message: <p> ");
static char error_end[] = "</body></html>";
static char error_report[] =
"<html><body><h3>Report error</h3><p>An error occurred while running the report.</body></html>";
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

View File

@ -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. */

View File

@ -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}

View File

@ -31,7 +31,7 @@
#ifdef GTKHTML_HAVE_GCONF
#include <gconf/gconf.h>
#endif
#include <g-wrap-runtime-guile.h>
#include <X11/Xlib.h>
#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 <g-wrap-runtime-guile.h>
/** 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 (_("<html><body><h3>Report error</h3>"
"<p>An error occurred while running the report.</p>"
"</body></html>"));
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. */

View File

@ -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

View File

@ -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 <glib.h>
#include <guile/gh.h>
#include <string.h>
#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);
}

View File

@ -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