Implement new custom report dialog.

Implements a new interface for accessing "saved" or "custom" reports.
Specifically, the current sub-menu is replaced with a dialog holding a
GtkTreeView of the saved reports. From here the user can either run or
delete an existing saved report.

* allows deletion of existing saved reports
* allows immediate access to new saved reports from this session (no
  need to restart gnucash to get access to new saved reports!)
* keeps a single rolling backup of saved reports in case of errors


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18001 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Andrew Sackville-West 2009-03-26 19:38:38 +00:00
parent 908813cf34
commit 07467f13c6
8 changed files with 658 additions and 14 deletions

View File

@ -22,6 +22,7 @@ AM_CPPFLAGS = \
libgncmod_report_gnome_la_SOURCES = \ libgncmod_report_gnome_la_SOURCES = \
swig-report-gnome.c \ swig-report-gnome.c \
dialog-column-view.c \ dialog-column-view.c \
dialog-custom-report.c \
dialog-style-sheet.c \ dialog-style-sheet.c \
gnc-plugin-page-report.c \ gnc-plugin-page-report.c \
gncmod-report-gnome.c \ gncmod-report-gnome.c \
@ -30,6 +31,7 @@ libgncmod_report_gnome_la_SOURCES = \
gncincludedir = ${GNC_INCLUDE_DIR} gncincludedir = ${GNC_INCLUDE_DIR}
gncinclude_HEADERS = \ gncinclude_HEADERS = \
dialog-column-view.h \ dialog-column-view.h \
dialog-custom-report.h \
dialog-style-sheet.h \ dialog-style-sheet.h \
gnc-plugin-page-report.h \ gnc-plugin-page-report.h \
window-report.h window-report.h
@ -61,7 +63,9 @@ gncmod_DATA = report-gnome.scm
noinst_DATA = .scm-links noinst_DATA = .scm-links
gladedir = $(GNC_GLADE_DIR) gladedir = $(GNC_GLADE_DIR)
glade_DATA = report.glade glade_DATA = \
report.glade \
custom-report-dialog.glade
uidir = $(GNC_UI_DIR) uidir = $(GNC_UI_DIR)

View File

