Skip to content

Commit

Permalink
Bug753307 - Custom Report be selectable as default Report for Printing
Browse files Browse the repository at this point in the history
This commit changes the preference in Business->'Report for Printing'
to be saved as a book property and allow the selection of any Invoice
Report to be used as the default.
  • Loading branch information
Bob-IT committed Feb 1, 2023
1 parent 63f8e73 commit 019214f
Show file tree
Hide file tree
Showing 17 changed files with 596 additions and 37 deletions.
246 changes: 246 additions & 0 deletions gnucash/gnome/business-gnome-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@

#include "gnc-general-search.h"
#include "qof.h"
#include "qofbook.h"
#include "business-gnome-utils.h"
#include "dialog-customer.h"
#include "dialog-job.h"
#include "dialog-vendor.h"
#include "dialog-employee.h"
#include "dialog-invoice.h"

#include "guile-mappings.h"
#include "gnc-guile-utils.h"
#include "gnc-prefs.h"
#include "gnc-commodity.h"

typedef enum
Expand All @@ -57,6 +61,248 @@ typedef enum
GNCSEARCH_TYPE_EDIT
} GNCSearchType;

enum
{
COL_INV_NAME = 0,
COL_INV_GUID,
COL_INV_MISSING,
NUM_INV_COLS
};

#define PRINTABLE_INVOICE_GUID "5123a759ceb9483abf2182d01c140e8d"
#define TAX_INVOICE_GUID "0769e242be474010b4acf264a5512e6e"
#define EASY_INVOICE_GUID "67112f318bef4fc496bdc27d106bbda4"
#define FANCY_INVOICE_GUID "3ce293441e894423a2425d7a22dd1ac6"

enum
{
PRINTABLE_INVOICE_PREF_NUM = 0,
TAX_INVOICE_PREF_NUM,
EASY_INVOICE_PREF_NUM,
FANCY_INVOICE_PREF_NUM,
};

static const char* invoice_printreport_values[] =
{
/* The list below are the guids of reports that can
* be used to print an invoice.
*
* Important: This list matches the order of existing saved
* preference entries.
*/
PRINTABLE_INVOICE_GUID,
TAX_INVOICE_GUID,
EASY_INVOICE_GUID,
FANCY_INVOICE_GUID,
NULL
};

#define GNC_PREFS_GROUP_INVOICE "dialogs.business.invoice"
#define GNC_PREF_INV_PRINT_RPT "invoice-printreport"

const char *
gnc_get_builtin_default_invoice_print_report (void)
{
return PRINTABLE_INVOICE_GUID;
}

const char *
gnc_migrate_default_invoice_print_report (void)
{
QofBook *book = gnc_get_current_book ();
int old_style_value = gnc_prefs_get_int (GNC_PREFS_GROUP_INVOICE,
GNC_PREF_INV_PRINT_RPT);

if (old_style_value >= TAX_INVOICE_PREF_NUM &&
old_style_value <= FANCY_INVOICE_PREF_NUM)
{
const gchar *ret = invoice_printreport_values[old_style_value];
qof_book_set_default_invoice_report (book, ret, " ");
return ret;
}
else
return gnc_get_builtin_default_invoice_print_report ();
}

char *
gnc_get_default_invoice_print_report (void)
{
QofBook *book = gnc_get_current_book ();
gchar *default_guid = qof_book_get_default_invoice_report_guid (book);

if (!default_guid)
return g_strdup (gnc_migrate_default_invoice_print_report ());

return default_guid;
}

static gboolean
select_default (GtkWidget *combo, const gchar *default_guid)
{
GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX(combo));
GtkTreeIter iter;
gboolean found = FALSE;
gboolean valid_iter = gtk_tree_model_get_iter_first (model, &iter);

while (valid_iter)
{
gchar *guid;
gtk_tree_model_get (model, &iter, COL_INV_GUID, &guid, -1);

if (g_strcmp0 (default_guid, guid) == 0)
{
gtk_combo_box_set_active_iter (GTK_COMBO_BOX(combo), &iter);
g_free (guid);
found = TRUE;
break;
}
g_free (guid);
valid_iter = gtk_tree_model_iter_next (model, &iter);
}
return found;
}

