diff --git a/src/report/report-gnome/Makefile.am b/src/report/report-gnome/Makefile.am
index 037e489c58..f25bce3a56 100644
--- a/src/report/report-gnome/Makefile.am
+++ b/src/report/report-gnome/Makefile.am
@@ -22,6 +22,7 @@ AM_CPPFLAGS = \
libgncmod_report_gnome_la_SOURCES = \
swig-report-gnome.c \
dialog-column-view.c \
+ dialog-custom-report.c \
dialog-style-sheet.c \
gnc-plugin-page-report.c \
gncmod-report-gnome.c \
@@ -30,6 +31,7 @@ libgncmod_report_gnome_la_SOURCES = \
gncincludedir = ${GNC_INCLUDE_DIR}
gncinclude_HEADERS = \
dialog-column-view.h \
+ dialog-custom-report.h \
dialog-style-sheet.h \
gnc-plugin-page-report.h \
window-report.h
@@ -61,7 +63,9 @@ gncmod_DATA = report-gnome.scm
noinst_DATA = .scm-links
gladedir = $(GNC_GLADE_DIR)
-glade_DATA = report.glade
+glade_DATA = \
+ report.glade \
+ custom-report-dialog.glade
uidir = $(GNC_UI_DIR)
diff --git a/src/report/report-gnome/custom-report-dialog.glade b/src/report/report-gnome/custom-report-dialog.glade
new file mode 100644
index 0000000000..5795ca01fb
--- /dev/null
+++ b/src/report/report-gnome/custom-report-dialog.glade
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+ 5
+
+ GTK_WINDOW_TOPLEVEL
+ GTK_WIN_POS_CENTER_ON_PARENT
+ False
+ True
+ False
+ True
+ True
+ True
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ GDK_GRAVITY_NORTH_WEST
+ True
+ False
+ False
+
+
+
+
+ True
+ False
+ 2
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+
+ True
+ Delete the currently selected report
+ True
+ gtk-delete
+ True
+ GTK_RELIEF_NORMAL
+ True
+ 0
+
+
+
+
+
+
+ True
+ Exit the custom report dialog
+ True
+ gtk-cancel
+ True
+ GTK_RELIEF_NORMAL
+ True
+ 0
+
+
+
+
+
+
+ True
+ Run the currently selected report
+ True
+ True
+ GTK_RELIEF_NORMAL
+ True
+ 0
+
+
+
+
+ True
+ 0.5
+ 0.5
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+ True
+ False
+ 2
+
+
+
+ True
+ gtk-go-forward
+ 4
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+ True
+ _Run
+ True
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+
+
+
+
+
+ 0
+ False
+ True
+ GTK_PACK_END
+
+
+
+
+
+ 150
+ True
+ True
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
+ GTK_SHADOW_NONE
+ GTK_CORNER_TOP_LEFT
+
+
+
+ True
+ True
+ False
+ False
+ False
+ True
+ False
+ False
+ False
+
+
+
+
+
+ 0
+ True
+ True
+
+
+
+
+
+
+
diff --git a/src/report/report-gnome/dialog-custom-report.c b/src/report/report-gnome/dialog-custom-report.c
new file mode 100644
index 0000000000..599a56f6bb
--- /dev/null
+++ b/src/report/report-gnome/dialog-custom-report.c
@@ -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
+#include
+#include
+#include
+#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);
+
+}
diff --git a/src/report/report-gnome/dialog-custom-report.h b/src/report/report-gnome/dialog-custom-report.h
new file mode 100644
index 0000000000..9b13c0e98f
--- /dev/null
+++ b/src/report/report-gnome/dialog-custom-report.h
@@ -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 */
+
+
+
+
diff --git a/src/report/report-gnome/report-gnome.i b/src/report/report-gnome/report-gnome.i
index 7a1878180a..81c7ceae42 100644
--- a/src/report/report-gnome/report-gnome.i
+++ b/src/report/report-gnome/report-gnome.i
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
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_column_view_edit_options(SCM options, SCM view);
+void gnc_ui_custom_report(GncMainWindow * window);
+
diff --git a/src/report/report-gnome/report-gnome.scm b/src/report/report-gnome/report-gnome.scm
index 20456f4b1f..3fc44d0658 100644
--- a/src/report/report-gnome/report-gnome.scm
+++ b/src/report/report-gnome/report-gnome.scm
@@ -96,6 +96,7 @@
(add-template-menu-item (car item) (cdr item)))
(sort *template-items* sort-templates)))
+
(define (gnc:report-menu-setup)
(define asset-liability-menu
(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)))
(define utility-menu
(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
(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 income-expense-menu)
(gnc-add-scm-extension asset-liability-menu)
(gnc-add-scm-extension budget-menu)
(gnc-add-scm-extension utility-menu)
- (gnc-add-scm-extension custom-menu)
;; run report-hook danglers
(gnc:hook-run-danglers HOOK-REPORT)
@@ -131,4 +137,9 @@
(list gnc:menuname-reports gnc:menuname-utility "")
(lambda (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))
diff --git a/src/report/report-system/report-system.scm b/src/report/report-system/report-system.scm
index 887e521b58..56066bea5f 100644
--- a/src/report/report-system/report-system.scm
+++ b/src/report/report-system/report-system.scm
@@ -155,6 +155,8 @@
(export gnc:report-stylesheet)
(export gnc:report-set-stylesheet!)
(export gnc:all-report-template-names)
+(export gnc:custom-report-template-names)
+(export gnc:delete-report)
(export gnc:find-report-template)
(export gnc:report-generate-restore-forms)
(export gnc:report-generate-saved-forms)
diff --git a/src/report/report-system/report.scm b/src/report/report-system/report.scm
index d2a91cf182..014391142c 100644
--- a/src/report/report-system/report.scm
+++ b/src/report/report-system/report.scm
@@ -455,6 +455,20 @@
'() *gnc:_report-templates_*)
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)
(hash-ref *gnc:_report-templates_* report-type))
@@ -570,7 +584,7 @@
(gnc-info-dialog
'()
(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)))
(gnc:gettext report-name)
(gnc:gettext "Untitled"))
@@ -578,15 +592,24 @@
))))
(define (gnc:report-template-save-to-savefile report-template)
- (let* ((conf-file-name gnc:current-saved-reports)
- (saved-form (gnc:report-template-generate-saved-forms report-template))
- (save-result (eval-string saved-form)))
- (if (record? save-result)
- (begin
- (display saved-form
- (open-file conf-file-name "a"))
- (force-output)
- ))))
+ (let ((conf-file-name gnc:current-saved-reports)
+ (saved-form (gnc:report-template-generate-saved-forms report-template)))
+ (display saved-form
+ (open-file conf-file-name "a"))
+ (force-output)))
+
+;; save all custom reports, moving the old version of the
+;; 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;
@@ -646,3 +669,12 @@
(let ((opt-value (gnc:option-value option)))
(map (lambda (x) (car x)) opt-value))
#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))))
\ No newline at end of file