34 #include <glib/gi18n.h>
45 #include "dialog-print-check.h"
46 #include "dialog-utils.h"
49 #include "gnc-date-format.h"
56 #include "engine-helpers.h"
61 #define G_LOG_DOMAIN "gnc.printing.checks"
65 G_GNUC_UNUSED
static QofLogModule log_module =
"gnc.printing.checks";
67 #define GNC_PREFS_GROUP "dialogs.checkprinting"
68 #define GNC_PREF_CHECK_FORMAT_GUID "check-format-guid"
69 #define GNC_PREF_CHECK_POSITION "check-position"
70 #define GNC_PREF_FIRST_PAGE_COUNT "first-page-count"
71 #define GNC_PREF_DATE_FORMAT_USER "date-format-custom"
72 #define GNC_PREF_CUSTOM_PAYEE "custom-payee"
73 #define GNC_PREF_CUSTOM_DATE "custom-date"
74 #define GNC_PREF_CUSTOM_WORDS "custom-amount-words"
75 #define GNC_PREF_CUSTOM_NUMBER "custom-amount-number"
76 #define GNC_PREF_CUSTOM_ADDRESS "custom-address"
77 #define GNC_PREF_CUSTOM_NOTES "custom-notes"
78 #define GNC_PREF_CUSTOM_MEMO "custom-memo"
79 #define GNC_PREF_CUSTOM_TRANSLATION "custom-translation"
80 #define GNC_PREF_CUSTOM_ROTATION "custom-rotation"
81 #define GNC_PREF_CUSTOM_UNITS "custom-units"
82 #define GNC_PREF_PRINT_DATE_FMT "print-date-format"
83 #define GNC_PREF_DEFAULT_FONT "default-font"
84 #define GNC_PREF_BLOCKING_CHARS "blocking-chars"
85 #define GNC_PREF_SPLITS_AMOUNT "splits-amount"
86 #define GNC_PREF_SPLITS_MEMO "splits-memo"
87 #define GNC_PREF_SPLITS_ACCOUNT "splits-account"
90 #define DEFAULT_FONT "sans 12"
91 #define CHECK_FMT_DIR "checks"
92 #define CHECK_NAME_EXTENSION ".chk"
93 #define DEGREES_TO_RADIANS (G_PI / 180.0)
95 #define BLOCKING_CHAR_OFF 0
96 #define BLOCKING_CHAR_ON 1
98 #define KF_GROUP_TOP "Top"
99 #define KF_GROUP_POS "Check Positions"
100 #define KF_GROUP_ITEMS "Check Items"
101 #define KF_KEY_GUID "Guid"
102 #define KF_KEY_TITLE "Title"
103 #define KF_KEY_ROTATION "Rotation"
104 #define KF_KEY_TRANSLATION "Translation"
105 #define KF_KEY_FONT "Font"
106 #define KF_KEY_ALIGN "Align"
107 #define KF_KEY_BLOCKING "Blocking_Chars"
108 #define KF_KEY_SHOW_GRID "Show_Grid"
109 #define KF_KEY_SHOW_BOXES "Show_Boxes"
110 #define KF_KEY_NAMES "Names"
111 #define KF_KEY_HEIGHT "Height"
112 #define KF_KEY_TYPE "Type"
113 #define KF_KEY_COORDS "Coords"
114 #define KF_KEY_TEXT "Text"
115 #define KF_KEY_FILENAME "Filename"
116 #define KF_KEY_DATE_FORMAT "DateFormat"
117 #define KF_KEY_SPLITS_AMOUNT "SplitsAmount"
118 #define KF_KEY_SPLITS_MEMO "SplitsMemo"
119 #define KF_KEY_SPLITS_ACCOUNT "SplitsAccount"
137 void gnc_ui_print_check_response_cb (GtkDialog *dialog, gint response,
PrintCheckDialog *pcd);
138 void gnc_print_check_format_changed (GtkComboBox *widget,
PrintCheckDialog *pcd);
139 void gnc_print_check_position_changed (GtkComboBox *widget,
PrintCheckDialog *pcd);
140 void gnc_print_check_save_button_clicked (GtkButton *button,
PrintCheckDialog *pcd);
141 void gnc_check_format_title_changed (GtkEditable *editable, GtkWidget *ok_button);
155 #define ENUM_CHECK_ITEM_TYPE(_) \
175 DEFINE_ENUM(CheckItemType, ENUM_CHECK_ITEM_TYPE)
176 FROM_STRING_DEC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
177 FROM_STRING_FUNC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
178 AS_STRING_DEC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
179 AS_STRING_FUNC(CheckItemType, ENUM_CHECK_ITEM_TYPE)
278 GtkWindow *caller_window;
284 GtkWidget *format_combobox;
286 GtkWidget *position_combobox;
288 GtkSpinButton *first_page_count;
289 GtkWidget *custom_table;
290 GtkSpinButton *payee_x, *payee_y;
291 GtkSpinButton *date_x, *date_y;
292 GtkSpinButton *words_x, *words_y;
293 GtkSpinButton *number_x, *number_y;
294 GtkSpinButton *address_x, *address_y;
295 GtkSpinButton *notes_x, *notes_y;
296 GtkSpinButton *memo_x, *memo_y;
297 GtkSpinButton *splits_amount_x, *splits_amount_y;
298 GtkSpinButton *splits_memo_x, *splits_memo_y;
299 GtkSpinButton *splits_account_x, *splits_account_y;
300 GtkSpinButton *translation_x, *translation_y;
301 GtkSpinButton *check_rotation;
302 GtkWidget *translation_label;
304 GtkWidget *units_combobox;
306 GtkWidget *date_format;
308 GtkWidget *check_address_name;
309 GtkWidget *check_address_1;
310 GtkWidget *check_address_2;
311 GtkWidget *check_address_3;
312 GtkWidget *check_address_4;
326 find_existing_format (GtkListStore *store, gchar *guid, GtkTreeIter *iter_out)
331 g_return_val_if_fail(store, NULL);
332 g_return_val_if_fail(guid, NULL);
334 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
339 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
343 if (strcmp(format->
guid, guid) != 0)
350 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
365 address = g_strconcat(gtk_entry_get_text(GTK_ENTRY(pcd->check_address_name)),
"\n",
366 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_1)),
"\n",
367 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_2)),
"\n",
368 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_3)),
"\n",
369 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_4)),
383 gchar* amount = NULL;
390 if ( !s_list )
return NULL;
392 amount = g_strconcat(
"", NULL);
396 Split *split = node->data;
398 if (split != pcd->split)
400 const gchar* split_amount;
402 split_amount = xaccPrintAmount(
xaccSplitGetAmount(split), gnc_split_amount_print_info(split, TRUE));
404 if (amount && *amount)
405 amount = g_strconcat(amt_temp,
"\n", split_amount, NULL);
407 amount = g_strconcat(amt_temp, split_amount, NULL);
422 const gchar* split_memo;
429 if ( !s_list )
return NULL;
431 memo = g_strconcat(
"", NULL);
435 Split *split = node->data;
437 if (split != pcd->split)
443 memo = g_strconcat(memo_temp,
"\n", split_memo, NULL);
445 memo = g_strconcat(memo_temp, split_memo, NULL);
459 gchar* account = NULL;
466 if ( !s_list )
return NULL;
468 account = g_strconcat(
"", NULL);
472 Split *split = node->data;
474 if (split != pcd->split)
477 const gchar* aName = NULL;
481 account_temp = account;
482 if (account && *account)
483 account = g_strconcat(account_temp,
"\n", aName, NULL);
485 account = g_strconcat(account_temp, aName, NULL);
486 g_free(account_temp);
505 if ( !pcd )
return FALSE;
508 if (g_list_length(pcd->splits) != 1)
513 format = pcd->selected_format;
514 if ( !format )
return TRUE;
516 for (elem = pcd->selected_format->
items; elem; elem = g_slist_next(elem))
519 if ( item->
type == ADDRESS )
return TRUE;
535 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pcd->format_combobox),
538 model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
539 gtk_tree_model_get(model, &iter,
COL_DATA, &check, -1);
541 check ? check->
guid :
"custom");
543 active = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
545 active = gtk_spin_button_get_value_as_int(pcd->first_page_count);
547 active = gnc_date_format_get_format (GNC_DATE_FORMAT(pcd->date_format));
551 format = gnc_date_format_get_custom (GNC_DATE_FORMAT(pcd->date_format));
561 gtk_spin_button_get_value(pcd->payee_x),
562 gtk_spin_button_get_value(pcd->payee_y));
564 gtk_spin_button_get_value(pcd->date_x),
565 gtk_spin_button_get_value(pcd->date_y));
567 gtk_spin_button_get_value(pcd->words_x),
568 gtk_spin_button_get_value(pcd->words_y));
570 gtk_spin_button_get_value(pcd->number_x),
571 gtk_spin_button_get_value(pcd->number_y));
573 gtk_spin_button_get_value(pcd->notes_x),
574 gtk_spin_button_get_value(pcd->notes_y));
576 gtk_spin_button_get_value(pcd->memo_x),
577 gtk_spin_button_get_value(pcd->memo_y));
579 gtk_spin_button_get_value(pcd->address_x),
580 gtk_spin_button_get_value(pcd->address_y));
582 gtk_spin_button_get_value(pcd->splits_amount_x),
583 gtk_spin_button_get_value(pcd->splits_amount_y));
585 gtk_spin_button_get_value(pcd->splits_memo_x),
586 gtk_spin_button_get_value(pcd->splits_memo_y));
588 gtk_spin_button_get_value(pcd->splits_account_x),
589 gtk_spin_button_get_value(pcd->splits_account_y));
591 gtk_spin_button_get_value(pcd->translation_x),
592 gtk_spin_button_get_value(pcd->translation_y));
594 gtk_spin_button_get_value(pcd->check_rotation));
595 active = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->units_combobox));
605 gchar *format, *guid;
612 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox), 0);
613 else if (strcmp(guid,
"custom") == 0)
614 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox),
615 pcd->format_max - 1);
618 model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
619 if (find_existing_format(GTK_LIST_STORE(model), guid, &iter))
621 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(pcd->format_combobox), &iter);
625 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox), 0);
632 if (active < 0 || active > pcd->position_max)
634 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->position_combobox), active);
636 gtk_spin_button_set_value(pcd->first_page_count, (gdouble) active);
638 gnc_date_format_set_format(GNC_DATE_FORMAT(pcd->date_format), active);
644 gnc_date_format_set_custom(GNC_DATE_FORMAT(pcd->date_format), format);
651 gtk_spin_button_set_value(pcd->payee_x, x);
652 gtk_spin_button_set_value(pcd->payee_y, y);
655 gtk_spin_button_set_value(pcd->date_x, x);
656 gtk_spin_button_set_value(pcd->date_y, y);
658 gtk_spin_button_set_value(pcd->words_x, x);
659 gtk_spin_button_set_value(pcd->words_y, y);
661 gtk_spin_button_set_value(pcd->number_x, x);
662 gtk_spin_button_set_value(pcd->number_y, y);
664 gtk_spin_button_set_value(pcd->address_x, x);
665 gtk_spin_button_set_value(pcd->address_y, y);
667 gtk_spin_button_set_value(pcd->notes_x, x);
668 gtk_spin_button_set_value(pcd->notes_y, y);
670 gtk_spin_button_set_value(pcd->memo_x, x);
671 gtk_spin_button_set_value(pcd->memo_y, y);
673 gtk_spin_button_set_value(pcd->splits_amount_x, x);
674 gtk_spin_button_set_value(pcd->splits_amount_y, y);
676 gtk_spin_button_set_value(pcd->splits_memo_x, x);
677 gtk_spin_button_set_value(pcd->splits_memo_y, y);
679 gtk_spin_button_set_value(pcd->splits_account_x, x);
680 gtk_spin_button_set_value(pcd->splits_account_y, y);
682 gtk_spin_button_set_value(pcd->translation_x, x);
683 gtk_spin_button_set_value(pcd->translation_y, y);
685 gtk_spin_button_set_value(pcd->check_rotation, x);
687 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->units_combobox), active);
696 selected = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->units_combobox));
716 pcd_key_file_save_xy (GKeyFile *key_file,
const gchar *group_name,
717 const gchar *key_name, gdouble multip,
718 GtkSpinButton *spin0, GtkSpinButton *spin1)
722 dd[0] = multip * gtk_spin_button_get_value(spin0);
723 dd[1] = multip * gtk_spin_button_get_value(spin1);
726 dd[0] = round(dd[0] * 1000) / 1000;
727 dd[1] = round(dd[1] * 1000) / 1000;
728 g_key_file_set_double_list(key_file, group_name, key_name, dd, 2);
737 pcd_key_file_save_item_xy (GKeyFile *key_file,
int index,
738 CheckItemType type, gdouble multip,
739 GtkSpinButton *spin0, GtkSpinButton *spin1)
742 key = g_strdup_printf(
"Type_%d", index);
743 g_key_file_set_string(key_file, KF_GROUP_ITEMS, key,
744 CheckItemTypeasString(type));
746 key = g_strdup_printf(
"Coords_%d", index);
747 pcd_key_file_save_xy(key_file, KF_GROUP_ITEMS, key, multip, spin0, spin1);
759 GError *error = NULL;
765 gchar *filename, *pathname;
767 multip = pcd_get_custom_multip(pcd);
769 key_file = g_key_file_new();
772 g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf);
773 g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
774 g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, FALSE);
775 g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, FALSE);
776 g_key_file_set_double(key_file, KF_GROUP_TOP, KF_KEY_ROTATION,
777 gtk_spin_button_get_value(pcd->check_rotation));
778 pcd_key_file_save_xy(key_file, KF_GROUP_TOP, KF_KEY_TRANSLATION, multip,
779 pcd->translation_x, pcd->translation_y);
781 pcd_key_file_save_item_xy(key_file, i++, PAYEE, multip,
782 pcd->payee_x, pcd->payee_y);
783 pcd_key_file_save_item_xy(key_file, i++, DATE, multip,
784 pcd->date_x, pcd->date_y);
785 pcd_key_file_save_item_xy(key_file, i++, AMOUNT_WORDS, multip,
786 pcd->words_x, pcd->words_y);
787 pcd_key_file_save_item_xy(key_file, i++, AMOUNT_NUMBER, multip,
788 pcd->number_x, pcd->number_y);
789 pcd_key_file_save_item_xy(key_file, i++, ADDRESS, multip,
790 pcd->address_x, pcd->address_y);
791 pcd_key_file_save_item_xy(key_file, i++, NOTES, multip,
792 pcd->notes_x, pcd->notes_y);
793 pcd_key_file_save_item_xy(key_file, i++, MEMO, multip,
794 pcd->memo_x, pcd->memo_y);
795 pcd_key_file_save_item_xy(key_file, i++, SPLITS_AMOUNT, multip,
796 pcd->splits_amount_x, pcd->splits_amount_y);
797 pcd_key_file_save_item_xy(key_file, i++, SPLITS_MEMO, multip,
798 pcd->splits_memo_x, pcd->splits_memo_y);
799 pcd_key_file_save_item_xy(key_file, i++, SPLITS_ACCOUNT, multip,
800 pcd->splits_account_x, pcd->splits_account_y);
802 filename = g_strconcat(title, CHECK_NAME_EXTENSION, NULL);
810 initialize_format_combobox(pcd);
812 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox),
813 pcd->format_max - 1);
817 dialog = gtk_message_dialog_new(GTK_WINDOW(pcd->dialog),
818 GTK_DIALOG_DESTROY_WITH_PARENT,
820 GTK_BUTTONS_CLOSE,
"%s",
821 _(
"Cannot save check format file."));
822 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
823 "%s", error->message);
824 gtk_dialog_run(GTK_DIALOG(dialog));
825 gtk_widget_destroy(dialog);
836 gnc_check_format_title_changed (GtkEditable *editable, GtkWidget *ok_button)
841 text = gtk_entry_get_text(GTK_ENTRY(editable));
842 sensitive = text && *text;
843 gtk_widget_set_sensitive(ok_button, sensitive);
852 gnc_print_check_save_button_clicked(GtkButton *unused,
PrintCheckDialog *pcd)
854 GtkWidget *dialog, *entry, *button;
858 builder = gtk_builder_new();
859 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"Format Title Dialog");
862 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"Format Title Dialog"));
863 entry = GTK_WIDGET(gtk_builder_get_object (builder,
"format_title"));
864 button = GTK_WIDGET(gtk_builder_get_object (builder,
"ok_button"));
865 gnc_check_format_title_changed(GTK_EDITABLE(entry), button);
866 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, pcd);
868 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(pcd->dialog));
869 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
871 gtk_widget_destroy(dialog);
872 g_object_unref(G_OBJECT(builder));
876 title = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
877 gtk_widget_destroy (dialog);
879 g_object_unref(G_OBJECT(builder));
881 pcd_save_custom_data(pcd, title);
890 doubles_to_string(gdouble *dd, gint len)
895 str = g_string_new_len(NULL, 50);
896 for (i = 0; i < len; i++)
897 g_string_append_printf(str,
"%f ", dd[i]);
898 return g_string_free(str, FALSE);
912 format_read_item_placement(
const gchar *file,
916 GError *error = NULL;
918 gchar *key, *value, *name;
925 for (item_num = 1;; item_num++)
934 key = g_strdup_printf(
"%s_%d", KF_KEY_TYPE, item_num);
935 value = g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
938 if ((error->domain == G_KEY_FILE_ERROR)
939 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND))
946 g_debug(
"Check file %s, group %s, key %s, value: %s",
947 file, KF_GROUP_ITEMS, key, value);
951 name = g_utf8_strup(value, -1);
952 data->
type = CheckItemTypefromString(name);
958 key = g_strdup_printf(
"%s_%d", KF_KEY_COORDS, item_num);
959 dd = g_key_file_get_double_list(key_file, KF_GROUP_ITEMS,
960 key, &dd_len, &error);
963 value = doubles_to_string(dd, dd_len);
964 g_debug(
"Check file %s, group %s, key %s, length %"G_GSIZE_FORMAT
"; values: %s",
965 file, KF_GROUP_ITEMS, key, dd_len, value);
981 (
"Check file %s, group %s, key %s, error: 2 or 4 values only",
982 file, KF_GROUP_ITEMS, key);
994 if (data->
type != PICTURE)
996 key = g_strdup_printf(
"%s_%d", KF_KEY_FONT, item_num);
998 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
1001 g_debug(
"Check file %s, group %s, key %s, value: %s",
1002 file, KF_GROUP_ITEMS, key, data->
font);
1006 if (!((error->domain == G_KEY_FILE_ERROR)
1007 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1008 g_warning(
"Check file %s, group %s, key %s, error: %s",
1009 file, KF_GROUP_ITEMS, key, error->message);
1010 g_clear_error(&error);
1014 key = g_strdup_printf(
"%s_%d", KF_KEY_ALIGN, item_num);
1016 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
1019 g_debug(
"Check file %s, group %s, key %s, value: %s",
1020 file, KF_GROUP_ITEMS, key, value);
1021 name = g_utf8_strdown(value, -1);
1022 if (strcmp(name,
"right") == 0)
1023 data->
align = PANGO_ALIGN_RIGHT;
1024 else if (strcmp(name,
"center") == 0)
1025 data->
align = PANGO_ALIGN_CENTER;
1027 data->
align = PANGO_ALIGN_LEFT;
1033 if (!((error->domain == G_KEY_FILE_ERROR)
1034 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1035 g_warning(
"Check file %s, group %s, key %s, error: %s",
1036 file, KF_GROUP_ITEMS, key, error->message);
1037 data->
align = PANGO_ALIGN_LEFT;
1038 g_clear_error(&error);
1042 key = g_strdup_printf(
"%s_%d", KF_KEY_BLOCKING, item_num);
1044 g_key_file_get_boolean(key_file, KF_GROUP_ITEMS, key, &error);
1047 g_debug(
"Check file %s, group %s, key %s, value: %d",
1048 file, KF_GROUP_ITEMS, key, bval);
1053 if (!((error->domain == G_KEY_FILE_ERROR)
1054 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1055 g_warning(
"Check file %s, group %s, key %s, error: %s",
1056 file, KF_GROUP_ITEMS, key, error->message);
1058 g_clear_error(&error);
1066 key = g_strdup_printf(
"%s_%d", KF_KEY_FILENAME, item_num);
1068 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key,
1072 g_debug(
"Check file %s, group %s, key %s, value: %s",
1073 file, KF_GROUP_ITEMS, key, data->
filename);
1077 key = g_strdup_printf(
"%s_%d", KF_KEY_TEXT, item_num);
1079 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key,
1083 g_debug(
"Check file %s, group %s, key %s, value: %s",
1084 file, KF_GROUP_ITEMS, key, data->
text);
1089 key = g_strdup_printf(
"%s_%d", KF_KEY_DATE_FORMAT, item_num);
1090 bval = g_key_file_get_boolean(key_file, KF_GROUP_ITEMS, key, &error);
1093 g_debug(
"Check file %s, group %s, key %s, value: %d",
1094 file, KF_GROUP_ITEMS, key, bval);
1099 if (!((error->domain == G_KEY_FILE_ERROR)
1100 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1101 g_warning(
"Check file %s, group %s, key %s, error: %s",
1102 file, KF_GROUP_ITEMS, key, error->message);
1104 g_clear_error(&error);
1112 list = g_slist_append(list, data);
1120 g_warning(
"Check file %s, group %s, key %s, error: %s",
1121 file, KF_GROUP_ITEMS, key, error->message);
1124 g_error_free(error);
1154 format_read_multicheck_info(
const gchar *file,
1157 GError *error = NULL;
1158 GSList *list = NULL;
1159 gchar *key, **names;
1163 key = g_strdup_printf(
"%s", KF_KEY_HEIGHT);
1164 format->
height = g_key_file_get_double(key_file, KF_GROUP_POS, key, &error);
1167 if ((error->domain == G_KEY_FILE_ERROR)
1168 && ((error->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
1169 || (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1171 g_clear_error(&error);
1176 g_warning(
"Check file %s, error reading group %s, key %s: %s",
1177 file, KF_GROUP_POS, key, error->message);
1183 names = g_key_file_get_string_list(key_file, KF_GROUP_POS, KF_KEY_NAMES,
1187 if ((error->domain == G_KEY_FILE_ERROR)
1188 && ((error->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
1189 || (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1195 g_warning(
"Check file %s, error reading group %s, key %s: %s",
1196 file, KF_GROUP_POS, key, error->message);
1201 for (i = 0; i < length; i++)
1202 list = g_slist_append(list, g_strdup(names[i]));
1212 free_check_position(gchar *name)
1223 format_read_general_info(
const gchar *file,
1226 GError *error = NULL;
1232 value = g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, &error);
1235 g_warning(
"Check file %s, group %s, key %s, error: %s",
1236 file, KF_GROUP_TOP, KF_KEY_GUID, error->message);
1237 g_error_free(error);
1240 parts = g_strsplit(value,
"-", -1);
1241 format->
guid = g_strjoinv(
"", parts);
1243 g_debug(
"Check file %s, group %s, key %s, value: %s",
1244 file, KF_GROUP_TOP, KF_KEY_GUID, format->
guid);
1247 g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, &error);
1250 g_debug(
"Check file %s, group %s, key %s, value: %s",
1251 file, KF_GROUP_TOP, KF_KEY_TITLE, format->
title);
1255 g_warning(
"Check file %s, group %s, key %s, error: %s",
1256 file, KF_GROUP_TOP, KF_KEY_TITLE, error->message);
1261 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_BLOCKING,
1265 g_debug(
"Check file %s, group %s, key %s, value: %d",
1266 file, KF_GROUP_TOP, KF_KEY_BLOCKING, format->
blocking);
1270 if (!((error->domain == G_KEY_FILE_ERROR)
1271 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1272 g_warning(
"Check file %s, group %s, key %s, error: %s",
1273 file, KF_GROUP_TOP, KF_KEY_BLOCKING, error->message);
1282 g_clear_error(&error);
1286 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_DATE_FORMAT,
1290 g_debug(
"Check file %s, group %s, key %s, value: %d",
1295 if (!((error->domain == G_KEY_FILE_ERROR)
1296 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1297 g_warning(
"Check file %s, group %s, key %s, error: %s",
1298 file, KF_GROUP_TOP, KF_KEY_DATE_FORMAT, error->message);
1307 g_clear_error(&error);
1311 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_GRID,
1315 g_debug(
"Check file %s, group %s, key %s, value: %d",
1316 file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, format->
show_grid);
1320 if (!((error->domain == G_KEY_FILE_ERROR)
1321 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1322 g_warning(
"Check file %s, group %s, key %s, error: %s",
1323 file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, error->message);
1325 g_clear_error(&error);
1329 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES,
1333 g_debug(
"Check file %s, group %s, key %s, value: %d",
1334 file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, format->
show_boxes);
1338 if (!((error->domain == G_KEY_FILE_ERROR)
1339 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1340 g_warning(
"Check file %s, group %s, key %s, error: %s",
1341 file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, error->message);
1343 g_clear_error(&error);
1347 g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_FONT, &error);
1350 g_debug(
"Check file %s, group %s, key %s, value: %s",
1351 file, KF_GROUP_TOP, KF_KEY_FONT, format->
font);
1355 if (!((error->domain == G_KEY_FILE_ERROR)
1356 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1357 g_warning(
"Check file %s, group %s, key %s, error: %s",
1358 file, KF_GROUP_TOP, KF_KEY_FONT, error->message);
1359 g_clear_error(&error);
1363 g_key_file_get_double(key_file, KF_GROUP_TOP, KF_KEY_ROTATION, &error);
1366 g_debug(
"Check file %s, group %s, key %s, value: %f",
1367 file, KF_GROUP_TOP, KF_KEY_ROTATION, format->
rotation);
1371 if (!((error->domain == G_KEY_FILE_ERROR)
1372 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1373 g_warning(
"Check file %s, group %s, key %s, error: %s",
1374 file, KF_GROUP_TOP, KF_KEY_ROTATION, error->message);
1376 g_clear_error(&error);
1379 dd = g_key_file_get_double_list(key_file, KF_GROUP_TOP, KF_KEY_TRANSLATION,
1383 value = doubles_to_string(dd, dd_len);
1384 g_debug(
"Check file %s, group %s, key %s, length %"G_GSIZE_FORMAT
"; values: %s",
1385 file, KF_GROUP_TOP, KF_KEY_TRANSLATION, dd_len, value);
1395 g_warning(
"Check file %s, error top %s, key %s: 2 values only",
1396 file, KF_GROUP_TOP, KF_KEY_TRANSLATION);
1402 if (!((error->domain == G_KEY_FILE_ERROR)
1403 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1404 g_warning(
"Check file %s, group top %s, key %s: %s",
1405 file, KF_GROUP_ITEMS, KF_KEY_TRANSLATION, error->message);
1406 g_clear_error(&error);
1420 g_free(data->
title);
1422 g_slist_foreach(data->
positions, (GFunc) free_check_position, NULL);
1424 g_slist_foreach(data->
items, (GFunc) format_free_item_placement, NULL);
1425 g_slist_free(data->
items);
1436 const gchar *dirname,
const gchar *file)
1442 pathname = g_build_filename(dirname, file, (
char *)NULL);
1447 g_warning(
"Check file %s, cannot load file", file);
1452 format->
group = groupname;
1454 if (format_read_general_info(file, key_file, format))
1456 format->
positions = format_read_multicheck_info(file, key_file, format);
1457 format->
items = format_read_item_placement(file, key_file, format);
1460 g_key_file_free(key_file);
1461 if ((NULL == format->
title) || (NULL == format->
items))
1463 g_warning(
"Check file %s, no items read. Dropping file.", file);
1464 free_check_format(format);
1478 const gchar *groupname,
const gchar *dirname)
1482 const gchar *filename;
1485 gboolean found = FALSE;
1487 dir = g_dir_open(dirname, 0, NULL);
1491 while ((filename = g_dir_read_name(dir)) != NULL)
1493 if (g_str_has_prefix(filename,
"#"))
1495 if (!g_str_has_suffix(filename,
".chk"))
1498 format = read_one_check_format(pcd, groupname, dirname, filename);
1502 existing = find_existing_format(store, format->
guid, NULL);
1505 dialog = gtk_message_dialog_new
1506 (GTK_WINDOW(pcd->dialog),
1507 GTK_DIALOG_DESTROY_WITH_PARENT,
1508 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
"%s",
1509 _(
"There is a duplicate check format file."));
1510 gtk_message_dialog_format_secondary_text
1511 (GTK_MESSAGE_DIALOG(dialog),
1517 _(
"The GUIDs in the %s check format file '%s' and "
1518 "the %s check format file '%s' match."),
1521 gtk_dialog_run(GTK_DIALOG(dialog));
1522 gtk_widget_destroy(dialog);
1526 gtk_list_store_append(store, &iter);
1538 gtk_list_store_append(store, &iter);
1539 gtk_list_store_set(store, &iter,
COL_SEP, TRUE, -1);
1551 gchar *dirname, *pkgdatadir;
1553 pkgdatadir = gnc_path_get_pkgdatadir();
1554 dirname = g_build_filename(pkgdatadir, CHECK_FMT_DIR, (
char *)NULL);
1558 read_one_check_directory(pcd, store, _(
"application"), dirname);
1566 read_one_check_directory(pcd, store, _(
"user"), dirname);
1572 format_is_a_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
1576 gtk_tree_model_get(model, iter,
COL_SEP, &separator, -1);
1584 GtkListStore *store;
1587 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
1588 read_formats(pcd, store);
1589 gtk_list_store_append(store, &iter);
1590 gtk_list_store_set(store, &iter,
COL_NAME, _(
"Custom"), -1);
1591 pcd->format_max = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
1592 gtk_combo_box_set_model(GTK_COMBO_BOX(pcd->format_combobox),
1593 GTK_TREE_MODEL(store));
1594 gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(pcd->format_combobox),
1595 format_is_a_separator, NULL, NULL);
1608 GtkBuilder *builder;
1615 pcd->plugin_page = plugin_page;
1616 pcd->splits = g_list_copy(splits);
1618 builder = gtk_builder_new();
1619 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment1");
1620 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment2");
1621 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment3");
1622 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment4");
1623 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment5");
1624 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment6");
1625 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment7");
1626 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment8");
1627 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment9");
1628 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment10");
1629 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment11");
1630 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment12");
1631 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment13");
1632 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment14");
1633 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment15");
1634 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment16");
1635 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment17");
1636 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment18");
1637 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment19");
1638 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment20");
1639 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment21");
1640 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment22");
1641 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment23");
1642 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"adjustment24");
1643 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"liststore1");
1644 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"liststore2");
1645 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"liststore3");
1646 gnc_builder_add_from_file (builder,
"dialog-print-check.glade",
"Print Check Dialog");
1648 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, pcd);
1650 pcd->builder = builder;
1651 pcd->dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"Print Check Dialog"));
1654 pcd->format_combobox = GTK_WIDGET(gtk_builder_get_object (builder,
"check_format_combobox"));
1655 pcd->position_combobox = GTK_WIDGET(gtk_builder_get_object (builder,
"check_position_combobox"));
1656 pcd->first_page_count = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"first_page_count_entry"));
1658 pcd->custom_table = GTK_WIDGET(gtk_builder_get_object (builder,
"custom_table"));
1659 pcd->payee_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"payee_x_entry"));
1660 pcd->payee_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"payee_y_entry"));
1661 pcd->date_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"date_x_entry"));
1662 pcd->date_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"date_y_entry"));
1663 pcd->words_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"amount_words_x_entry"));
1664 pcd->words_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"amount_words_y_entry"));
1665 pcd->number_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"amount_numbers_x_entry"));
1666 pcd->number_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"amount_numbers_y_entry"));
1667 pcd->notes_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"notes_x_entry"));
1668 pcd->notes_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"notes_y_entry"));
1669 pcd->memo_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"memo_x_entry"));
1670 pcd->memo_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"memo_y_entry"));
1671 pcd->address_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"address_x_entry"));
1672 pcd->address_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"address_y_entry"));
1673 pcd->splits_amount_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_amount_x_entry"));
1674 pcd->splits_amount_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_amount_y_entry"));
1675 pcd->splits_memo_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_memo_x_entry"));
1676 pcd->splits_memo_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_memo_y_entry"));
1677 pcd->splits_account_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_account_x_entry"));
1678 pcd->splits_account_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"splits_account_y_entry"));
1679 pcd->translation_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"translation_x_entry"));
1680 pcd->translation_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"translation_y_entry"));
1681 pcd->translation_label = GTK_WIDGET(gtk_builder_get_object (builder,
"translation_label"));
1682 pcd->check_rotation = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"check_rotation_entry"));
1683 pcd->units_combobox = GTK_WIDGET(gtk_builder_get_object (builder,
"units_combobox"));
1685 window = GTK_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1686 gtk_window_set_transient_for(GTK_WINDOW(pcd->dialog), window);
1687 pcd->caller_window = GTK_WINDOW(window);
1690 table = GTK_WIDGET(gtk_builder_get_object (builder,
"options_table"));
1691 pcd->date_format = gnc_date_format_new_without_label();
1692 gtk_table_attach_defaults(GTK_TABLE(table), pcd->date_format, 1, 3, 4, 7);
1696 pcd->default_font = font ? font : g_strdup(DEFAULT_FONT);
1699 initialize_format_combobox(pcd);
1702 pcd->check_address_name = GTK_WIDGET(gtk_builder_get_object (builder,
"check_address_name"));
1703 pcd->check_address_1 = GTK_WIDGET(gtk_builder_get_object (builder,
"check_address_1"));
1704 pcd->check_address_2 = GTK_WIDGET(gtk_builder_get_object (builder,
"check_address_2"));
1705 pcd->check_address_3 = GTK_WIDGET(gtk_builder_get_object (builder,
"check_address_3"));
1706 pcd->check_address_4 = GTK_WIDGET(gtk_builder_get_object (builder,
"check_address_4"));
1710 if (g_list_length(pcd->splits) == 1)
1723 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"lower_left")));
1725 gnc_ui_print_restore_dialog(pcd);
1726 gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(pcd->dialog));
1728 g_object_unref(G_OBJECT(builder));
1729 gtk_widget_show_all(pcd->dialog);
1741 draw_grid(GtkPrintContext *context, gint width, gint height,
const gchar *font)
1743 const double dash_pattern[2] = { 1.0, 5.0 };
1744 PangoFontDescription *desc;
1745 PangoLayout *layout;
1751 layout = gtk_print_context_create_pango_layout(context);
1752 desc = pango_font_description_from_string(font);
1753 pango_layout_set_font_description(layout, desc);
1754 pango_font_description_free(desc);
1755 pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
1756 pango_layout_set_width(layout, -1);
1759 cr = gtk_print_context_get_cairo_context(context);
1761 cairo_set_line_width(cr, 1.0);
1762 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
1763 cairo_set_dash(cr, dash_pattern, 2, 0);
1766 for (i = -200; i < (height + 200); i += 50)
1768 text = g_strdup_printf(
"%d", (
int)i);
1769 cairo_move_to(cr, -200, i);
1770 cairo_line_to(cr, width + 200, i);
1772 pango_layout_set_text(layout, text, -1);
1773 cairo_move_to(cr, 0, i);
1774 pango_cairo_show_layout(cr, layout);
1779 for (i = -200; i < (width + 200); i += 50)
1781 text = g_strdup_printf(
"%d", (
int)i);
1782 cairo_move_to(cr, i, -200);
1783 cairo_line_to(cr, i, height + 200);
1785 pango_layout_set_text(layout, text, -1);
1786 cairo_move_to(cr, i, 0);
1787 pango_cairo_show_layout(cr, layout);
1793 g_object_unref(layout);
1803 draw_text(GtkPrintContext *context,
const gchar *text,
check_item_t *data,
1804 PangoFontDescription *default_desc)
1806 PangoFontDescription *desc;
1807 PangoLayout *layout;
1809 gint layout_height, layout_width;
1810 gdouble width, height;
1813 if ((NULL == text) || (strlen(text) == 0))
1817 layout = gtk_print_context_create_pango_layout(context);
1820 desc = pango_font_description_from_string(data->
font);
1821 pango_layout_set_font_description(layout, desc);
1822 pango_font_description_free(desc);
1826 pango_layout_set_font_description(layout, default_desc);
1828 pango_layout_set_alignment(layout,
1829 data->w ? data->
align : PANGO_ALIGN_LEFT);
1830 pango_layout_set_width(layout, data->w ? data->w * PANGO_SCALE : -1);
1831 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
1834 new_text = g_strdup_printf(
"***%s***", text);
1835 pango_layout_set_text(layout, new_text, -1);
1840 pango_layout_set_text(layout, text, -1);
1842 pango_layout_get_size(layout, &layout_width, &layout_height);
1843 width = (gdouble) layout_width / PANGO_SCALE;
1844 height = (gdouble) layout_height / PANGO_SCALE;
1846 cr = gtk_print_context_get_cairo_context(context);
1850 if (data->w && data->
h)
1852 g_debug(
"Text clip rectangle, coords %f,%f, size %f,%f",
1853 data->x, data->
y - data->
h, data->w, data->
h);
1854 cairo_rectangle(cr, data->x, data->
y - data->
h, data->w, data->
h);
1855 cairo_clip_preserve(cr);
1859 g_debug(
"Text move to %f,%f, print '%s'", data->x, data->
y,
1860 text ? text :
"(null)");
1861 cairo_move_to(cr, data->x, data->
y - height);
1862 pango_cairo_show_layout(cr, layout);
1866 g_object_unref(layout);
1882 read_image (
const gchar *filename)
1885 gchar *pkgdatadir, *dirname, *tmp_name;
1887 if (g_path_is_absolute(filename))
1888 return gtk_image_new_from_file(filename);
1890 pkgdatadir = gnc_path_get_pkgdatadir();
1891 tmp_name = g_build_filename(pkgdatadir, CHECK_FMT_DIR, filename, (
char *)NULL);
1892 if (!g_file_test(tmp_name, G_FILE_TEST_EXISTS))
1896 tmp_name = g_build_filename(dirname, filename, (
char *)NULL);
1899 image = gtk_image_new_from_file(tmp_name);
1910 draw_picture(GtkPrintContext *context,
check_item_t *data)
1913 GdkPixbuf *pixbuf, *scaled_pixbuf;
1916 gdouble scale_w, scale_h, scale;
1918 cr = gtk_print_context_get_cairo_context(context);
1922 image = GTK_IMAGE(read_image(data->
filename));
1923 pixbuf = gtk_image_get_pixbuf(image);
1926 g_object_ref(pixbuf);
1930 g_warning(
"Filename '%s' cannot be read or understood.",
1932 pixbuf = gtk_widget_render_icon(GTK_WIDGET(image),
1933 GTK_STOCK_MISSING_IMAGE,
1936 pix_w = gdk_pixbuf_get_width(pixbuf);
1937 pix_h = gdk_pixbuf_get_height(pixbuf);
1940 if (data->w && data->
h)
1942 cairo_rectangle(cr, data->x, data->
y - data->
h, data->w, data->
h);
1943 g_debug(
"Picture clip rectangle, user coords %f,%f, user size %f,%f",
1944 data->x, data->
y - data->
h, data->w, data->
h);
1948 cairo_rectangle(cr, data->x, data->
y - pix_h, pix_w, pix_h);
1949 g_debug(
"Picture clip rectangle, user coords %f,%f, pic size %d,%d",
1950 data->x, data->
y - data->
h, pix_w, pix_h);
1952 cairo_clip_preserve(cr);
1955 scale_w = scale_h = 1;
1956 if (data->w && (pix_w > data->w))
1957 scale_w = data->w / pix_w;
1958 if (data->
h && (pix_h > data->
h))
1959 scale_h = data->
h / pix_h;
1960 scale = MIN(scale_w, scale_h);
1964 scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, pix_w * scale,
1966 GDK_INTERP_BILINEAR);
1967 pix_h = gdk_pixbuf_get_height(scaled_pixbuf);
1968 gdk_cairo_set_source_pixbuf(cr, scaled_pixbuf, data->x,
1971 g_object_unref(scaled_pixbuf);
1975 gdk_cairo_set_source_pixbuf(cr, pixbuf, data->x, data->
y - pix_h);
1977 g_object_unref(pixbuf);
1982 gtk_widget_destroy(GTK_WIDGET(image));
1986 #define DATE_FMT_HEIGHT 8
1987 #define DATE_FMT_SLOP 2
2002 draw_date_format(GtkPrintContext *context,
const gchar *date_format,
2003 check_item_t *data, PangoFontDescription *default_desc,
2006 PangoFontDescription *date_desc;
2008 gchar *text = NULL, *expanded = NULL;
2012 setlocale(LC_ALL, NULL);
2015 date_desc = pango_font_description_copy_static(default_desc);
2016 pango_font_description_set_size(date_desc, DATE_FMT_HEIGHT * PANGO_SCALE);
2018 date_item.
y += (DATE_FMT_HEIGHT + DATE_FMT_SLOP);
2019 date_item.w = width;
2020 date_item.
h = DATE_FMT_HEIGHT + DATE_FMT_SLOP;
2021 date_item.
align = PANGO_ALIGN_CENTER;
2024 cdn_fmt = g_string_new_len(NULL, 50);
2025 for (c = date_format; c && *c; )
2027 if ((c[0] !=
'%') || (c[1] ==
'\0'))
2035 cdn_fmt = g_string_append(cdn_fmt,
"YYYYMMDD");
2038 cdn_fmt = g_string_append(cdn_fmt,
"YYYY");
2041 cdn_fmt = g_string_append(cdn_fmt,
"YY");
2044 cdn_fmt = g_string_append(cdn_fmt,
"MM");
2048 cdn_fmt = g_string_append(cdn_fmt,
"DD");
2051 expanded = g_strdup_printf(
"%s%s",
2062 text = g_string_free(cdn_fmt, FALSE);
2063 draw_text(context, text, &date_item, date_desc);
2067 pango_font_description_free(date_desc);
2075 draw_page_items(GtkPrintContext *context,
2079 PangoFontDescription *default_desc;
2083 const gchar *date_format;
2084 gchar *text = NULL, buf[100];
2088 gchar *address = NULL;
2092 g_return_if_fail(trans);
2096 default_desc = pango_font_description_from_string(format->
font);
2098 default_desc = pango_font_description_from_string(pcd->default_font);
2101 for (elem = format->
items; elem; elem = g_slist_next(elem))
2110 g_date_clear (&date, 1);
2113 gnc_date_format_get_custom(GNC_DATE_FORMAT
2114 (pcd->date_format));
2115 g_date_strftime(buf, 100, date_format, &date);
2116 width = draw_text(context, buf, item, default_desc);
2117 draw_date_format(context, date_format, item, default_desc, width);
2134 draw_text(context, gnc_get_action_num(trans, pcd->split), item,
2139 draw_text(context, gnc_get_num_action(trans, pcd->split), item,
2144 info = gnc_default_print_info(FALSE);
2145 draw_text(context, xaccPrintAmount(amount, info),
2146 item, default_desc);
2150 text = numeric_to_words(amount);
2151 draw_text(context, text, item, default_desc);
2156 draw_text(context, item->
text, item, default_desc);
2160 address = get_check_address(pcd);
2161 draw_text(context, address, item, default_desc);
2166 text = get_check_splits_amount(pcd);
2167 draw_text(context, text, item, default_desc);
2172 text = get_check_splits_memo(pcd);
2173 draw_text(context, text, item, default_desc);
2177 case SPLITS_ACCOUNT:
2178 text = get_check_splits_account(pcd);
2179 draw_text(context, text, item, default_desc);
2184 draw_picture(context, item);
2188 text = g_strdup_printf(
"(unknown check field, type %d)", item->
type);
2189 draw_text(context, text, item, default_desc);
2195 pango_font_description_free(default_desc);
2203 draw_page_boxes(GtkPrintContext *context,
2210 cr = gtk_print_context_get_cairo_context(context);
2213 for (elem = format->
items; elem; elem = g_slist_next(elem))
2216 if (!item->w || !item->
h)
2218 cairo_rectangle(cr, item->x, item->
y - item->
h, item->w, item->
h);
2230 draw_check_format(GtkPrintContext *context, gint position,
2235 gdouble x, y, r, multip;
2237 cr = gtk_print_context_get_cairo_context(context);
2239 g_debug(
"Page translated by %f,%f", format->
trans_x, format->
trans_y);
2240 cairo_rotate(cr, format->
rotation * DEGREES_TO_RADIANS);
2241 g_debug(
"Page rotated by %f degrees", format->
rotation);
2247 gtk_print_context_get_width(context),
2248 gtk_print_context_get_height(context),
2254 if ((position > 0) && (position < pcd->position_max))
2259 cairo_translate(cr, 0, format->
height);
2260 g_debug(
"Position %d translated by %f (pre-defined)", position, format->
height);
2262 else if (position == pcd->position_max)
2265 multip = pcd_get_custom_multip(pcd);
2266 x = multip * gtk_spin_button_get_value(pcd->translation_x);
2267 y = multip * gtk_spin_button_get_value(pcd->translation_y);
2268 cairo_translate(cr, x, y);
2269 g_debug(
"Position translated by %f,%f (custom)", x, y);
2270 r = gtk_spin_button_get_value(pcd->check_rotation);
2271 cairo_rotate(cr, r * DEGREES_TO_RADIANS);
2272 g_debug(
"Position rotated by %f degrees (custom)", r);
2278 draw_page_boxes(context, format, user_data);
2281 draw_page_items(context, format, user_data);
2286 draw_check_custom(GtkPrintContext *context, gpointer user_data)
2290 PangoFontDescription *desc;
2294 const gchar *date_format;
2295 gchar *text = NULL, buf[100];
2297 gdouble x, y, multip, degrees;
2303 g_return_if_fail(trans);
2305 desc = pango_font_description_from_string(pcd->default_font);
2307 multip = pcd_get_custom_multip(pcd);
2308 degrees = gtk_spin_button_get_value(pcd->check_rotation);
2309 cr = gtk_print_context_get_cairo_context(context);
2310 cairo_rotate(cr, degrees * DEGREES_TO_RADIANS);
2311 g_debug(
"Page rotated by %f degrees", degrees);
2313 x = multip * gtk_spin_button_get_value(pcd->translation_x);
2314 y = multip * gtk_spin_button_get_value(pcd->translation_y);
2315 cairo_translate(cr, x, y);
2316 g_debug(
"Page translated by %f,%f", x, y);
2318 item.x = multip * gtk_spin_button_get_value(pcd->payee_x);
2319 item.
y = multip * gtk_spin_button_get_value(pcd->payee_y);
2322 item.x = multip * gtk_spin_button_get_value(pcd->date_x);
2323 item.
y = multip * gtk_spin_button_get_value(pcd->date_y);
2324 g_date_clear (&date, 1);
2326 date_format = gnc_date_format_get_custom(GNC_DATE_FORMAT(pcd->date_format));
2327 g_date_strftime(buf, 100, date_format, &date);
2328 draw_text(context, buf, &item, desc);
2330 item.x = multip * gtk_spin_button_get_value(pcd->number_x);
2331 item.
y = multip * gtk_spin_button_get_value(pcd->number_y);
2332 info = gnc_default_print_info(FALSE);
2334 draw_text(context, xaccPrintAmount(amount, info), &item, desc);
2336 item.x = multip * gtk_spin_button_get_value(pcd->words_x);
2337 item.
y = multip * gtk_spin_button_get_value(pcd->words_y);
2338 text = numeric_to_words(amount);
2339 draw_text(context, text, &item, desc);
2342 item.x = multip * gtk_spin_button_get_value(pcd->address_x);
2343 item.
y = multip * gtk_spin_button_get_value(pcd->address_y);
2344 address = get_check_address(pcd);
2345 draw_text(context, address, &item, desc);
2348 item.x = multip * gtk_spin_button_get_value(pcd->splits_amount_x);
2349 item.
y = multip * gtk_spin_button_get_value(pcd->splits_amount_y);
2350 text = get_check_splits_amount(pcd);
2351 draw_text(context, text, &item, desc);
2354 item.x = multip * gtk_spin_button_get_value(pcd->splits_memo_x);
2355 item.
y = multip * gtk_spin_button_get_value(pcd->splits_memo_y);
2356 text = get_check_splits_memo(pcd);
2357 draw_text(context, text, &item, desc);
2360 item.x = multip * gtk_spin_button_get_value(pcd->splits_account_x);
2361 item.
y = multip * gtk_spin_button_get_value(pcd->splits_account_y);
2362 text = get_check_splits_account(pcd);
2363 draw_text(context, text, &item, desc);
2366 item.x = multip * gtk_spin_button_get_value(pcd->notes_x);
2367 item.
y = multip * gtk_spin_button_get_value(pcd->notes_y);
2370 item.x = multip * gtk_spin_button_get_value(pcd->memo_x);
2371 item.
y = multip * gtk_spin_button_get_value(pcd->memo_y);
2374 pango_font_description_free(desc);
2383 draw_page(GtkPrintOperation *operation,
2384 GtkPrintContext *context, gint page_nr, gpointer user_data)
2389 format = pcd->selected_format;
2392 gint first_check, last_check;
2393 gint first_page_count;
2394 guint check_count = g_list_length(pcd->splits);
2396 gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2397 gint checks_per_page;
2400 if (position == pcd->position_max)
2403 checks_per_page = 1;
2404 first_page_count = 1;
2408 checks_per_page = pcd->position_max;
2409 first_page_count = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2415 last_check = first_page_count - 1;
2416 next_split = pcd->splits;
2420 first_check = first_page_count + (page_nr - 1) * checks_per_page;
2421 last_check = MIN(check_count - 1, first_check + checks_per_page - 1);
2422 next_split = g_list_nth(pcd->splits, first_check);
2424 if (position < pcd->position_max)
2428 for (check_number = first_check; check_number <= last_check;
2429 check_number++, position++)
2431 pcd->split = (
Split *) next_split->data;
2432 next_split = g_list_next(next_split);
2433 draw_check_format(context, position, format, user_data);
2439 pcd->split = (
Split *) g_list_nth_data(pcd->splits, page_nr);
2440 g_return_if_fail(pcd->split);
2441 draw_check_custom(context, user_data);
2451 begin_print(GtkPrintOperation *operation,
2452 GtkPrintContext *context, gpointer user_data)
2455 guint check_count = g_list_length(pcd->splits);
2456 gint first_page_count;
2458 gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2460 if (pcd->selected_format && pcd->position_max > 1 && position < pcd->position_max)
2462 first_page_count = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2463 pages = ((check_count - first_page_count) + pcd->position_max - 1) /
2464 pcd->position_max + 1;
2467 pages = check_count;
2468 gtk_print_operation_set_n_pages(operation, pages);
2478 GtkPrintOperation *print;
2479 GtkPrintOperationResult res;
2481 print = gtk_print_operation_new();
2484 gtk_print_operation_set_unit(print, GTK_UNIT_POINTS);
2485 gtk_print_operation_set_use_full_page(print, TRUE);
2486 g_signal_connect(print,
"begin_print", G_CALLBACK(begin_print), pcd);
2487 g_signal_connect(print,
"draw_page", G_CALLBACK(draw_page), pcd);
2489 res = gtk_print_operation_run(print,
2490 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2491 pcd->caller_window, NULL);
2493 if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
2496 g_object_unref(print);
2501 gnc_print_check_set_sensitive (GtkWidget *widget, gpointer data)
2504 if (GTK_IS_LABEL(widget) || GTK_IS_SEPARATOR(widget))
2506 sensitive = GPOINTER_TO_INT(data);
2507 gtk_widget_set_sensitive(widget, sensitive);
2512 gnc_print_check_format_changed (GtkComboBox *widget,
2515 GtkListStore *p_store;
2516 GtkTreeModel *f_model;
2517 GtkTreeIter f_iter, iter;
2524 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pcd->format_combobox), &f_iter))
2526 f_model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
2527 gtk_tree_model_get(f_model, &f_iter,
COL_DATA, &format,
COL_SEP, &separator, -1);
2531 pnum = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2534 pcd->selected_format = format;
2535 p_store = gtk_list_store_new (1, G_TYPE_STRING);
2536 gtk_combo_box_set_model(GTK_COMBO_BOX(pcd->position_combobox),
2537 GTK_TREE_MODEL(p_store));
2542 pcd->position_max = g_slist_length(format->
positions);
2543 for (elem = format->
positions; elem; elem = g_slist_next(elem))
2545 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2546 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, elem->data, -1);
2552 pcd->position_max = 1;
2553 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2554 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, _(
"Top"), -1);
2559 pcd->position_max = 0;
2561 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2562 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, _(
"Custom"), -1);
2565 sensitive = (pcd->position_max > 0);
2566 gtk_widget_set_sensitive(GTK_WIDGET(pcd->position_combobox), sensitive);
2571 sensitive = (!separator && !format);
2572 gtk_container_foreach(GTK_CONTAINER(pcd->custom_table),
2573 gnc_print_check_set_sensitive,
2574 GINT_TO_POINTER(sensitive));
2578 pnum = MAX(MIN(pnum, pcd->position_max), 0);
2579 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->position_combobox), pnum);
2582 sensitive = check_format_has_address(pcd);
2583 gtk_widget_set_sensitive(pcd->check_address_name, sensitive);
2584 gtk_widget_set_sensitive(pcd->check_address_1, sensitive);
2585 gtk_widget_set_sensitive(pcd->check_address_2, sensitive);
2586 gtk_widget_set_sensitive(pcd->check_address_3, sensitive);
2587 gtk_widget_set_sensitive(pcd->check_address_4, sensitive);
2592 gnc_print_check_position_changed (GtkComboBox *widget,
2598 gint first_page_max, first_page_min, first_page_value;
2600 pnum = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2603 sensitive = pnum == pcd->position_max;
2604 gtk_widget_set_sensitive(GTK_WIDGET(pcd->translation_x), sensitive);
2605 gtk_widget_set_sensitive(GTK_WIDGET(pcd->translation_y), sensitive);
2606 gtk_widget_set_sensitive(GTK_WIDGET(pcd->check_rotation), sensitive);
2607 gtk_widget_set_sensitive(GTK_WIDGET(pcd->units_combobox), sensitive);
2610 check_count = g_list_length(pcd->splits);
2611 first_page_max = MAX(1, MIN(pcd->position_max - pnum, check_count));
2613 pnum = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2614 first_page_value = MAX(MIN(pnum, first_page_max), first_page_min);
2615 gtk_spin_button_set_range(pcd->first_page_count, (gdouble)first_page_min, (gdouble)first_page_max);
2616 gtk_spin_button_set_value(pcd->first_page_count, (gdouble)first_page_value);
2617 sensitive = first_page_max > 1;
2618 gtk_widget_set_sensitive(GTK_WIDGET(pcd->first_page_count), sensitive);
2623 gnc_ui_print_check_response_cb(GtkDialog *dialog,
2629 case GTK_RESPONSE_HELP:
2633 case GTK_RESPONSE_OK:
2634 gnc_ui_print_check_dialog_ok_cb(pcd);
2635 gnc_ui_print_save_dialog(pcd);
2636 gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
2639 case GTK_RESPONSE_CANCEL:
2640 gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
2644 gtk_widget_destroy(pcd->dialog);
2645 g_free(pcd->default_font);
2646 g_list_free(pcd->splits);
void guid_replace(GncGUID *guid)
time64 xaccTransGetDate(const Transaction *trans)
gchar * gnc_prefs_get_string(const gchar *group, const gchar *pref_name)
Date and Time handling routines.
utility functions for the GnuCash UI
An exact-rational-number library for gnucash. (to be renamed qofnumeric.h in libqof2) ...
gboolean gnc_prefs_set_int(const gchar *group, const gchar *pref_name, gint value)
GKeyFile helper routines.
void gnc_print_operation_save_print_settings(GtkPrintOperation *op)
void gnc_prefs_reset(const gchar *group, const gchar *pref_name)
Transaction * xaccSplitGetParent(const Split *split)
API for Transactions and Splits (journal entries)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gboolean gnc_prefs_set_string(const gchar *group, const gchar *pref_name, const gchar *value)
gchar * gnc_build_dotgnucash_path(const gchar *filename)
Make a path to filename in the user's configuration directory.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
const char * xaccTransGetNotes(const Transaction *trans)
gchar * gnc_get_account_name_for_register(const Account *account)
Functions providing a register page for the GnuCash UI.
void gnc_print_operation_init(GtkPrintOperation *op, const gchar *jobname)
gboolean print_date_format
gboolean gnc_key_file_save_to_file(const gchar *filename, GKeyFile *key_file, GError **error)
#define GUID_ENCODING_LENGTH
const gchar * qof_date_format_get_string(QofDateFormat df)
gboolean gnc_prefs_set_float(const gchar *group, const gchar *pref_name, gdouble value)
gboolean gnc_prefs_set_coords(const gchar *group, const gchar *pref_name, gdouble x, gdouble y)
void gnc_prefs_get_coords(const gchar *group, const gchar *pref_name, gdouble *x, gdouble *y)
const char * xaccTransGetDescription(const Transaction *trans)
GKeyFile * gnc_key_file_load_from_file(const gchar *filename, gboolean ignore_error, gboolean return_empty_struct, GError **caller_error)
gnc_numeric gnc_numeric_abs(gnc_numeric a)
void gnc_gnome_help(const char *file_name, const char *anchor)
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
Account * xaccSplitGetAccount(const Split *s)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
const gchar * gnc_dotgnucash_dir(void)
Ensure that the user's configuration directory exists and is minimally populated. ...
const char * xaccSplitGetMemo(const Split *split)
File path resolution utility functions.
API for Transactions and Splits (journal entries)
SplitList * xaccTransGetSplitList(const Transaction *trans)
const gchar * QofLogModule
void gnc_gdate_set_time64(GDate *gd, time64 time)
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
gnc_numeric xaccSplitGetAmount(const Split *split)