/********************************************************************
* update_invoice_list
*
* this procedure does the real work of displaying a sorted list of
* available invoice reports
********************************************************************/
static gchar *
update_invoice_list (GtkWidget *combo)
{
SCM get_rpt_guids = scm_c_eval_string ("gnc:custom-report-invoice-template-guids");
SCM template_menu_name = scm_c_eval_string ("gnc:report-template-menu-name/report-guid");
SCM reportlist;
SCM rpt_guids;

GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX(combo));
GtkListStore *store = GTK_LIST_STORE(model);
gchar *default_guid = gnc_get_default_invoice_print_report ();
gchar *default_name = NULL;
gboolean have_default = FALSE;

gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model),
COL_INV_NAME, GTK_SORT_ASCENDING);

reportlist = scm_call_0 (get_rpt_guids);
rpt_guids = reportlist;

gtk_list_store_clear (store);

if (scm_is_list (rpt_guids))
{
int i;
GtkTreeIter iter;

for (i = 0; !scm_is_null (rpt_guids); i++)
{
gchar *guid_str = scm_to_utf8_string (SCM_CAR(rpt_guids));
gchar *name = gnc_scm_to_utf8_string (scm_call_2(template_menu_name,
SCM_CAR(rpt_guids), SCM_BOOL_F));

gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COL_INV_NAME, name,
COL_INV_GUID, guid_str,
COL_INV_MISSING, FALSE,
-1);
g_free (name);
g_free (guid_str);

rpt_guids = SCM_CDR(rpt_guids);
}
}

have_default = select_default (combo, default_guid);

if (!have_default)
{
GtkTreeIter iter;
QofBook *book = gnc_get_current_book ();
default_name = qof_book_get_default_invoice_report_name (book);

gtk_list_store_prepend (store, &iter);
gtk_list_store_set (store, &iter,
COL_INV_NAME, default_name,
COL_INV_GUID, default_guid,
COL_INV_MISSING, TRUE,
-1);

gtk_combo_box_set_active_iter (GTK_COMBO_BOX(combo), &iter);
}
g_free (default_guid);
return default_name;
}

static void
combo_changed_cb (GtkComboBox *widget, gpointer user_data)
{
GtkTreeIter iter;

if (gtk_combo_box_get_active_iter (widget, &iter))
{
GtkTreeModel *model = gtk_combo_box_get_model (widget);
gboolean missing;
gtk_tree_model_get (model, &iter, COL_INV_MISSING, &missing, -1);
// set visibility of the warning image
gtk_widget_set_visible (GTK_WIDGET(user_data), missing);
gtk_widget_queue_resize (GTK_WIDGET(widget));
}
}

void
gnc_default_print_report_list (GtkWidget *combo, GtkWidget *warning)
{
gchar *default_name = update_invoice_list (combo);

if (default_name)
{
/* Translators: %s is the default invoice report name. */
gchar *tool_tip = g_strdup_printf (_("'%s' is missing"),
default_name);
gtk_widget_show (warning);

gtk_widget_set_tooltip_text (warning, tool_tip);
g_free (tool_tip);
}
g_free (default_name);
g_signal_connect (G_OBJECT(combo), "changed",
G_CALLBACK(combo_changed_cb), warning);
}

void
gnc_default_print_report_list_combo_set_report (GtkComboBox *cbox,
const gchar *guid)
{
if (guid && *guid)
select_default (GTK_WIDGET(cbox), guid);
else
select_default (GTK_WIDGET(cbox), gnc_get_builtin_default_invoice_print_report ());
}

gchar*
gnc_default_print_report_list_combo_get_report (GtkComboBox *cbox)
{
GtkTreeModel *model = gtk_combo_box_get_model (cbox);
GtkTreeIter iter;
gchar *report = NULL;

if (gtk_combo_box_get_active_iter (cbox, &iter))
{
gchar *report_guid;
gchar *report_name;
gtk_tree_model_get (model, &iter, COL_INV_NAME, &report_name,
COL_INV_GUID, &report_guid,
-1);

report = g_strconcat (report_guid, "/", report_name, NULL);
g_free (report_guid);
g_free (report_name);
}
return report;
}