@ -0,0 +1,183 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="custom_report_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">False</property>
<signal name="close" handler="custom_report_dialog_close_cb"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="delete_custom_report">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Delete the currently selected report</property>
<property name="can_focus">True</property>
<property name="label">gtk-delete</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_delete_custom_report_clicked"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="cancel_custom_report">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Exit the custom report dialog</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="cancel_custom_report_clicked_cb"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="run_custom_report">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Run the currently selected report</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="run_custom_report_clicked_cb"/>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-forward</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Run</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="height_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="custom_report_list_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal name="row_activated" handler="on_custom_report_list_view_row_activated"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -0,0 +1,359 @@
/********************************************************************\
* dialog-custom-report.h -- dialog for managing custom reports *
* *
* *
* Copyright (C) 2009 *
* *
* Andrew Sackville-West *
* (andrew@swclan.homelinux.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@gnu.org *
\********************************************************************/
#include "config.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <libguile.h>
#include "swig-runtime.h"
#include "dialog-custom-report.h"
#include "dialog-options.h"
#include "dialog-utils.h"
#include "gnc-main-window.h"
#include "option-util.h"
#include "window-report.h"
#include "guile-mappings.h"
#include "gnc-gui-query.h"
#include "gnc-ui.h"
#include "gnc-report.h"
#include "gnc-plugin-page-report.h"
/* convenience for accessing columns in the GtkListStore that holds
the reports */
enum
{
COL_NAME = 0,
COL_NUM,
NUM_COLS
};
/* all the pertinent stuff needed to pass around */
typedef struct _CustomReportDialog
{
/* dialog */
GtkWidget *dialog;
GtkWidget *reportview;
GncMainWindow *window;
/* data */
SCM reportlist;
} CustomReportDialog;
static void
custom_report_dialog_close_cb(GtkWidget* widget,
CustomReportDialog *crd)
{
gtk_widget_destroy(crd->dialog);
g_free(crd);
}
static void
cancel_custom_report_clicked_cb(GtkWidget* widget,
CustomReportDialog *crd)
{
custom_report_dialog_close_cb(NULL, crd);
}
/**
* update_report_list
*
* this procedure does the real work of displaying a sorted list of
* available custom reports
*
*/
static void
update_report_list(GtkListStore *store, CustomReportDialog *crd)
{
SCM get_names = scm_c_eval_string("gnc:custom-report-template-names");
SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid");
SCM names;
const gchar *name;
int i;
GtkTreeIter iter;
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), COL_NAME, GTK_SORT_ASCENDING);
crd->reportlist = scm_call_0(get_names);
names = crd->reportlist;
gtk_list_store_clear(store);
if(SCM_LISTP(names)) {
/* for all the names in the list, store them, with a reference,
in the gtkliststore */
for (i=0; !SCM_NULLP(names); i++) {
name = SCM_STRING_CHARS(scm_call_2(template_menu_name, SCM_CAR(names), SCM_BOOL_F));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
COL_NAME, name,
COL_NUM, i,
-1);
names = SCM_CDR(names);
}
}
}
static GtkTreeModel *
create_and_fill_report_list(CustomReportDialog *crd)
{
GtkListStore *store;
GtkTreeIter iter;
store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_INT);
update_report_list(store, crd);
return GTK_TREE_MODEL (store);
}
static void
set_reports_model(CustomReportDialog *crd)
{
GtkCellRenderer *renderer;
GtkTreeModel *model;
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1, "Report Name", renderer, "text", COL_NAME, NULL);
model = create_and_fill_report_list(crd);
gtk_tree_view_set_model (GTK_TREE_VIEW (crd->reportview), model);
g_object_unref(model);
}
/**
*
* custom_report_run_report
*
* this procedure sets up and calls the report on the scheme
* side. This is what makes the report actually run.
*/
static void
custom_report_run_report(SCM guid,
CustomReportDialog *crd)
{
SCM make_report = scm_c_eval_string("gnc:make-report");
int report_id;
GncMainWindow *window = crd->window;
if(!SCM_NULLP(guid))
{
/* this runs the report */
report_id = SCM_INUM(scm_call_1(make_report, guid));
/* do this *before* the report because sometimes the report
takes a while... */
custom_report_dialog_close_cb(NULL, crd);
/* display the report */
gnc_main_window_open_report(report_id, window);
}
}
/**
* get_custom_report_selection
*
* this helper function is called to get the selection when the user
* clicks on "Run" or "Delete". Includes calling a dialog when there
* is no selection.
*
* const gchar* message -- the message to provide user if there is no
* actual selection found.
*
*/
static SCM
get_custom_report_selection(CustomReportDialog *crd,
const gchar* message)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
SCM guid;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(crd->reportview));
if (gtk_tree_selection_get_selected(sel, &model, &iter))
{
int num;
gtk_tree_model_get(model, &iter, COL_NUM, &num, -1);
guid = scm_list_ref(crd->reportlist, scm_int2num(num));
}
else
{
/* no selection, notify user */
gnc_error_dialog(GTK_WIDGET(crd->window), "%s", message);
return SCM_EOL;
}
return guid;
}
/**
* on_custom_report_list_view_row_activated
*
* this is the double-click signal. No need to call
* get_custom_report_selection as the double-click implies the
* selection.
*
*/
static void
on_custom_report_list_view_row_activated(GtkTreeView *view,
GtkTreePath *path,
GtkTreeViewColumn *column,
CustomReportDialog *crd)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model(view);
if(gtk_tree_model_get_iter(model, &iter, path))
{
int num;
SCM guid;
gtk_tree_model_get(model, &iter, COL_NUM, &num, -1);
guid = scm_list_ref(crd->reportlist, scm_int2num(num));
custom_report_run_report(guid, crd);
}
}
/**
* on_delete_custom_report_clicked
*
* this will delete the report, update the reports list and leave the
* dialog active for additional usage.
*
*/
static void
on_delete_custom_report_clicked(GtkWidget *button,
CustomReportDialog *crd)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid");
SCM guid;
gchar* report_name;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(crd->reportview));
guid = get_custom_report_selection(crd, _("You must select a report to delete."));
report_name = SCM_STRING_CHARS(scm_call_2(template_menu_name, guid, SCM_BOOL_F));
/* we must confirm the user wants to delete their precious custom report! */
if (!SCM_NULLP(guid)
&& gnc_verify_dialog(crd->dialog, FALSE, "Are you sure you want to delete %s?", report_name))
{
SCM del_report = scm_c_eval_string("gnc:delete-report");
scm_call_1(del_report, guid);
update_report_list(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(crd->reportview)))
, crd);
}
}
static void
run_custom_report_clicked_cb (GtkWidget* button,
CustomReportDialog *crd)
{
SCM guid = get_custom_report_selection(crd, _("You must select a report to run."));
custom_report_run_report(guid, crd);
}
/**
* gnc_ui_custom_report
*
* this is the primary driver for the custom report dialog.
*
*/
void gnc_ui_custom_report(GncMainWindow * window)
{
GladeXML* xml;
CustomReportDialog *crd;
crd = g_new0(CustomReportDialog, 1);
xml = gnc_glade_xml_new("custom-report-dialog.glade", "custom_report_dialog");
crd->dialog = glade_xml_get_widget(xml, "custom_report_dialog");
crd->reportview = glade_xml_get_widget(xml, "custom_report_list_view");
set_reports_model(crd);
crd->window = window;
/* connect the signals */
glade_xml_signal_connect_data(xml, "cancel_custom_report_clicked_cb", G_CALLBACK(cancel_custom_report_clicked_cb), crd);
glade_xml_signal_connect_data(xml, "custom_report_dialog_close_cb", G_CALLBACK(custom_report_dialog_close_cb), crd);
glade_xml_signal_connect_data(xml, "on_custom_report_list_view_row_activated", G_CALLBACK(on_custom_report_list_view_row_activated), crd);
glade_xml_signal_connect_data(xml, "on_delete_custom_report_clicked", G_CALLBACK(on_delete_custom_report_clicked), crd);
glade_xml_signal_connect_data(xml, "run_custom_report_clicked_cb", G_CALLBACK(run_custom_report_clicked_cb), crd);
gtk_widget_show_all(crd->dialog);
}

