r23097 - gnucash/trunk/src/report - Implement Save and Save As for custom report templates
Geert Janssens
gjanssens at code.gnucash.org
Sat Jul 6 16:51:23 EDT 2013
Author: gjanssens
Date: 2013-07-06 16:51:23 -0400 (Sat, 06 Jul 2013)
New Revision: 23097
Trac: http://svn.gnucash.org/trac/changeset/23097
Modified:
gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report-ui.xml
gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
gnucash/trunk/src/report/report-system/report-system.scm
gnucash/trunk/src/report/report-system/report.scm
Log:
Implement Save and Save As for custom report templates
This fixes bug 649284 - Allow saving of Custom Reports without changing name, overwriting existing report
Modified: gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report-ui.xml
===================================================================
--- gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report-ui.xml 2013-07-06 20:51:11 UTC (rev 23096)
+++ gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report-ui.xml 2013-07-06 20:51:23 UTC (rev 23097)
@@ -3,6 +3,7 @@
<menu name="File" action="FileAction">
<placeholder name="FileSavePlaceholder">
<menuitem name="FileReportSave" action="ReportSaveAction" />
+ <menuitem name="FileReportSaveAs" action="ReportSaveAsAction" />
</placeholder>
<placeholder name="FilePrintPlaceholder">
<menuitem name="FileExportPDF" action="FilePrintPDFAction"/>
@@ -36,6 +37,7 @@
<toolitem name="ReportToolbarStop" action="ReportStopAction" />
<separator name="ReportToolbarSep1" />
<toolitem name="ReportToolbarSave" action="ReportSaveAction" />
+ <toolitem name="ReportToolbarSaveAs" action="ReportSaveAsAction" />
<toolitem name="ReportToolbarExport" action="ReportExportAction" />
<toolitem name="ReportToolbarOptions" action="ReportOptionsAction" />
<toolitem name="ReportToolbarPrint" action="FilePrintAction" />
Modified: gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
===================================================================
--- gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c 2013-07-06 20:51:11 UTC (rev 23096)
+++ gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c 2013-07-06 20:51:23 UTC (rev 23097)
@@ -47,6 +47,7 @@
#include <errno.h>
#include "gfec.h"
+#include "dialog-custom-report.h"
#include "gnc-component-manager.h"
#include "gnc-engine.h"
#include "gnc-gconf-utils.h"
@@ -173,6 +174,7 @@
static void gnc_plugin_page_report_reload_cb(GtkAction *action, GncPluginPageReport *rep);
static void gnc_plugin_page_report_stop_cb(GtkAction *action, GncPluginPageReport *rep);
static void gnc_plugin_page_report_save_cb(GtkAction *action, GncPluginPageReport *rep);
+static void gnc_plugin_page_report_save_as_cb(GtkAction *action, GncPluginPageReport *rep);
static void gnc_plugin_page_report_export_cb(GtkAction *action, GncPluginPageReport *rep);
static void gnc_plugin_page_report_options_cb(GtkAction *action, GncPluginPageReport *rep);
static void gnc_plugin_page_report_print_cb(GtkAction *action, GncPluginPageReport *rep);
@@ -582,8 +584,6 @@
{
GncPluginPageReport *report;
GncPluginPageReportPrivate *priv;
- GtkActionGroup *action_group;
- GtkAction *action;
SCM dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
const gchar *old_name;
gchar *new_name;
@@ -602,12 +602,7 @@
new_name = gnc_option_db_lookup_string_option(priv->cur_odb, "General",
"Report name", NULL);
if (strcmp(old_name, new_name) != 0)
- {
main_window_update_page_name(GNC_PLUGIN_PAGE(report), new_name);
- action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(report));
- action = gtk_action_group_get_action (action_group, "ReportSaveAction");
- gtk_action_set_sensitive(action, TRUE);
- }
g_free(new_name);
/* it's probably already dirty, but make sure */
@@ -894,8 +889,6 @@
gnc_plugin_page_report_name_changed (GncPluginPage *page, const gchar *name)
{
GncPluginPageReportPrivate *priv;
- GtkActionGroup *action_group;
- GtkAction *action;
static gint count = 1, max_count = 10;
const gchar *old_name;
@@ -923,15 +916,6 @@
/* Have to manually call the option change hook. */
gnc_plugin_page_report_option_change_cb(page);
-
- /* Careful. This is called at report construction time. */
- action_group = gnc_plugin_page_get_action_group(page);
- if (action_group)
- {
- /* Allow the user to save the report now. */
- action = gtk_action_group_get_action (action_group, "ReportSaveAction");
- gtk_action_set_sensitive(action, TRUE);
- }
LEAVE(" ");
}
@@ -1044,14 +1028,18 @@
G_CALLBACK (gnc_plugin_page_report_reload_cb)
},
{
- "ReportSaveAction", GTK_STOCK_SAVE, N_("Add _Report"), "",
- N_("Add the current report to the `Custom' menu for later use. "
- "The report will be saved in the file ~/.gnucash/saved-reports-2.4. "
- "It will be accessible as menu entry in the report menu at the "
- "next startup of GnuCash."),
+ "ReportSaveAction", GTK_STOCK_SAVE, N_("Save _Report"), "<control><alt>s",
+ N_("Update the current report's saved configuration. "
+ "The report will be saved in the file ~/.gnucash/saved-reports-2.4. "),
G_CALLBACK(gnc_plugin_page_report_save_cb)
},
{
+ "ReportSaveAsAction", GTK_STOCK_SAVE_AS, N_("Save Report As..."), "<control><alt><shift>s",
+ N_("Add the current report's configuration to the `Custom Reports' menu. "
+ "The report will be saved in the file ~/.gnucash/saved-reports-2.4. "),
+ G_CALLBACK(gnc_plugin_page_report_save_as_cb)
+ },
+ {
"ReportExportAction", GTK_STOCK_CONVERT, N_("Export _Report"), NULL,
N_("Export HTML-formatted report to file"),
G_CALLBACK(gnc_plugin_page_report_export_cb)
@@ -1096,7 +1084,6 @@
static const gchar *initially_insensitive_actions[] =
{
- "ReportSaveAction",
NULL
};
@@ -1473,28 +1460,67 @@
}
static void
-gnc_plugin_page_report_save_cb( GtkAction *action, GncPluginPageReport *report )
+gnc_plugin_page_report_save_as_cb( GtkAction *action, GncPluginPageReport *report )
{
GncPluginPageReportPrivate *priv;
SCM save_func;
+ SCM rpt_id;
priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
if (priv->cur_report == SCM_BOOL_F)
return;
- save_func = scm_c_eval_string("gnc:report-save-to-savefile");
- scm_call_1(save_func, priv->cur_report);
+ /* Create a new report template based on the current report's settings
+ * and allow the user to rename the template.
+ */
+ save_func = scm_c_eval_string("gnc:report-to-template-new");
+ rpt_id = scm_call_1(save_func, priv->cur_report);
+ /* Open Custom Reports dialog to allow user to change the name */
+ if (!scm_is_null (rpt_id))
{
- GtkActionGroup *action_group =
- gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(report));
- GtkAction *action =
- gtk_action_group_get_action (action_group, "ReportSaveAction");
- gtk_action_set_sensitive(action, FALSE);
+ GncPluginPage *reportPage = GNC_PLUGIN_PAGE (report);
+ GtkWidget *window = reportPage->window;
+
+ if (window)
+ g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
+
+ gnc_ui_custom_report_edit_name (GNC_MAIN_WINDOW (window), rpt_id);
}
+
}
static void
+gnc_plugin_page_report_save_cb( GtkAction *action, GncPluginPageReport *report )
+{
+ GncPluginPageReportPrivate *priv;
+ SCM check_func, save_func;
+ SCM rpt_id;
+
+ priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
+ if (priv->cur_report == SCM_BOOL_F)
+ return;
+
+ check_func = scm_c_eval_string("gnc:is-custom-report-type");
+ if (scm_is_true (scm_call_1 (check_func, priv->cur_report)))
+ {
+ /* The current report is already based on a custom report.
+ * Replace the existing one instead of adding a new one
+ */
+ save_func = scm_c_eval_string("gnc:report-to-template-update");
+ rpt_id = scm_call_1(save_func, priv->cur_report);
+ }
+ else
+ {
+ /* The current report is not based on a custom report.
+ * So let's create a new report template based on this report
+ * and allow the user to change the name.
+ */
+ gnc_plugin_page_report_save_as_cb (action, report);
+ }
+}
+
+static void
gnc_plugin_page_report_export_cb( GtkAction *action, GncPluginPageReport *report )
{
GncPluginPageReportPrivate *priv;
Modified: gnucash/trunk/src/report/report-system/report-system.scm
===================================================================
--- gnucash/trunk/src/report/report-system/report-system.scm 2013-07-06 20:51:11 UTC (rev 23096)
+++ gnucash/trunk/src/report/report-system/report-system.scm 2013-07-06 20:51:23 UTC (rev 23097)
@@ -166,7 +166,8 @@
(export gnc:find-report-template)
(export gnc:report-generate-restore-forms)
(export gnc:report-generate-saved-forms)
-(export gnc:report-save-to-savefile)
+(export gnc:report-to-template-new)
+(export gnc:report-to-template-update)
(export gnc:report-render-html)
(export gnc:report-run)
(export gnc:report-templates-for-each)
Modified: gnucash/trunk/src/report/report-system/report.scm
===================================================================
--- gnucash/trunk/src/report/report-system/report.scm 2013-07-06 20:51:11 UTC (rev 23096)
+++ gnucash/trunk/src/report/report-system/report.scm 2013-07-06 20:51:23 UTC (rev 23097)
@@ -490,7 +490,22 @@
*gnc:_report-templates_*))
unique?))
+;; Generate a unique custom template name using the given string as a base
+;; If this string already exists as a custom template name, a
+;; number will be appended to it.
+(define (gnc:report-template-make-unique-name new-name)
+ (let* ((unique-name new-name)
+ (counter 0)
+ (unique? (gnc:report-template-has-unique-name? #f unique-name)))
+ (while (not unique?)
+ (begin
+ (set! counter (+ counter 1))
+ (set! unique-name (string-append new-name (number->string counter)))
+ (set! unique? (gnc:report-template-has-unique-name? #f unique-name))))
+ unique-name))
+
+
;; Load and save functions
(define (gnc:report-generate-restore-forms report)
@@ -571,7 +586,7 @@
(thunk report)))
;; save them
- (let ((name (gnc:report-name report))
+ (let ((name (gnc:report-template-make-unique-name (gnc:report-name report)))
(type (gnc:report-type report))
(templ-name (gnc:report-template-name (hash-ref *gnc:_report-templates_* (gnc:report-type report))))
(options (gnc:report-options report))
@@ -604,25 +619,61 @@
(string-append (symbol->string key) " - " (car (caddr args)))))
#f))))
-(define (gnc:report-save-to-savefile report)
- (let* ((saved-form (gnc:report-generate-saved-forms report))
- ;; Immediate evaluate the saved form to both load it into the
- ;; runtime, but also so we can check if it's "allowed" to actually
- ;; be written to the saved reports file by inspecting the result.
- ;; #Bug#342206.
+;; Convert a report into a report template and save this template in the savefile
+;; Under specific conditions the we will attempt to replace the current report's
+;; template instead of simply adding a new template to the file.
+;; These condititions are:
+;; 1. the report is an instance of an existing custom report template
+;; (ie a template that is stored in the savefile already)
+;; 2. an overwrite is requestes by setting overwrite? to #t
+(define (gnc:report-to-template report overwrite?)
+ (let* ((custom-template-id (gnc:report-custom-template report))
+ (overwrite-ok? (and (gnc:report-template-is-custom/template-guid? custom-template-id) overwrite?))
+ ;; Generate a serialized report-template with a random guid
+ (saved-form (gnc:report-generate-saved-forms report))
+ ;; Immediatly evaluate the serialized report template to
+ ;; - check if it's error free and can be deserialized
+ ;; - load it into the runtime for immediate use by the user
+ ;; (Bug #342206)
(save-result (eval-string saved-form)))
+
(if (record? save-result)
- (let ((report-port (gnc:open-saved-reports "a")))
- (if report-port
- (begin
- (display saved-form report-port)
- (close report-port)
- ))
- ;; Inform the calling function of the newly created template's guid
- (gnc:report-template-report-guid save-result))
- ;; Couldn't save report - return false
- #f)))
+ (begin
+ ;; If it's ok to overwrite the old template, delete it now.
+ (if overwrite-ok?
+ (let ((templ-name (gnc:report-template-name (hash-ref *gnc:_report-templates_* custom-template-id))))
+ ;; We're overwriting, which needs some additional steps
+ ;; 1. Remove the newly generated template from the template list again
+ (hash-remove! *gnc:_report-templates_* (gnc:report-template-report-guid save-result))
+ ;; 2. We still have the template record available though, so adapt it to
+ ;; the template we want to override (ie update guid and name)
+ (gnc:report-template-set-report-guid! save-result custom-template-id)
+ (gnc:report-template-set-name save-result templ-name)
+ ;; 3. Overwrite the template with the new one
+ (hash-set! *gnc:_report-templates_* custom-template-id save-result)
+ ))
+ ;; Regardless of how we got here, we now have a new template to write
+ ;; so let's write it
+ (if (gnc:save-all-reports)
+ (let ((templ-guid (gnc:report-template-report-guid save-result)))
+ ;; Indicate the report was instantiated from the new template
+ (gnc:report-set-custom-template! report templ-guid)
+ ;; Inform the calling function of the new template's guid
+ templ-guid)
+ #f))
+ #f)))
+
+;; Convert a report into a new report template and add this template to the save file
+(define (gnc:report-to-template-new report)
+ (gnc:report-to-template report #f))
+
+;; Get the current report's template and try to update it with the report's current
+;; settings. This will only be possible if the report was already based on a
+;; custom report template. If that's not the case, a new template will be added instead.
+(define (gnc:report-to-template-update report)
+ (gnc:report-to-template report #t))
+
(define (gnc:report-template-save-to-savefile report-template)
(let* ((report-port (gnc:open-saved-reports "a")))
(if report-port
More information about the gnucash-changes
mailing list