2001-05-10 Bill Gribble <grib@billgribble.com>

* src/gnome/dialog-column-view.c: change handling of component
	reports.  now we explicitly handle the case of the column view,
	which is the only report that needs to save/restore its children.

	* src/gnome/gnc-html-guppi.c: add printing support for graphs.
	Doesn't really work on my system ATM.  I'll follow up on it.

	* src/gnome/window-main.c: move save/restore forms out of gnome
	MDI config string.  rename some functions.

	* src/gnome/window-report.c: save the initial report in a window
	for special treatment.  It's the one that gets saved and restored,
	and whose title appears in the tab.

	* src/scm/*: remove instances of report-add-child and friends.
	The concept is unnecessary.

	* src/scm/main-window.scm: save report and account data to a new
	file named after the book in the directory ~/.gnucash/books.

	* src/scm/options.scm: run option-changed callbacks in the order
	they were added.  Add gnc:options-touch to dirty the options
	without changing anything.

	* src/scm/report.scm: add new optional fields for the
	define-report form: 'options-cleanup-cb and 'options-changed-cb.
	'options-cleanup-cb is called before book save to allow you to
	clean up any mess that you don't want saved.  'options-changed-cb
	is called after any report option is changed.  Both are optional.

	Also get rid of the concept of 'display-lists' for reports and
	let the displays update themselves with callbacks.  Get rid of
	parents and children for the reports.

	* src/scm/report/view-column.scm: revamp to handle options
	processing, saving, and rendering better.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@4160 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-05-10 22:30:45 +00:00
parent 629e1d185b
commit d2aaaf20dc
14 changed files with 388 additions and 351 deletions

View File

@ -1,3 +1,42 @@
2001-05-10 Bill Gribble <grib@billgribble.com>
* src/gnome/dialog-column-view.c: change handling of component
reports. now we explicitly handle the case of the column view,
which is the only report that needs to save/restore its children.
* src/gnome/gnc-html-guppi.c: add printing support for graphs.
Doesn't really work on my system ATM. I'll follow up on it.
* src/gnome/window-main.c: move save/restore forms out of gnome
MDI config string. rename some functions.
* src/gnome/window-report.c: save the initial report in a window
for special treatment. It's the one that gets saved and restored,
and whose title appears in the tab.
* src/scm/*: remove instances of report-add-child and friends.
The concept is unnecessary.
* src/scm/main-window.scm: save report and account data to a new
file named after the book in the directory ~/.gnucash/books.
* src/scm/options.scm: run option-changed callbacks in the order
they were added. Add gnc:options-touch to dirty the options
without changing anything.
* src/scm/report.scm: add new optional fields for the
define-report form: 'options-cleanup-cb and 'options-changed-cb.
'options-cleanup-cb is called before book save to allow you to
clean up any mess that you don't want saved. 'options-changed-cb
is called after any report option is changed. Both are optional.
Also get rid of the concept of 'display-lists' for reports and
let the displays update themselves with callbacks. Get rid of
parents and children for the reports.
* src/scm/report/view-column.scm: revamp to handle options
processing, saving, and rendering better.
2001-05-10 James LewisMoss <jimdres@mindspring.com>
* src/scm/main.scm ((gnc:main)): remove the main window startup

View File

@ -51,6 +51,19 @@ struct gncp_column_view_edit {
int contents_selected;
};
static void
gnc_column_view_set_option(GNCOptionDB * odb, char * section, char * name,
SCM new_value) {
GNCOption * option =
gnc_option_db_get_option_by_name(odb, section, name);
if(option) {
gnc_option_db_set_option(odb, section, name, new_value);
/* set_option doesn't do this */
option->changed = TRUE;
}
}
static void
gnc_column_view_edit_destroy(gnc_column_view_edit * view) {
gnc_options_dialog_destroy(view->optwin);
@ -168,6 +181,7 @@ gnc_column_view_edit_apply_cb(GNCOptionWin * w, gpointer user_data) {
gnc_column_view_edit * win = user_data;
if(!win) return;
printf("calling option_db_commit\n");
gnc_option_db_commit(win->odb);
gh_call2(dirty_report, win->view, SCM_BOOL_T);
}
@ -176,14 +190,6 @@ static void
gnc_column_view_edit_close_cb(GNCOptionWin * win, gpointer user_data) {
gnc_column_view_edit * r = user_data;
SCM set_editor = gh_eval_str("gnc:report-set-editor-widget!");
SCM get_windows = gh_eval_str("gnc:report-display-list");
SCM windows;
for(windows = gh_call1(get_windows, r->view);
!gh_null_p(windows); windows = gh_cdr(windows)) {
gnc_report_window_remove_edited_report(gw_wcp_get_ptr(gh_car(windows)),
r->view);
}
gh_call2(set_editor, r->view, SCM_BOOL_F);
gnc_column_view_edit_destroy(r);
@ -262,31 +268,28 @@ gnc_column_view_edit_options(SCM options, SCM view) {
}
}
void
gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data) {
gnc_column_view_edit * r =
gtk_object_get_data(GTK_OBJECT(user_data), "view_edit_struct");
SCM make_report = gh_eval_str("gnc:make-report");
SCM mark_report = gh_eval_str("gnc:report-set-needs-save?!");
SCM find_report = gh_eval_str("gnc:find-report");
SCM add_child = gh_eval_str("gnc:report-add-child-by-id!");
SCM set_parent = gh_eval_str("gnc:report-set-parent!");
SCM template_name;
SCM set_value = gh_eval_str("gnc:option-set-value");
SCM new_report;
SCM report_obj;
SCM newlist = SCM_EOL;
SCM oldlist = r->contents_list;
int count;
int oldlength;
if(gh_list_p(r->available_list) &&
(gh_length(r->available_list) > r->available_selected)) {
template_name = gh_list_ref(r->available_list,
gh_int2scm(r->available_selected));
new_report = gh_call1(make_report, template_name);
gh_call2(add_child, r->view, new_report);
gh_call2(set_parent, gh_call1(find_report, new_report), r->view);
gh_call2(mark_report, gh_call1(find_report, new_report), SCM_BOOL_T);
oldlength = gh_length(r->contents_list);
if(oldlength > r->contents_selected) {
@ -294,17 +297,19 @@ gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data) {
newlist = gh_cons(gh_car(oldlist), newlist);
oldlist = gh_cdr(oldlist);
}
newlist = gh_append2(gh_reverse(gh_cons(SCM_LIST3(new_report,
newlist = gh_append2(gh_reverse(gh_cons(SCM_LIST4(new_report,
gh_int2scm(1),
gh_int2scm(1)),
gh_int2scm(1),
SCM_BOOL_F),
newlist)),
oldlist);
}
else {
newlist = gh_append2(oldlist,
SCM_LIST1(SCM_LIST3(new_report,
SCM_LIST1(SCM_LIST4(new_report,
gh_int2scm(1),
gh_int2scm(1))));
gh_int2scm(1),
SCM_BOOL_F)));
r->contents_selected = oldlength;
}
@ -312,9 +317,8 @@ gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data) {
r->contents_list = newlist;
scm_protect_object(r->contents_list);
gnc_option_db_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_column_view_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_options_dialog_changed (r->optwin);
}
@ -350,8 +354,8 @@ gnc_column_view_edit_remove_cb(GtkButton * button, gpointer user_data) {
r->contents_list = newlist;
scm_protect_object(r->contents_list);
gnc_option_db_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_column_view_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_options_dialog_changed (r->optwin);
}
@ -386,9 +390,9 @@ gnc_edit_column_view_move_up_cb(GtkButton * button, gpointer user_data) {
r->contents_selected = r->contents_selected - 1;
gnc_option_db_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_column_view_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_options_dialog_changed (r->optwin);
update_display_lists(r);
@ -422,8 +426,8 @@ gnc_edit_column_view_move_down_cb(GtkButton * button, gpointer user_data) {
r->contents_selected = r->contents_selected + 1;
gnc_option_db_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_column_view_set_option(r->odb, "__general", "report-list",
r->contents_list);
gnc_options_dialog_changed (r->optwin);

View File

@ -63,6 +63,15 @@ gnc_html_guppi_shutdown(void) {
guppi_tank_shutdown();
}
static void
gnc_html_guppi_print_cb(GtkHTMLEmbedded * eb, GnomePrintContext * pc,
gpointer data) {
GtkWidget * w = data;
GuppiObject * o = gtk_object_get_user_data(GTK_OBJECT(w));
guppi_object_print(o, pc);
}
/* the handlers for pie. bar, and scatter charts */
static int
handle_piechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer data) {
@ -70,7 +79,13 @@ handle_piechart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer data) {
int retval;
widg = gnc_html_embedded_piechart(html, eb->width, eb->height,
eb->params);
if(widg) {
if(gtk_signal_lookup("draw_print", gtk_html_embedded_get_type())) {
gtk_signal_connect(GTK_OBJECT(eb), "draw_print", gnc_html_guppi_print_cb,
widg);
}
gtk_widget_show_all(widg);
gtk_container_add(GTK_CONTAINER(eb), widg);
gtk_widget_set_usize(GTK_WIDGET(eb), eb->width, eb->height);
@ -89,6 +104,11 @@ handle_barchart(gnc_html * html, GtkHTMLEmbedded * eb, gpointer data) {
widg = gnc_html_embedded_barchart(html, eb->width, eb->height,
eb->params);
if(widg) {
if(gtk_signal_lookup("draw_print", gtk_html_embedded_get_type())) {
gtk_signal_connect(GTK_OBJECT(eb), "draw_print", gnc_html_guppi_print_cb,
widg);
}
gtk_widget_show_all(widg);
gtk_container_add(GTK_CONTAINER(eb), widg);
gtk_widget_set_usize(GTK_WIDGET(eb), eb->width, eb->height);
@ -107,6 +127,11 @@ handle_scatter(gnc_html * html, GtkHTMLEmbedded * eb, gpointer data) {
widg = gnc_html_embedded_scatter(html, eb->width, eb->height,
eb->params);
if(widg) {
if(gtk_signal_lookup("draw_print", gtk_html_embedded_get_type())) {
gtk_signal_connect(GTK_OBJECT(eb), "draw_print", gnc_html_guppi_print_cb,
widg);
}
gtk_widget_show_all(widg);
gtk_container_add(GTK_CONTAINER(eb), widg);
gtk_widget_set_usize(GTK_WIDGET(eb), eb->width, eb->height);
@ -536,8 +561,10 @@ gnc_html_embedded_piechart(gnc_html * parent, int w, int h,
free_strings(labels, datasize);
free_strings(colors, datasize);
if(chart)
if(chart) {
gtk_object_set_user_data(GTK_OBJECT(chart->widget), chart->guppiobject);
return chart->widget;
}
else
return NULL;
}
@ -782,8 +809,10 @@ gnc_html_embedded_barchart(gnc_html * parent,
free_strings(row_labels, datarows);
free_strings(col_colors, datacols);
if(chart)
if(chart) {
gtk_object_set_user_data(GTK_OBJECT(chart->widget), chart->guppiobject);
return chart->widget;
}
else
return NULL;
}
@ -884,8 +913,10 @@ gnc_html_embedded_scatter(gnc_html * parent,
g_free(x_data);
g_free(y_data);
if(chart)
if(chart) {
gtk_object_set_user_data(GTK_OBJECT(chart->widget), chart->guppiobject);
return chart->widget;
}
else
return NULL;
}

View File

@ -658,28 +658,6 @@ gnc_html_url_requested_cb(GtkHTML * html, char * url,
}
#ifdef USE_GUPPI
static void
gnc_html_guppi_print_cb(GtkHTMLEmbedded * eb, GnomePrintContext * pc,
gpointer data) {
GtkWidget * w = data;
GuppiObject * o = gtk_object_get_user_data(GTK_OBJECT(w));
/* this is a magical scaling factor (gtkhtml and guppi assume different
* screen resolutions) */
gnome_print_scale(pc, 0.6944, 0.6944);
guppi_object_print(o, pc);
}
static void
gnc_html_guppi_redraw_cb(GtkHTMLEmbedded * eb,
GdkPixmap * pix, GdkGC * gc, gint x, gint y,
gpointer data) {
/* nothing special to do */
}
#endif /* USE_GUPPI */
/********************************************************************
* gnc_html_object_requested_cb - called when an applet needs to be
* loaded.

View File

@ -174,7 +174,7 @@ gnc_main_window_app_created_cb(GnomeMDI * mdi, GnomeApp * app,
}
static void
gnc_childwin_set_title (GNCMainChildInfo *childwin)
gnc_main_window_child_set_title (GNCMainChildInfo *childwin)
{
GNCBook *book;
const char *filename;
@ -224,7 +224,7 @@ gnc_app_set_title (GnomeApp *app)
childwin = gtk_object_get_user_data (GTK_OBJECT (child));
if (!childwin) return;
gnc_childwin_set_title (childwin);
gnc_main_window_child_set_title (childwin);
}
static void
@ -339,7 +339,7 @@ gnc_main_window_child_changed_cb(GnomeMDI * mdi, GnomeMDIChild * not_used,
}
/* set the window title */
gnc_childwin_set_title (childwin);
gnc_main_window_child_set_title (childwin);
/* install menu hints if relevant */
if(mdi->active_child) {
@ -400,107 +400,44 @@ gnc_main_window_configure_mdi_cb (gpointer data)
* MDI session restore time
********************************************************************/
static void
gfec_create_child_error (const char *error_string)
{
g_warning ("error creating mdi child\n\n%s",
error_string ? error_string : "(null)");
}
GnomeMDIChild *
gnc_main_window_create_child(const gchar * configstring) {
GnomeMDIChild *child;
URLType type;
char * location;
char * label;
char * url;
SCM scm;
if (!configstring)
return NULL;
scm = gfec_eval_string(configstring, gfec_create_child_error);
if (!gh_string_p(scm))
return NULL;
url = gh_scm2newstr(scm, NULL);
if (!url)
return NULL;
type = gnc_html_parse_url(NULL, url, &location, &label);
type = gnc_html_parse_url(NULL, configstring, &location, &label);
g_free(location);
g_free(label);
switch(type) {
case URL_TYPE_REPORT:
child = gnc_report_window_create_child(url);
child = gnc_report_window_create_child(configstring);
break;
case URL_TYPE_ACCTTREE:
child = gnc_acct_tree_window_create_child(url);
child = gnc_acct_tree_window_create_child(configstring);
break;
default:
child = NULL;
}
free (url);
return child;
}
/********************************************************************
* gnc_main_window_child_save_func()
* save a Scheme form that will allow the child to be restored. This
* is called at MDI session save time.
********************************************************************/
static char *
gnc_main_window_child_save_func(GnomeMDIChild * child, gpointer user_data) {
GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child));
SCM save_report = gh_eval_str("gnc:report-generate-restore-forms-complete");
SCM save_acctree = gh_eval_str("gnc:acct-tree-generate-restore-forms");
URLType type;
char * location;
char * label;
type = gnc_html_parse_url(NULL, child->name, &location, &label);
g_free(location);
g_free(label);
switch(type) {
case URL_TYPE_REPORT: {
gnc_report_window * win = mc->user_data;
SCM report = gnc_report_window_get_report(win);
if(report != SCM_BOOL_F) {
return gh_scm2newstr(gh_call1(save_report, report), NULL);
}
else {
return NULL;
}
break;
}
case URL_TYPE_ACCTTREE: {
GNCAcctTreeWin * win = mc->user_data;
SCM options = gnc_acct_tree_window_get_options(win);
int options_id = gnc_acct_tree_window_get_id(win);
if(options != SCM_BOOL_F) {
return gh_scm2newstr(gh_call2(save_acctree, options,
gh_int2scm(options_id)), NULL);
}
else {
return NULL;
}
break;
}
default:
return NULL;
}
return g_strdup(child->name);
}
@ -673,7 +610,7 @@ gnc_main_window_child_refresh(gpointer data) {
/* pesky child_set_name tries to change the window title... set
* it back. */
if((gnc_ui_get_data()->mdi->active_child == child->child) && child->app) {
gnc_childwin_set_title (child);
gnc_main_window_child_set_title (child);
}
}

View File

@ -52,10 +52,19 @@ struct _gnc_report_window {
GNCMainChildInfo * mc;
GtkWidget * container;
SCM scm_report;
SCM name_change_callback_id;
GNCOptionDB * odb; /* used to get callbacks from parameter edit */
/* the report that's currently being shown. For any option change
* we need to rerun the report */
SCM cur_report;
GNCOptionDB * cur_odb;
SCM option_change_cb_id;
/* initial_report is special; it's the one that's saved and
* restored. The name_change_callback only gets called when
* the initial_report name is changed. */
SCM initial_report;
GNCOptionDB * initial_odb;
SCM name_change_cb_id;
SCM edited_reports;
gnc_html * html;
@ -89,9 +98,9 @@ gnc_report_window_view_labeler(GnomeMDIChild * child, GtkWidget * current,
if(rwin) {
report = rwin->user_data;
if(report->scm_report != SCM_BOOL_F) {
if(report->initial_report != SCM_BOOL_F) {
name = gh_scm2newstr(gh_call1(get_name,
report->scm_report),
report->initial_report),
NULL);
}
else {
@ -303,13 +312,13 @@ gnc_report_window_export_button_cb(GtkWidget * w, gpointer data) {
gboolean do_html;
get_export_thunk = gh_eval_str ("gnc:report-export-thunk");
export_thunk = gh_call1 (get_export_thunk, report->scm_report);
export_thunk = gh_call1 (get_export_thunk, report->cur_report);
if (gh_procedure_p (export_thunk))
{
SCM result;
result = gh_call1 (export_thunk, report->scm_report);
result = gh_call1 (export_thunk, report->cur_report);
if (gh_symbol_p (result))
{
@ -336,10 +345,12 @@ gnc_report_window_export_button_cb(GtkWidget * w, gpointer data) {
static int
gnc_report_window_params_cb(GtkWidget * w, gpointer data) {
gnc_report_window * report = data;
SCM window_type = gh_eval_str("<gnc:report-window*>");
SCM start_editor = gh_eval_str("gnc:report-edit-options");
if(report->scm_report != SCM_BOOL_F) {
if(gh_call1(start_editor, report->scm_report) == SCM_BOOL_F) {
SCM window = gw_wcp_assimilate_ptr(report, window_type);
if(report->cur_report != SCM_BOOL_F) {
if(gh_call1(start_editor, report->cur_report) == SCM_BOOL_F) {
gnc_warning_dialog("There are no options for this report.");
}
}
@ -351,8 +362,8 @@ gnc_report_window_reload_button_cb(GtkWidget * w, gpointer data) {
gnc_report_window * report = data;
SCM dirty_report = gh_eval_str("gnc:report-set-dirty?!");
if(report->scm_report != SCM_BOOL_F) {
gh_call2(dirty_report, report->scm_report, SCM_BOOL_T);
if(report->cur_report != SCM_BOOL_F) {
gh_call2(dirty_report, report->cur_report, SCM_BOOL_T);
gnc_html_reload(report->html);
}
return TRUE;
@ -391,6 +402,17 @@ gnc_report_window_reload(gnc_report_window * win) {
gnc_html_reload(win->html);
}
static void
gnc_report_window_option_change_cb(gpointer data) {
gnc_report_window * report = data;
SCM dirty_report = gh_eval_str("gnc:report-set-dirty?!");
if(report->cur_report != SCM_BOOL_F) {
/* it's probably already dirty, but make sure */
gh_call2(dirty_report, report->cur_report, SCM_BOOL_T);
gnc_html_reload(report->html);
}
}
/********************************************************************
* gnc_report_window_load_cb
@ -406,14 +428,12 @@ gnc_report_window_load_cb(gnc_html * html, URLType type,
SCM find_report = gh_eval_str("gnc:find-report");
SCM get_options = gh_eval_str("gnc:report-options");
SCM get_editor = gh_eval_str("gnc:report-options-editor");
SCM show_report = gh_eval_str("gnc:report-register-display");
SCM unshow_report = gh_eval_str("gnc:report-unregister-display");
SCM scm_wintype = gh_eval_str("<gnc:report-window*>");
SCM set_needs_save = gh_eval_str("gnc:report-set-needs-save?!");
SCM inst_report;
SCM inst_options;
SCM inst_options_ed;
if(location && (strlen(location) > 3) &&
if((type == URL_TYPE_REPORT) && location && (strlen(location) > 3) &&
!strncmp("id=", location, 3)) {
sscanf(location+3, "%d", &report_id);
}
@ -428,34 +448,38 @@ gnc_report_window_load_cb(gnc_html * html, URLType type,
return;
}
/* unregister ourselves as a "displayer" of the current report */
if(win->scm_report != SCM_BOOL_F) {
gh_call2(unshow_report, win->scm_report,
gw_wcp_assimilate_ptr(win, scm_wintype));
}
if(win->initial_report == SCM_BOOL_F) {
scm_unprotect_object(win->initial_report);
win->initial_report = inst_report;
scm_protect_object(win->initial_report);
gh_call2(set_needs_save, inst_report, SCM_BOOL_T);
if(win->odb) {
gnc_option_db_unregister_change_callback_id(win->odb,
win->name_change_callback_id);
gnc_option_db_destroy(win->odb);
win->initial_odb = gnc_option_db_new(gh_call1(get_options, inst_report));
win->name_change_cb_id =
gnc_option_db_register_change_callback(win->initial_odb,
gnc_main_window_child_refresh,
win->mc,
"General", "Report name");
}
win->odb = gnc_option_db_new(gh_call1(get_options, inst_report));
win->name_change_callback_id =
gnc_option_db_register_change_callback(win->odb,
gnc_main_window_child_refresh,
win->mc,
"General", "Report name");
scm_unprotect_object(win->scm_report);
win->scm_report = inst_report;
scm_protect_object(win->scm_report);
if(win->scm_report != SCM_BOOL_F) {
gh_call2(show_report, win->scm_report,
gw_wcp_assimilate_ptr(win, scm_wintype));
if((win->cur_report != SCM_BOOL_F) && (win->cur_odb != NULL)) {
gnc_option_db_unregister_change_callback_id(win->cur_odb,
win->option_change_cb_id);
gnc_option_db_destroy(win->cur_odb);
win->cur_odb = NULL;
}
scm_unprotect_object(win->cur_report);
win->cur_report = inst_report;
scm_protect_object(win->cur_report);
win->cur_odb = gnc_option_db_new(gh_call1(get_options, inst_report));
win->option_change_cb_id =
gnc_option_db_register_change_callback(win->cur_odb,
gnc_report_window_option_change_cb,
win, NULL, NULL);
if(gnc_html_history_forward_p(gnc_html_get_history(win->html))) {
gnc_report_window_set_fwd_button(win, TRUE);
}
@ -541,11 +565,13 @@ gnc_report_window_new(GNCMainChildInfo * mc) {
report->mc = mc;
report->html = gnc_html_new();
report->scm_report = SCM_BOOL_F;
report->cur_report = SCM_BOOL_F;
report->initial_report = SCM_BOOL_F;
report->edited_reports = SCM_EOL;
report->name_change_callback_id = SCM_BOOL_F;
report->name_change_cb_id = SCM_BOOL_F;
scm_protect_object(report->scm_report);
scm_protect_object(report->cur_report);
scm_protect_object(report->initial_report);
scm_protect_object(report->edited_reports);
gnc_html_history_set_node_destroy_cb(gnc_html_get_history(report->html),
@ -678,18 +704,11 @@ gnc_report_window_create_menu(gnc_report_window * report,
void
gnc_report_window_destroy(gnc_report_window * win) {
SCM scm_wintype = gh_eval_str("<gnc:report-window*>");
SCM unshow_report = gh_eval_str("gnc:report-unregister-display");
SCM get_editor = gh_eval_str("gnc:report-editor-widget");
SCM set_editor = gh_eval_str("gnc:report-set-editor-widget!");
SCM disp_list;
SCM edited, editor;
if(win->scm_report != SCM_BOOL_F) {
gh_call2(unshow_report, win->scm_report,
gw_wcp_assimilate_ptr(win, scm_wintype));
}
/* close any open editors */
for(edited = scm_list_copy(win->edited_reports); !gh_null_p(edited);
edited = gh_cdr(edited)) {
@ -700,12 +719,12 @@ gnc_report_window_destroy(gnc_report_window * win) {
}
}
if(win->odb) {
gnc_option_db_unregister_change_callback_id(win->odb,
win->name_change_callback_id);
if(win->initial_odb) {
gnc_option_db_unregister_change_callback_id(win->initial_odb,
win->name_change_cb_id);
gnc_option_db_destroy(win->odb);
win->odb = NULL;
gnc_option_db_destroy(win->initial_odb);
win->initial_odb = NULL;
}
gnc_html_destroy(win->html);
@ -713,7 +732,7 @@ gnc_report_window_destroy(gnc_report_window * win) {
win->container = NULL;
win->html = NULL;
scm_unprotect_object(win->scm_report);
scm_unprotect_object(win->cur_report);
scm_unprotect_object(win->edited_reports);
g_free(win);
@ -731,7 +750,7 @@ gnc_report_window_get_container(gnc_report_window * report) {
SCM
gnc_report_window_get_report(gnc_report_window * report) {
return report->scm_report;
return report->cur_report;
}
void
@ -776,7 +795,7 @@ struct report_default_params_data {
GNCOptionWin * win;
GNCOptionDB * db;
SCM scm_options;
SCM scm_report;
SCM cur_report;
};
@ -788,7 +807,7 @@ gnc_options_dialog_apply_cb(GNCOptionWin * propertybox,
if(!win) return;
gnc_option_db_commit(win->db);
gh_call2(dirty_report, win->scm_report, SCM_BOOL_T);
gh_call2(dirty_report, win->cur_report, SCM_BOOL_T);
}
static void
@ -802,16 +821,8 @@ gnc_options_dialog_close_cb(GNCOptionWin * propertybox,
gpointer user_data) {
struct report_default_params_data * win = user_data;
SCM set_editor = gh_eval_str("gnc:report-set-editor-widget!");
SCM get_windows = gh_eval_str("gnc:report-display-list");
SCM windows;
for(windows = gh_call1(get_windows, win->scm_report);
!gh_null_p(windows); windows = gh_cdr(windows)) {
gnc_report_window_remove_edited_report(gw_wcp_get_ptr(gh_car(windows)),
win->scm_report);
}
gh_call2(set_editor, win->scm_report, SCM_BOOL_F);
gh_call2(set_editor, win->cur_report, SCM_BOOL_F);
gnc_option_db_destroy(win->db);
scm_unprotect_object(win->scm_options);
gnc_options_dialog_destroy(win->win);
@ -823,7 +834,6 @@ GtkWidget *
gnc_report_window_default_params_editor(SCM options, SCM report) {
SCM get_editor = gh_eval_str("gnc:report-editor-widget");
SCM set_editor = gh_eval_str("gnc:report-set-editor-widget!");
SCM ptr_type = gh_eval_str("<gnc:UIWidget>");
SCM ptr;
SCM new_edited;
@ -838,12 +848,12 @@ gnc_report_window_default_params_editor(SCM options, SCM report) {
g_new0(struct report_default_params_data, 1);
prm->scm_options = options;
prm->scm_report = report;
prm->cur_report = report;
prm->db = gnc_option_db_new(prm->scm_options);
prm->win = gnc_options_dialog_new(TRUE);
scm_protect_object(prm->scm_options);
scm_protect_object(prm->scm_report);
scm_protect_object(prm->cur_report);
gnc_build_options_dialog_contents(prm->win, prm->db);
gnc_option_db_clean(prm->db);

View File

@ -73,8 +73,6 @@
" No such option: " (car l) (cadr l)))))
optionlist)
(let ((id (gnc:make-report reportname options)))
(gnc:report-add-child-by-id! src-report id)
(gnc:report-set-parent! (gnc:find-report id) src-report)
(gnc:report-anchor-text id)))
(warn "gnc:make-report-anchor: No such report: " reportname))))

View File

@ -110,17 +110,72 @@ the account instead of opening a register.") #f))
(simple-format
#f " \"gnc-acct-tree:id=~S\")" id)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; book open and close hooks for mdi
;;
;; we need to save all the active report and acct tree info during
;; book close.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (gnc:main-window-book-close-handler book-url)
(gnc:main-window-save (gnc:get-ui-data) book-url))
(let* ((conf-file-name (gnc:html-encode-string book-url))
(file-dir (build-path (getenv "HOME") ".gnucash" "books"))
(book-path #f))
;; make sure the books directory is there
(if (not (access? file-dir X_OK)) (mkdir file-dir #o700))
(if conf-file-name
(let ((book-path (build-path (getenv "HOME") ".gnucash" "books"
conf-file-name)))
(with-output-to-port (open-output-file book-path)
(lambda ()
(hash-fold
(lambda (k v p)
(if (gnc:report-needs-save? v)
(display
(gnc:report-generate-restore-forms v))))
#t *gnc:_reports_*)
(hash-fold
(lambda (k v p)
(display (gnc:acct-tree-generate-restore-forms v k)) #t)
#t gnc:*acct-tree-options*)))))
(gnc:main-window-save (gnc:get-ui-data) book-url)
(let ((dead-reports '()))
;; get a list of the reports we'll be needing to nuke
(hash-fold
(lambda (k v p)
(set! dead-reports (cons k dead-reports)) #t) #t *gnc:_reports_*)
;; actually remove them (if they're being displayed, the
;; window's reference will keep the report alive until the
;; window is destroyed, but find-report will fail)
(for-each
(lambda (dr)
(hash-remove! *gnc:_reports_* dr))
dead-reports))))
(define (gnc:main-window-book-open-handler book-url)
(gnc:main-window-restore (gnc:get-ui-data) book-url))
(define (try-load file-suffix)
(let ((file (build-path (getenv "HOME") ".gnucash" "books" file-suffix)))
;; make sure the books directory is there
(if (access? file F_OK)
(if (not (false-if-exception (primitive-load file)))
(begin
(gnc:warn "failure loading " file)
#f))
#f)))
(let ((conf-file-name (gnc:html-encode-string book-url))
(dead-reports '()))
(if conf-file-name
(begin
(try-load conf-file-name)
(gnc:main-window-restore (gnc:get-ui-data) book-url)))))
(gnc:hook-add-dangler gnc:*book-opened-hook*
gnc:main-window-book-open-handler)
(gnc:hook-add-dangler gnc:*book-closed-hook*
gnc:main-window-book-close-handler)

View File

@ -930,11 +930,24 @@
(callback))))))))
(if options-changed
(hash-for-each run-callback callback-hash))
(let ((cblist '()))
(hash-for-each
(lambda (k v) (set! cblist (cons (cons k v) cblist)))
callback-hash)
(set! cblist (sort cblist
(lambda (a b)
(< (car a) (car b)))))
(for-each
(lambda (elt) (run-callback (car elt) (cdr elt)))
cblist)))
(clear-changes))
(define default-section #f)
(define (touch)
(set! options-changed #t)
(run-callbacks))
(define (set-default-section section-name)
(set! default-section section-name))
@ -950,6 +963,7 @@
((for-each) options-for-each)
((for-each-general) options-for-each-general)
((generate-restore-forms) generate-restore-forms)
((touch) touch)
((clear-changes) clear-changes)
((run-callbacks) run-callbacks)
((set-default-section) set-default-section)
@ -986,6 +1000,9 @@
(define (gnc:options-clear-changes options)
((options 'clear-changes)))
(define (gnc:options-touch options)
((options 'touch)))
(define (gnc:options-run-callbacks options)
((options 'run-callbacks)))

View File

@ -129,7 +129,9 @@
(define <report-template>
(make-record-type "<report-template>"
;; The data items in a report record
'(version name options-generator options-editor
'(version name
options-generator options-editor
options-cleanup-cb options-changed-cb
renderer in-menu? menu-path menu-name
menu-tip export-thunk)))
@ -147,6 +149,8 @@
#f ;; name
#f ;; options-generator
gnc:default-options-editor ;; options-editor
#f ;; options-cleanup-cb
#f ;; options-changed-cb
#f ;; renderer
#t ;; in-menu?
#f ;; menu-path
@ -182,6 +186,10 @@
(record-accessor <report-template> 'options-generator))
(define gnc:report-template-options-editor
(record-accessor <report-template> 'options-editor))
(define gnc:report-template-options-cleanup-cb
(record-accessor <report-template> 'options-cleanup-cb))
(define gnc:report-template-options-changed-cb
(record-accessor <report-template> 'options-changed-cb))
(define gnc:report-template-renderer
(record-accessor <report-template> 'renderer))
(define gnc:report-template-in-menu?
@ -234,8 +242,7 @@
(define <report>
(make-record-type "<report>"
'(type id options parent children
dirty? display-list editor-widget ctext)))
'(type id options dirty? needs-save? editor-widget ctext)))
(define gnc:report-type
(record-accessor <report> 'type))
@ -255,55 +262,18 @@
(define gnc:report-set-options!
(record-modifier <report> 'options))
(define gnc:report-children
(record-accessor <report> 'children))
(define gnc:report-needs-save?
(record-accessor <report> 'needs-save?))
(define gnc:report-set-parent-by-id!
(record-modifier <report> 'parent))
(define (gnc:report-set-parent! report parent)
(gnc:report-set-parent-by-id! report (gnc:report-id parent)))
(define gnc:report-parent
(record-accessor <report> 'parent))
(define gnc:report-set-children!
(record-modifier <report> 'children))
(define (gnc:report-add-child! report child)
(gnc:report-set-children!
report (cons (gnc:report-id child) (gnc:report-children report))))
(define (gnc:report-add-child-by-id! report child)
(gnc:report-set-children!
report (cons child (gnc:report-children report))))
(define gnc:report-set-needs-save?!
(record-modifier <report> 'needs-save?))
(define gnc:report-dirty?
(record-accessor <report> 'dirty?))
(define gnc:report-set-dirty?-internal!
(define gnc:report-set-dirty?!
(record-modifier <report> 'dirty?))
(define (gnc:report-set-dirty?! report val)
(gnc:report-set-dirty?-internal! report val)
(if val
(begin
(if (gnc:report-parent report)
(gnc:report-set-dirty?!
(gnc:find-report (gnc:report-parent report)) val))
;; reload the window
(for-each
(lambda (win)
(gnc:report-window-reload win))
(gnc:report-display-list report)))))
(define gnc:report-display-list
(record-accessor <report> 'display-list))
(define gnc:report-set-display-list!
(record-modifier <report> 'display-list))
(define gnc:report-editor-widget
(record-accessor <report> 'editor-widget))
@ -316,40 +286,8 @@
(define gnc:report-set-ctext!
(record-modifier <report> 'ctext))
(define (gnc:report-register-display report window)
(if (and window report
(not (member window (gnc:report-display-list report))))
(begin
(gnc:report-set-display-list!
report
(cons window (gnc:report-display-list report)))
(for-each
(lambda (rep)
(gnc:report-register-display (gnc:find-report rep) window))
(gnc:report-children report))
(let ((parent (gnc:find-report (gnc:report-parent report))))
(if parent
(gnc:report-register-display parent window))))))
(define (gnc:report-unregister-display report window)
(if (and report window
(member window (gnc:report-display-list report)))
(begin
(gnc:report-set-display-list!
report
(delete window (gnc:report-display-list report)))
(for-each
(lambda (rep)
(gnc:report-unregister-display (gnc:find-report rep) window))
(gnc:report-children report))
(let ((parent (gnc:find-report (gnc:report-parent report))))
(if parent
(gnc:report-unregister-display parent window))))))
(define (gnc:report-edit-options report)
(let* ((editor-widg (gnc:report-editor-widget report))
(displist (gnc:report-display-list report)))
(let* ((editor-widg (gnc:report-editor-widget report)))
(if editor-widg
(gnc:report-raise-editor report)
(begin
@ -359,24 +297,16 @@
((gnc:report-options-editor report)
(gnc:report-options report)
report))
(gnc:report-set-editor-widget! report editor-widg)
(if (and editor-widg (not (null? displist)))
(for-each
(lambda (repwin)
(gnc:report-window-add-edited-report repwin report))
displist)))
(gnc:report-set-editor-widget! report editor-widg))
(gnc:warning-dialog "This report has no options."))))))
(define (gnc:make-report template-name . rest)
(let ((r ((record-constructor <report>)
template-name ;; type
#f ;; id
#f ;; options
#f ;; parent
'() ;; children
#t ;; dirty
'() ;; display-list
#f ;; needs-save
#f ;; editor-widget
#f ;; ctext
))
@ -388,14 +318,22 @@
(if (not (null? rest))
(car rest)
(gnc:report-template-new-options template))))
(gnc:report-set-options! r options))
(gnc:report-set-options! r options)
(gnc:options-register-callback
#f #f
(lambda ()
(gnc:report-set-dirty?! r #t)
(let ((cb (gnc:report-template-options-changed-cb template)))
(if cb
(cb r))))
options))
(hash-set! *gnc:_reports_* (gnc:report-id r) r)
id))
(define (gnc:restore-report id template-name parent children options)
(define (gnc:restore-report id template-name options)
(let ((r ((record-constructor <report>)
template-name id options parent children #t '() #f #f)))
template-name id options #t #t #f #f)))
(if (>= id *gnc:_report-next-serial_*)
(set! *gnc:_report-next-serial_* (+ id 1)))
(hash-set! *gnc:_reports_* id r)))
@ -464,34 +402,17 @@
(define (gnc:find-report id)
(hash-ref *gnc:_reports_* id))
(define (gnc:report-generate-restore-forms-complete report)
(define (find-root r)
(let* ((pid (gnc:report-parent r))
(p (if pid (gnc:find-report pid) #f)))
(if (not p) r (find-root p))))
(define (generate-forms/children r)
(apply
string-append
(gnc:report-generate-restore-forms r)
(map
(lambda (c)
(let ((child (gnc:find-report c)))
(generate-forms/children child)))
(gnc:report-children r))))
(let ((toplevel (find-root report)))
(string-append
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
(simple-format #f ";; options for report ~A and all parents/children \n"
(gnc:report-name report))
"(let () \n"
(generate-forms/children toplevel)
(simple-format
#f " \"gnc-report:id=~S\"" (gnc:report-id report))
")\n")))
(define (gnc:report-generate-restore-forms report)
;; clean up the options if necessary. this is only needed
;; in special cases.
(let* ((template
(hash-ref *gnc:_report-templates_*
(gnc:report-type report)))
(thunk (gnc:report-template-options-cleanup-cb template)))
(if thunk
(thunk report)))
;; save them
(string-append
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
(simple-format #f ";; options for report ~S\n" (gnc:report-name report))
@ -500,10 +421,8 @@
(gnc:report-type report))
(gnc:generate-restore-forms (gnc:report-options report) "options")
(simple-format
#f " (gnc:restore-report ~S ~S ~S '~S options))\n"
(gnc:report-id report) (gnc:report-type report)
(gnc:report-parent report)
(gnc:report-children report))))
#f " (gnc:restore-report ~S ~S options))\n"
(gnc:report-id report) (gnc:report-type report))))
(define (gnc:backtrace-if-exception proc . args)
(define (dumper key . args)
@ -553,9 +472,9 @@
(if report
(begin
(set! html (gnc:report-render-html report #t))
(display "total time to run report: ")
(display (gnc:time-elapsed start-time (gettimeofday)))
(newline)
;; (display "total time to run report: ")
;; (display (gnc:time-elapsed start-time (gettimeofday)))
;; (newline)
;; (display html) (newline)
html)
#f)))))

View File

@ -281,9 +281,6 @@ balance at a given time"))
optname-accounts)
(map cadr finish))
(set! id (gnc:make-report reportname options))
(gnc:report-add-child-by-id! report-obj id)
(gnc:report-set-parent! (gnc:find-report id) report-obj)
;; set the URL.
(set! other-anchor (gnc:report-anchor-text id)))))

View File

@ -367,8 +367,6 @@ developing over time"))
(map car finish))
;; Set the URL to point to this report.
(set! id (gnc:make-report reportname options))
(gnc:report-add-child-by-id! report-obj id)
(gnc:report-set-parent! (gnc:find-report id) report-obj)
(set! other-anchor (gnc:report-anchor-text id)))))

View File

@ -51,12 +51,23 @@
(define (edit-options option-obj report-obj)
(gnc:column-view-edit-options option-obj report-obj))
(define (make-child-options-callback view child)
(let* ((view-opts (gnc:report-options view))
(child-opts (gnc:report-options child))
(id
(gnc:options-register-callback
#f #f
(lambda ()
(gnc:report-set-dirty?! child #t)
(gnc:options-touch view-opts))
child-opts)))
id))
(define (render-view report)
(let* ((view-doc (gnc:make-html-document))
(options (gnc:report-options report))
(reports
(gnc:option-value
(gnc:lookup-option options "__general" "report-list")))
(report-opt (gnc:lookup-option options "__general" "report-list"))
(reports (gnc:option-value report-opt))
(table-width
(gnc:option-value
(gnc:lookup-option
@ -67,6 +78,26 @@
(current-width 0)
(current-row-num 0))
;; make sure each subreport has an option change callback that
;; pings the parent
(let ((new-reports '()))
(for-each
(lambda (report-info)
(let ((child (car report-info))
(rowspan (cadr report-info))
(colspan (caddr report-info))
(callback (cadddr report-info)))
(if (not callback)
(begin
(set! callback
(make-child-options-callback
report (gnc:find-report child)))
(set! report-info
(list child rowspan colspan callback))))
(set! new-reports (cons report-info new-reports))))
reports)
(gnc:option-set-value report-opt (reverse new-reports)))
;; we really would rather do something smart here with the
;; report's cached text if possible. For the moment, we'll have
;; to rerun every report, every time... FIXME
@ -82,6 +113,7 @@
(let* ((subreport (gnc:find-report (car report-info)))
(colspan (cadr report-info))
(rowspan (caddr report-info))
(opt-callback (cadddr report-info))
(toplevel-cell (gnc:make-html-table-cell/size rowspan colspan))
(report-table (gnc:make-html-table))
(contents-cell (gnc:make-html-table-cell)))
@ -153,11 +185,41 @@
(gnc:html-document-add-object! view-doc column-tab)
;; and we're done.
view-doc))
(define (options-changed-cb report)
(let* ((options (gnc:report-options report))
(reports
(gnc:option-value
(gnc:lookup-option options "__general" "report-list"))))
(simple-format #t "view options changed cb\n")
(for-each
(lambda (child)
(gnc:report-set-dirty?! (gnc:find-report (car child)) #t))
reports)))
(define (cleanup-options report)
(let* ((options (gnc:report-options report))
(report-opt (gnc:lookup-option options "__general" "report-list"))
(reports (gnc:option-value report-opt))
(new-reports '()))
(for-each
(lambda (report-info)
(let ((rep (car report-info))
(rowspan (cadr report-info))
(colspan (caddr report-info)))
(set! report-info
(list rep rowspan colspan #f))
(set! new-reports (cons report-info new-reports))))
reports)
(gnc:option-set-value report-opt (reverse new-reports))))
;; define the view now.
(gnc:define-report
'version 1
'name (N_ "Multicolumn View")
'renderer render-view
'options-generator make-options
'options-editor edit-options))
'options-editor edit-options
'options-cleanup-cb cleanup-options
'options-changed-cb options-changed-cb))

View File

@ -36,23 +36,15 @@
(gnc:option-set-value
(gnc:lookup-option options section name) value))
(for-each
(lambda (child)
(gnc:report-add-child! (gnc:find-report view)
(gnc:find-report child))
(gnc:report-set-parent! (gnc:find-report child)
(gnc:find-report view)))
(list sub-welcome sub-accounts sub-expense-pie sub-income-pie sub-bar))
(set! options (gnc:report-options (gnc:find-report view)))
(set-option! "General" "Report name" "Welcome to GnuCash 1.6")
(set-option! "General" "Number of columns" 2)
(set-option! "__general" "report-list"
(list (list sub-welcome 1 1)
(list sub-accounts 1 1)
(list sub-expense-pie 1 1)
(list sub-income-pie 1 1)
(list sub-bar 2 1)))
(list (list sub-welcome 1 1 #f)
(list sub-accounts 1 1 #f)
(list sub-expense-pie 1 1 #f)
(list sub-income-pie 1 1 #f)
(list sub-bar 2 1 #f)))
(set! options (gnc:report-options (gnc:find-report sub-expense-pie)))
(set-option! "Display" "Plot Width" 400)