View File

@ -0,0 +1,50 @@
/********************************************************************\
* dialog-custom-report.h -- dialog for managing custom reports *
* *
* *
* Copyright (C) 2009 *
* *
* Andrew Sackville-West *
* (andrew@swclan.homelinux.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@gnu.org *
\********************************************************************/
#ifndef DIALOG_CUSTOM_REPORT_H
#define DIALOG_CUSTOM_REPORT_H
#include "gnc-main-window.h"
/** @addtogroup Reports
@{ */
/** @file dialog-custom-report.h
*
* This file contains the functions to present a GUI to manage custom
* reports
*/
void
gnc_ui_custom_report(GncMainWindow * window);
/** @} */
#endif /* DIALOG_CUSTOM_REPORT_H */

View File

@ -6,6 +6,7 @@
#include <dialog-column-view.h> #include <dialog-column-view.h>
#include <gnc-plugin-page-report.h> #include <gnc-plugin-page-report.h>
#include <window-report.h> #include <window-report.h>
#include <dialog-custom-report.h>
SCM scm_init_sw_report_gnome_module (void); SCM scm_init_sw_report_gnome_module (void);
%} %}
@ -17,3 +18,5 @@ void gnc_main_window_open_report(int report_id, GncMainWindow *window);
GtkWidget * gnc_report_window_default_params_editor(SCM options, SCM report); GtkWidget * gnc_report_window_default_params_editor(SCM options, SCM report);
GtkWidget * gnc_column_view_edit_options(SCM options, SCM view); GtkWidget * gnc_column_view_edit_options(SCM options, SCM view);
void gnc_ui_custom_report(GncMainWindow * window);

View File

@ -96,6 +96,7 @@
(add-template-menu-item (car item) (cdr item))) (add-template-menu-item (car item) (cdr item)))
(sort *template-items* sort-templates))) (sort *template-items* sort-templates)))
(define (gnc:report-menu-setup) (define (gnc:report-menu-setup)
(define asset-liability-menu (define asset-liability-menu
(gnc:make-menu gnc:menuname-asset-liability (list gnc:menuname-reports))) (gnc:make-menu gnc:menuname-asset-liability (list gnc:menuname-reports)))
@ -105,17 +106,22 @@
(gnc:make-menu gnc:menuname-budget (list gnc:menuname-reports))) (gnc:make-menu gnc:menuname-budget (list gnc:menuname-reports)))
(define utility-menu (define utility-menu
(gnc:make-menu gnc:menuname-utility (list gnc:menuname-reports))) (gnc:make-menu gnc:menuname-utility (list gnc:menuname-reports)))
(define custom-menu
(gnc:make-menu gnc:menuname-custom (list gnc:menuname-reports)))
(define tax-menu (define tax-menu
(gnc:make-menu gnc:menuname-taxes (list gnc:menuname-reports))) (gnc:make-menu gnc:menuname-taxes (list gnc:menuname-reports)))
(gnc-add-scm-extension
(gnc:make-menu-item
(N_ "Custom Reports")
(N_ "Manage and run custom reports")
(list gnc:menuname-reports)
(lambda (window)
(gnc:spawn-custom-report-dialog window))))
;; (gnc-add-scm-extension tax-menu) ;; (gnc-add-scm-extension tax-menu)
(gnc-add-scm-extension income-expense-menu) (gnc-add-scm-extension income-expense-menu)
(gnc-add-scm-extension asset-liability-menu) (gnc-add-scm-extension asset-liability-menu)
(gnc-add-scm-extension budget-menu) (gnc-add-scm-extension budget-menu)
(gnc-add-scm-extension utility-menu) (gnc-add-scm-extension utility-menu)
(gnc-add-scm-extension custom-menu)
;; run report-hook danglers ;; run report-hook danglers
(gnc:hook-run-danglers HOOK-REPORT) (gnc:hook-run-danglers HOOK-REPORT)
@ -131,4 +137,9 @@
(list gnc:menuname-reports gnc:menuname-utility "") (list gnc:menuname-reports gnc:menuname-utility "")
(lambda (window) (lambda (window)
(gnc-main-window-open-report (gnc:make-welcome-report) window)))) (gnc-main-window-open-report (gnc:make-welcome-report) window))))
) )
(define (gnc:spawn-custom-report-dialog window)
(gnc:debug "called into custom report dialog, window is " window)
(gnc-ui-custom-report window))

