36#include <glib/gi18n.h>
37#include "dialog-utils.h"
39#include "gnc-date-edit.h"
48#include "engine-helpers.h"
49#include "qofbookslots.h"
64static std::string DEFAULT_FILTER_NUM_DAYS_GL =
"30";
65static std::string DEFAULT_FILTER =
"0x001f";
68static QofLogModule log_module = GNC_MOD_GUI;
75 GtkWidget* start_earliest;
76 GtkWidget* start_relative_check;
77 GtkWidget* start_relative;
78 GtkWidget* start_date_check;
79 GtkWidget* start_date;
80 GtkWidget* start_days_check;
81 GtkWidget* start_days;
83 GtkWidget* end_latest;
84 GtkWidget* end_relative_check;
85 GtkWidget* end_relative;
86 GtkWidget* end_date_check;
88 GtkWidget* end_days_check;
93 cleared_match_t original_cleared_match;
95 time64 original_start_time;
96 int original_start_days;
99 int original_end_days;
101 bool original_save_filter;
103 bool show_save_button;
151 std::string action_name;
156static std::array<status_action, 5> status_actions {{
157 {
"filter_status_reconciled", CLEARED_RECONCILED,
nullptr },
158 {
"filter_status_cleared", CLEARED_CLEARED,
nullptr },
159 {
"filter_status_voided", CLEARED_VOIDED,
nullptr },
160 {
"filter_status_frozen", CLEARED_FROZEN,
nullptr },
161 {
"filter_status_unreconciled", CLEARED_NO,
nullptr }
166gboolean_to_bool (gboolean value)
168 return value ? true :
false;
171static inline gboolean
172bool_to_gboolean (
bool value)
174 return value ? TRUE : FALSE;
178get_filter_default_num_of_days (GNCLedgerDisplayType ledger_type)
180 if (ledger_type == LD_GL)
181 return DEFAULT_FILTER_NUM_DAYS_GL;
188ppr_filter_time2dmy (
time64 raw_time)
191 char date_string[11];
194 strftime (date_string, 11,
"%d-%m-%Y", timeinfo);
195 PINFO(
"Date to string is %s", date_string);
198 return (date_string);
203ppr_filter_dmy2time (std::string date_string)
207 PINFO(
"Date from string is %s", date_string.c_str());
208 memset (&when, 0,
sizeof (when));
210 std::sscanf (date_string.c_str(),
"%d-%d-%d", &when.tm_mday,
211 &when.tm_mon, &when.tm_year);
214 when.tm_year -= 1900;
221get_time_for_days_ago (
int days,
bool use_day_start)
232 tm.tm_mday = tm.tm_mday - days;
238static std::vector<std::string>
239split_filter_by_delimiter (std::string str,
char delimiter)
241 std::istringstream ss;
242 std::vector<std::string> res;
245 while (std::getline (ss, token, delimiter))
247 res.push_back (token);
253ppr_check_for_empty_group (GKeyFile *state_file,
254 const gchar *state_section)
257 gchar **keys = g_key_file_get_keys (state_file, state_section, &num_keys,
nullptr);
266ppr_filter_load_filter (GNCSplitReg *gsr, GNCLedgerDisplayType ledger_type)
270 auto state_section = gsr_get_register_state_section (gsr);
271 GError* error =
nullptr;
273 auto filter = g_key_file_get_string (state_file, state_section,
274 KEY_PAGE_FILTER, &error);
275 std::string filter_str;
278 g_clear_error (&error);
280 filter_str = std::string (filter);
283 g_free (state_section);
285 if (!filter_str.empty())
288 return DEFAULT_FILTER +
";0;0;" + get_filter_default_num_of_days (ledger_type);
292set_filterdata_to_defaults (
FilterData *fd,
bool date_parts_only)
294 if (!date_parts_only)
296 fd->cleared_match = (cleared_match_t)std::stol (DEFAULT_FILTER,
nullptr, 16);
297 fd->save_filter =
false;
299 fd->start_ap = GNC_ACCOUNTING_PERIOD_INVALID;
302 fd->end_ap = GNC_ACCOUNTING_PERIOD_INVALID;
309get_trailing_int (
const std::string split_filter,
const std::string find_text)
312 std::size_t found = split_filter.find (find_text);
314 if (found != std::string::npos)
316 std::string found_str = split_filter.substr (found + find_text.length(), std::string::npos);
317 ret_int = std::stol (found_str,
nullptr, 10);
323update_fd_with_date_filter_parts (
FilterData *fd,
const std::string filter_part,
324 bool start_filter,
int ap_trailing_int,
int days_trailing_int)
326 if (ap_trailing_int != -1)
328 GDate *tmp_date =
nullptr;
348 g_date_free (tmp_date);
353 if (days_trailing_int != -1)
357 fd->start_days = days_trailing_int;
358 fd->start_time = get_time_for_days_ago (fd->start_days,
true);
362 fd->end_days = days_trailing_int;
363 fd->end_time = get_time_for_days_ago (fd->end_days,
false);
368 time64 tmp_time = ppr_filter_dmy2time (filter_part);
375 fd->save_filter =
true;
379ppr_filter_load_filter_parts (GNCSplitReg *gsr, GNCLedgerDisplayType ledger_type,
FilterData *fd)
381 set_filterdata_to_defaults (fd,
false);
382 fd->dialog =
nullptr;
387 std::string filter_str = ppr_filter_load_filter (gsr, ledger_type);
389 PINFO(
"Loaded Filter String is %s", filter_str.c_str());
391 std::vector<std::string> split_filter = split_filter_by_delimiter (filter_str,
';');
392 int split_filter_size = split_filter.size();
394 if (split_filter_size > 0 && (split_filter[0].compare (DEFAULT_FILTER)) != 0)
396 PINFO(
"Loaded Filter Status is %s", split_filter[0].c_str());
398 fd->cleared_match = (cleared_match_t)std::stol (split_filter[0],
nullptr, 16);
399 fd->save_filter =
true;
402 if (split_filter_size > 1 && (split_filter[1].compare (std::string (
"0"))) != 0)
404 PINFO(
"Loaded Filter Start Date is %s", split_filter[1].c_str());
406 int ap_trailing_int = get_trailing_int (split_filter[1],
"SAP");
407 int days_trailing_int = get_trailing_int (split_filter[1],
"SDAY");
409 update_fd_with_date_filter_parts (fd, split_filter[1],
true, ap_trailing_int, days_trailing_int);
412 if (split_filter_size > 2 && (split_filter[2].compare (std::string (
"0"))) != 0)
414 PINFO(
"Loaded Filter End Date is %s", split_filter[2].c_str());
416 int ap_trailing_int = get_trailing_int (split_filter[2],
"EAP");
417 int days_trailing_int = get_trailing_int (split_filter[2],
"EDAY");
419 update_fd_with_date_filter_parts (fd, split_filter[2],
false, ap_trailing_int, days_trailing_int);
423 fd->days = (int)std::stol (get_filter_default_num_of_days (ledger_type),
nullptr, 10);
425 if (split_filter_size > 3 &&
426 (split_filter[3].compare (get_filter_default_num_of_days (ledger_type)) != 0))
428 PINFO(
"Loaded Filter Days is %s", split_filter[3].c_str());
430 fd->days = (int)std::stol (split_filter[3],
nullptr, 10);
431 fd->save_filter =
true;
436ppr_filter_save_filter (GNCSplitReg *gsr, std::string filter)
439 GNCLedgerDisplayType ledger_type = gnc_ledger_display_type (gsr->ledger);
441 std::string default_filter_str = DEFAULT_FILTER +
";0;0;" +
442 get_filter_default_num_of_days (ledger_type);
446 auto state_section = gsr_get_register_state_section (gsr);
448 if (filter.empty() || (filter.compare (default_filter_str) == 0))
450 if (g_key_file_has_key (state_file, state_section, KEY_PAGE_FILTER,
nullptr))
451 g_key_file_remove_key (state_file, state_section, KEY_PAGE_FILTER,
nullptr);
453 ppr_check_for_empty_group (state_file, state_section);
457 PINFO(
"The filter to save is %s", filter.c_str());
458 g_key_file_set_string (state_file, state_section, KEY_PAGE_FILTER,
461 g_free (state_section);
465ppr_filter_save_filter_parts (GNCSplitReg *gsr,
FilterData *fd)
470 std::string save_filter_str;
474 static const size_t buffer_size = 10;
475 char buffer [buffer_size];
478 std::snprintf (buffer, buffer_size,
"0x%04x", fd->cleared_match);
479 save_filter_str.append (buffer);
482 if (fd->start_ap != GNC_ACCOUNTING_PERIOD_INVALID)
483 save_filter_str.append (
";SAP" + std::to_string (fd->start_ap));
484 else if (fd->start_days > 0)
485 save_filter_str.append (
";SDAY" + std::to_string (fd->start_days));
486 else if (fd->start_time != 0)
487 save_filter_str.append (
";" + ppr_filter_time2dmy (fd->start_time));
489 save_filter_str.append (
";0");
492 if (fd->end_ap != GNC_ACCOUNTING_PERIOD_INVALID)
493 save_filter_str.append (
";EAP" + std::to_string (fd->end_ap));
494 else if (fd->end_days > 0)
495 save_filter_str.append (
";EDAY" + std::to_string (fd->end_days));
496 else if (fd->end_time != 0)
497 save_filter_str.append (
";" + ppr_filter_time2dmy (fd->end_time));
499 save_filter_str.append (
";0");
504 save_filter_str.append (
";" + std::to_string (fd->days));
507 save_filter_str.append (
";0");
509 ppr_filter_save_filter (gsr, save_filter_str);
513update_match_filter_text (cleared_match_t match,
const guint mask,
514 const gchar* filter_name, GList **show, GList **hide)
516 if ((match & mask) == mask)
517 *show = g_list_prepend (*show, g_strdup (filter_name));
519 *hide = g_list_prepend (*hide, g_strdup (filter_name));
533 GList *t_list =
nullptr;
540 if (fd->start_time != 0)
543 t_list = g_list_prepend
544 (t_list, g_strdup_printf (
"%s %s", _(
"Start Date:"), sdate));
551 t_list = g_list_prepend
552 (t_list, g_strdup_printf (
"%s %d", _(
"Show previous number of days:"),
556 if (fd->end_time != 0)
559 t_list = g_list_prepend
560 (t_list, g_strdup_printf (
"%s %s", _(
"End Date:"), edate));
565 if (fd->cleared_match != CLEARED_ALL)
567 GList *show =
nullptr;
568 GList *hide =
nullptr;
570 update_match_filter_text (fd->cleared_match, 0x01, _(
"Unreconciled"),
572 update_match_filter_text (fd->cleared_match, 0x02, _(
"Cleared"),
574 update_match_filter_text (fd->cleared_match, 0x04, _(
"Reconciled"),
576 update_match_filter_text (fd->cleared_match, 0x08, _(
"Frozen"),
578 update_match_filter_text (fd->cleared_match, 0x10, _(
"Voided"),
581 show = g_list_reverse (show);
582 hide = g_list_reverse (hide);
587 t_list = g_list_prepend
588 (t_list, g_strdup_printf (
"%s %s", _(
"Show:"), str));
595 t_list = g_list_prepend
596 (t_list, g_strdup_printf (
"%s %s", _(
"Hide:"), str));
600 g_list_free_full (show, g_free);
601 g_list_free_full (hide, g_free);
604 t_list = g_list_reverse (t_list);
607 t_list = g_list_prepend (t_list, g_strdup (_(
"Filter By:")));
610 if (gsr->filter_text)
611 g_free (gsr->filter_text);
616 g_list_free_full (t_list, g_free);
639 LEAVE(
"no query found");
647 if (reg->type != SEARCH_LEDGER)
649 GSList *param_list = qof_query_build_param_list (SPLIT_RECONCILE,
nullptr);
651 g_slist_free (param_list);
655 if (fd->cleared_match != CLEARED_ALL)
656 xaccQueryAddClearedMatch (query, fd->cleared_match, QOF_QUERY_AND);
683 LEAVE(
"no query found");
691 if (reg->type != SEARCH_LEDGER)
693 GSList *param_list = qof_query_build_param_list (SPLIT_TRANS,
694 TRANS_DATE_POSTED,
nullptr);
696 g_slist_free (param_list);
699 if (fd->start_time || fd->end_time)
702 xaccQueryAddDateMatchTT (query,
703 fd->start_time != 0, fd->start_time,
704 fd->end_time != 0, fd->end_time,
710 time64 start = get_time_for_days_ago (fd->days,
true);
711 xaccQueryAddDateMatchTT (query, TRUE, start, FALSE, 0, QOF_QUERY_AND);
730 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
734 set_filterdata_to_defaults (fd,
false);
736 ppr_filter_update_date_query (plugin_page);
747 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
755 GNCLedgerDisplayType ledger_type = gnc_ledger_display_type (gsr->ledger);
758 fd->save_filter =
false;
760 ppr_filter_load_filter_parts (gsr, ledger_type, fd);
762 if (ledger_type == LD_GL)
766 if (reg->type != GENERAL_JOURNAL)
767 set_filterdata_to_defaults (fd,
false);
770 ppr_filter_update_status_query (plugin_page);
771 ppr_filter_update_date_query (plugin_page);
787 g_return_if_fail (GTK_IS_CHECK_BUTTON(button));
788 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
790 auto name = gtk_buildable_get_name (GTK_BUILDABLE(button));
792 ENTER(
"toggle button %s (%p), plugin_page %p", name, button, rfd->plugin_page);
797 int value = CLEARED_NONE;
798 for (
const auto& action : status_actions)
800 if (action.action_name.compare (name) == 0)
802 value = action.value;
808 if (gtk_toggle_button_get_active (button))
809 fd->cleared_match = (cleared_match_t)(fd->cleared_match | value);
811 fd->cleared_match = (cleared_match_t)(fd->cleared_match & ~value);
813 ppr_filter_update_status_query (rfd->plugin_page);
819set_sensitive_start_widget (
RegisterFilterDialog *rfd, GtkWidget *enable_widget, gboolean active)
821 gtk_widget_set_sensitive (GTK_WIDGET(rfd->start_earliest), !active);
822 gtk_widget_set_sensitive (GTK_WIDGET(rfd->start_relative), FALSE);
823 gtk_widget_set_sensitive (GTK_WIDGET(rfd->start_date), FALSE);
824 gtk_widget_set_sensitive (GTK_WIDGET(rfd->start_days), FALSE);
825 gtk_widget_set_sensitive (GTK_WIDGET(enable_widget), active);
831 gtk_widget_set_sensitive (GTK_WIDGET(rfd->end_latest), !active);
832 gtk_widget_set_sensitive (GTK_WIDGET(rfd->end_relative), FALSE);
833 gtk_widget_set_sensitive (GTK_WIDGET(rfd->end_date), FALSE);
834 gtk_widget_set_sensitive (GTK_WIDGET(rfd->end_days), FALSE);
835 gtk_widget_set_sensitive (GTK_WIDGET(enable_widget), active);
839set_checkbutton_with_blocking (GtkWidget *widget1, GtkWidget *widget2,
844 PINFO(
"Block GtkToggleButton %p for setting active %s",
845 widget1, active ?
"TRUE" :
"FALSE");
846 g_signal_handlers_block_by_func (widget1,
847 (gpointer)function, rfd);
848 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget1), active);
849 g_signal_handlers_unblock_by_func (widget1,
850 (gpointer)function, rfd);
854 PINFO(
"Block GtkToggleButton %p for setting active %s",
855 widget2, active ?
"TRUE" :
"FALSE");
856 g_signal_handlers_block_by_func (widget2,
857 (gpointer)function, rfd);
858 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget2), active);
859 g_signal_handlers_unblock_by_func (widget2,
860 (gpointer)function, rfd);
876 g_return_if_fail (GTK_IS_BUTTON(button));
877 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
879 ENTER(
"(button %p, page %p)", button, rfd->plugin_page);
884 for (
const auto& action : status_actions)
886 set_checkbutton_with_blocking (action.widget,
nullptr,
892 fd->cleared_match = CLEARED_ALL;
893 ppr_filter_update_status_query (rfd->plugin_page);
909 g_return_if_fail (GTK_IS_BUTTON(button));
910 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
912 ENTER(
"(button %p, page %p)", button, rfd->plugin_page);
917 for (
const auto& action : status_actions)
919 set_checkbutton_with_blocking (action.widget,
nullptr,
925 fd->cleared_match = CLEARED_NONE;
926 ppr_filter_update_status_query (rfd->plugin_page);
931print_info_time64_date (
const gchar *text,
time64 date)
934 PINFO(
"%s, %s", text, date_txt);
945 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->start_date_check)))
947 time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(rfd->start_date));
949 fd->start_time = time_val;
950 fd->start_ap = GNC_ACCOUNTING_PERIOD_INVALID;
951 print_info_time64_date (
"Start date is", fd->start_time);
953 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->start_relative_check)))
958 print_info_time64_date (
"Start date relative is", fd->start_time);
961 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->start_days_check)))
963 fd->start_days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(rfd->start_days));
964 fd->start_time = get_time_for_days_ago (fd->start_days,
true);
965 fd->start_ap = GNC_ACCOUNTING_PERIOD_INVALID;
966 print_info_time64_date (
"Start date using days is", fd->start_time);
971 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->end_date_check)))
973 time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(rfd->end_date));
975 fd->end_time = time_val;
976 fd->end_ap = GNC_ACCOUNTING_PERIOD_INVALID;
977 print_info_time64_date (
"End date is", fd->end_time);
979 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->end_relative_check)))
984 print_info_time64_date (
"End date relative is", fd->end_time);
987 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rfd->end_days_check)))
989 fd->end_days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(rfd->end_days));
990 fd->end_time = get_time_for_days_ago (fd->end_days,
false);
991 fd->end_ap = GNC_ACCOUNTING_PERIOD_INVALID;
992 print_info_time64_date (
"End date using days is", fd->end_time);
1012 g_return_if_fail (GTK_IS_RADIO_BUTTON(button));
1013 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1015 ENTER(
"(button %p, page %p)", button, rfd->plugin_page);
1019 auto name = gtk_buildable_get_name (GTK_BUILDABLE(button));
1020 gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
1022 if (active && g_strcmp0 (name,
"filter_show_range") == 0)
1024 gtk_widget_set_sensitive (rfd->table, active);
1025 gtk_widget_set_sensitive (rfd->num_days, !active);
1026 get_filter_times (rfd);
1028 else if (active && g_strcmp0 (name,
"filter_show_days") == 0)
1030 gtk_widget_set_sensitive (rfd->table, !active);
1031 gtk_widget_set_sensitive (rfd->num_days, active);
1032 fd->days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(rfd->num_days));
1036 gtk_widget_set_sensitive (rfd->table, FALSE);
1037 gtk_widget_set_sensitive (rfd->num_days, FALSE);
1038 set_filterdata_to_defaults (fd,
true);
1040 ppr_filter_update_date_query (rfd->plugin_page);
1057 g_return_if_fail (GTK_IS_SPIN_BUTTON(button));
1058 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1060 ENTER(
"(button %p, page %p)", button, rfd->plugin_page);
1064 fd->days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(button));
1065 ppr_filter_update_date_query (rfd->plugin_page);
1071ppr_filter_gde_changed_cb (GtkWidget* unused,
1074 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1076 ENTER(
"(widget %s(%p), page %p)",
1077 gtk_buildable_get_name (GTK_BUILDABLE(unused)), unused, rfd->plugin_page);
1079 get_filter_times (rfd);
1080 ppr_filter_update_date_query (rfd->plugin_page);
1107 g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
1108 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1110 ENTER(
"(radio %s(%p), page %p)",
1111 gtk_buildable_get_name (GTK_BUILDABLE(radio)), radio, rfd->plugin_page);
1113 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
1115 LEAVE(
"1st callback of pair. Defer to 2nd callback.");
1119 auto name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
1120 gboolean active = !g_strcmp0 (name,
"start_date_choose");
1121 gtk_widget_set_sensitive (rfd->start_date, active);
1122 get_filter_times (rfd);
1123 ppr_filter_update_date_query (rfd->plugin_page);
1150 g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
1151 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1153 ENTER(
"(radio %s(%p), page %p)",
1154 gtk_buildable_get_name (GTK_BUILDABLE(radio)), radio, rfd->plugin_page);
1156 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
1158 LEAVE(
"1st callback of pair. Defer to 2nd callback.");
1162 auto name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
1163 gboolean active = !g_strcmp0 (name,
"end_date_choose");
1164 gtk_widget_set_sensitive (rfd->end_date, active);
1165 get_filter_times (rfd);
1166 ppr_filter_update_date_query (rfd->plugin_page);
1172ppr_filter_relative_changed_cb (GtkWidget *widget,
1175 g_return_if_fail (GNC_IS_PERIOD_SELECT(widget));
1176 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1178 ENTER(
"Period Select (%p), active_id %d, plugin_page %p",
1182 get_filter_times (rfd);
1183 ppr_filter_update_date_query (rfd->plugin_page);
1201 g_return_if_fail (GTK_IS_SPIN_BUTTON(button));
1202 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1204 ENTER(
"(button %p, page %p)", button, rfd->plugin_page);
1208 auto name = gtk_buildable_get_name (GTK_BUILDABLE(button));
1210 if (g_strcmp0 (name,
"start_days_spin") == 0)
1211 fd->start_days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(button));
1213 if (g_strcmp0 (name,
"end_days_spin") == 0)
1214 fd->end_days = gtk_spin_button_get_value (GTK_SPIN_BUTTON(button));
1216 get_filter_times (rfd);
1217 ppr_filter_update_date_query (rfd->plugin_page);
1234 g_return_if_fail (GTK_IS_CHECK_BUTTON(button));
1235 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1237 ENTER(
"Start toggle button (%p), plugin_page %p", button, rfd->plugin_page);
1239 auto name = gtk_buildable_get_name (GTK_BUILDABLE(button));
1241 gboolean active = gtk_toggle_button_get_active (button);
1243 gtk_widget_set_sensitive (rfd->start_earliest, !active);
1245 if (g_strcmp0 (name,
"start_date_check") == 0)
1247 set_sensitive_start_widget (rfd, rfd->start_date, active);
1249 set_checkbutton_with_blocking (rfd->start_relative_check,
1250 rfd->start_days_check,
1254 if (g_strcmp0 (name,
"start_relative_check") == 0)
1256 set_sensitive_start_widget (rfd, rfd->start_relative, active);
1258 set_checkbutton_with_blocking (rfd->start_date_check,
1259 rfd->start_days_check,
1263 if (g_strcmp0 (name,
"start_days_check") == 0)
1265 set_sensitive_start_widget (rfd, rfd->start_days, active);
1267 set_checkbutton_with_blocking (rfd->start_date_check,
1268 rfd->start_relative_check,
1272 get_filter_times (rfd);
1273 ppr_filter_update_date_query (rfd->plugin_page);
1290 g_return_if_fail (GTK_IS_CHECK_BUTTON(button));
1291 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1293 ENTER(
"End toggle button (%p), plugin_page %p", button, rfd->plugin_page);
1295 auto name = gtk_buildable_get_name (GTK_BUILDABLE(button));
1297 gboolean active = gtk_toggle_button_get_active (button);
1299 gtk_widget_set_sensitive (rfd->end_latest, !active);
1301 if (g_strcmp0 (name,
"end_date_check") == 0)
1303 set_sensitive_end_widget (rfd, rfd->end_date, active);
1305 set_checkbutton_with_blocking (rfd->end_relative_check,
1306 rfd->end_days_check,
1310 if (g_strcmp0 (name,
"end_relative_check") == 0)
1312 set_sensitive_end_widget (rfd, rfd->end_relative, active);
1314 set_checkbutton_with_blocking (rfd->end_date_check,
1315 rfd->end_days_check,
1319 if (g_strcmp0 (name,
"end_days_check") == 0)
1321 set_sensitive_end_widget (rfd, rfd->end_days, active);
1323 set_checkbutton_with_blocking (rfd->end_date_check,
1324 rfd->end_relative_check,
1328 get_filter_times (rfd);
1329 ppr_filter_update_date_query (rfd->plugin_page);
1345 g_return_if_fail (GTK_IS_CHECK_BUTTON(button));
1346 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1348 ENTER(
"Save toggle button (%p), plugin_page %p", button, rfd->plugin_page);
1353 if (gtk_toggle_button_get_active (button))
1354 fd->save_filter =
true;
1356 fd->save_filter =
false;
1376 g_return_if_fail (GTK_IS_DIALOG(dialog));
1377 g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(rfd->plugin_page));
1384 if ((fd->start_time > 0 && fd->end_time > 0) && (fd->start_time > fd->end_time))
1386 auto response = gnc_ok_cancel_dialog (GTK_WINDOW(rfd->dialog),
1387 GTK_RESPONSE_CANCEL,
1388 _(
"The Start date is after the End date.\n"
1389 "Select Cancel to change dates.\n"));
1390 if (response == GTK_RESPONSE_CANCEL)
1394 if (response != GTK_RESPONSE_OK)
1397 fd->cleared_match = rfd->original_cleared_match;
1399 ppr_filter_update_status_query (rfd->plugin_page);
1402 fd->start_ap = rfd->original_start_ap;
1403 fd->start_time = rfd->original_start_time;
1404 fd->start_days = rfd->original_start_days;
1405 fd->end_ap = rfd->original_end_ap;
1406 fd->end_time = rfd->original_end_time;
1407 fd->end_days = rfd->original_end_days;
1409 fd->days = rfd->original_days;
1410 fd->save_filter = rfd->original_save_filter;
1411 ppr_filter_update_date_query (rfd->plugin_page);
1416 if (!fd->save_filter && rfd->original_save_filter)
1417 ppr_filter_save_filter (gsr,
"");
1419 rfd->original_save_filter = fd->save_filter;
1421 if (fd->save_filter)
1422 ppr_filter_save_filter_parts (gsr, fd);
1424 rfd->dialog =
nullptr;
1425 fd->dialog =
nullptr;
1427 gtk_widget_destroy (GTK_WIDGET(dialog));
1432setup_period_select (GtkBuilder *builder, gboolean start_type,
const gchar *hbox_txt)
1436 auto hbox = GTK_WIDGET(gtk_builder_get_object (builder, hbox_txt));
1437 gtk_box_pack_start (GTK_BOX(hbox), period_select, TRUE, TRUE, 0);
1438 gtk_widget_show (period_select);
1440 gtk_widget_set_sensitive (GTK_WIDGET(period_select), FALSE);
1441 return period_select;
1445setup_date_edit (GtkBuilder *builder,
const gchar *hbox_txt)
1447 GtkWidget *date_widget = gnc_date_edit_new (
gnc_time (
nullptr), FALSE, FALSE);
1448 auto hbox = GTK_WIDGET(gtk_builder_get_object (builder, hbox_txt));
1449 gtk_box_pack_start (GTK_BOX(hbox), date_widget, TRUE, TRUE, 0);
1450 gtk_widget_show (date_widget);
1451 gtk_widget_set_sensitive (GTK_WIDGET(date_widget), FALSE);
1458 time64 start_time, end_time, time_val;
1461 auto builder = gtk_builder_new();
1462 gnc_builder_add_from_file (builder,
"gnc-plugin-page-register.glade",
"days_adjustment");
1463 gnc_builder_add_from_file (builder,
"gnc-plugin-page-register.glade",
"start_days_adjustment");
1464 gnc_builder_add_from_file (builder,
"gnc-plugin-page-register.glade",
"end_days_adjustment");
1465 gnc_builder_add_from_file (builder,
"gnc-plugin-page-register.glade",
"filter_by_dialog");
1466 auto dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"filter_by_dialog"));
1467 rfd->dialog = dialog;
1468 fd->dialog = rfd->dialog;
1470 gtk_window_set_transient_for (GTK_WINDOW(dialog),
1471 gnc_window_get_gtk_window (GNC_WINDOW(
1472 GNC_PLUGIN_PAGE(rfd->plugin_page)->window)));
1475 auto title = g_strdup_printf (_ (
"Filter %s by…"),
1477 gtk_window_set_title (GTK_WINDOW(dialog), title);
1481 for (
auto& action : status_actions)
1483 auto toggle = GTK_WIDGET(gtk_builder_get_object (builder,
1484 action.action_name.c_str()));
1485 bool value = fd->cleared_match & action.value;
1486 action.widget = toggle;
1487 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(toggle), bool_to_gboolean (value));
1489 rfd->original_cleared_match = fd->cleared_match;
1491 auto button = GTK_WIDGET(gtk_builder_get_object (builder,
"filter_save"));
1492 if (fd->save_filter)
1493 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), TRUE);
1495 rfd->original_save_filter = fd->save_filter;
1498 gtk_widget_set_visible (GTK_WIDGET(button), bool_to_gboolean (rfd->show_save_button));
1501 rfd->num_days = GTK_WIDGET(gtk_builder_get_object (builder,
"filter_show_num_days"));
1502 button = GTK_WIDGET(gtk_builder_get_object (builder,
"filter_show_days"));
1506 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), TRUE);
1507 gtk_widget_set_sensitive (GTK_WIDGET(rfd->num_days), TRUE);
1508 gtk_spin_button_set_value (GTK_SPIN_BUTTON(rfd->num_days), fd->days);
1509 rfd->original_days = fd->days;
1517 gtk_widget_set_sensitive (GTK_WIDGET(rfd->num_days), FALSE);
1518 rfd->original_days = 0;
1522 xaccQueryGetDateMatchTT (query, &start_time, &end_time);
1526 rfd->original_start_time = start_time;
1527 fd->start_time = start_time;
1528 rfd->original_end_time = end_time;
1529 fd->end_time = end_time;
1531 button = GTK_WIDGET(gtk_builder_get_object (builder,
"filter_show_range"));
1532 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), start_time || end_time);
1533 auto table = GTK_WIDGET(gtk_builder_get_object (builder,
"select_range_table"));
1535 gtk_widget_set_sensitive (GTK_WIDGET(
table), start_time || end_time);
1537 rfd->start_earliest = GTK_WIDGET(gtk_builder_get_object (builder,
"earliest_label"));
1538 rfd->start_date_check = GTK_WIDGET(gtk_builder_get_object (builder,
"start_date_check"));
1539 rfd->start_relative_check = GTK_WIDGET(gtk_builder_get_object (builder,
"start_relative_check"));
1540 rfd->start_days_check = GTK_WIDGET(gtk_builder_get_object (builder,
"start_days_check"));
1543 rfd->start_relative = setup_period_select (builder, TRUE,
"start_relative_hbox");
1544 rfd->start_date = setup_date_edit (builder,
"start_date_hbox");
1545 rfd->start_days = GTK_WIDGET(gtk_builder_get_object (builder,
"start_days_spin"));
1548 if (start_time == 0)
1550 set_sensitive_start_widget (rfd, rfd->start_earliest, TRUE);
1551 time_val = xaccQueryGetEarliestDateFound (query);
1555 rfd->original_start_ap = fd->start_ap;
1556 if (fd->start_ap != GNC_ACCOUNTING_PERIOD_INVALID)
1558 set_sensitive_start_widget (rfd, rfd->start_relative, TRUE);
1560 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->start_relative_check), TRUE);
1562 else if (fd->start_days != 0)
1564 set_sensitive_start_widget (rfd, rfd->start_days, TRUE);
1565 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->start_days_check), TRUE);
1566 gtk_spin_button_set_value (GTK_SPIN_BUTTON(rfd->start_days), fd->start_days);
1567 rfd->original_start_days = fd->start_days;
1572 set_sensitive_start_widget (rfd, rfd->start_date, TRUE);
1573 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->start_date_check), TRUE);
1575 time_val = start_time;
1577 g_signal_connect (G_OBJECT(rfd->start_relative),
"changed",
1578 G_CALLBACK(ppr_filter_relative_changed_cb), rfd);
1582 gnc_date_edit_set_time (GNC_DATE_EDIT(rfd->start_date), time_val);
1583 g_signal_connect (G_OBJECT(rfd->start_date),
"date-changed",
1584 G_CALLBACK(ppr_filter_gde_changed_cb), rfd);
1587 rfd->end_latest = GTK_WIDGET(gtk_builder_get_object (builder,
"latest_label"));
1588 rfd->end_date_check = GTK_WIDGET(gtk_builder_get_object (builder,
"end_date_check"));
1589 rfd->end_relative_check = GTK_WIDGET(gtk_builder_get_object (builder,
"end_relative_check"));
1590 rfd->end_days_check = GTK_WIDGET(gtk_builder_get_object (builder,
"end_days_check"));
1593 rfd->end_relative = setup_period_select (builder, FALSE,
"end_relative_hbox");
1594 rfd->end_date = setup_date_edit (builder,
"end_date_hbox");
1595 rfd->end_days = GTK_WIDGET(gtk_builder_get_object (builder,
"end_days_spin"));
1600 set_sensitive_end_widget (rfd, rfd->end_latest, TRUE);
1601 time_val = xaccQueryGetLatestDateFound (query);
1605 rfd->original_end_ap = fd->end_ap;
1606 if (fd->end_ap != GNC_ACCOUNTING_PERIOD_INVALID)
1608 set_sensitive_end_widget (rfd, rfd->end_relative, TRUE);
1610 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->end_relative_check), TRUE);
1612 else if (fd->end_days != 0)
1614 set_sensitive_end_widget (rfd, rfd->end_days, TRUE);
1615 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->end_days_check), TRUE);
1616 gtk_spin_button_set_value (GTK_SPIN_BUTTON(rfd->end_days), fd->end_days);
1617 rfd->original_end_days = fd->end_days;
1621 set_sensitive_end_widget (rfd, rfd->end_date, TRUE);
1622 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(rfd->end_date_check), TRUE);
1624 time_val = end_time;
1626 g_signal_connect (G_OBJECT(rfd->end_relative),
"changed",
1627 G_CALLBACK(ppr_filter_relative_changed_cb), rfd);
1631 gnc_date_edit_set_time (GNC_DATE_EDIT(rfd->end_date), time_val);
1632 g_signal_connect (G_OBJECT(rfd->end_date),
"date-changed",
1633 G_CALLBACK(ppr_filter_gde_changed_cb), rfd);
1637 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, rfd);
1640 gtk_widget_show (dialog);
1641 g_object_unref (G_OBJECT(builder));
1666 rfd->plugin_page = plugin_page;
1667 rfd->show_save_button = show_save_button;
1669 ppr_filter_dialog_create (rfd, fd, query);
Date and Time handling routines.
Functions for adding content to a window.
A custom widget for selecting accounting periods.
Functions providing a register page filter for the GnuCash UI.
Functions providing a register page for the GnuCash UI.
Generic api to store and retrieve preferences.
Functions to load, save and get gui state.
utility functions for the GnuCash UI
Functions that are supported by all types of windows.
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
char * qof_print_date(time64 t)
Convenience; calls through to qof_print_date_dmy_buff().
time64 gnc_time64_get_day_start(time64 time_val)
The gnc_time64_get_day_start() routine will take the given time in seconds and adjust it to the first...
time64 gnc_time64_get_today_start(void)
The gnc_time64_get_today_start() routine returns a time64 value corresponding to the first second of ...
time64 gnc_time64_get_day_end(time64 time_val)
The gnc_time64_get_day_end() routine will take the given time in seconds and adjust it to the last se...
void gnc_tm_get_today_end(struct tm *tm)
The gnc_tm_get_today_end() routine takes a pointer to a struct tm and fills it in with the last secon...
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
time64 gnc_time(time64 *tbuf)
get the current time
struct tm * gnc_localtime(const time64 *secs)
fill out a time struct from a 64-bit time value.
time64 gnc_time64_get_day_end_gdate(const GDate *date)
The gnc_time64_get_day_end() routine will take the given time in GLib GDate format and adjust it to t...
time64 gnc_time64_get_day_start_gdate(const GDate *date)
The gnc_time64_get_day_start() routine will take the given time in GLib GDate format and adjust it to...
void gnc_tm_get_today_start(struct tm *tm)
The gnc_tm_get_today_start() routine takes a pointer to a struct tm and fills it in with the first se...
time64 gnc_time64_get_today_end(void)
The gnc_time64_get_today_end() routine returns a time64 value corresponding to the last second of tod...
GDate * gnc_period_select_get_date(GncPeriodSelect *period)
Get the currently selected accounting period choice from a GncPeriodSelect widget.
GncAccountingPeriod
This specifies a time interval.
GDate * gnc_accounting_period_end_gdate(GncAccountingPeriod which, const GDate *fy_end, const GDate *contains)
This function returns the ending date for an accounting period.
GDate * gnc_accounting_period_start_gdate(GncAccountingPeriod which, const GDate *fy_end, const GDate *contains)
This function returns the starting date for an accounting period.
GncAccountingPeriod gnc_period_select_get_active(GncPeriodSelect *period)
Get the currently selected accounting period from a GncPeriodSelect widget.
GtkWidget * gnc_period_select_new(gboolean starting_labels)
Create a new GncPeriodSelect widget which is used to select a accounting period like "previous month"...
void gnc_period_select_set_active(GncPeriodSelect *period, GncAccountingPeriod which)
Set which item in the GncPeriodSelect is initially selected.
gint gnc_state_drop_sections_for(const gchar *partial_name)
Drop all sections from the state file whose name contains partial_name.
GKeyFile * gnc_state_get_current(void)
Returns a pointer to the most recently loaded state.
SplitRegister * gnc_ledger_display_get_split_register(GNCLedgerDisplay *ld)
return the split register associated with a ledger display
gchar * gnc_list_formatter(GList *strings)
This function takes a GList of char*, and uses locale-sensitive list formatter.
gchar * gnc_g_list_stringjoin(GList *list_of_strings, const gchar *sep)
Return a string joining a GList whose elements are gchar* strings.
#define PINFO(format, args...)
Print an informational note.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define ENTER(format, args...)
Print a function entry debugging message.
void qof_query_purge_terms(QofQuery *q, QofQueryParamList *param_list)
Remove query terms of a particular type from q.
void gnc_ppr_filter_start_toggle_cb(GtkToggleButton *button, RegisterFilterDialog *rfd)
This function is called when one of the check buttons for start relative or start date is changed.
void gnc_ppr_filter_days_changed_cb(GtkSpinButton *button, RegisterFilterDialog *rfd)
This function is called when the "number of days" spin button is changed which is then saved and upda...
void gnc_ppr_filter_status_clear_all_cb(GtkButton *button, RegisterFilterDialog *rfd)
This function is called whenever the "clear all" status button is clicked.
void gnc_ppr_filter_select_range_cb(GtkRadioButton *button, RegisterFilterDialog *rfd)
This function is called when the radio buttons changes state.
void gnc_plugin_page_register_update_for_search_query(GncPluginPageRegister *page)
This checks if the register is a search register and if so saves the query.
void gnc_ppr_filter_clear_current_filter(GncPluginPage *plugin_page)
This function is used to clear the current filter so that a specific split can be shown in the regist...
void gnc_ppr_filter_response_cb(GtkDialog *dialog, gint response, RegisterFilterDialog *rfd)
This function is called when the "Filter By…" dialog is closed.
FilterData * gnc_plugin_page_register_get_filter_data(GncPluginPage *plugin_page)
Get the FilterData data structure associated with this register page.
void gnc_ppr_filter_set_tooltip(GncPluginPage *plugin_page, FilterData *fd)
This function is used to update the tooltip shown in the register which shows a summary of the curren...
Query * gnc_plugin_page_register_get_query(GncPluginPage *plugin_page)
This function is called to get the query associated with this plugin page.
void gnc_ppr_filter_by(GncPluginPage *plugin_page, Query *query, FilterData *fd, bool show_save_button)
This function is called for the filter dialog.
void gnc_ppr_filter_end_toggle_cb(GtkToggleButton *button, RegisterFilterDialog *rfd)
This function is called when one of the check buttons for end relative or end date is changed.
void gnc_ppr_filter_start_end_days_changed_cb(GtkSpinButton *button, RegisterFilterDialog *rfd)
This function is called when the "days ago" spin button is changed which is then saved and updates th...
void gnc_ppr_filter_update_register(GncPluginPage *plugin_page)
This function is called to update the register.
void gnc_plugin_page_register_query_update(GncPluginPageRegister *page, Query *query)
This updates the query after the filters have been applied.
void gnc_ppr_filter_status_one_cb(GtkToggleButton *button, RegisterFilterDialog *rfd)
This function is called whenever one of the status entries is checked or unchecked.
void gnc_ppr_filter_save_cb(GtkToggleButton *button, RegisterFilterDialog *rfd)
This function is called whenever the save status is checked or unchecked.
void gnc_ppr_filter_end_cb(GtkWidget *radio, RegisterFilterDialog *rfd)
This function is called when one of the end date radio buttons is selected.
GNCSplitReg * gnc_plugin_page_register_get_gsr(GncPluginPage *plugin_page)
Get the GNCSplitReg data structure associated with this register page.
void gnc_ppr_filter_start_cb(GtkWidget *radio, RegisterFilterDialog *rfd)
This function is called when one of the start date radio buttons is selected.
void gnc_plugin_register_set_enable_refresh(GncPluginPageRegister *page, gboolean enable_refresh)
This allows controlling when refreshes happen, used to reduce refreshes when different aspects of the...
void gnc_ppr_filter_status_select_all_cb(GtkButton *button, RegisterFilterDialog *rfd)
This function is called whenever the "select all" status button is clicked.
The instance data structure for a content plugin.