static GtkWidget * gnc_owner_new (GtkWidget *label, GtkWidget *hbox,
QofBook *book, GncOwner *owner,
GNCSearchType type)
Expand Down
48 changes: 48 additions & 0 deletions gnucash/gnome/business-gnome-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,54 @@ extern "C" {

#define GNC_PREF_AUTO_PAY "auto-pay"

/** Retrieve the buitin guid for the Invoice Report to be
* used as the default to print Invoices
*
* @return The guid of the saved Invoice Report
*/
const char *gnc_get_builtin_default_invoice_print_report (void);

/** Migrate the Default Invoice Report from prefs to book properties
* used to print Invoices
*
* @return The guid of the saved Invoice Report
*/
const char * gnc_migrate_default_invoice_print_report (void);

/** Retrieve the guid of the Invoice Report to be used to
* print Invoices
*
* @return The guid of the saved Invoice Report
*/
char *gnc_get_default_invoice_print_report (void);

/** Setup a combo used for displaying list of Invoice Reports.
*
* @param combo The GtkComboBox that presents the list.
*
* @param warning The warning image, displayed if the default guid is
* not in the Invoice list.
*/
void gnc_default_print_report_list (GtkWidget *combo, GtkWidget *warning);

/** Retrieve the string representing the Invoice Report used as the default
* to print Invoices. This is a concatination of report name and guid
*
* @param combo The GtkComboBox that presents the list.
*
* @return The string used to represent the selected Invoice Report
*/
gchar *gnc_default_print_report_list_combo_get_report (GtkComboBox *cbox);

/** Set the active report to the guid string
*
* @param combo The GtkComboBox that presents the list.
*
* @param guid The guid of the Invoice Report
*/
void gnc_default_print_report_list_combo_set_report (GtkComboBox *cbox,
const gchar *guid);


GtkWidget * gnc_owner_select_create (GtkWidget *label, GtkWidget *hbox,
QofBook *book, GncOwner *owner);
Expand Down
50 changes: 50 additions & 0 deletions gnucash/gnome/business-options-gnome.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,54 @@ create_option_widget<GncOptionUIType::TAX_TABLE>(GncOption& option,
wrap_widget(option, widget, page_box, row);
}

class GncGtkInvReportUIItem : public GncOptionGtkUIItem
{
public:
GncGtkInvReportUIItem(GtkWidget* widget) :
GncOptionGtkUIItem(widget, GncOptionUIType::INV_REPORT) {}
void set_ui_item_from_option(GncOption& option) noexcept override
{
auto guid_string{option.get_value<std::string>()};
gnc_default_print_report_list_combo_set_report (GTK_COMBO_BOX(get_widget()),
guid_string.c_str());
}
void set_option_from_ui_item(GncOption& option) noexcept override
{
auto report_guid_name = gnc_default_print_report_list_combo_get_report (GTK_COMBO_BOX(get_widget()));
option.set_value(std::string{report_guid_name});
g_free (report_guid_name);
}
};

template<> void
create_option_widget<GncOptionUIType::INV_REPORT>(GncOption& option,
GtkGrid *page_box,
int row)
{
constexpr const char* glade_file{"business-options-gnome.glade"};
constexpr const char* glade_store{"liststore_print_invoice"};
constexpr const char* glade_hbox{"invoice_report_hbox"};
constexpr const char* glade_menu{"invoice_report_combo"};
constexpr const char* glade_warning{"invoice_warning_image"};
auto builder{gtk_builder_new()};

gnc_builder_add_from_file(builder, glade_file, glade_store);
gnc_builder_add_from_file(builder, glade_file, glade_hbox);
auto widget{GTK_WIDGET(gtk_builder_get_object(builder, glade_menu))};
auto widget_hbox{GTK_WIDGET(gtk_builder_get_object(builder, glade_hbox))};
auto widget_warning{GTK_WIDGET(gtk_builder_get_object(builder, glade_warning))};
g_object_set_data(G_OBJECT(widget), "warning-image", widget_warning);
gnc_default_print_report_list (GTK_WIDGET(widget), GTK_WIDGET(widget_warning));
option.set_ui_item(std::make_unique<GncGtkInvReportUIItem>(widget));
option.set_ui_item_from_option();

g_signal_connect (G_OBJECT (widget), "changed",
G_CALLBACK (gnc_option_changed_widget_cb), &option);

wrap_widget (option, widget_hbox, page_box, row);
g_object_unref(builder); // Needs to wait until after widget has been reffed.
}

void
gnc_business_options_gnome_initialize(void)
{
Expand All @@ -198,4 +246,6 @@ gnc_business_options_gnome_initialize(void)
create_option_widget<GncOptionUIType::INVOICE>);
GncOptionUIFactory::set_func(GncOptionUIType::TAX_TABLE,
create_option_widget<GncOptionUIType::TAX_TABLE>);
GncOptionUIFactory::set_func(GncOptionUIType::INV_REPORT,
create_option_widget<GncOptionUIType::INV_REPORT>);
}

0 comments on commit 019214f

Please sign in to comment.