View File

@ -155,6 +155,8 @@
(export gnc:report-stylesheet) (export gnc:report-stylesheet)
(export gnc:report-set-stylesheet!) (export gnc:report-set-stylesheet!)
(export gnc:all-report-template-names) (export gnc:all-report-template-names)
(export gnc:custom-report-template-names)
(export gnc:delete-report)
(export gnc:find-report-template) (export gnc:find-report-template)
(export gnc:report-generate-restore-forms) (export gnc:report-generate-restore-forms)
(export gnc:report-generate-saved-forms) (export gnc:report-generate-saved-forms)

View File

@ -455,6 +455,20 @@
'() *gnc:_report-templates_*) '() *gnc:_report-templates_*)
string<?)) string<?))
;; return a list of the custom report template "names" (really a list
;; of report-guids).
(define (gnc:custom-report-template-names)
(sort
(hash-fold
(lambda (k v p)
(if (gnc:report-template-parent-type v)
(begin
(gnc:debug "template " v)
(cons k p))
p))
'() *gnc:_report-templates_*)
string<?))
(define (gnc:find-report-template report-type) (define (gnc:find-report-template report-type)
(hash-ref *gnc:_report-templates_* report-type)) (hash-ref *gnc:_report-templates_* report-type))
@ -570,7 +584,7 @@
(gnc-info-dialog (gnc-info-dialog
'() '()
(sprintf (sprintf
#f (_ "Your report \"%s\" has been saved into the configuration file \"%s\". The report will be available in the menu Reports -> Custom at the next startup of GnuCash.") #f (_ "Your report \"%s\" has been saved into the configuration file \"%s\".")
(if (and report-name (not (string-null? report-name))) (if (and report-name (not (string-null? report-name)))
(gnc:gettext report-name) (gnc:gettext report-name)
(gnc:gettext "Untitled")) (gnc:gettext "Untitled"))
@ -578,15 +592,24 @@
)))) ))))
(define (gnc:report-template-save-to-savefile report-template) (define (gnc:report-template-save-to-savefile report-template)
(let* ((conf-file-name gnc:current-saved-reports) (let ((conf-file-name gnc:current-saved-reports)
(saved-form (gnc:report-template-generate-saved-forms report-template)) (saved-form (gnc:report-template-generate-saved-forms report-template)))
(save-result (eval-string saved-form))) (display saved-form
(if (record? save-result) (open-file conf-file-name "a"))
(begin (force-output)))
(display saved-form
(open-file conf-file-name "a")) ;; save all custom reports, moving the old version of the
(force-output) ;; saved-reports file aside as a backup
)))) (define (gnc:save-all-reports)
(let ((temp-path (gnc-build-dotgnucash-path "saved-reports-2.4-backup")))
(gnc:debug "saving all reports...")
(rename-file gnc:current-saved-reports temp-path)
(hash-for-each (lambda (k v)
(if (gnc:report-template-parent-type v)
(begin
(gnc:debug "saving report " k)
(gnc:report-template-save-to-savefile v))))
*gnc:_report-templates_*)))
;; gets the renderer from the report template; ;; gets the renderer from the report template;
@ -646,3 +669,12 @@
(let ((opt-value (gnc:option-value option))) (let ((opt-value (gnc:option-value option)))
(map (lambda (x) (car x)) opt-value)) (map (lambda (x) (car x)) opt-value))
#f))) #f)))
;; delete an existing report from the hash table and then call to
;; resave the saved-reports file... report is gone
(define (gnc:delete-report report)
(if (hash-ref *gnc:_report-templates_* report)
(begin
(gnc:debug "Deleting report " report)
(hash-remove! *gnc:_report-templates_* report)
(gnc:save-all-reports))))