183{
184
185 CheckItemType type;
187 gdouble x, y;
192 gdouble w, h;
197 gchar *filename;
200 gchar *text;
203 gchar *font;
207 gboolean blocking;
212 gboolean print_date_format;
216 PangoAlignment align;
220
221
222
223
224
225
226typedef struct _check_format
227{
228
229 gchar *guid;
231 const gchar *group;
233 gchar *filename;
236 gchar *title;
239 gboolean blocking;
242 gboolean print_date_format;
245 gboolean show_grid;
247 gboolean show_boxes;
250 gdouble rotation;
252 gdouble trans_x;
254 gdouble trans_y;
256 gchar *font;
258 gdouble height;
260 GSList *positions;
262 GSList *items;
264
265
266
267
268
269
270
271
273{
274 GtkBuilder *builder;
275 GtkWidget *dialog;
276 GtkWindow *caller_window;
277
278 Split *split;
279 GList *splits;
281
282 GtkWidget *format_combobox;
283 gint format_max;
284 GtkWidget *position_combobox;
285 gint position_max;
286 GtkSpinButton *first_page_count;
287 GtkWidget *custom_table;
288 GtkSpinButton *payee_x, *payee_y;
289 GtkSpinButton *date_x, *date_y;
290 GtkSpinButton *words_x, *words_y;
291 GtkSpinButton *number_x, *number_y;
292 GtkSpinButton *address_x, *address_y;
293 GtkSpinButton *notes_x, *notes_y;
294 GtkSpinButton *memo_x, *memo_y;
295 GtkSpinButton *splits_amount_x, *splits_amount_y;
296 GtkSpinButton *splits_memo_x, *splits_memo_y;
297 GtkSpinButton *splits_account_x, *splits_account_y;
298 GtkSpinButton *translation_x, *translation_y;
299 GtkSpinButton *check_rotation;
300 GtkWidget *translation_label;
301
302 GtkWidget *units_combobox;
303
304 GtkWidget *date_format;
305
306 GtkWidget *check_address_name;
307 GtkWidget *check_address_1;
308 GtkWidget *check_address_2;
309 GtkWidget *check_address_3;
310 GtkWidget *check_address_4;
311
312 gchar *default_font;
313
315};
316
317
318
319
320
321
322
324find_existing_format (GtkListStore *store, gchar *guid, GtkTreeIter *iter_out)
325{
326 GtkTreeIter iter;
328
329 g_return_val_if_fail(store, NULL);
330 g_return_val_if_fail(guid, NULL);
331
332 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
333 return NULL;
334
335 do
336 {
337 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
339 if (format == NULL)
340 continue;
341 if (strcmp(format->
guid, guid) != 0)
342 continue;
343
344 if (iter_out)
345 *iter_out = iter;
346 return format;
347 }
348 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
349
350 return NULL;
351}
352
353
354
355
356
357
358
359gchar *
360get_check_address( PrintCheckDialog *pcd)
361{
362 gchar *address;
363 address = g_strconcat(gtk_entry_get_text(GTK_ENTRY(pcd->check_address_name)), "\n",
364 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_1)), "\n",
365 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_2)), "\n",
366 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_3)), "\n",
367 gtk_entry_get_text(GTK_ENTRY(pcd->check_address_4)),
368 NULL);
369 return address;
370}
371
373{
374 const Transaction* trans;
375 gnc_numeric amount;
376};
377
378static void
380{
381
383
384 trans_amount->amount = gnc_numeric_add_fixed(trans_amount->amount, amount);
385}
386
387
388
389static gnc_numeric
390get_check_amount(PrintCheckDialog *pcd)
391{
392 gnc_numeric amount;
393 if (pcd->account)
394 {
395
396
399 trans_amount.amount = gnc_numeric_zero();
400 gnc_account_foreach_descendant(pcd->account, (AccountCb)subtotal_subaccount, &trans_amount);
401 amount = trans_amount.amount;
402 }
403 else
404 {
405
407 }
409}
410
412
414
415
416gchar *
417get_check_splits_amount(PrintCheckDialog *pcd)
418{
419 gchar* amount = NULL;
420 Transaction *trans;
421 GList *node;
423
426 if ( !s_list ) return NULL;
427
428 amount = g_strconcat("", NULL);
429 node = s_list;
430 while ( node )
431 {
432 Split *split = node->data;
433
434 if (split != pcd->split)
435 {
436 const gchar* split_amount;
437 gchar* amt_temp;
439 amt_temp = amount;
440 if (amount && *amount)
441 amount = g_strconcat(amt_temp, "\n", split_amount, NULL);
442 else
443 amount = g_strconcat(amt_temp, split_amount, NULL);
444 g_free(amt_temp);
445 }
446 node = node->next;
447 }
448 return amount;
449}
450
451
452
453
454gchar *
455get_check_splits_memo(PrintCheckDialog *pcd)
456{
457 gchar* memo = NULL;
458 const gchar* split_memo;
459 Transaction *trans;
460 GList *node;
462
465 if ( !s_list ) return NULL;
466
467 memo = g_strconcat("", NULL);
468 node = s_list;
469 while ( node )
470 {
471 Split *split = node->data;
472
473 if (split != pcd->split)
474 {
475 gchar* memo_temp;
477 memo_temp = memo;
478 if (memo && *memo)
479 memo = g_strconcat(memo_temp, "\n", split_memo, NULL);
480 else
481 memo = g_strconcat(memo_temp, split_memo, NULL);
482 g_free(memo_temp);
483 }
484 node = node->next;
485 }
486 return memo;
487}
488
489
490
491
492gchar *
493get_check_splits_account(PrintCheckDialog *pcd)
494{
495 gchar* account = NULL;
496 Transaction *trans;
497 GList *node;
499
502 if ( !s_list ) return NULL;
503
504 account = g_strconcat("", NULL);
505 node = s_list;
506 while ( node )
507 {
508 Split *split = node->data;
509
510 if (split != pcd->split)
511 {
512 gchar* account_temp;
513 const gchar* aName = NULL;
517 account_temp = account;
518 if (account && *account)
519 account = g_strconcat(account_temp, "\n", aName, NULL);
520 else
521 account = g_strconcat(account_temp, aName, NULL);
522 g_free(account_temp);
523 }
524 node = node->next;
525 }
526 return account;
527}
529
530
531
532
533static gboolean
534check_format_has_address ( PrintCheckDialog *pcd )
535{
536
538 GSList *elem;
540
541 if ( !pcd ) return FALSE;
542
543
544 if (g_list_length(pcd->splits) != 1)
545 return FALSE;
546
547
548
549 format = pcd->selected_format;
550 if ( !format ) return TRUE;
551
552 for (elem = pcd->selected_format->items; elem; elem = g_slist_next(elem))
553 {
554 item = elem->data;
555 if ( item->
type == ADDRESS )
return TRUE;
556 }
557 return FALSE;
558}
559
560
561static void
562gnc_ui_print_save_dialog(PrintCheckDialog *pcd)
563{
564 GtkTreeModel *model;
565 GtkTreeIter iter;
567 const gchar *format;
568 gint active;
569
570
571 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pcd->format_combobox),
572 &iter))
573 {
574 model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
575 gtk_tree_model_get(model, &iter,
COL_DATA, &check, -1);
577 check ? check->
guid :
"custom");
578 }
579 active = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
581 active = gtk_spin_button_get_value_as_int(pcd->first_page_count);
583 active = gnc_date_format_get_format (GNC_DATE_FORMAT(pcd->date_format));
586 {
587 format = gnc_date_format_get_custom (GNC_DATE_FORMAT(pcd->date_format));
589 }
590 else
591 {
593 }
594
595
597 gtk_spin_button_get_value(pcd->payee_x),
598 gtk_spin_button_get_value(pcd->payee_y));
600 gtk_spin_button_get_value(pcd->date_x),
601 gtk_spin_button_get_value(pcd->date_y));
603 gtk_spin_button_get_value(pcd->words_x),
604 gtk_spin_button_get_value(pcd->words_y));
606 gtk_spin_button_get_value(pcd->number_x),
607 gtk_spin_button_get_value(pcd->number_y));
609 gtk_spin_button_get_value(pcd->notes_x),
610 gtk_spin_button_get_value(pcd->notes_y));
612 gtk_spin_button_get_value(pcd->memo_x),
613 gtk_spin_button_get_value(pcd->memo_y));
615 gtk_spin_button_get_value(pcd->address_x),
616 gtk_spin_button_get_value(pcd->address_y));
618 gtk_spin_button_get_value(pcd->splits_amount_x),
619 gtk_spin_button_get_value(pcd->splits_amount_y));
621 gtk_spin_button_get_value(pcd->splits_memo_x),
622 gtk_spin_button_get_value(pcd->splits_memo_y));
624 gtk_spin_button_get_value(pcd->splits_account_x),
625 gtk_spin_button_get_value(pcd->splits_account_y));
627 gtk_spin_button_get_value(pcd->translation_x),
628 gtk_spin_button_get_value(pcd->translation_y));
630 gtk_spin_button_get_value(pcd->check_rotation));
631 active = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->units_combobox));
633}
634
635
636static void
637gnc_ui_print_restore_dialog(PrintCheckDialog *pcd)
638{
639 GtkTreeModel *model;
640 GtkTreeIter iter;
641 gchar *format, *guid;
642 gdouble x, y;
643 gint active;
644
645
647 if (!(guid && *guid))
648 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox), 0);
649 else if (strcmp(guid, "custom") == 0)
650 {
651 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox),
652 pcd->format_max - 1);
653 }
654 else
655 {
656 model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
657 if (find_existing_format(GTK_LIST_STORE(model), guid, &iter))
658 {
659 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(pcd->format_combobox), &iter);
660 }
661 else
662 {
663 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox), 0);
664 }
665 }
666 g_free (guid);
667
669
670
671
672 if (active < 0 || active > pcd->position_max)
673 active = 0;
674 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->position_combobox), active);
676 gtk_spin_button_set_value(pcd->first_page_count, (gdouble) active);
678 gnc_date_format_set_format(GNC_DATE_FORMAT(pcd->date_format), active);
680 {
682 if (format && *format)
683 {
684 gnc_date_format_set_custom(GNC_DATE_FORMAT(pcd->date_format), format);
685 g_free(format);
686 }
687 }
688
689
691 gtk_spin_button_set_value(pcd->payee_x, x);
692 gtk_spin_button_set_value(pcd->payee_y, y);
693
695 gtk_spin_button_set_value(pcd->date_x, x);
696 gtk_spin_button_set_value(pcd->date_y, y);
698 gtk_spin_button_set_value(pcd->words_x, x);
699 gtk_spin_button_set_value(pcd->words_y, y);
701 gtk_spin_button_set_value(pcd->number_x, x);
702 gtk_spin_button_set_value(pcd->number_y, y);
704 gtk_spin_button_set_value(pcd->address_x, x);
705 gtk_spin_button_set_value(pcd->address_y, y);
707 gtk_spin_button_set_value(pcd->notes_x, x);
708 gtk_spin_button_set_value(pcd->notes_y, y);
710 gtk_spin_button_set_value(pcd->memo_x, x);
711 gtk_spin_button_set_value(pcd->memo_y, y);
713 gtk_spin_button_set_value(pcd->splits_amount_x, x);
714 gtk_spin_button_set_value(pcd->splits_amount_y, y);
716 gtk_spin_button_set_value(pcd->splits_memo_x, x);
717 gtk_spin_button_set_value(pcd->splits_memo_y, y);
719 gtk_spin_button_set_value(pcd->splits_account_x, x);
720 gtk_spin_button_set_value(pcd->splits_account_y, y);
722 gtk_spin_button_set_value(pcd->translation_x, x);
723 gtk_spin_button_set_value(pcd->translation_y, y);
725 gtk_spin_button_set_value(pcd->check_rotation, x);
727 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->units_combobox), active);
728}
729
730
731static gdouble
732pcd_get_custom_multip(PrintCheckDialog *pcd)
733{
734 gint selected;
735
736 selected = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->units_combobox));
737 switch (selected)
738 {
739 default:
740 return 72.0;
741 case 1:
742 return 28.346;
743 case 2:
744 return 2.8346;
745 case 3:
746 return 1.0;
747 }
748}
749
750
751
752
753
754
755static void
756pcd_key_file_save_xy (GKeyFile *key_file, const gchar *group_name,
757 const gchar *key_name, gdouble multip,
758 GtkSpinButton *spin0, GtkSpinButton *spin1)
759{
760 gdouble dd[2];
761
762 dd[0] = multip * gtk_spin_button_get_value(spin0);
763 dd[1] = multip * gtk_spin_button_get_value(spin1);
764
765
766 dd[0] = round(dd[0] * 1000) / 1000;
767 dd[1] = round(dd[1] * 1000) / 1000;
768 g_key_file_set_double_list(key_file, group_name, key_name, dd, 2);
769}
770
771
772
773
774
775
776static void
777pcd_key_file_save_item_xy (GKeyFile *key_file, int index,
778 CheckItemType type, gdouble multip,
779 GtkSpinButton *spin0, GtkSpinButton *spin1)
780{
781 gchar *key;
782 key = g_strdup_printf("Type_%d", index);
783 g_key_file_set_string(key_file, KF_GROUP_ITEMS, key,
784 CheckItemTypeasString(type));
785 g_free(key);
786 key = g_strdup_printf("Coords_%d", index);
787 pcd_key_file_save_xy(key_file, KF_GROUP_ITEMS, key, multip, spin0, spin1);
788 g_free(key);
789}
790
791
792
793
794
795static void
796pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title)
797{
798 GKeyFile *key_file;
799 GError *error = NULL;
800 GtkWidget *dialog;
801 gdouble multip;
802 gint i = 1;
805 gchar *filename, *pathname;
806
807 multip = pcd_get_custom_multip(pcd);
808
809 key_file = g_key_file_new();
812 g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf);
813 g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
814 g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, FALSE);
815 g_key_file_set_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, FALSE);
816 g_key_file_set_double(key_file, KF_GROUP_TOP, KF_KEY_ROTATION,
817 gtk_spin_button_get_value(pcd->check_rotation));
818 pcd_key_file_save_xy(key_file, KF_GROUP_TOP, KF_KEY_TRANSLATION, multip,
819 pcd->translation_x, pcd->translation_y);
820
821 pcd_key_file_save_item_xy(key_file, i++, PAYEE, multip,
822 pcd->payee_x, pcd->payee_y);
823 pcd_key_file_save_item_xy(key_file, i++, DATE, multip,
824 pcd->date_x, pcd->date_y);
825 pcd_key_file_save_item_xy(key_file, i++, AMOUNT_WORDS, multip,
826 pcd->words_x, pcd->words_y);
827 pcd_key_file_save_item_xy(key_file, i++, AMOUNT_NUMBER, multip,
828 pcd->number_x, pcd->number_y);
829 pcd_key_file_save_item_xy(key_file, i++, ADDRESS, multip,
830 pcd->address_x, pcd->address_y);
831 pcd_key_file_save_item_xy(key_file, i++, NOTES, multip,
832 pcd->notes_x, pcd->notes_y);
833 pcd_key_file_save_item_xy(key_file, i++, MEMO, multip,
834 pcd->memo_x, pcd->memo_y);
835 pcd_key_file_save_item_xy(key_file, i++, SPLITS_AMOUNT, multip,
836 pcd->splits_amount_x, pcd->splits_amount_y);
837 pcd_key_file_save_item_xy(key_file, i++, SPLITS_MEMO, multip,
838 pcd->splits_memo_x, pcd->splits_memo_y);
839 pcd_key_file_save_item_xy(key_file, i++, SPLITS_ACCOUNT, multip,
840 pcd->splits_account_x, pcd->splits_account_y);
841
842 filename = g_strconcat(title, CHECK_NAME_EXTENSION, NULL);
843 pathname = g_build_filename(gnc_userdata_dir(), CHECK_FMT_DIR,
844 filename, NULL);
845
847 {
849
850 initialize_format_combobox(pcd);
851
852 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->format_combobox),
853 pcd->format_max - 1);
854 }
855 else
856 {
857 dialog = gtk_message_dialog_new(GTK_WINDOW(pcd->dialog),
858 GTK_DIALOG_DESTROY_WITH_PARENT,
859 GTK_MESSAGE_ERROR,
860 GTK_BUTTONS_CLOSE, "%s",
861 _(
"Cannot save check format file."));
862 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
863 _(
"Cannot open file %s"),
865 gtk_dialog_run(GTK_DIALOG(dialog));
866 gtk_widget_destroy(dialog);
867 g_error_free(error);
868 }
869 g_free(pathname);
870 g_free(filename);
871}
872
873
874
875
876void
877gnc_check_format_title_changed (GtkEditable *editable, GtkWidget *ok_button)
878{
879 const gchar *text;
880 gboolean sensitive;
881
882 text = gtk_entry_get_text(GTK_ENTRY(editable));
883 sensitive = text && *text;
884 gtk_widget_set_sensitive(ok_button, sensitive);
885}
886
887
888
889
890
891
892void
893gnc_print_check_save_button_clicked(GtkButton *unused, PrintCheckDialog *pcd)
894{
895 GtkWidget *dialog, *entry, *button;
896 GtkBuilder *builder;
897 gchar *title;
898
899 builder = gtk_builder_new();
900 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "format_title_dialog");
901
902
903 dialog = GTK_WIDGET(gtk_builder_get_object (builder, "format_title_dialog"));
904 entry = GTK_WIDGET(gtk_builder_get_object (builder, "format_title"));
905 button = GTK_WIDGET(gtk_builder_get_object (builder, "ok_button"));
906 gnc_check_format_title_changed(GTK_EDITABLE(entry), button);
907 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, pcd);
908
909 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(pcd->dialog));
910 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
911 {
912 gtk_widget_destroy(dialog);
913 g_object_unref(G_OBJECT(builder));
914 return;
915 }
916
917 title = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
918 gtk_widget_destroy (dialog);
919
920 g_object_unref(G_OBJECT(builder));
921
922 pcd_save_custom_data(pcd, title);
923 g_free(title);
924}
925
926
927
928
929
930static gchar *
931doubles_to_string(gdouble *dd, gint len)
932{
933 GString *str;
934 gint i;
935
936 str = g_string_new_len(NULL, 50);
937 for (i = 0; i < len; i++)
938 g_string_append_printf(str, "%f ", dd[i]);
939 return g_string_free(str, FALSE);
940}
941
942
943
944
945
946
947
948
949
950
951
952static GSList *
953format_read_item_placement(const gchar *file,
955{
957 GError *error = NULL;
958 GSList *list = NULL;
959 gchar *key, *value, *name;
960 int item_num;
961 gboolean bval;
962 gdouble *dd;
963 gsize dd_len;
964
965
966 for (item_num = 1;; item_num++)
967 {
968
969
971 if (NULL == data)
972 return list;
973
974
975 key = g_strdup_printf("%s_%d", KF_KEY_TYPE, item_num);
976 value = g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
977 if (error)
978 {
979 if ((error->domain == G_KEY_FILE_ERROR)
980 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND))
981 {
982
983 goto cleanup;
984 }
985 goto failed;
986 }
987 DEBUG(
"Check file %s, group %s, key %s, value: %s",
988 file, KF_GROUP_ITEMS, key, value);
989 g_free(key);
990
991
992 name = g_utf8_strup(value, -1);
993 data->type = CheckItemTypefromString(name);
994 g_free(name);
995 g_free(value);
996
997
998
999 key = g_strdup_printf("%s_%d", KF_KEY_COORDS, item_num);
1000 dd = g_key_file_get_double_list(key_file, KF_GROUP_ITEMS,
1001 key, &dd_len, &error);
1002 if (error)
1003 goto failed;
1004 value = doubles_to_string(dd, dd_len);
1005 DEBUG(
"Check file %s, group %s, key %s, length %"G_GSIZE_FORMAT
"; values: %s",
1006 file, KF_GROUP_ITEMS, key, dd_len, value);
1007 g_free(value);
1008
1009
1010 switch (dd_len)
1011 {
1012 case 4:
1013 data->w = dd[2];
1014 data->h = dd[3];
1015
1016 case 2:
1017 data->x = dd[0];
1018 data->y = dd[1];
1019 break;
1020 default:
1021 g_warning
1022 ("Check file %s, group %s, key %s, error: 2 or 4 values only",
1023 file, KF_GROUP_ITEMS, key);
1024 goto cleanup;
1025 }
1026 g_free(dd);
1027 g_free(key);
1028
1029
1030
1031
1032
1033
1034
1035 if (data->type != PICTURE)
1036 {
1037 key = g_strdup_printf("%s_%d", KF_KEY_FONT, item_num);
1038 data->font =
1039 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
1040 if (!error)
1041 {
1042 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1043 file, KF_GROUP_ITEMS, key, data->font);
1044 }
1045 else
1046 {
1047 if (!((error->domain == G_KEY_FILE_ERROR)
1048 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1049 g_warning("Check file %s, group %s, key %s, error: %s",
1050 file, KF_GROUP_ITEMS, key, error->message);
1051 g_clear_error(&error);
1052 }
1053 g_free(key);
1054
1055 key = g_strdup_printf("%s_%d", KF_KEY_ALIGN, item_num);
1056 value =
1057 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key, &error);
1058 if (!error)
1059 {
1060 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1061 file, KF_GROUP_ITEMS, key, value);
1062 name = g_utf8_strdown(value, -1);
1063 if (strcmp(name, "right") == 0)
1064 data->align = PANGO_ALIGN_RIGHT;
1065 else if (strcmp(name, "center") == 0)
1066 data->align = PANGO_ALIGN_CENTER;
1067 else
1068 data->align = PANGO_ALIGN_LEFT;
1069 g_free(name);
1070 g_free(value);
1071 }
1072 else
1073 {
1074 if (!((error->domain == G_KEY_FILE_ERROR)
1075 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1076 g_warning("Check file %s, group %s, key %s, error: %s",
1077 file, KF_GROUP_ITEMS, key, error->message);
1078 data->align = PANGO_ALIGN_LEFT;
1079 g_clear_error(&error);
1080 }
1081 g_free(key);
1082
1083 key = g_strdup_printf("%s_%d", KF_KEY_BLOCKING, item_num);
1084 bval =
1085 g_key_file_get_boolean(key_file, KF_GROUP_ITEMS, key, &error);
1086 if (!error)
1087 {
1088 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1089 file, KF_GROUP_ITEMS, key, bval);
1090 data->blocking = bval;
1091 }
1092 else
1093 {
1094 if (!((error->domain == G_KEY_FILE_ERROR)
1095 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1096 g_warning("Check file %s, group %s, key %s, error: %s",
1097 file, KF_GROUP_ITEMS, key, error->message);
1099 g_clear_error(&error);
1100 }
1101 g_free(key);
1102 }
1103
1104 switch (data->type)
1105 {
1106 case PICTURE:
1107 key = g_strdup_printf("%s_%d", KF_KEY_FILENAME, item_num);
1108 data->filename =
1109 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key,
1110 &error);
1111 if (error)
1112 goto failed;
1113 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1114 file, KF_GROUP_ITEMS, key, data->filename);
1115 g_free(key);
1116 break;
1117 case TEXT:
1118 key = g_strdup_printf("%s_%d", KF_KEY_TEXT, item_num);
1119 data->text =
1120 g_key_file_get_string(key_file, KF_GROUP_ITEMS, key,
1121 &error);
1122 if (error)
1123 goto failed;
1124 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1125 file, KF_GROUP_ITEMS, key, data->text);
1126 g_free(key);
1127 break;
1128 case DATE:
1129
1130 key = g_strdup_printf("%s_%d", KF_KEY_DATE_FORMAT, item_num);
1131 bval = g_key_file_get_boolean(key_file, KF_GROUP_ITEMS, key, &error);
1132 if (!error)
1133 {
1134 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1135 file, KF_GROUP_ITEMS, key, bval);
1136 data->print_date_format = bval;
1137 }
1138 else
1139 {
1140 if (!((error->domain == G_KEY_FILE_ERROR)
1141 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1142 g_warning("Check file %s, group %s, key %s, error: %s",
1143 file, KF_GROUP_ITEMS, key, error->message);
1145 g_clear_error(&error);
1146 }
1147 g_free(key);
1148 break;
1149 default:
1150 break;
1151 }
1152
1153 list = g_slist_append(list, data);
1154 data = NULL;
1155 }
1156
1157
1158 return list;
1159
1160failed:
1161 g_warning("Check file %s, group %s, key %s, error: %s",
1162 file, KF_GROUP_ITEMS, key, error->message);
1163cleanup:
1164 if (error)
1165 g_error_free(error);
1166 if (data)
1167 g_free(data);
1168 if (key)
1169 g_free(key);
1170 return list;
1171}
1172
1173
1174
1175
1176static void
1178{
1179 if (data->font)
1180 g_free(data->font);
1181 if (data->text)
1182 g_free(data->text);
1183 if (data->filename)
1184 g_free(data->filename);
1185 g_free(data);
1186}
1187
1188
1189
1190
1191
1192
1193
1194static GSList *
1195format_read_multicheck_info(const gchar *file,
1197{
1198 GError *error = NULL;
1199 GSList *list = NULL;
1200 gchar *key, **names;
1201 gsize length;
1202 gint i;
1203
1204 key = g_strdup_printf("%s", KF_KEY_HEIGHT);
1205 format->
height = g_key_file_get_double(key_file, KF_GROUP_POS, key, &error);
1206 if (error)
1207 {
1208 if ((error->domain == G_KEY_FILE_ERROR)
1209 && ((error->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
1210 || (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1211 {
1212 g_clear_error(&error);
1214 }
1215 else
1216 {
1217 g_warning("Check file %s, error reading group %s, key %s: %s",
1218 file, KF_GROUP_POS, key, error->message);
1219 g_free(key);
1220 return NULL;
1221 }
1222 }
1223
1224 names = g_key_file_get_string_list(key_file, KF_GROUP_POS, KF_KEY_NAMES,
1225 &length, &error);
1226 if (error)
1227 {
1228 if ((error->domain == G_KEY_FILE_ERROR)
1229 && ((error->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
1230 || (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1231 {
1232
1233 g_free(key);
1234 return NULL;
1235 }
1236 g_warning("Check file %s, error reading group %s, key %s: %s",
1237 file, KF_GROUP_POS, key, error->message);
1238 g_free(key);
1239 return list;
1240 }
1241
1242 for (i = 0; i < length; i++)
1243 list = g_slist_append(list, g_strdup(names[i]));
1244
1245 g_strfreev(names);
1246 return list;
1247}
1248
1249
1250
1251
1252static void
1253free_check_position(gchar *name)
1254{
1255 g_free(name);
1256}
1257
1258
1259
1260
1261
1262
1263static gboolean
1264format_read_general_info(const gchar *file,
1266{
1267 GError *error = NULL;
1268 gchar **parts;
1269 gchar *value;
1270 double *dd;
1271 gsize dd_len;
1272
1273 value = g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, &error);
1274 if (error)
1275 {
1276 g_warning("Check file %s, group %s, key %s, error: %s",
1277 file, KF_GROUP_TOP, KF_KEY_GUID, error->message);
1278 g_error_free(error);
1279 return FALSE;
1280 }
1281 parts = g_strsplit(value, "-", -1);
1282 format->
guid = g_strjoinv(
"", parts);
1283 g_strfreev(parts);
1284 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1285 file, KF_GROUP_TOP, KF_KEY_GUID, format->
guid);
1286
1288 g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, &error);
1289 if (!error)
1290 {
1291 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1292 file, KF_GROUP_TOP, KF_KEY_TITLE, format->
title);
1293 }
1294 else
1295 {
1296 g_warning("Check file %s, group %s, key %s, error: %s",
1297 file, KF_GROUP_TOP, KF_KEY_TITLE, error->message);
1298 return FALSE;
1299 }
1300
1302 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_BLOCKING,
1303 &error);
1304 if (!error)
1305 {
1306 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1307 file, KF_GROUP_TOP, KF_KEY_BLOCKING, format->
blocking);
1308 }
1309 else
1310 {
1311 if (!((error->domain == G_KEY_FILE_ERROR)
1312 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1313 g_warning("Check file %s, group %s, key %s, error: %s",
1314 file, KF_GROUP_TOP, KF_KEY_BLOCKING, error->message);
1316 {
1318 }
1319 else
1320 {
1322 }
1323 g_clear_error(&error);
1324 }
1325
1327 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_DATE_FORMAT,
1328 &error);
1329 if (!error)
1330 {
1331 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1333 }
1334 else
1335 {
1336 if (!((error->domain == G_KEY_FILE_ERROR)
1337 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1338 g_warning("Check file %s, group %s, key %s, error: %s",
1339 file, KF_GROUP_TOP, KF_KEY_DATE_FORMAT, error->message);
1341 {
1343 }
1344 else
1345 {
1347 }
1348 g_clear_error(&error);
1349 }
1350
1352 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_GRID,
1353 &error);
1354 if (!error)
1355 {
1356 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1357 file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, format->
show_grid);
1358 }
1359 else
1360 {
1361 if (!((error->domain == G_KEY_FILE_ERROR)
1362 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1363 g_warning("Check file %s, group %s, key %s, error: %s",
1364 file, KF_GROUP_TOP, KF_KEY_SHOW_GRID, error->message);
1366 g_clear_error(&error);
1367 }
1368
1370 g_key_file_get_boolean(key_file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES,
1371 &error);
1372 if (!error)
1373 {
1374 DEBUG(
"Check file %s, group %s, key %s, value: %d",
1375 file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, format->
show_boxes);
1376 }
1377 else
1378 {
1379 if (!((error->domain == G_KEY_FILE_ERROR)
1380 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1381 g_warning("Check file %s, group %s, key %s, error: %s",
1382 file, KF_GROUP_TOP, KF_KEY_SHOW_BOXES, error->message);
1384 g_clear_error(&error);
1385 }
1386
1388 g_key_file_get_string(key_file, KF_GROUP_TOP, KF_KEY_FONT, &error);
1389 if (!error)
1390 {
1391 DEBUG(
"Check file %s, group %s, key %s, value: %s",
1392 file, KF_GROUP_TOP, KF_KEY_FONT, format->
font);
1393 }
1394 else
1395 {
1396 if (!((error->domain == G_KEY_FILE_ERROR)
1397 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1398 g_warning("Check file %s, group %s, key %s, error: %s",
1399 file, KF_GROUP_TOP, KF_KEY_FONT, error->message);
1400 g_clear_error(&error);
1401 }
1402
1404 g_key_file_get_double(key_file, KF_GROUP_TOP, KF_KEY_ROTATION, &error);
1405 if (!error)
1406 {
1407 DEBUG(
"Check file %s, group %s, key %s, value: %f",
1408 file, KF_GROUP_TOP, KF_KEY_ROTATION, format->
rotation);
1409 }
1410 else
1411 {
1412 if (!((error->domain == G_KEY_FILE_ERROR)
1413 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1414 g_warning("Check file %s, group %s, key %s, error: %s",
1415 file, KF_GROUP_TOP, KF_KEY_ROTATION, error->message);
1417 g_clear_error(&error);
1418 }
1419
1420 dd = g_key_file_get_double_list(key_file, KF_GROUP_TOP, KF_KEY_TRANSLATION,
1421 &dd_len, &error);
1422 if (!error)
1423 {
1424 value = doubles_to_string(dd, dd_len);
1425 DEBUG(
"Check file %s, group %s, key %s, length %"G_GSIZE_FORMAT
"; values: %s",
1426 file, KF_GROUP_TOP, KF_KEY_TRANSLATION, dd_len, value);
1427 g_free(value);
1428
1429 if (dd_len == 2)
1430 {
1433 }
1434 else
1435 {
1436 g_warning("Check file %s, error top %s, key %s: 2 values only",
1437 file, KF_GROUP_TOP, KF_KEY_TRANSLATION);
1438 }
1439 g_free(dd);
1440 }
1441 else
1442 {
1443 if (!((error->domain == G_KEY_FILE_ERROR)
1444 && (error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND)))
1445 g_warning("Check file %s, group top %s, key %s: %s",
1446 file, KF_GROUP_ITEMS, KF_KEY_TRANSLATION, error->message);
1447 g_clear_error(&error);
1448 }
1449
1450 return TRUE;
1451}
1452
1453
1454
1455
1456static void
1458{
1459 g_return_if_fail(data);
1460 g_free(data->guid);
1461 g_free(data->filename);
1462 g_free(data->title);
1463 g_free(data->font);
1464 g_slist_foreach(data->positions, (GFunc) free_check_position, NULL);
1465 g_slist_free(data->positions);
1466 g_slist_foreach(data->items, (GFunc) format_free_item_placement, NULL);
1467 g_slist_free(data->items);
1468 g_free(data);
1469}
1470
1471
1472
1473
1474
1475
1477read_one_check_format(PrintCheckDialog *pcd, const gchar *groupname,
1478 const gchar *dirname, const gchar *file)
1479{
1480 gchar *pathname;
1481 GKeyFile *key_file;
1483
1484 pathname = g_build_filename(dirname, file, (char *)NULL);
1486 g_free(pathname);
1487 if (!key_file)
1488 {
1489 g_warning("Check file %s, cannot load file", file);
1490 return NULL;
1491 }
1492
1494 format->
group = groupname;
1496 if (format_read_general_info(file, key_file, format))
1497 {
1498 format->
positions = format_read_multicheck_info(file, key_file, format);
1499 format->
items = format_read_item_placement(file, key_file, format);
1500 }
1501
1502 g_key_file_free(key_file);
1503 if ((NULL == format->
title) || (NULL == format->
items))
1504 {
1505 g_warning("Check file %s, no items read. Dropping file.", file);
1506 free_check_format(format);
1507 return NULL;
1508 }
1509
1510 return format;
1511}
1512
1513
1514
1515
1516
1517
1518static void
1519read_one_check_directory(PrintCheckDialog *pcd, GtkListStore *store,
1520 const gchar *groupname, const gchar *dirname)
1521{
1523 GDir *dir;
1524 const gchar *filename;
1525 GtkTreeIter iter;
1526 GtkWidget *dialog;
1527 gboolean found = FALSE;
1528
1529 dir = g_dir_open(dirname, 0, NULL);
1530 if (dir == NULL)
1531 return;
1532
1533 while ((filename = g_dir_read_name(dir)) != NULL)
1534 {
1535 if (g_str_has_prefix(filename, "#"))
1536 continue;
1537 if (!g_str_has_suffix(filename, ".chk"))
1538 continue;
1539
1540 format = read_one_check_format(pcd, groupname, dirname, filename);
1541 if (NULL == format)
1542 continue;
1543
1544 existing = find_existing_format(store, format->
guid, NULL);
1545 if (existing)
1546 {
1547 dialog = gtk_message_dialog_new
1548 (GTK_WINDOW(pcd->dialog),
1549 GTK_DIALOG_DESTROY_WITH_PARENT,
1550 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s",
1551 _(
"There is a duplicate check format file."));
1552 gtk_message_dialog_format_secondary_text
1553 (GTK_MESSAGE_DIALOG(dialog),
1554
1555
1556
1557
1558
1559
1560 _(
"The GUIDs in the %s check format file '%s' and "
1561 "the %s check format file '%s' match."),
1562 existing->group, existing->filename,
1564 gtk_dialog_run(GTK_DIALOG(dialog));
1565 gtk_widget_destroy(dialog);
1566 free_check_format (format);
1567 }
1568 else
1569 {
1570 gtk_list_store_append(store, &iter);
1573 found = TRUE;
1574 }
1575 }
1576 g_dir_close(dir);
1577
1578
1579
1580 if (found)
1581 {
1582 gtk_list_store_append(store, &iter);
1583 gtk_list_store_set(store, &iter,
COL_SEP, TRUE, -1);
1584 }
1585}
1586
1587
1588
1589
1590
1591
1592static void
1593read_formats(PrintCheckDialog *pcd, GtkListStore *store)
1594{
1595 gchar *dirname, *pkgdatadir;
1596
1597 pkgdatadir = gnc_path_get_pkgdatadir();
1598 dirname = g_build_filename(pkgdatadir, CHECK_FMT_DIR, (char *)NULL);
1599
1600
1601
1602 read_one_check_directory(pcd, store,
_(
"application"), dirname);
1603 g_free(dirname);
1604 g_free(pkgdatadir);
1605
1606 dirname = gnc_build_userdata_path(CHECK_FMT_DIR);
1607
1608
1609
1610 read_one_check_directory(pcd, store,
_(
"user"), dirname);
1611 g_free(dirname);
1612}
1613
1614
1615static gboolean
1616format_is_a_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
1617{
1618 gboolean separator;
1619
1620 gtk_tree_model_get(model, iter,
COL_SEP, &separator, -1);
1621 return separator;
1622}
1623
1624
1625static void
1626initialize_format_combobox (PrintCheckDialog *pcd)
1627{
1628 GtkListStore *store;
1629 GtkTreeIter iter;
1630
1631 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
1632 read_formats(pcd, store);
1633 gtk_list_store_append(store, &iter);
1634 gtk_list_store_set(store, &iter,
COL_NAME,
_(
"Custom"), -1);
1635 pcd->format_max = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
1636 gtk_combo_box_set_model(GTK_COMBO_BOX(pcd->format_combobox),
1637 GTK_TREE_MODEL(store));
1638 gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(pcd->format_combobox),
1639 format_is_a_separator, NULL, NULL);
1640 g_object_unref (store);
1641}
1642
1643
1644
1645
1646
1647
1648
1649
1650void
1651gnc_ui_print_check_dialog_create(GtkWidget *parent,
1652 GList *splits,
1654{
1655 PrintCheckDialog *pcd;
1656 GtkBuilder *builder;
1658 gchar *font;
1659 Transaction *trans = NULL;
1660
1661 pcd = g_new0(PrintCheckDialog, 1);
1662 pcd->caller_window = GTK_WINDOW(parent);
1663 pcd->splits = g_list_copy(splits);
1664 pcd->account = account;
1665
1666 builder = gtk_builder_new();
1667 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment1");
1668 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment2");
1669 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment3");
1670 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment4");
1671 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment5");
1672 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment6");
1673 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment7");
1674 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment8");
1675 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment9");
1676 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment10");
1677 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment11");
1678 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment12");
1679 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment13");
1680 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment14");
1681 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment15");
1682 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment16");
1683 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment17");
1684 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment18");
1685 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment19");
1686 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment20");
1687 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment21");
1688 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment22");
1689 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment23");
1690 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment24");
1691 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "liststore1");
1692 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "liststore2");
1693 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "liststore3");
1694 gnc_builder_add_from_file (builder, "dialog-print-check.glade", "print_check_dialog");
1695
1696 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, pcd);
1697
1698 pcd->builder = builder;
1699 pcd->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "print_check_dialog"));
1700
1701
1702 gtk_widget_set_name (GTK_WIDGET(pcd->dialog), "gnc-id-print-check");
1703
1704
1705 pcd->format_combobox = GTK_WIDGET(gtk_builder_get_object (builder, "check_format_combobox"));
1706 pcd->position_combobox = GTK_WIDGET(gtk_builder_get_object (builder, "check_position_combobox"));
1707 pcd->first_page_count = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "first_page_count_entry"));
1708
1709 pcd->custom_table = GTK_WIDGET(gtk_builder_get_object (builder, "custom_table"));
1710 pcd->payee_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "payee_x_entry"));
1711 pcd->payee_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "payee_y_entry"));
1712 pcd->date_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "date_x_entry"));
1713 pcd->date_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "date_y_entry"));
1714 pcd->words_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "amount_words_x_entry"));
1715 pcd->words_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "amount_words_y_entry"));
1716 pcd->number_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "amount_numbers_x_entry"));
1717 pcd->number_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "amount_numbers_y_entry"));
1718 pcd->notes_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "notes_x_entry"));
1719 pcd->notes_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "notes_y_entry"));
1720 pcd->memo_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "memo_x_entry"));
1721 pcd->memo_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "memo_y_entry"));
1722 pcd->address_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "address_x_entry"));
1723 pcd->address_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "address_y_entry"));
1724 pcd->splits_amount_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_amount_x_entry"));
1725 pcd->splits_amount_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_amount_y_entry"));
1726 pcd->splits_memo_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_memo_x_entry"));
1727 pcd->splits_memo_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_memo_y_entry"));
1728 pcd->splits_account_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_account_x_entry"));
1729 pcd->splits_account_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "splits_account_y_entry"));
1730 pcd->translation_x = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "translation_x_entry"));
1731 pcd->translation_y = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "translation_y_entry"));
1732 pcd->translation_label = GTK_WIDGET(gtk_builder_get_object (builder, "translation_label"));
1733 pcd->check_rotation = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "check_rotation_entry"));
1734 pcd->units_combobox = GTK_WIDGET(gtk_builder_get_object (builder, "units_combobox"));
1735
1736 gtk_window_set_transient_for(GTK_WINDOW(pcd->dialog), pcd->caller_window);
1737
1738
1739 table = GTK_WIDGET(gtk_builder_get_object (builder,
"options_table"));
1740 pcd->date_format = gnc_date_format_new_without_label();
1741 gtk_grid_attach (GTK_GRID(
table), pcd->date_format, 1, 4, 1, 1);
1742
1743
1745 pcd->default_font = font && *font ? font : g_strdup(DEFAULT_FONT);
1746
1747
1748 initialize_format_combobox(pcd);
1749
1750
1751 pcd->check_address_name = GTK_WIDGET(gtk_builder_get_object (builder, "check_address_name"));
1752 pcd->check_address_1 = GTK_WIDGET(gtk_builder_get_object (builder, "check_address_1"));
1753 pcd->check_address_2 = GTK_WIDGET(gtk_builder_get_object (builder, "check_address_2"));
1754 pcd->check_address_3 = GTK_WIDGET(gtk_builder_get_object (builder, "check_address_3"));
1755 pcd->check_address_4 = GTK_WIDGET(gtk_builder_get_object (builder, "check_address_4"));
1756
1757
1758
1759 if (g_list_length(pcd->splits) == 1)
1760 {
1762
1765 {
1768
1769
1770 gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), gncOwnerGetName(&owner));
1771 gtk_entry_set_text(GTK_ENTRY(pcd->check_address_1), gncAddressGetAddr1 (gncOwnerGetAddr(&owner)));
1772 gtk_entry_set_text(GTK_ENTRY(pcd->check_address_2), gncAddressGetAddr2 (gncOwnerGetAddr(&owner)));
1773 gtk_entry_set_text(GTK_ENTRY(pcd->check_address_3), gncAddressGetAddr3 (gncOwnerGetAddr(&owner)));
1774 gtk_entry_set_text(GTK_ENTRY(pcd->check_address_4), gncAddressGetAddr4 (gncOwnerGetAddr(&owner)));
1775 }
1776 }
1777
1778
1779 if ( trans && (0 == gtk_entry_get_text_length (GTK_ENTRY(pcd->check_address_name))) )
1781
1782 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "lower_left")));
1783
1784 gnc_ui_print_restore_dialog(pcd);
1785 gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(pcd->dialog), GTK_WINDOW (parent));
1786
1787 g_object_unref(G_OBJECT(builder));
1788 gtk_widget_show_all(pcd->dialog);
1789}
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799static void
1800draw_grid(GtkPrintContext *context, gint width, gint height, const gchar *font)
1801{
1802 const double dash_pattern[2] = { 1.0, 5.0 };
1803 PangoFontDescription *desc;
1804 PangoLayout *layout;
1805 cairo_t *cr;
1806 gchar *text;
1807 gint i;
1808
1809
1810 layout = gtk_print_context_create_pango_layout(context);
1811 desc = pango_font_description_from_string(font);
1812 pango_layout_set_font_description(layout, desc);
1813 pango_font_description_free(desc);
1814 pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
1815 pango_layout_set_width(layout, -1);
1816
1817
1818 cr = gtk_print_context_get_cairo_context(context);
1819 cairo_save(cr);
1820 cairo_set_line_width(cr, 1.0);
1821 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
1822 cairo_set_dash(cr, dash_pattern, 2, 0);
1823
1824
1825 for (i = -200; i < (height + 200); i += 50)
1826 {
1827 text = g_strdup_printf("%d", (int)i);
1828 cairo_move_to(cr, -200, i);
1829 cairo_line_to(cr, width + 200, i);
1830 cairo_stroke(cr);
1831 pango_layout_set_text(layout, text, -1);
1832 cairo_move_to(cr, 0, i);
1833 pango_cairo_show_layout(cr, layout);
1834 g_free(text);
1835 }
1836
1837
1838 for (i = -200; i < (width + 200); i += 50)
1839 {
1840 text = g_strdup_printf("%d", (int)i);
1841 cairo_move_to(cr, i, -200);
1842 cairo_line_to(cr, i, height + 200);
1843 cairo_stroke(cr);
1844 pango_layout_set_text(layout, text, -1);
1845 cairo_move_to(cr, i, 0);
1846 pango_cairo_show_layout(cr, layout);
1847 g_free(text);
1848 }
1849
1850
1851 cairo_restore(cr);
1852 g_object_unref(layout);
1853}
1854
1855
1856
1857
1858
1859
1860
1861static gdouble
1862draw_text(GtkPrintContext *context,
const gchar *text,
check_item_t *data,
1863 PangoFontDescription *default_desc)
1864{
1865 PangoFontDescription *desc;
1866 PangoLayout *layout;
1867 cairo_t *cr;
1868 gint layout_height, layout_width;
1869 gdouble width, height;
1870 gchar *new_text;
1871
1872 if ((NULL == text) || (strlen(text) == 0))
1873 return 0.0;
1874
1875
1876 layout = gtk_print_context_create_pango_layout(context);
1877 if (data->font)
1878 {
1879 desc = pango_font_description_from_string(data->font);
1880 pango_layout_set_font_description(layout, desc);
1881 pango_font_description_free(desc);
1882 }
1883 else
1884 {
1885 pango_layout_set_font_description(layout, default_desc);
1886 }
1887 pango_layout_set_alignment(layout,
1888 data->w ? data->align : PANGO_ALIGN_LEFT);
1889 pango_layout_set_width(layout, data->w ? data->w * PANGO_SCALE : -1);
1890 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
1891 if ( data->blocking )
1892 {
1893 new_text = g_strdup_printf("***%s***", text);
1894 pango_layout_set_text(layout, new_text, -1);
1895 g_free(new_text);
1896 }
1897 else
1898 {
1899 pango_layout_set_text(layout, text, -1);
1900 }
1901 pango_layout_get_size(layout, &layout_width, &layout_height);
1902 width = (gdouble) layout_width / PANGO_SCALE;
1903 height = (gdouble) layout_height / PANGO_SCALE;
1904
1905 cr = gtk_print_context_get_cairo_context(context);
1906 cairo_save(cr);
1907
1908
1909 if (data->w && data->h)
1910 {
1911 DEBUG(
"Text clip rectangle, coords %f,%f, size %f,%f",
1912 data->x, data->y - data->h, data->w, data->h);
1913 cairo_rectangle(cr, data->x, data->y - data->h, data->w, data->h);
1914 cairo_clip_preserve(cr);
1915 }
1916
1917
1918 DEBUG(
"Text move to %f,%f, print '%s'", data->x, data->y,
1919 text ? text : "(null)");
1920 cairo_move_to(cr, data->x, data->y - height);
1921 pango_cairo_show_layout(cr, layout);
1922
1923
1924 cairo_restore(cr);
1925 g_object_unref(layout);
1926 return width;
1927
1928}
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940static GtkWidget *
1941read_image (const gchar *filename)
1942{
1943 GtkWidget *image;
1944 gchar *pkgdatadir, *dirname, *tmp_name;
1945
1946 if (g_path_is_absolute(filename))
1947 return gtk_image_new_from_file(filename);
1948
1949 pkgdatadir = gnc_path_get_pkgdatadir();
1950 tmp_name = g_build_filename(pkgdatadir, CHECK_FMT_DIR, filename, (char *)NULL);
1951 if (!g_file_test(tmp_name, G_FILE_TEST_EXISTS))
1952 {
1953 g_free(tmp_name);
1954 dirname = gnc_build_userdata_path(CHECK_FMT_DIR);
1955 tmp_name = g_build_filename(dirname, filename, (char *)NULL);
1956 g_free(dirname);
1957 }
1958 image = gtk_image_new_from_file(tmp_name);
1959 g_free(tmp_name);
1960 return image;
1961}
1962
1963
1964
1965
1966
1967
1968static void
1969draw_picture(GtkPrintContext *context,
check_item_t *data)
1970{
1971 cairo_t *cr;
1972 GdkPixbuf *pixbuf, *scaled_pixbuf;
1973 GtkImage *image;
1974 gint pix_w, pix_h;
1975 gdouble scale_w, scale_h, scale;
1976
1977 cr = gtk_print_context_get_cairo_context(context);
1978 cairo_save(cr);
1979
1980
1981 image = GTK_IMAGE(read_image(data->filename));
1982 pixbuf = gtk_image_get_pixbuf(image);
1983 if (pixbuf)
1984 {
1985 g_object_ref(pixbuf);
1986 }
1987 else
1988 {
1989 GtkIconTheme *def_theme = gtk_icon_theme_get_default ();
1990
1991 g_warning("Filename '%s' cannot be read or understood.",
1992 data->filename);
1993
1994 pixbuf = gtk_icon_theme_load_icon (def_theme,
1995 "image-missing",
1996 16,
1997 GTK_ICON_LOOKUP_USE_BUILTIN,
1998 NULL);
1999 }
2000 pix_w = gdk_pixbuf_get_width(pixbuf);
2001 pix_h = gdk_pixbuf_get_height(pixbuf);
2002
2003
2004 if (data->w && data->h)
2005 {
2006 cairo_rectangle(cr, data->x, data->y - data->h, data->w, data->h);
2007 DEBUG(
"Picture clip rectangle, user coords %f,%f, user size %f,%f",
2008 data->x, data->y - data->h, data->w, data->h);
2009 }
2010 else
2011 {
2012 cairo_rectangle(cr, data->x, data->y - pix_h, pix_w, pix_h);
2013 DEBUG(
"Picture clip rectangle, user coords %f,%f, pic size %d,%d",
2014 data->x, data->y - data->h, pix_w, pix_h);
2015 }
2016 cairo_clip_preserve(cr);
2017
2018
2019 scale_w = scale_h = 1;
2020 if (data->w && (pix_w > data->w))
2021 scale_w = data->w / pix_w;
2022 if (data->h && (pix_h > data->h))
2023 scale_h = data->h / pix_h;
2024 scale = MIN(scale_w, scale_h);
2025
2026 if (scale != 1)
2027 {
2028 scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, pix_w * scale,
2029 pix_h * scale,
2030 GDK_INTERP_BILINEAR);
2031 pix_h = gdk_pixbuf_get_height(scaled_pixbuf);
2032 gdk_cairo_set_source_pixbuf(cr, scaled_pixbuf, data->x,
2033 data->y - pix_h);
2034
2035 g_object_unref(scaled_pixbuf);
2036 }
2037 else
2038 {
2039 gdk_cairo_set_source_pixbuf(cr, pixbuf, data->x, data->y - pix_h);
2040 }
2041 g_object_unref(pixbuf);
2042 cairo_paint(cr);
2043
2044
2045 cairo_restore(cr);
2046 gtk_widget_destroy(GTK_WIDGET(image));
2047}
2048
2049
2050#define DATE_FMT_HEIGHT 8
2051#define DATE_FMT_SLOP 2
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065static void
2066draw_date_format(GtkPrintContext *context, const gchar *date_format,
2067 check_item_t *data, PangoFontDescription *default_desc,
2068 gdouble width)
2069{
2070 PangoFontDescription *date_desc;
2072 gchar *text = NULL, *expanded = NULL;
2073 const gchar *c;
2074 GString *cdn_fmt;
2075
2076 if ( !data->print_date_format ) return;
2077
2078 date_desc = pango_font_description_copy_static(default_desc);
2079 pango_font_description_set_size(date_desc, DATE_FMT_HEIGHT * PANGO_SCALE);
2080 date_item = *data;
2081 date_item.
y += (DATE_FMT_HEIGHT + DATE_FMT_SLOP);
2082 date_item.w = width;
2083 date_item.
h = DATE_FMT_HEIGHT + DATE_FMT_SLOP;
2084 date_item.
align = PANGO_ALIGN_CENTER;
2085
2086
2087 cdn_fmt = g_string_new_len(NULL, 50);
2088 for (c = date_format; c && *c; )
2089 {
2090 if ((c[0] != '%') || (c[1] == '\0'))
2091 {
2092 c += 1;
2093 continue;
2094 }
2095 switch (c[1])
2096 {
2097 case 'F':
2098 cdn_fmt = g_string_append(cdn_fmt, "YYYYMMDD");
2099 break;
2100 case 'Y':
2101 cdn_fmt = g_string_append(cdn_fmt, "YYYY");
2102 break;
2103 case 'y':
2104 cdn_fmt = g_string_append(cdn_fmt, "YY");
2105 break;
2106 case 'm':
2107 cdn_fmt = g_string_append(cdn_fmt, "MM");
2108 break;
2109 case 'd':
2110 case 'e':
2111 cdn_fmt = g_string_append(cdn_fmt, "DD");
2112 break;
2113 case 'x':
2114 expanded = g_strdup_printf("%s%s",
2116 c + 2);
2117 c = expanded;
2118 continue;
2119 default:
2120 break;
2121 }
2122 c += 2;
2123 }
2124
2125 text = g_string_free(cdn_fmt, FALSE);
2126 draw_text(context, text, &date_item, date_desc);
2127 g_free(text);
2128 if (expanded)
2129 g_free(expanded);
2130 pango_font_description_free(date_desc);
2131}
2132
2133
2134
2135
2136
2137static void
2138draw_page_items(GtkPrintContext *context,
2140{
2141 PrintCheckDialog *pcd = (PrintCheckDialog *) user_data;
2142 PangoFontDescription *default_desc;
2143 Transaction *trans;
2144 gnc_numeric amount;
2146 const gchar *date_format;
2147 gchar *text = NULL, buf[100];
2148 GSList *elem;
2150 gdouble width;
2151 gchar *address = NULL;
2152
2154
2155 g_return_if_fail(trans);
2156 amount = get_check_amount(pcd);
2157
2159 default_desc = pango_font_description_from_string(format->
font);
2160 else
2161 default_desc = pango_font_description_from_string(pcd->default_font);
2162
2163
2164 for (elem = format->
items; elem; elem = g_slist_next(elem))
2165 {
2166 item = elem->data;
2167
2169 {
2170 case DATE:
2171 {
2172 GDate date;
2173 g_date_clear (&date, 1);
2175 date_format =
2176 gnc_date_format_get_custom(GNC_DATE_FORMAT
2177 (pcd->date_format));
2178 g_date_strftime(buf, 100, date_format, &date);
2179 width = draw_text(context, buf, item, default_desc);
2180 draw_date_format(context, date_format, item, default_desc, width);
2181 break;
2182 }
2183
2184 case PAYEE:
2186 break;
2187
2188 case NOTES:
2190 break;
2191
2192 case MEMO:
2194 break;
2195
2196 case ACTION:
2197 draw_text(context, gnc_get_action_num(trans, pcd->split), item,
2198 default_desc);
2199 break;
2200
2201 case CHECK_NUMBER:
2202 draw_text(context, gnc_get_num_action(trans, pcd->split), item,
2203 default_desc);
2204 break;
2205
2206 case AMOUNT_NUMBER:
2207 info = gnc_default_print_info(FALSE);
2209 item, default_desc);
2210 break;
2211
2212 case AMOUNT_WORDS:
2213 text = numeric_to_words(amount);
2214 draw_text(context, text, item, default_desc);
2215 g_free(text);
2216 break;
2217
2218 case TEXT:
2219 draw_text(context, item->
text, item, default_desc);
2220 break;
2221
2222 case ADDRESS:
2223 address = get_check_address(pcd);
2224 draw_text(context, address, item, default_desc);
2225 g_free(address);
2226 break;
2227
2228 case SPLITS_AMOUNT:
2229 text = get_check_splits_amount(pcd);
2230 draw_text(context, text, item, default_desc);
2231 g_free(text);
2232 break;
2233
2234 case SPLITS_MEMO:
2235 text = get_check_splits_memo(pcd);
2236 draw_text(context, text, item, default_desc);
2237 g_free(text);
2238 break;
2239
2240 case SPLITS_ACCOUNT:
2241 text = get_check_splits_account(pcd);
2242 draw_text(context, text, item, default_desc);
2243 g_free(text);
2244 break;
2245
2246 case PICTURE:
2247 draw_picture(context, item);
2248 break;
2249
2250 default:
2251 text = g_strdup_printf(
"(unknown check field, type %d)", item->
type);
2252 draw_text(context, text, item, default_desc);
2253 g_free(text);
2254 break;
2255 }
2256 }
2257
2258 pango_font_description_free(default_desc);
2259}
2260
2261
2262
2263
2264
2265static void
2266draw_page_boxes(GtkPrintContext *context,
2268{
2269 cairo_t *cr;
2270 GSList *elem;
2272
2273 cr = gtk_print_context_get_cairo_context(context);
2274
2275
2276 for (elem = format->
items; elem; elem = g_slist_next(elem))
2277 {
2278 item = elem->data;
2279 if (!item->w || !item->
h)
2280 continue;
2281 cairo_rectangle(cr, item->x, item->
y - item->
h, item->w, item->
h);
2282 cairo_stroke(cr);
2283 }
2284}
2285
2286
2287
2288
2289
2290
2291
2292static void
2293draw_check_format(GtkPrintContext *context, gint position,
2295{
2296 PrintCheckDialog *pcd = (PrintCheckDialog *) user_data;
2297 gdouble x, y, r, multip;
2298 cairo_t *cr = gtk_print_context_get_cairo_context(context);
2299
2300
2301 if ((position > 0) && (position < pcd->position_max))
2302 {
2303
2304
2305
2306 cairo_translate(cr, 0, format->
height);
2307
2308 DEBUG(
"Position %d translated by %f relative to previous check (pre-defined)", position, format->
height);
2309 DEBUG(
" by %f relative to page (pre-defined)", position * format->
height);
2310 }
2311 else if (position == pcd->position_max)
2312 {
2313
2314 multip = pcd_get_custom_multip(pcd);
2315 x = multip * gtk_spin_button_get_value(pcd->translation_x);
2316 y = multip * gtk_spin_button_get_value(pcd->translation_y);
2317 cairo_translate(cr, x, y);
2318 DEBUG(
"Position translated by %f,%f (custom)", x, y);
2319 r = gtk_spin_button_get_value(pcd->check_rotation);
2320 cairo_rotate(cr, r * DEGREES_TO_RADIANS);
2321 DEBUG(
"Position rotated by %f degrees (custom)", r);
2322 }
2323
2324
2325
2327 draw_page_boxes(context, format, user_data);
2328
2329
2330 draw_page_items(context, format, user_data);
2331}
2332
2333
2334static void
2335draw_check_custom(GtkPrintContext *context, gpointer user_data)
2336{
2337 PrintCheckDialog *pcd = (PrintCheckDialog *) user_data;
2339 PangoFontDescription *desc;
2340 Transaction *trans;
2341 gnc_numeric amount;
2342 cairo_t *cr;
2343 const gchar *date_format;
2344 gchar *text = NULL, buf[100];
2346 gdouble x, y, multip, degrees;
2347 GDate date;
2348 gchar *address;
2349
2351
2352 g_return_if_fail(trans);
2353
2354 desc = pango_font_description_from_string(pcd->default_font);
2355
2356 multip = pcd_get_custom_multip(pcd);
2357 degrees = gtk_spin_button_get_value(pcd->check_rotation);
2358 cr = gtk_print_context_get_cairo_context(context);
2359 cairo_rotate(cr, degrees * DEGREES_TO_RADIANS);
2360 DEBUG(
"Page rotated by %f degrees", degrees);
2361
2362 x = multip * gtk_spin_button_get_value(pcd->translation_x);
2363 y = multip * gtk_spin_button_get_value(pcd->translation_y);
2364 cairo_translate(cr, x, y);
2365 DEBUG(
"Page translated by %f,%f", x, y);
2366
2367 item.x = multip * gtk_spin_button_get_value(pcd->payee_x);
2368 item.
y = multip * gtk_spin_button_get_value(pcd->payee_y);
2370
2371 item.x = multip * gtk_spin_button_get_value(pcd->date_x);
2372 item.
y = multip * gtk_spin_button_get_value(pcd->date_y);
2373 g_date_clear (&date, 1);
2375 date_format = gnc_date_format_get_custom(GNC_DATE_FORMAT(pcd->date_format));
2376 g_date_strftime(buf, 100, date_format, &date);
2377 draw_text(context, buf, &item, desc);
2378
2379 item.x = multip * gtk_spin_button_get_value(pcd->number_x);
2380 item.
y = multip * gtk_spin_button_get_value(pcd->number_y);
2381 info = gnc_default_print_info(FALSE);
2384
2385 item.x = multip * gtk_spin_button_get_value(pcd->words_x);
2386 item.
y = multip * gtk_spin_button_get_value(pcd->words_y);
2387 text = numeric_to_words(amount);
2388 draw_text(context, text, &item, desc);
2389 g_free(text);
2390
2391 item.x = multip * gtk_spin_button_get_value(pcd->address_x);
2392 item.
y = multip * gtk_spin_button_get_value(pcd->address_y);
2393 address = get_check_address(pcd);
2394 draw_text(context, address, &item, desc);
2395 g_free(address);
2396
2397 item.x = multip * gtk_spin_button_get_value(pcd->splits_amount_x);
2398 item.
y = multip * gtk_spin_button_get_value(pcd->splits_amount_y);
2399 text = get_check_splits_amount(pcd);
2400 draw_text(context, text, &item, desc);
2401 g_free(text);
2402
2403 item.x = multip * gtk_spin_button_get_value(pcd->splits_memo_x);
2404 item.
y = multip * gtk_spin_button_get_value(pcd->splits_memo_y);
2405 text = get_check_splits_memo(pcd);
2406 draw_text(context, text, &item, desc);
2407 g_free(text);
2408
2409 item.x = multip * gtk_spin_button_get_value(pcd->splits_account_x);
2410 item.
y = multip * gtk_spin_button_get_value(pcd->splits_account_y);
2411 text = get_check_splits_account(pcd);
2412 draw_text(context, text, &item, desc);
2413 g_free(text);
2414
2415 item.x = multip * gtk_spin_button_get_value(pcd->notes_x);
2416 item.
y = multip * gtk_spin_button_get_value(pcd->notes_y);
2418
2419 item.x = multip * gtk_spin_button_get_value(pcd->memo_x);
2420 item.
y = multip * gtk_spin_button_get_value(pcd->memo_y);
2422
2423 pango_font_description_free(desc);
2424}
2425
2426
2427
2428
2429
2430
2431static void
2432draw_page(GtkPrintOperation *operation,
2433 GtkPrintContext *context, gint page_nr, gpointer user_data)
2434{
2435 PrintCheckDialog *pcd = (PrintCheckDialog *) user_data;
2437 cairo_t *cr = gtk_print_context_get_cairo_context(context);
2438
2439 format = pcd->selected_format;
2440 if (format)
2441 {
2442 gint first_check, last_check;
2443 gint first_page_count;
2444 guint check_count = g_list_length(pcd->splits);
2445 gint check_number;
2446 gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2447 gint last_blank_check_pos;
2448 gint checks_per_page;
2449 GList *next_split;
2450
2451 if (position == pcd->position_max)
2452 {
2453
2454 checks_per_page = 1;
2455 first_page_count = 1;
2456 }
2457 else
2458 {
2459 checks_per_page = pcd->position_max;
2460 first_page_count = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2461 }
2462
2463 if (page_nr == 0)
2464 {
2465 first_check = 0;
2466 last_check = first_page_count - 1;
2467 next_split = pcd->splits;
2468 }
2469 else
2470 {
2471 first_check = first_page_count + (page_nr - 1) * checks_per_page;
2472 last_check = MIN(check_count - 1, first_check + checks_per_page - 1);
2473 next_split = g_list_nth(pcd->splits, first_check);
2474
2475 if (position < pcd->position_max)
2476 position = 0;
2477 }
2478
2479
2482 cairo_rotate(cr, format->
rotation * DEGREES_TO_RADIANS);
2484
2485
2487 {
2488 draw_grid(context,
2489 gtk_print_context_get_width(context),
2490 gtk_print_context_get_height(context),
2491 pcd->default_font);
2492 }
2493
2494 last_blank_check_pos = position - 1;
2495
2496 if ((page_nr == 0)
2497 && (last_blank_check_pos > 0)
2498 && (position < pcd->position_max))
2499 cairo_translate(cr, 0, format->
height * last_blank_check_pos);
2500
2501 for (check_number = first_check; check_number <= last_check;
2502 check_number++, position++)
2503 {
2504 pcd->split = (Split *) next_split->data;
2505 next_split = g_list_next(next_split);
2506 draw_check_format(context, position, format, user_data);
2507 }
2508 }
2509 else
2510 {
2511
2512 pcd->split = (Split *) g_list_nth_data(pcd->splits, page_nr);
2513 g_return_if_fail(pcd->split);
2514 draw_check_custom(context, user_data);
2515 }
2516}
2517
2518
2519
2520
2521
2522
2523static void
2524begin_print(GtkPrintOperation *operation,
2525 GtkPrintContext *context, gpointer user_data)
2526{
2527 PrintCheckDialog *pcd = (PrintCheckDialog *) user_data;
2528 guint check_count = g_list_length(pcd->splits);
2529 gint pages;
2530 gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2531
2532 if (pcd->selected_format
2533 && pcd->position_max > 1
2534
2535
2536
2537
2538
2539 && position < pcd->position_max)
2540
2541
2542 {
2543 gint first_page_count, remaining_count;
2544
2545 first_page_count = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2546 remaining_count = check_count - first_page_count;
2547 pages = 1
2548 + remaining_count / pcd->position_max;
2549
2550 if ((remaining_count % pcd->position_max) > 0)
2551 pages++;
2552
2553
2554 }
2555 else
2556 pages = check_count;
2557 gtk_print_operation_set_n_pages(operation, pages);
2558}
2559
2560
2561
2562
2563
2564static void
2565gnc_ui_print_check_dialog_ok_cb(PrintCheckDialog *pcd)
2566{
2567 GtkPrintOperation *print;
2568 GtkPrintOperationResult res;
2569
2570 print = gtk_print_operation_new();
2571
2573 gtk_print_operation_set_unit(print, GTK_UNIT_POINTS);
2574 gtk_print_operation_set_use_full_page(print, TRUE);
2575 g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), pcd);
2576 g_signal_connect(print, "draw_page", G_CALLBACK(draw_page), pcd);
2577
2578 res = gtk_print_operation_run(print,
2579 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2580 pcd->caller_window, NULL);
2581
2582 if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
2584
2585 g_object_unref(print);
2586}
2587
2588
2589static void
2590gnc_print_check_set_sensitive (GtkWidget *widget, gpointer data)
2591{
2592 gboolean sensitive;
2593 if (GTK_IS_LABEL(widget) || GTK_IS_SEPARATOR(widget))
2594 return;
2595 sensitive = GPOINTER_TO_INT(data);
2596 gtk_widget_set_sensitive(widget, sensitive);
2597}
2598
2599
2600void
2601gnc_print_check_format_changed (GtkComboBox *widget,
2602 PrintCheckDialog *pcd)
2603{
2604 GtkListStore *p_store;
2605 GtkTreeModel *f_model;
2606 GtkTreeIter f_iter, iter;
2607 gboolean sensitive;
2608 gint pnum;
2610 gboolean separator;
2611 GSList *elem;
2612
2613 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pcd->format_combobox), &f_iter))
2614 return;
2615 f_model = gtk_combo_box_get_model(GTK_COMBO_BOX(pcd->format_combobox));
2616 gtk_tree_model_get(f_model, &f_iter,
COL_DATA, &format,
COL_SEP, &separator, -1);
2617 if (separator)
2618 return;
2619
2620 pnum = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2621
2622
2623 pcd->selected_format = format;
2624 p_store = gtk_list_store_new (1, G_TYPE_STRING);
2625 gtk_combo_box_set_model(GTK_COMBO_BOX(pcd->position_combobox),
2626 GTK_TREE_MODEL(p_store));
2627 if (format)
2628 {
2630 {
2631 pcd->position_max = g_slist_length(format->
positions);
2632 for (elem = format->
positions; elem; elem = g_slist_next(elem))
2633 {
2634 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2635 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, elem->data, -1);
2636 }
2637 }
2638 else
2639 {
2640
2641 pcd->position_max = 1;
2642 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2643 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0,
_(
"Top"), -1);
2644 }
2645 }
2646 else
2647 {
2648 pcd->position_max = 0;
2649 }
2650 gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
2651 gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0,
_(
"Custom"), -1);
2652 g_object_unref (p_store);
2653
2654
2655 sensitive = (pcd->position_max > 0);
2656 gtk_widget_set_sensitive(GTK_WIDGET(pcd->position_combobox), sensitive);
2657
2658
2659
2660
2661 sensitive = (!separator && !format);
2662 gtk_container_foreach(GTK_CONTAINER(pcd->custom_table),
2663 gnc_print_check_set_sensitive,
2664 GINT_TO_POINTER(sensitive));
2665
2666
2667
2668 pnum = MAX(MIN(pnum, pcd->position_max), 0);
2669 gtk_combo_box_set_active(GTK_COMBO_BOX(pcd->position_combobox), pnum);
2670
2671
2672 sensitive = check_format_has_address(pcd);
2673 gtk_widget_set_sensitive(pcd->check_address_name, sensitive);
2674 gtk_widget_set_sensitive(pcd->check_address_1, sensitive);
2675 gtk_widget_set_sensitive(pcd->check_address_2, sensitive);
2676 gtk_widget_set_sensitive(pcd->check_address_3, sensitive);
2677 gtk_widget_set_sensitive(pcd->check_address_4, sensitive);
2678}
2679
2680
2681void
2682gnc_print_check_position_changed (GtkComboBox *widget,
2683 PrintCheckDialog *pcd)
2684{
2685 gboolean sensitive;
2686 gint pnum;
2687 guint check_count;
2688 gint first_page_max, first_page_min, first_page_value;
2689
2690 pnum = gtk_combo_box_get_active(GTK_COMBO_BOX(pcd->position_combobox));
2691
2692
2693 sensitive = pnum == pcd->position_max;
2694 gtk_widget_set_sensitive(GTK_WIDGET(pcd->translation_x), sensitive);
2695 gtk_widget_set_sensitive(GTK_WIDGET(pcd->translation_y), sensitive);
2696 gtk_widget_set_sensitive(GTK_WIDGET(pcd->check_rotation), sensitive);
2697 gtk_widget_set_sensitive(GTK_WIDGET(pcd->units_combobox), sensitive);
2698
2699
2700 check_count = g_list_length(pcd->splits);
2701 first_page_max = MAX(1, MIN(pcd->position_max - pnum, check_count));
2702 first_page_min = 1;
2703 pnum = gtk_spin_button_get_value_as_int(pcd->first_page_count);
2704 first_page_value = MAX(MIN(pnum, first_page_max), first_page_min);
2705 gtk_spin_button_set_range(pcd->first_page_count, (gdouble)first_page_min, (gdouble)first_page_max);
2706 gtk_spin_button_set_value(pcd->first_page_count, (gdouble)first_page_value);
2707 sensitive = first_page_max > 1;
2708 gtk_widget_set_sensitive(GTK_WIDGET(pcd->first_page_count), sensitive);
2709}
2710
2711
2712void
2713gnc_ui_print_check_response_cb(GtkDialog *dialog,
2714 gint response,
2715 PrintCheckDialog *pcd)
2716{
2717 switch (response)
2718 {
2719 case GTK_RESPONSE_HELP:
2721 return;
2722
2723 case GTK_RESPONSE_OK:
2724 gnc_ui_print_check_dialog_ok_cb(pcd);
2725 gnc_ui_print_save_dialog(pcd);
2726 gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
2727 break;
2728
2729 case GTK_RESPONSE_CANCEL:
2730 gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
2731 break;
2732 }
2733
2734 gtk_widget_destroy(pcd->dialog);
2735 g_free(pcd->default_font);
2736 g_list_free(pcd->splits);
2737 g_free(pcd);
2738}
@ COL_NAME
This column holds a copy of the check format name and is what is displayed to the user in the combobo...
@ COL_DATA
This column holds a pointer to the check format data read in from a file.
@ COL_SEP
This column contains the value TRUE if this entry specifies a separator line.
void gnc_print_operation_init(GtkPrintOperation *op, const gchar *jobname)
If print settings have been saved by gnc_print_operation_save_print_settings(), then set them on the ...
void gnc_print_operation_save_print_settings(GtkPrintOperation *op)
Retrieve the print settings from the GtkPrintOperation op and save them in a static variable.
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
const gchar * qof_date_format_get_string(QofDateFormat df)
This function returns a strftime formatting string for printing an all numeric date (e....
@ QOF_DATE_FORMAT_LOCALE
Take from locale information.
@ QOF_DATE_FORMAT_CUSTOM
Used by the check printing code.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
const char * xaccTransGetNotes(const Transaction *trans)
Gets the transaction Notes.
gnc_numeric xaccTransGetAccountAmount(const Transaction *trans, const Account *acc)
Same as xaccTransGetAccountValue, but uses the Account's commodity.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
GList SplitList
GList of Split.
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gboolean gnc_key_file_save_to_file(const gchar *filename, GKeyFile *key_file, GError **error)
Write a key/value file from memory to disk.
GKeyFile * gnc_key_file_load_from_file(const gchar *filename, gboolean ignore_error, gboolean return_empty_struct, GError **caller_error)
Open and read a key/value file from disk into memory.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
void guid_replace(GncGUID *guid)
Generate a new guid.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
char * gnc_get_account_name_for_register(const Account *account)
Get either the full name of the account or the simple name, depending on the configuration parameter ...
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
#define DEBUG(format, args...)
Print a debugging message.
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value.
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
gboolean gncOwnerGetOwnerFromTxn(Transaction *txn, GncOwner *owner)
Convenience function to get the owner from a transaction.
gboolean gnc_prefs_set_float(const gchar *group, const gchar *pref_name, gdouble value)
Store a float value into the preferences backend.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
void gnc_prefs_get_coords(const gchar *group, const gchar *pref_name, gdouble *x, gdouble *y)
Get a pair of coordinates from the preferences backend.
void gnc_prefs_reset(const gchar *group, const gchar *pref_name)
Reset a preference to its default value in the preferences backend.
gboolean gnc_prefs_set_coords(const gchar *group, const gchar *pref_name, gdouble x, gdouble y)
Store coordinates into the preferences backend.
gchar * gnc_prefs_get_string(const gchar *group, const gchar *pref_name)
Get a string value from the preferences backend.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
gboolean gnc_prefs_set_string(const gchar *group, const gchar *pref_name, const gchar *value)
Store a string into the preferences backend.
gboolean gnc_prefs_set_int(const gchar *group, const gchar *pref_name, gint value)
Store an integer value into the preferences backend.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
The type used to store guids in C.
gdouble y
The x/y coordinates where this item should be printed.
PangoAlignment align
The alignment of a text based item.
gchar * text
The text to be displayed (for text based items.) Otherwise unused.
CheckItemType type
What type of item is this?