187{
188 { "FilePrintAction", gnc_plugin_page_report_print_cb, nullptr, nullptr, nullptr },
189 { "FilePrintPDFAction", gnc_plugin_page_report_exportpdf_cb, nullptr, nullptr, nullptr },
190 { "EditCopyAction", gnc_plugin_page_report_copy_cb, nullptr, nullptr, nullptr },
191 { "EditTaxOptionsAction", gnc_plugin_page_report_edit_tax_cb, nullptr, nullptr, nullptr },
192 { "ViewRefreshAction", gnc_plugin_page_report_reload_cb, nullptr, nullptr, nullptr },
193 { "ReportSaveAction", gnc_plugin_page_report_save_cb, nullptr, nullptr, nullptr },
194 { "ReportSaveAsAction", gnc_plugin_page_report_save_as_cb, nullptr, nullptr, nullptr },
195 { "ReportExportAction", gnc_plugin_page_report_export_cb, nullptr, nullptr, nullptr },
196 { "ReportOptionsAction", gnc_plugin_page_report_options_cb, nullptr, nullptr, nullptr },
197 { "ReportBackAction", gnc_plugin_page_report_back_cb, nullptr, nullptr, nullptr },
198 { "ReportForwAction", gnc_plugin_page_report_forw_cb, nullptr, nullptr, nullptr },
199 { "ReportReloadAction", gnc_plugin_page_report_reload_cb, nullptr, nullptr, nullptr },
200 { "ReportStopAction", gnc_plugin_page_report_stop_cb, nullptr, nullptr, nullptr },
201};
202static guint num_report_actions = G_N_ELEMENTS(report_actions);
203static const gchar *initially_insensitive_actions[] =
204{
205 nullptr
206};
207
208static const gchar *disable_during_load_actions[] =
209{
210 "FilePrintAction",
211 "FilePrintPDFAction",
212 "ReportOptionsAction",
213 nullptr
214};
215
217static const gchar *gnc_plugin_load_ui_items [] =
218{
219 "FilePlaceholder3",
220 "FilePlaceholder4",
221 "FilePlaceholder5",
222 "EditPlaceholder3",
223 "EditPlaceholder5",
224 "EditPlaceholder6",
225 "ViewPlaceholder4",
226 "ReportsPlaceholder1",
227 NULL,
228};
229
232{
233 { "FilePrintAction", N_("Print") },
234 { "ReportExportAction", N_("Export") },
235 { "ReportOptionsAction", N_("Options") },
236
237
238 { "ReportSaveAction", N_("Save Config") },
239
240
241 { "ReportSaveAsAction", N_("Save Config As…") },
242 { "FilePrintPDFAction", N_("Export as PDF") },
243 { nullptr, nullptr },
244};
245
246static void
247gnc_plugin_page_report_get_property( GObject *obj,
248 guint prop_id,
249 GValue *value,
250 GParamSpec *pspec )
251{
254
255 rep = GNC_PLUGIN_PAGE_REPORT( obj );
256 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(rep);
257
258 switch ( prop_id )
259 {
260 case PROP_REPORT_ID:
261 g_value_set_int( value, priv->
reportId );
262 break;
263 default:
264 PERR(
"Unknown property id %d", prop_id );
265 break;
266 }
267}
268
269static void
270gnc_plugin_page_report_set_property( GObject *obj,
271 guint prop_id,
272 const GValue *value,
273 GParamSpec *pspec )
274{
277
278 rep = GNC_PLUGIN_PAGE_REPORT( obj );
279 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(rep);
280
281 DEBUG(
"setting property with id %d / %p to value %d",
282 prop_id, priv, g_value_get_int( value ) );
283
284 switch ( prop_id )
285 {
286 case PROP_REPORT_ID:
287 priv->
reportId = g_value_get_int( value );
288 break;
289 default:
290 PERR(
"unknown property id %d", prop_id );
291 break;
292 }
293
294}
295
300static gboolean
301gnc_plugin_page_report_focus_widget (
GncPluginPage *report_plugin_page)
302{
303 if (GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
304 {
306 GtkWidget *window;
307 GAction *action;
308
309 if (!priv)
310 return FALSE;
311
312
314 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
315
317 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
318
320 report_plugin_page,
321 gnc_plugin_load_ui_items);
322
323
325
326 gnc_plugin_page_report_menu_updates (report_plugin_page);
327
329
331 {
332 GtkWidget *widget = gnc_html_get_webview (priv->
html);
333
334 if (!priv->loaded)
335 gnc_plugin_page_report_load_uri (report_plugin_page);
336
337 if (widget && GTK_IS_WIDGET(widget))
338 {
339 if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
340 gtk_widget_grab_focus (GTK_WIDGET(widget));
341 }
342 }
343 }
344 return FALSE;
345}
346
347static void
349{
350 GObjectClass *object_class = G_OBJECT_CLASS (klass);
352
353 object_class->constructor = gnc_plugin_page_report_constructor;
354 object_class->finalize = gnc_plugin_page_report_finalize;
355
356 object_class->set_property = gnc_plugin_page_report_set_property;
357 object_class->get_property = gnc_plugin_page_report_get_property;
358
359 gnc_plugin_page_class->
tab_icon = GNC_ICON_ACCOUNT_REPORT;
360 gnc_plugin_page_class->
plugin_name = GNC_PLUGIN_PAGE_REPORT_NAME;
361
362 gnc_plugin_page_class->
create_widget = gnc_plugin_page_report_create_widget;
363 gnc_plugin_page_class->
destroy_widget = gnc_plugin_page_report_destroy_widget;
364 gnc_plugin_page_class->
save_page = gnc_plugin_page_report_save_page;
365 gnc_plugin_page_class->
recreate_page = gnc_plugin_page_report_recreate_page;
368 gnc_plugin_page_class->
finish_pending = gnc_plugin_page_report_finish_pending;
370
371
372 auto paramspec{static_cast<GParamFlags>(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)};
373 g_object_class_install_property( object_class,
374 PROP_REPORT_ID,
375 g_param_spec_int( "report-id",
376 _(
"The numeric ID of the report."),
377 _(
"The numeric ID of the report."),
378 -1, G_MAXINT, -1,
379 paramspec));
380}
381
382static void
383gnc_plugin_page_report_finalize (GObject *object)
384{
385 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REPORT (object));
386
387 ENTER(
"object %p",
object);
388 G_OBJECT_CLASS (gnc_plugin_page_report_parent_class)->finalize (object);
390}
391
392static void
393gnc_plugin_page_report_set_progressbar (
GncPluginPage *page, gboolean
set)
394{
395 GtkWidget *progressbar;
396 GtkAllocation allocation;
397
398 progressbar = gnc_window_get_progressbar (GNC_WINDOW(page->
window));
399 gtk_widget_get_allocation (GTK_WIDGET(progressbar), &allocation);
400
401
402 if (set)
403 gtk_widget_set_size_request (GTK_WIDGET(progressbar), -1, allocation.height);
404 else
405 gtk_widget_set_size_request (GTK_WIDGET(progressbar), -1, -1);
406}
407
408static void
410{
414 URLType type;
415 char * id_name;
416 char * child_name;
417 char * url_location = nullptr;
418 char * url_label = nullptr;
419
420 report = GNC_PLUGIN_PAGE_REPORT(page);
421 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
422 if (!priv)
423 return;
424
426 id_name = g_strdup_printf(
"id=%d", priv->
reportId );
427 child_name = gnc_build_url( URL_TYPE_REPORT, id_name, nullptr );
428 type = gnc_html_parse_url( priv->
html, child_name, &url_location, &url_label);
429 DEBUG(
"passing id_name=[%s] child_name=[%s] type=[%s], location=[%s], label=[%s]",
430 id_name, child_name ? child_name : "(null)",
431 type ? type : "(null)", url_location ? url_location : "(null)",
432 url_label ? url_label : "(null)" );
433
434 g_free(id_name);
435 g_free(child_name);
436
437 g_object_add_weak_pointer(G_OBJECT(page), (gpointer*)(&weak_page));
438 gtk_widget_show_all( GTK_WIDGET(priv->
container) );
439
440 priv->loaded = TRUE;
441
442
443 gnc_window_set_progressbar_window( GNC_WINDOW(page->
window) );
444
445
446 gnc_plugin_page_report_set_progressbar( page, TRUE );
447
448 gnc_html_show_url(priv->
html, type, url_location, url_label, 0);
449 g_free(url_location);
450
451 if (weak_page)
452 {
453 gnc_plugin_page_report_set_progressbar( page, FALSE );
454 g_object_remove_weak_pointer(G_OBJECT(page), (gpointer*)(&weak_page));
455 }
456
458 disable_during_load_actions, TRUE);
459
460 gnc_window_set_progressbar_window( nullptr );
461}
462
463
464static gboolean
465webkit_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
466{
469 GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask ();
471
473 return FALSE;
474
475 if ((event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_Page_Down ||
476 event->keyval == GDK_KEY_KP_Page_Up || event->keyval == GDK_KEY_KP_Page_Down)
477 && (event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
478 {
479 GtkNotebook *notebook = GTK_NOTEBOOK(gtk_widget_get_parent (GTK_WIDGET(priv->
container)));
480 gint pages = gtk_notebook_get_n_pages (notebook);
481 gint current_page = gtk_notebook_get_current_page (notebook);
482
483 if (event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_KP_Page_Up)
484 {
485 if (current_page == 0)
486 gtk_notebook_set_current_page (notebook, pages - 1);
487 else
488 gtk_notebook_prev_page (notebook);
489 }
490 else
491 {
492 if (pages == current_page + 1)
493 gtk_notebook_set_current_page (notebook, 0);
494 else
495 gtk_notebook_next_page (notebook);
496 }
497 return TRUE;
498 }
499 return FALSE;
500}
501
502static
503GtkWidget*
505{
508 GtkWindow *topLvl;
509 GtkWidget *webview;
510 URLType type;
511 char * id_name;
512 char * child_name;
513 char * url_location = nullptr;
514 char * url_label = nullptr;
515
516 ENTER(
"page %p", page);
517
518 report = GNC_PLUGIN_PAGE_REPORT(page);
519 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
520
521#ifndef WEBKIT1
522
523 priv->webkit2 = TRUE;
524#endif
525
527
528 priv->
html = gnc_html_factory_create_html();
529 gnc_html_set_parent( priv->
html, topLvl );
530 priv->loaded = FALSE;
531
532 gnc_html_history_set_node_destroy_cb(gnc_html_get_history(priv->
html),
533 gnc_plugin_page_report_history_destroy_cb,
534 (gpointer)priv);
535
536 priv->
container = GTK_CONTAINER(gtk_frame_new(
nullptr));
537 gtk_frame_set_shadow_type(GTK_FRAME(priv->
container), GTK_SHADOW_NONE);
538
539
540 gtk_widget_set_name (GTK_WIDGET(priv->
container),
"gnc-id-report-page");
541
542 gtk_container_add(GTK_CONTAINER(priv->
container),
543 gnc_html_get_widget(priv->
html));
544
545 priv->component_manager_id =
546 gnc_register_gui_component(WINDOW_REPORT_CM_CLASS, nullptr,
547 close_handler, page);
548 gnc_gui_component_set_session(priv->component_manager_id,
549 gnc_get_current_session());
550
551 gnc_html_set_urltype_cb(priv->
html, gnc_plugin_page_report_check_urltype);
552 gnc_html_set_load_cb(priv->
html, gnc_plugin_page_report_load_cb, report);
553
554
555
556 id_name = g_strdup_printf(
"id=%d", priv->
reportId );
557 child_name = gnc_build_url( URL_TYPE_REPORT, id_name, nullptr );
558 type = gnc_html_parse_url( priv->
html, child_name, &url_location, &url_label);
559
560 gnc_plugin_page_report_load_cb (priv->
html, type, id_name, url_label, report);
561 g_free(id_name);
562 g_free(child_name);
563 g_free (url_label);
564 g_free (url_location);
565
566
568
569 g_signal_connect (G_OBJECT(page), "inserted",
571 nullptr);
572
573
574 webview = gnc_html_get_webview (priv->
html);
575 if (webview)
576 {
577 gtk_widget_add_events (webview, gtk_widget_get_events (webview) |
578 GDK_KEY_PRESS_MASK);
579
580 g_signal_connect (webview, "key-press-event",
581 G_CALLBACK(webkit_key_press_event_cb),
582 page);
583 }
584
585 gtk_widget_show_all( GTK_WIDGET(priv->
container) );
588}
589
590
591
592
593
594static int
595gnc_plugin_page_report_check_urltype(URLType t)
596{
597 if (!g_strcmp0 (t, URL_TYPE_REPORT))
598 {
599 return TRUE;
600 }
601 else
602 {
603 return FALSE;
604 }
605}
606
611static void
613{
616 SCM set_needs_save = scm_c_eval_string("gnc:report-set-needs-save?!");
617 SCM inst_report;
618 int report_id;
619
620 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
622 priv->initial_report = SCM_BOOL_F;
623 priv->edited_reports = SCM_EOL;
624 priv->name_change_cb_id = 0;
625
626 g_object_get( ppage, "report-id", &report_id, nullptr );
627
628 PINFO(
"report-id: %d\n", report_id);
629
630
631
632 if ((inst_report = gnc_report_find(report_id)) == SCM_BOOL_F)
633 {
634 return;
635 }
636
637 if (priv->initial_report == SCM_BOOL_F)
638 {
639 priv->initial_report = inst_report;
640 scm_gc_protect_object(priv->initial_report);
641 }
642
643
644 PINFO(
"set needs save");
645 scm_call_2(set_needs_save, inst_report, SCM_BOOL_T);
646}
647
648
649
650
651
652static void
653gnc_plugin_page_report_load_cb (GncHtml * html, URLType type,
654 const gchar * location, const gchar * label,
655 gpointer data)
656{
659 int report_id;
660 SCM set_needs_save = scm_c_eval_string("gnc:report-set-needs-save?!");
661 SCM inst_report;
662
663 ENTER(
"load_cb: type=[%s], location=[%s], label=[%s]",
664 type ? type : "(null)", location ? location : "(null)",
665 label ? label : "(null)" );
666
667
668
669
670 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
671 if (!g_strcmp0 (type, URL_TYPE_REPORT)
672 && location
673 && (strlen(location) > 3)
674 && !strncmp("id=", location, 3))
675 {
676 report_id = gnc_report_id_string_to_report_id (location + 3);
677 if (report_id < 0)
678 {
679 LEAVE (
"id_string error %s", location);
680 return;
681 }
682 DEBUG(
"parsed id=%d", report_id );
683 }
684 else if (!g_strcmp0( type, URL_TYPE_OPTIONS)
685 && location
686 && (strlen(location) > 10)
687 && !strncmp("report-id=", location, 10))
688 {
689 report_id = atoi(location + 10);
690 inst_report = gnc_report_find(report_id);
691 if (inst_report != SCM_BOOL_F)
692 {
693 gnc_plugin_page_report_add_edited_report(priv, inst_report);
694 }
696 return;
697 }
698 else
699 {
700 LEAVE(
" unknown URL type [%s] location [%s]", type, location );
701 return;
702 }
703
704
705
706 if ((inst_report = gnc_report_find(report_id)) == SCM_BOOL_F)
707 {
708 LEAVE(
"error getting inst_report" );
709 return;
710 }
711
712 if (priv->initial_report == SCM_BOOL_F)
713 {
714 priv->initial_report = inst_report;
715 scm_gc_protect_object(priv->initial_report);
716
717 DEBUG(
"calling set_needs_save for report with id=%d", report_id);
718 scm_call_2(set_needs_save, inst_report, SCM_BOOL_T);
719
720 priv->initial_odb = gnc_get_report_optiondb(inst_report);
721
722 priv->name_change_cb_id =
723 priv->initial_odb->register_callback(
724 gnc_plugin_page_report_refresh, priv);
725
726 }
727
729 {
730 priv->
cur_odb->unregister_callback(priv->option_change_cb_id);
731 priv->option_change_cb_id = 0;
733 }
734
739
740 priv->
cur_odb = gnc_get_report_optiondb(inst_report);
741
742 priv->option_change_cb_id =
743 priv->
cur_odb->register_callback(
744 gnc_plugin_page_report_option_change_cb, report);
745
746 if (gnc_html_history_forward_p(gnc_html_get_history(priv->
html)))
747 {
748 gnc_plugin_page_report_set_fwd_button(report, TRUE);
749 }
750 else
751 {
752 gnc_plugin_page_report_set_fwd_button(report, FALSE);
753 }
754
755 if (gnc_html_history_back_p(gnc_html_get_history(priv->
html)))
756 {
757 gnc_plugin_page_report_set_back_button(report, TRUE);
758 }
759 else
760 {
761 gnc_plugin_page_report_set_back_button(report, FALSE);
762 }
763
765}
766
767
779static void
780gnc_plugin_page_report_option_change_cb(gpointer data)
781{
785 SCM dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
786
787 g_return_if_fail(GNC_IS_PLUGIN_PAGE_REPORT(data));
788 report = GNC_PLUGIN_PAGE_REPORT(data);
789 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
790 page = GNC_PLUGIN_PAGE(report);
791
792 DEBUG(
"option_change" );
794 return;
795 DEBUG(
"set-dirty, queue-draw" );
796
797
799 auto new_name{priv->
cur_odb->lookup_string_option(
"General",
800 "Report name")};
801 if (new_name != old_name)
802 {
803
804
805 char *clean_name{g_strdup(new_name.c_str())};
807 ENTER(
"Cleaned-up new report name: %s", clean_name ? clean_name :
"(null)");
809 g_free(clean_name);
810 }
811
812
813 scm_call_2(dirty_report, priv->
cur_report, SCM_BOOL_T);
814
816 disable_during_load_actions, FALSE);
817
818 priv->reloading = TRUE;
819
820
821 gnc_window_set_progressbar_window( GNC_WINDOW(page->
window) );
822
823
824 gnc_plugin_page_report_set_progressbar( page, TRUE );
825
826
827 gnc_html_reload( priv->
html, TRUE );
828
829 gnc_plugin_page_report_set_progressbar( page, FALSE );
830
831
832 gnc_window_set_progressbar_window( nullptr );
833
835 disable_during_load_actions, TRUE);
836 priv->reloading = FALSE;
837}
838
839
840static void
841gnc_plugin_page_report_history_destroy_cb(gnc_html_history_node * node,
842 gpointer user_data)
843{
844#if 0
845 static SCM remover = SCM_BOOL_F;
846 int report_id;
847
848 if (remover == SCM_BOOL_F)
849 {
850 remover = scm_c_eval_string("gnc:report-remove-by-id");
851 }
852
853 if (node
854 && !g_strcmp0 (node->type, URL_TYPE_REPORT)\
855 && !strncmp("id=", node->location, 3))
856 {
857 sscanf(node->location + 3, "%d", &report_id);
858
859
860 }
861 else
862 {
863 return;
864 }
865#endif
866}
867
868
869static void
870gnc_plugin_page_report_refresh(gpointer data)
871{
872
873 DEBUG(
"report-refresh called" );
874
875 return;
876}
877
878static void
879gnc_plugin_page_report_destroy_widget(
GncPluginPage *plugin_page)
880{
882
883
884
885 PINFO(
"destroy widget");
886 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(plugin_page);
887
888
890
891
892 g_idle_remove_by_data (plugin_page);
893
894 if (priv->component_manager_id)
895 {
896 gnc_unregister_gui_component(priv->component_manager_id);
897 priv->component_manager_id = 0;
898 }
899
900 gnc_plugin_page_report_destroy(priv);
901 gnc_report_remove_by_id(priv->
reportId);
902}
903
904
907#define SCHEME_OPTIONS "SchemeOptions"
908#define SCHEME_OPTIONS_N "SchemeOptions%d"
909
910
920static void
922 GKeyFile *key_file,
923 const gchar *group_name)
924{
927 SCM gen_save_text, scm_text;
928 SCM get_embedded_list, embedded, item, tmp_report;
929 SCM get_options;
930 gint count, id;
931 gchar *text, *key_name;
932
933 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REPORT(plugin_page));
934 g_return_if_fail (key_file != nullptr);
935 g_return_if_fail (group_name != nullptr);
936
937 ENTER(
"page %p, key_file %p, group_name %s", plugin_page, key_file,
938 group_name);
939
940 report = GNC_PLUGIN_PAGE_REPORT(plugin_page);
941 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
942
945 {
946 LEAVE(
"not saving invalid report");
947 return;
948 }
949
950 gen_save_text = scm_c_eval_string("gnc:report-serialize");
951 get_embedded_list = scm_c_eval_string("gnc:report-embedded-list");
952 get_options = scm_c_eval_string("gnc:report-options");
953 embedded = scm_call_1(get_embedded_list, scm_call_1(get_options, priv->
cur_report));
954 count = scm_ilength(embedded);
955 while (count-- > 0)
956 {
957 item = SCM_CAR(embedded);
958 embedded = SCM_CDR(embedded);
959 if (!scm_is_number(item))
960 continue;
961 id = scm_to_int (item);
962 tmp_report = gnc_report_find(id);
963 scm_text = scm_call_1(gen_save_text, tmp_report);
964 if (!scm_is_string (scm_text))
965 {
966 DEBUG(
"child report %d: nothing to save",
id);
967 continue;
968 }
969
970 key_name = g_strdup_printf(SCHEME_OPTIONS_N, id);
971 text = gnc_scm_strip_comments(scm_text);
972 g_key_file_set_value(key_file, group_name, key_name, text);
973 g_free(text);
974 g_free(key_name);
975 }
976
977 scm_text = scm_call_1(gen_save_text, priv->
cur_report);
978 if (!scm_is_string (scm_text))
979 {
980 LEAVE(
"nothing to save");
981 return;
982 }
983
984 text = gnc_scm_strip_comments(scm_text);
986 g_free(text);
988}
989
990
1001gnc_plugin_page_report_recreate_page (GtkWidget *window,
1002 GKeyFile *key_file,
1003 const gchar *group_name)
1004{
1006 gchar **keys;
1007 gsize i, num_keys;
1008 GError *error = nullptr;
1009 gchar *option_string;
1010 gint report_id;
1011 SCM scm_id, final_id = SCM_BOOL_F;
1012 SCM report;
1013
1014 g_return_val_if_fail(key_file, nullptr);
1015 g_return_val_if_fail(group_name, nullptr);
1016 ENTER(
"key_file %p, group_name %s", key_file, group_name);
1017
1018 keys = g_key_file_get_keys(key_file, group_name, &num_keys, &error);
1019 if (error)
1020 {
1021 g_warning("error reading group %s key list: %s",
1022 group_name, error->message);
1023 g_error_free(error);
1025 return nullptr;
1026 }
1027
1028 for (i = 0; i < num_keys; i++)
1029 {
1031 continue;
1032 option_string = g_key_file_get_value(key_file, group_name,
1033 keys[i], &error);
1034 if (error)
1035 {
1036 g_warning("error reading group %s key %s: %s",
1037 group_name, keys[i], error->message);
1038 g_error_free(error);
1039 g_strfreev (keys);
1041 return nullptr;
1042 }
1043 scm_id = scm_eval_string(scm_from_utf8_string(option_string));
1044 g_free(option_string);
1045
1046 if (!scm_integer_p(scm_id))
1047 {
1048 DEBUG(
"report id not an integer for key %s", keys[i]);
1049 g_strfreev (keys);
1050 return nullptr;
1051 }
1052
1053 if (final_id == SCM_BOOL_F)
1054 {
1056 {
1057 final_id = scm_id;
1058 }
1059 }
1060 }
1061 g_strfreev (keys);
1062
1063 if (final_id == SCM_BOOL_F)
1064 {
1065 LEAVE(
"report not specified");
1066 return nullptr;
1067 }
1068
1069 report_id = scm_to_int(final_id);
1070 report = gnc_report_find(report_id);
1071 if (!report)
1072 {
1073 LEAVE(
"report doesn't exist");
1074 return nullptr;
1075 }
1076
1078
1080 return page;
1081}
1082
1083
1094static void
1095gnc_plugin_page_report_name_changed (
GncPluginPage *page,
const gchar *name)
1096{
1098
1099 g_return_if_fail(GNC_IS_PLUGIN_PAGE_REPORT(page));
1100 g_return_if_fail(name != nullptr);
1101
1102 ENTER(
"page %p, name %s", page, name);
1103 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(page);
1104
1106 {
1107
1108
1109 auto old_name = priv->
cur_odb->lookup_string_option(
"General",
1110 "Report name");
1111 std::string name_str{name};
1112 DEBUG(
"Comparing old name '%s' to new name '%s'",
1113 old_name.empty() ? "(null)" : old_name.c_str(), name);
1114 if (old_name == name_str)
1115 {
1117 return;
1118 }
1119
1120
1121 priv->
cur_odb->set_string_option(
"General",
"Report name", name_str);
1122
1123 }
1124
1125
1126 gnc_plugin_page_report_option_change_cb(page);
1128}
1129
1130static void
1131gnc_plugin_page_report_update_edit_menu (
GncPluginPage *page, gboolean hide)
1132{
1134 GAction *action;
1135
1137 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), TRUE);
1139 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
1141 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
1142}
1143
1144static gboolean
1146{
1149
1150 report = GNC_PLUGIN_PAGE_REPORT(page);
1151 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1152 return !priv->reloading;
1153}
1154
1155
1156
1157
1158
1159
1160void
1162{
1163 SCM get_editor = scm_c_eval_string("gnc:report-editor-widget");
1164 SCM set_editor = scm_c_eval_string("gnc:report-set-editor-widget!");
1165 SCM edited, editor;
1166
1167
1168 for (edited = scm_list_copy(priv->edited_reports); !scm_is_null(edited);
1169 edited = SCM_CDR(edited))
1170 {
1171 editor = scm_call_1(get_editor, SCM_CAR(edited));
1172 scm_call_2(set_editor, SCM_CAR(edited), SCM_BOOL_F);
1173 if (editor != SCM_BOOL_F)
1174 {
1175#define FUNC_NAME "gtk_widget_destroy"
1176 auto w{static_cast<GtkWidget*>(SWIG_MustGetPtr(editor, SWIG_TypeQuery("_p_GtkWidget"), 1, 0))};
1177#undef FUNC_NAME
1178 gtk_widget_destroy(GTK_WIDGET(w));
1179 }
1180 }
1181
1182 if (priv->initial_odb)
1183 {
1184
1186 priv->initial_odb = nullptr;
1187 }
1188
1189 gnc_html_destroy(priv->
html);
1190 priv->
html =
nullptr;
1191
1194
1197 if (priv->edited_reports != SCM_EOL)
1198 scm_gc_unprotect_object(priv->edited_reports);
1199}
1200
1201static void
1203{
1205 priv->action_group = NULL;
1206}
1207
1208static GObject*
1209gnc_plugin_page_report_constructor(GType this_type, guint n_properties, GObjectConstructParam *properties)
1210{
1211 GObject *obj = G_OBJECT_CLASS (gnc_plugin_page_report_parent_class)->constructor(this_type, n_properties, properties);
1212
1213 gint reportId = -42;
1214 for (decltype(n_properties) i = 0; i < n_properties; i++)
1215 {
1216 GObjectConstructParam prop = properties[i];
1217 if (strcmp(prop.pspec->name, "report-id") == 0)
1218 {
1219 reportId = g_value_get_int(prop.value);
1220 }
1221 }
1222
1223 gnc_plugin_page_report_constr_init(GNC_PLUGIN_PAGE_REPORT(obj), reportId);
1224
1225 return obj;
1226}
1227
1228static void
1229gnc_plugin_page_report_menu_update (
GncPluginPage *plugin_page,
1231{
1232 GncMainWindow *window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1233 GtkWidget *tool_item;
1234
1235 for (gint i = 0; (tooltip_list[i].
action_name !=
nullptr); i++)
1236 {
1238 tooltip_list[i].action_name,
1239 _(tooltip_list[i].label),
1240 _(tooltip_list[i].tooltip));
1241
1243 tooltip_list[i].action_name);
1244 if (tool_item)
1245 {
1246 gtk_widget_set_tooltip_text (GTK_WIDGET(tool_item),
_(tooltip_list[i].tooltip));
1247 g_object_set (G_OBJECT(tool_item), "has-tooltip", false, nullptr);
1248 }
1249 }
1250
1252}
1253
1254static void
1255gnc_plugin_page_report_menu_updates (
GncPluginPage *plugin_page)
1256{
1259 GncMainWindow *window;
1261 GAction *action;
1262
1263 gchar *saved_reports_path = gnc_build_userdata_path (SAVED_REPORTS_FILE);
1264 gchar *report_save_str = g_strdup_printf (
1265 _(
"Update the current report's saved configuration. "
1266 "The report configuration will be saved in the file %s."), saved_reports_path);
1267 gchar *report_saveas_str = g_strdup_printf (
1268 _(
"Add the current report's configuration to the 'Reports->Saved Report Configurations' menu. "
1269 "The report configuration will be saved in the file %s."), saved_reports_path);
1270
1271 report = GNC_PLUGIN_PAGE_REPORT(plugin_page);
1272 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1273
1275
1276 tooltip_list[0] = { "ReportSaveAction", N_("Save _Report Configuration"), report_save_str };
1277 tooltip_list[1] = { "ReportSaveAsAction", N_("Save Report Configuration As…"), report_saveas_str };
1278 tooltip_list[2] = { nullptr, nullptr, nullptr };
1279
1280 gnc_plugin_page_report_menu_update (plugin_page, tooltip_list);
1281
1282
1284 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), true);
1285
1286 if (priv->webkit2)
1287 {
1289 gtk_widget_hide (pdf_item);
1290 }
1291 g_free (saved_reports_path);
1292 g_free (report_save_str);
1293 g_free (report_saveas_str);
1294}
1295
1296static void
1298{
1301 gboolean use_new;
1302 gchar *name;
1303
1304 DEBUG(
"property reportId=%d", reportId);
1305 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(plugin_page);
1307 priv->webkit2 = FALSE;
1308
1309 gnc_plugin_page_report_setup( GNC_PLUGIN_PAGE(plugin_page));
1310
1311
1312 parent = GNC_PLUGIN_PAGE(plugin_page);
1314 name = gnc_report_name (priv->initial_report);
1315 g_object_set (G_OBJECT(plugin_page),
1316 "page-name", name,
1317 "ui-description", "gnc-plugin-page-report.ui",
1318 "use-new-window", use_new,
1319 nullptr);
1320 g_free (name);
1321
1322
1324
1325
1327 g_action_map_add_action_entries (G_ACTION_MAP(priv->action_group),
1328 report_actions,
1329 num_report_actions,
1330 plugin_page);
1331
1333 FALSE);
1335 disable_during_load_actions, FALSE);
1336}
1337
1340{
1341 DEBUG(
"report id = %d", reportId );
1342 auto plugin_page{g_object_new(GNC_TYPE_PLUGIN_PAGE_REPORT, "report-id",
1343 reportId, nullptr)};
1344 DEBUG(
"plugin_page: %p", plugin_page );
1345 DEBUG(
"set %d on page %p", reportId, plugin_page );
1346 return GNC_PLUGIN_PAGE( plugin_page );
1347}
1348
1349void
1351 SCM report)
1352{
1353 SCM new_edited = scm_delete(priv->edited_reports, report);
1354 if (priv->edited_reports != SCM_EOL)
1355 scm_gc_unprotect_object(priv->edited_reports);
1356 priv->edited_reports = new_edited;
1357 if (new_edited != SCM_EOL)
1358 scm_gc_protect_object(priv->edited_reports);
1359}
1360
1361void
1363 SCM report)
1364{
1365 SCM new_edited = scm_cons(report, priv->edited_reports);
1366 if (priv->edited_reports != SCM_EOL)
1367 scm_gc_unprotect_object(priv->edited_reports);
1368 priv->edited_reports = new_edited;
1369 if (new_edited != SCM_EOL)
1370 scm_gc_protect_object(priv->edited_reports);
1371}
1372
1373void
1374gnc_plugin_page_report_raise_editor(SCM report)
1375{
1376 SCM get_editor = scm_c_eval_string("gnc:report-editor-widget");
1377 SCM editor = scm_call_1(get_editor, report);
1378#define FUNC_NAME "gtk_window_present"
1379 auto w{static_cast<GtkWidget *>(SWIG_MustGetPtr(editor, SWIG_TypeQuery("_p_GtkWidget"), 1, 0))};
1380#undef FUNC_NAME
1381 gtk_window_present(GTK_WINDOW(w));
1382}
1383
1384static void
1385close_handler (gpointer user_data)
1386{
1388 DEBUG(
"in close handler\n");
1390}
1391
1392static void
1394{
1396 "ReportForwAction");
1397 if (action != NULL)
1398 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), enabled);
1399}
1400
1401static void
1403{
1405 "ReportBackAction");
1406 if (action != NULL)
1407 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), enabled);
1408}
1409
1410
1411
1412
1413static void
1414gnc_plugin_page_report_forw_cb (GSimpleAction *simple,
1415 GVariant *parameter,
1416 gpointer user_data)
1417{
1420 gnc_html_history_node * node = nullptr;
1421
1423 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1424 gnc_html_history_forward(gnc_html_get_history(priv->
html));
1425 node = gnc_html_history_get_current(gnc_html_get_history(priv->
html));
1426 if (node)
1427 {
1428 gnc_html_show_url(priv->
html, node->type, node->location,
1429 node->label, 0);
1430 }
1431}
1432
1433static void
1434gnc_plugin_page_report_back_cb (GSimpleAction *simple,
1435 GVariant *parameter,
1436 gpointer user_data)
1437{
1440 gnc_html_history_node * node;
1441
1443 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1444 gnc_html_history_back(gnc_html_get_history(priv->
html));
1445 node = gnc_html_history_get_current(gnc_html_get_history(priv->
html));
1446 if (node)
1447 {
1448 gnc_html_show_url(priv->
html, node->type, node->location,
1449 node->label, 0);
1450 }
1451}
1452
1453void
1455{
1456 gnc_plugin_page_report_reload_cb (nullptr, nullptr, report);
1457}
1458
1459static void
1460gnc_plugin_page_report_reload_cb (GSimpleAction *simple,
1461 GVariant *parameter,
1462 gpointer user_data)
1463{
1467 SCM dirty_report;
1468
1470 page = GNC_PLUGIN_PAGE(report);
1471 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1473 return;
1474
1475 DEBUG(
"reload-redraw" );
1476 dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
1477 scm_call_2(dirty_report, priv->
cur_report, SCM_BOOL_T);
1478
1479
1480
1482 disable_during_load_actions, FALSE);
1483
1484 priv->reloading = TRUE;
1485
1486 gnc_window_set_progressbar_window( GNC_WINDOW(page->
window) );
1487
1488
1489 gnc_plugin_page_report_set_progressbar( page, TRUE );
1490
1491 gnc_html_reload( priv->
html, TRUE );
1492
1493 gnc_plugin_page_report_set_progressbar( page, FALSE );
1494
1495
1496 gnc_window_set_progressbar_window( nullptr );
1498 disable_during_load_actions, TRUE);
1499 priv->reloading = FALSE;
1500}
1501
1502static void
1503gnc_plugin_page_report_stop_cb (GSimpleAction *simple,
1504 GVariant *parameter,
1505 gpointer user_data)
1506{
1509
1510 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1511 gnc_html_cancel(priv->
html);
1512}
1513
1514
1515
1516static SCM
1517gnc_get_export_type_choice (SCM export_types, GtkWindow *parent)
1518{
1519 GList * choices = nullptr;
1520 gboolean bad = FALSE;
1521 GList * node;
1522 int choice;
1523 SCM tail;
1524
1525 if (!scm_is_list (export_types))
1526 return SCM_BOOL_F;
1527
1528 for (tail = export_types; !scm_is_null (tail); tail = SCM_CDR (tail))
1529 {
1530 SCM pair = SCM_CAR (tail);
1531 char * name;
1532 SCM scm;
1533
1534 if (!scm_is_pair (pair))
1535 {
1536 g_warning ("unexpected list element");
1537 bad = TRUE;
1538 break;
1539 }
1540
1541 scm = SCM_CAR (pair);
1542 if (!scm_is_string (scm))
1543 {
1544 g_warning ("unexpected pair element");
1545 bad = TRUE;
1546 break;
1547 }
1548
1549 name = gnc_scm_to_utf8_string (scm);
1550 choices = g_list_prepend (choices, name);
1551 }
1552
1553 if (!bad)
1554 {
1555 choices = g_list_reverse (choices);
1556
1557 choices = g_list_prepend (choices, g_strdup (
_(
"HTML")));
1558
1559 choice = gnc_choose_radio_option_dialog
1560 (GTK_WIDGET (parent),
_(
"Choose export format"),
1561 _(
"Choose the export format for this report:"),
1562 nullptr, 0, choices);
1563 }
1564 else
1565 choice = -1;
1566
1567 for (node = choices; node; node = node->next)
1568 g_free (node->data);
1569 g_list_free (choices);
1570
1571 if (choice < 0)
1572 return SCM_BOOL_F;
1573
1574 if (choice == 0)
1575 return SCM_BOOL_T;
1576
1577 choice--;
1578 if (choice >= scm_ilength (export_types))
1579 return SCM_BOOL_F;
1580
1581 return scm_list_ref (export_types, scm_from_int (choice));
1582}
1583
1584static char *
1585gnc_get_export_filename (SCM choice, GtkWindow *parent)
1586{
1587 char * filepath;
1588 GStatBuf statbuf;
1589 char * title;
1590 const gchar * html_type =
_(
"HTML");
1591 char * type;
1592 int rc;
1593 char * default_dir;
1594
1595 if (choice == SCM_BOOL_T)
1596 type = g_strdup (html_type);
1597 else
1598 type = gnc_scm_to_utf8_string(SCM_CAR (choice));
1599
1600
1601 title = g_strdup_printf (
_(
"Save %s To File"), type);
1602 default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_REPORT);
1603
1604 filepath = gnc_file_dialog (parent, title, nullptr, default_dir,
1605 GNC_FILE_DIALOG_EXPORT);
1606
1607
1608 if (filepath && strchr (filepath, '.') == nullptr)
1609 {
1610 char* extension = g_ascii_strdown (type, -1);
1611 char* newpath = g_strdup_printf ("%s.%s", filepath, extension);
1612 g_free (extension);
1613 g_free (filepath);
1614 filepath = newpath;
1615 }
1616
1617 g_free (type);
1618 g_free (title);
1619 g_free (default_dir);
1620
1621 if (!filepath)
1622 return nullptr;
1623
1624 default_dir = g_path_get_dirname(filepath);
1625 gnc_set_default_directory (GNC_PREFS_GROUP_REPORT, default_dir);
1626 g_free(default_dir);
1627
1628 rc = g_stat (filepath, &statbuf);
1629
1630
1631 if (rc != 0 && errno != ENOENT)
1632 {
1633
1634 const char *format =
_(
"You cannot save to that filename.\n\n%s");
1635
1636 gnc_error_dialog (parent, format, strerror(errno));
1637 g_free(filepath);
1638 return nullptr;
1639 }
1640
1641
1642 if (rc == 0 && !S_ISREG (statbuf.st_mode))
1643 {
1644 const char *message =
_(
"You cannot save to that file.");
1645
1646 gnc_error_dialog (parent, "%s", message);
1647 g_free(filepath);
1648 return nullptr;
1649 }
1650
1651 if (rc == 0)
1652 {
1653 const char *format =
_(
"The file %s already exists. "
1654 "Are you sure you want to overwrite it?");
1655
1656 if (!gnc_verify_dialog (parent, FALSE, format, filepath))
1657 {
1658 g_free(filepath);
1659 return nullptr;
1660 }
1661 }
1662
1663 return filepath;
1664}
1665
1666static void
1667gnc_plugin_page_report_edit_tax_cb (GSimpleAction *simple,
1668 GVariant *parameter,
1669 gpointer user_data)
1670{
1672 GtkWidget *window;
1673
1674 window = GNC_PLUGIN_PAGE(report)->window;
1675 gnc_tax_info_dialog (window, nullptr);
1676}
1677
1678static void
1679gnc_plugin_page_report_save_as_cb (GSimpleAction *simple,
1680 GVariant *parameter,
1681 gpointer user_data)
1682{
1685 SCM save_func;
1686 SCM rpt_id;
1687
1688 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1690 return;
1691
1692
1693
1694
1695 save_func = scm_c_eval_string("gnc:report-to-template-new");
1696 rpt_id = scm_call_1(save_func, priv->
cur_report);
1697
1698
1699 if (!scm_is_null (rpt_id))
1700 {
1702 GtkWidget *window = reportPage->
window;
1703
1704 if (window)
1705 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
1706
1707 gnc_ui_custom_report_edit_name (GNC_MAIN_WINDOW (window), rpt_id);
1708 }
1709
1710}
1711
1712static void
1713gnc_plugin_page_report_save_cb (GSimpleAction *simple,
1714 GVariant *parameter,
1715 gpointer user_data)
1716{
1719 SCM check_func, save_func;
1720 SCM rpt_id;
1721
1722 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1724 return;
1725
1726 check_func = scm_c_eval_string("gnc:is-custom-report-type");
1727 if (scm_is_true (scm_call_1 (check_func, priv->
cur_report)))
1728 {
1729 auto report_name_str{priv->
cur_odb->lookup_string_option(
"General",
"Report name")};
1731
1732 if (!gnc_action_dialog (window,
_(
"_Overwrite"),
false,
_(
"This will update and \
1733overwrite the existing saved report named \"%s\"."), report_name_str.c_str()))
1734 return;
1735
1736
1737
1738
1739 save_func = scm_c_eval_string("gnc:report-to-template-update");
1740 rpt_id = scm_call_1(save_func, priv->
cur_report);
1741 (void)rpt_id;
1742 }
1743 else
1744 {
1745
1746
1747
1748
1749 gnc_plugin_page_report_save_as_cb (simple, parameter, report);
1750 }
1751}
1752
1753static void
1754gnc_plugin_page_report_export_cb (GSimpleAction *simple,
1755 GVariant *parameter,
1756 gpointer user_data)
1757{
1760 char * filepath;
1761 SCM export_types;
1762 SCM export_thunk;
1763 gboolean result;
1764 SCM choice;
1766 (GNC_PLUGIN_PAGE (report)));
1767
1768 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1769 export_types = scm_call_1 (scm_c_eval_string ("gnc:report-export-types"),
1771
1772 export_thunk = scm_call_1 (scm_c_eval_string ("gnc:report-export-thunk"),
1774
1775 if (scm_is_list (export_types) && scm_is_procedure (export_thunk))
1776 choice = gnc_get_export_type_choice (export_types, parent);
1777 else
1778 choice = SCM_BOOL_T;
1779
1780 if (choice == SCM_BOOL_F)
1781 return;
1782
1783 filepath = gnc_get_export_filename (choice, parent);
1784 if (!filepath)
1785 return;
1786
1787 if (scm_is_pair (choice))
1788 {
1789 SCM type = scm_cdr (choice);
1790 SCM document = scm_call_2 (export_thunk, priv->
cur_report, type);
1791 SCM query_result = scm_c_eval_string ("gnc:html-document?");
1792 SCM get_export_string = scm_c_eval_string ("gnc:html-document-export-string");
1793 SCM get_export_error = scm_c_eval_string ("gnc:html-document-export-error");
1794
1795 if (scm_is_false (scm_call_1 (query_result, document)))
1796 gnc_error_dialog (parent, "%s",
1797 _(
"This report must be upgraded to return a "
1798 "document object with export-string or "
1799 "export-error."));
1800 else
1801 {
1802 SCM export_string = scm_call_1 (get_export_string, document);
1803 SCM export_error = scm_call_1 (get_export_error, document);
1804
1805 if (scm_is_string (export_string))
1806 {
1807 GError *err = nullptr;
1808 gchar *exported = scm_to_utf8_string (export_string);
1809 if (!g_file_set_contents (filepath, exported, -1, &err))
1810 gnc_error_dialog (parent, "Error during export: %s", err->message);
1811 g_free (exported);
1812 if (err)
1813 g_error_free (err);
1814 }
1815 else if (scm_is_string (export_error))
1816 {
1817 gchar *str = scm_to_utf8_string (export_error);
1818 gnc_error_dialog (parent, "error during export: %s", str);
1819 g_free (str);
1820 }
1821 else
1822 gnc_error_dialog (parent, "%s",
1823 _(
"This report must be upgraded to return a "
1824 "document object with export-string or "
1825 "export-error."));
1826 }
1827 result = TRUE;
1828 }
1829 else
1830 result = gnc_html_export_to_file (priv->
html, filepath);
1831
1832 if (!result)
1833 {
1834 const char *fmt =
_(
"Could not open the file %s. "
1835 "The error is: %s");
1836 gnc_error_dialog (parent, fmt, filepath ? filepath : "(null)",
1837 strerror (errno) ? strerror (errno) : "" );
1838 }
1839
1840 g_free(filepath);
1841 return;
1842}
1843
1844static void
1845gnc_plugin_page_report_options_cb (GSimpleAction *simple,
1846 GVariant *parameter,
1847 gpointer user_data)
1848{
1852 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
1854 return;
1855
1856 if (gnc_report_edit_options (priv->
cur_report, parent))
1857 gnc_plugin_page_report_add_edited_report(priv, priv->
cur_report);
1858}
1859
1860static GncInvoice*
1862{
1865 "Invoice Number");
1866 return GNC_INVOICE(opt_val);
1867}
1868
1869#define GNC_PREFS_GROUP_REPORT_PDFEXPORT GNC_PREFS_GROUP_GENERAL_REPORT ".pdf-export"
1870#define GNC_PREF_FILENAME_DATE_FMT "filename-date-format"
1871#define GNC_PREF_FILENAME_FMT "filename-format"
1872
1874{
1875 gchar *job_name = nullptr;
1876 gchar *report_name = nullptr;
1877 const gchar *report_number = "";
1878 gchar *job_date;
1879 const gchar *default_jobname = N_("GnuCash-Report");
1880
1881 g_assert(priv);
1882
1883 {
1884
1887 GNC_PREF_FILENAME_DATE_FMT);
1888 const gchar *date_format_string;
1889 if (!(format_code && *format_code))
1890 {
1891 g_free(format_code);
1892 format_code = g_strdup("locale");
1893 }
1894
1895 if (gnc_date_string_to_dateformat (format_code, &date_format_here))
1896 PERR(
"Incorrect date format code, using ISO-8601.");
1897
1899
1901 g_free (format_code);
1902 }
1903
1904
1906 report_name = g_strdup (
_(default_jobname));
1907 else
1908 {
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920 GncInvoice *invoice;
1921 auto report_name_str = priv->
cur_odb->lookup_string_option(
"General",
1922 "Report name");
1923 if (!report_name_str.empty())
1924 report_name = g_strdup(report_name_str.c_str());
1925 else
1926 report_name = g_strdup (
_(default_jobname));
1927
1928 if (g_strcmp0(report_name,
_(
"Printable Invoice")) == 0
1929 || g_strcmp0(report_name,
_(
"Tax Invoice")) == 0
1930 || g_strcmp0(report_name,
_(
"Easy Invoice")) == 0
1931 || g_strcmp0(report_name,
_(
"Fancy Invoice")) == 0)
1932 {
1933
1934
1935 g_free(report_name);
1936 report_name = g_strdup(
_(
"Invoice"));
1937 }
1938
1939 invoice = lookup_invoice(priv);
1940 if (invoice)
1941 {
1942
1943 report_number = gncInvoiceGetID(invoice);
1944 }
1945 }
1946
1947 if (report_name && job_date)
1948 {
1949
1951
1952 if (format && *format)
1953 {
1954 job_name = g_strdup_printf(format, report_name,
1955 report_number, job_date);
1956 }
1957 else
1958 {
1959 PWARN(
"No GNC_PREF_FILENAME_FMT!");
1960 job_name = g_strdup_printf ("%s %s %s", report_name,
1961 report_number, job_date);
1962 }
1963 g_free(format);
1964 }
1965 g_free (report_name);
1966 g_free (job_date);
1967
1968 {
1969 char forbidden_char = '/';
1970
1971
1972 while (strchr(job_name, forbidden_char))
1973 {
1974 *strchr(job_name, forbidden_char) = '_';
1975 }
1976 }
1977
1978 {
1979
1980
1981
1982
1983
1984 auto& value = static_report_printnames[job_name];
1985 value++;
1986
1987 if (value > 1)
1988 {
1989
1990 gchar *tmp = g_strdup_printf("%s_%d", job_name, value);
1991 g_free(job_name);
1992 job_name = tmp;
1993 }
1994 }
1995
1996 return job_name;
1997}
1998
1999static void
2000gnc_plugin_page_report_print_cb (GSimpleAction *simple,
2001 GVariant *parameter,
2002 gpointer user_data)
2003{
2006 gchar *job_name = report_create_jobname(priv);
2007
2008
2009
2010#ifdef WEBKIT1
2011 gnc_html_print (priv->
html, job_name, FALSE);
2012#else
2013 gnc_html_print (priv->
html, job_name);
2014#endif
2015
2016 g_free (job_name);
2017}
2018
2019static void
2020gnc_plugin_page_report_exportpdf_cb (GSimpleAction *simple,
2021 GVariant *parameter,
2022 gpointer user_data)
2023{
2026 gchar *job_name = report_create_jobname(priv);
2027 GncInvoice *invoice;
2029
2030
2031 invoice = lookup_invoice(priv);
2032 if (invoice)
2033 {
2034
2035 owner = (
GncOwner*) gncInvoiceGetOwner(invoice);
2036 if (owner)
2037 {
2039 gchar *dirname = nullptr;
2041
2042
2043
2044 if (dirname && g_file_test (dirname,
2045 (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
2046 {
2047 gchar *tmp = g_build_filename (dirname, job_name, nullptr);
2048 g_free (job_name);
2049 job_name = tmp;
2050 }
2051 }
2052 }
2053
2054
2055
2056#ifdef WEBKIT1
2057 gnc_html_print (priv->
html, job_name, TRUE);
2058#else
2059 gnc_html_print (priv->
html, job_name);
2060#endif
2061
2062 if (owner)
2063 {
2064
2065
2066
2067
2069 if (print_settings && gtk_print_settings_has_key (print_settings,
2071 {
2072 const char* dirname = gtk_print_settings_get (print_settings,
2074
2075 if (g_file_test (dirname,
2076 (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
2077 {
2081 gncOwnerCommitEdit (owner);
2082 }
2083 }
2084 }
2085 g_free (job_name);
2086}
2087
2088static void
2089gnc_plugin_page_report_copy_cb (GSimpleAction *simple,
2090 GVariant *parameter,
2091 gpointer user_data)
2092{
2095
2096 priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
2097 gnc_html_copy_to_clipboard(priv->
html);
2098}
2099
2100
2101
2102
2103
2104
2105void
2106gnc_main_window_open_report(int report_id, GncMainWindow *window)
2107{
2109
2110 if (window)
2111 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
2112
2115}
2116
2117void
2118gnc_main_window_open_report_url(const char * url, GncMainWindow *window)
2119{
2121
2122 DEBUG(
"report url: [%s]\n", url );
2123
2124 if (window)
2125 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
2126
2129}
2130
GtkPrintSettings * gnc_print_get_settings()
Returns the pointer to our static GtkPrintSettings object.
#define GNC_GTK_PRINT_SETTINGS_EXPORT_DIR
Key for saving the PDF-export directory in the print settings.
GSimpleActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GSimpleActionGroup object associated with this page.
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
Retrieve a pointer to the GncMainWindow (GtkWindow) containing this page.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
GAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
Retrieve a GAction object associated with this page.
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
Add a book reference to the specified page.
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
void gnc_plugin_page_inserted_cb(GncPluginPage *page, gpointer user_data)
Set up the page_changed callback for when the current page is changed.
QofDateFormat
Enum for determining a date format.
char * gnc_print_time64(time64 time, const char *format)
print a time64 as a date string per format
time64 gnc_time(time64 *tbuf)
get the current time
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_ISO
ISO: yyyy-mm-dd.
void gnc_main_window_menu_add_accelerator_keys(GncMainWindow *window)
Scan the main window menu and add accelerator keys to main window accelerator group.
gboolean gnc_main_window_is_restoring_pages(GncMainWindow *window)
Check if the main window is restoring the plugin pages.
GncPluginPage * gnc_main_window_get_current_page(GncMainWindow *window)
Retrieve a pointer to the page that is currently at the front of the specified window.
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
void gnc_main_window_init_short_names(GncMainWindow *window, GncToolBarShortNames *toolbar_labels)
Update the labels of the toolbar items with short names.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
gboolean gnc_main_window_update_menu_for_action(GncMainWindow *window, const gchar *action_name, const gchar *label, const gchar *tooltip)
Find the GMenuModel item given the action name for the window specified.
GtkWidget * gnc_main_window_menu_find_menu_item(GncMainWindow *window, const gchar *action_name)
Find the menu item with the given action name for the window specified.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
GtkWidget * gnc_main_window_toolbar_find_tool_item(GncMainWindow *window, const gchar *action_name)
Find the toolbar item with the given action name for the window specified.
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
GncPluginPage * gnc_plugin_page_report_new(int reportId)
#define SCHEME_OPTIONS
The key name used it the state file for storing the report options.
void gnc_utf8_strip_invalid_and_controls(gchar *str)
Strip any non-utf8 characters and any control characters (everything < 0x20, , \f,...
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
#define PINFO(format, args...)
Print an informational note.
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
#define ENTER(format, args...)
Print a function entry debugging message.
const QofInstance * gnc_option_db_lookup_qofinstance_value(GncOptionDB *odb, const char *section, const char *name)
Retrieve the QofInstance value of an option in the GncOptionDB.
void gnc_option_db_destroy(GncOptionDB *odb)
Destruct and release a GncOptionDB.
void gncOwnerBeginEdit(GncOwner *owner)
These are convenience wrappers around gnc{Vendor,Customer,Job,Employee}* functions.
QofInstance * qofOwnerGetOwner(const GncOwner *owner)
return the owner itself as an entity.
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.
The class data structure for a content plugin.
void(* update_edit_menu_actions)(GncPluginPage *plugin_page, gboolean hide)
This function vector allows page specific actions to override the generic code for setting the sensit...
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
Save enough information about this page so that it can be recreated next time the user starts gnucash...
const gchar * tab_icon
The relative name of the icon that should be shown on the tab for this page.
const gchar * plugin_name
The textual name of this plugin.
void(* destroy_widget)(GncPluginPage *plugin_page)
Function called to destroy the display widget for a particular type of plugin.
gboolean(* finish_pending)(GncPluginPage *plugin_page)
This function vector is called to finish any outstanding activities.
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
Create a new page based on the information saved during a previous instantiation of gnucash.
void(* page_name_changed)(GncPluginPage *plugin_page, const gchar *name)
This function vector allows page specific actions to occur when the page name is changed.
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
Function called to create the display widget for a particular type of plugin.
gboolean(* focus_page_function)(GncPluginPage *plugin_page)
This function performs specific actions to set the focus on a specific widget.
The instance data structure for a content plugin.
GtkWidget * window
The window that contains the display widget for this plugin.