In the Print Checks dialog, provide an easy way for users to save the

data from the "Custom Format" page to a check format file.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15724 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton 2007-03-15 05:20:58 +00:00
parent a0352f8748
commit cfba9052a5
5 changed files with 306 additions and 8 deletions

View File

@ -163,6 +163,20 @@ g_key_file_get_double (GKeyFile *key_file, const gchar *group_name,
return double_value; return double_value;
} }
void
g_key_file_set_double (GKeyFile *key_file,
const gchar *group_name,
const gchar *key,
gdouble value)
{
gchar result[G_ASCII_DTOSTR_BUF_SIZE];
g_return_if_fail (key_file != NULL);
g_ascii_dtostr (result, sizeof (result), value);
g_key_file_set_value (key_file, group_name, key, result);
}
gdouble* gdouble*
g_key_file_get_double_list (GKeyFile *key_file, g_key_file_get_double_list (GKeyFile *key_file,
const gchar *group_name, const gchar *group_name,
@ -212,6 +226,34 @@ g_key_file_get_double_list (GKeyFile *key_file,
return double_values; return double_values;
} }
void
g_key_file_set_double_list (GKeyFile *key_file,
const gchar *group_name,
const gchar *key,
gdouble list[],
gsize length)
{
GString *values;
gsize i;
g_return_if_fail (key_file != NULL);
g_return_if_fail (list != NULL);
values = g_string_sized_new (length * 16);
for (i = 0; i < length; i++)
{
gchar result[G_ASCII_DTOSTR_BUF_SIZE];
g_ascii_dtostr( result, sizeof (result), list[i] );
g_string_append (values, result);
g_string_append_c (values, ';');
}
g_key_file_set_value (key_file, group_name, key, values->str);
g_string_free (values, TRUE);
}
/********************************************************************** /**********************************************************************
* *
* End of copied functions. * End of copied functions.

View File

@ -43,9 +43,15 @@ gdouble
g_key_file_get_double (GKeyFile *key_file, const gchar *group_name, g_key_file_get_double (GKeyFile *key_file, const gchar *group_name,
const gchar *key, GError **error); const gchar *key, GError **error);
void
g_key_file_set_double (GKeyFile *key_file, const gchar *group_name,
const gchar *key, gdouble value);
gdouble* gdouble*
g_key_file_get_double_list (GKeyFile *key_file, const gchar *group_name, g_key_file_get_double_list (GKeyFile *key_file, const gchar *group_name,
const gchar *key, gsize *length, GError **error); const gchar *key, gsize *length, GError **error);
void
g_key_file_set_double_list (GKeyFile *key_file, const gchar *group_name,
const gchar *key, gdouble list[], gsize length);
#endif #endif

View File

@ -376,7 +376,7 @@ gnc_validate_directory (const gchar *dirname)
const gchar * const gchar *
gnc_dotgnucash_dir (void) gnc_dotgnucash_dir (void)
{ {
static gchar *dotgnucash = NULL, *books_dir; static gchar *dotgnucash = NULL, *tmp_dir;
const gchar *home; const gchar *home;
if (dotgnucash) if (dotgnucash)
@ -393,9 +393,12 @@ gnc_dotgnucash_dir (void)
gnc_validate_directory(dotgnucash); gnc_validate_directory(dotgnucash);
/* Since we're in code that is only executed once.... */ /* Since we're in code that is only executed once.... */
books_dir = g_build_filename(dotgnucash, "books", (gchar *)NULL); tmp_dir = g_build_filename(dotgnucash, "books", (gchar *)NULL);
gnc_validate_directory(books_dir); gnc_validate_directory(tmp_dir);
g_free(books_dir); g_free(tmp_dir);
tmp_dir = g_build_filename(dotgnucash, "checks", (gchar *)NULL);
gnc_validate_directory(tmp_dir);
g_free(tmp_dir);
return dotgnucash; return dotgnucash;
} }

View File

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <libguile.h> #include <libguile.h>
#include <locale.h> #include <locale.h>
#include <math.h>
#include "glib-compat.h" #include "glib-compat.h"
@ -70,6 +71,8 @@
#define DEFAULT_FONT "sans 12" #define DEFAULT_FONT "sans 12"
#define CHECK_FMT_DIR "checks" #define CHECK_FMT_DIR "checks"
#define CUSTOM_CHECK_NAME "custom.chk"
#define CHECK_NAME_FILTER "*.chk"
#define DEGREES_TO_RADIANS (G_PI / 180.0) #define DEGREES_TO_RADIANS (G_PI / 180.0)
#define KF_GROUP_TOP "Top" #define KF_GROUP_TOP "Top"
@ -104,6 +107,7 @@ void gnc_print_check_position_changed(GtkComboBox *widget, PrintCheckDialog * pc
static void gnc_ui_print_save_dialog(PrintCheckDialog * pcd); static void gnc_ui_print_save_dialog(PrintCheckDialog * pcd);
static void gnc_ui_print_restore_dialog(PrintCheckDialog * pcd); static void gnc_ui_print_restore_dialog(PrintCheckDialog * pcd);
void gnc_ui_print_restore_dialog(PrintCheckDialog * pcd); void gnc_ui_print_restore_dialog(PrintCheckDialog * pcd);
void gnc_print_check_save_button_clicked(GtkButton *button, PrintCheckDialog *pcd);
/** This enum defines the types of items that gnucash knows how to /** This enum defines the types of items that gnucash knows how to
@ -128,6 +132,8 @@ void gnc_ui_print_restore_dialog(PrintCheckDialog * pcd);
DEFINE_ENUM(CheckItemType, ENUM_CHECK_ITEM_TYPE) DEFINE_ENUM(CheckItemType, ENUM_CHECK_ITEM_TYPE)
FROM_STRING_DEC(CheckItemType, ENUM_CHECK_ITEM_TYPE) FROM_STRING_DEC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
FROM_STRING_FUNC(CheckItemType, ENUM_CHECK_ITEM_TYPE) FROM_STRING_FUNC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
AS_STRING_DEC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
AS_STRING_FUNC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
/** This data structure describes a single item printed on a check. /** This data structure describes a single item printed on a check.
* It is build from a description in a text file. */ * It is build from a description in a text file. */
@ -369,6 +375,137 @@ pcd_get_custom_multip(PrintCheckDialog * pcd)
} }
/** Save a coordinate pair into a check description file. This function
* extracts the values from the spin buttons, adjusts them for the units
* multiplies (inch, pixel, etc), and then adds them to the gKeyFile. */
static void
pcd_key_file_save_xy (GKeyFile *key_file, const gchar *group_name,
const gchar *key_name, gdouble multip,
GtkSpinButton *spin0, GtkSpinButton *spin1)
{
gdouble dd[2];
dd[0] = multip * gtk_spin_button_get_value(spin0);
dd[1] = multip * gtk_spin_button_get_value(spin1);
/* Clip the numbers to three decimal places. */
dd[0] = round(dd[0] * 1000) / 1000;
dd[1] = round(dd[1] * 1000) / 1000;
g_key_file_set_double_list(key_file, group_name, key_name, dd, 2);
}
/** Save the information about a single printed item into a check description
* file. This function uses a helper function to extracts and save the item
* coordinates. */
static void
pcd_key_file_save_item_xy (GKeyFile *key_file, int index,
CheckItemType type, gdouble multip,
GtkSpinButton *spin0, GtkSpinButton *spin1)
{
gchar *key;
key = g_strdup_printf("Type_%d", index);
g_key_file_set_string(key_file, KF_GROUP_ITEMS, key,
CheckItemTypeasString(type));
g_free(key);
key = g_strdup_printf("Coords_%d", index);
pcd_key_file_save_xy(key_file, KF_GROUP_ITEMS, key, multip, spin0, spin1);
g_free(key);
}
/** Save all of the information from the custom check dialog into a check
* description file. */
static void
pcd_save_custom_data(PrintCheckDialog *pcd, gchar *filename)
{
GKeyFile *key_file;
GError *error = NULL;
GtkWidget *dialog;
gdouble multip;
gint i = 0;
multip = pcd_get_custom_multip(pcd);
key_file = g_key_file_new();
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE,
_("Custom Check"));
g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, FALSE);
g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, FALSE);
g_key_file_set_double(key_file, KF_GROUP_TOP, KF_KEY_ROTATION,
gtk_spin_button_get_value(pcd->check_rotation));
pcd_key_file_save_xy(key_file, KF_GROUP_TOP, KF_KEY_TRANSLATION, multip,
pcd->translation_x, pcd->translation_y);
pcd_key_file_save_item_xy(key_file, i++, PAYEE, multip,
pcd->payee_x, pcd->payee_y);
pcd_key_file_save_item_xy(key_file, i++, DATE, multip,
pcd->date_x, pcd->date_y);
pcd_key_file_save_item_xy(key_file, i++, AMOUNT_WORDS, multip,
pcd->words_x, pcd->words_y);
pcd_key_file_save_item_xy(key_file, i++, AMOUNT_NUMBER, multip,
pcd->number_x, pcd->number_y);
pcd_key_file_save_item_xy(key_file, i++, NOTES, multip,
pcd->notes_x, pcd->notes_y);
if (!gnc_key_file_save_to_file(filename, key_file, &error)) {
dialog = gtk_message_dialog_new(GTK_WINDOW(pcd->dialog),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
_("Cannot save check format file."));
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
error->message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_error_free(error);
}
}
/** This function is called when the user clicks the "save format" button in
* the check printing dialog. It presents another dialog to the user to get
* the filename for saving the data. */
void
gnc_print_check_save_button_clicked(GtkButton *button, PrintCheckDialog *pcd)
{
GtkFileChooser *chooser;
GtkFileFilter *filter;
GtkWidget *dialog;
gchar *check_dir, *filename;
dialog = gtk_file_chooser_dialog_new(_("Save Check Description"),
GTK_WINDOW(pcd->dialog),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
chooser = GTK_FILE_CHOOSER(dialog);
check_dir = g_build_filename(gnc_dotgnucash_dir(), CHECK_FMT_DIR, NULL);
gtk_file_chooser_set_current_folder(chooser, check_dir);
gtk_file_chooser_set_current_name(chooser, CUSTOM_CHECK_NAME);
g_free(check_dir);
filter = gtk_file_filter_new();
gtk_file_filter_set_name(filter, CHECK_NAME_FILTER);
gtk_file_filter_add_pattern(filter, CHECK_NAME_FILTER);
gtk_file_chooser_add_filter(chooser, filter);
filter = gtk_file_filter_new();
gtk_file_filter_set_name(filter, _("All Files"));
gtk_file_filter_add_pattern(filter, "*");
gtk_file_chooser_add_filter(chooser, filter);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
pcd_save_custom_data(pcd, filename);
g_free(filename);
}
gtk_widget_destroy (dialog);
}
/** This is an auxiliary debugging function for converting an array of doubles /** This is an auxiliary debugging function for converting an array of doubles
* into a printable string. */ * into a printable string. */
static gchar * static gchar *

View File

@ -257,7 +257,7 @@ Custom</property>
<child> <child>
<widget class="GtkTable" id="custom_table"> <widget class="GtkTable" id="custom_table">
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">11</property> <property name="n_rows">13</property>
<property name="n_columns">3</property> <property name="n_columns">3</property>
<property name="homogeneous">False</property> <property name="homogeneous">False</property>
<property name="row_spacing">0</property> <property name="row_spacing">0</property>
@ -938,6 +938,116 @@ Points</property>
<property name="y_options"></property> <property name="y_options"></property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkLabel" id="label847681">
<property name="visible">True</property>
<property name="label" translatable="yes"> </property>
<property name="use_underline">False</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</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="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">11</property>
<property name="bottom_attach">12</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="save_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="gnc_print_check_save_button_clicked" last_modification_time="Thu, 15 Mar 2007 03:09:02 GMT"/>
<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-save-as</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="label847682">
<property name="visible">True</property>
<property name="label" translatable="yes">_Save format</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>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">12</property>
<property name="bottom_attach">13</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="tab_expand">False</property> <property name="tab_expand">False</property>