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" 64 static std::string DEFAULT_FILTER_NUM_DAYS_GL =
"30";
65 static std::string DEFAULT_FILTER =
"0x001f";
68 static 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;
156 static 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 }
166 gboolean_to_bool (gboolean value)
168 return value ? true :
false;
171 static inline gboolean
172 bool_to_gboolean (
bool value)
174 return value ? TRUE : FALSE;
178 get_filter_default_num_of_days (GNCLedgerDisplayType ledger_type)
180 if (ledger_type == LD_GL)
181 return DEFAULT_FILTER_NUM_DAYS_GL;
188 ppr_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);
203 ppr_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;
221 get_time_for_days_ago (
int days,
bool use_day_start)
232 tm.tm_mday = tm.tm_mday - days;
238 static std::vector<std::string>
239 split_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);
253 ppr_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);
266 ppr_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);
292 set_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;
309 get_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);
323 update_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;
379 ppr_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;
436 ppr_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);
465 ppr_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);
513 update_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);
819 set_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);
839 set_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);
931 print_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);
1071 ppr_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);
1172 ppr_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));
1432 setup_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;
1445 setup_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);
Functions to load, save and get gui state.
Functions providing a register page filter for the GnuCash UI.
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...
The instance data structure for a content plugin.
Date and Time handling routines.
gchar * gnc_g_list_stringjoin(GList *list_of_strings, const gchar *sep)
Return a string joining a GList whose elements are gchar* strings.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
void qof_query_purge_terms(QofQuery *q, QofQueryParamList *param_list)
Remove query terms of a particular type from q.
FilterData * gnc_plugin_page_register_get_filter_data(GncPluginPage *plugin_page)
Get the FilterData data structure associated with this register page.
gint gnc_state_drop_sections_for(const gchar *partial_name)
Drop all sections from the state file whose name contains partial_name.
void gnc_ppr_filter_end_cb(GtkWidget *radio, RegisterFilterDialog *rfd)
This function is called when one of the end date radio buttons is selected.
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
Functions that are supported by all types of windows.
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_response_cb(GtkDialog *dialog, gint response, RegisterFilterDialog *rfd)
This function is called when the "Filter By…" dialog is closed.
GncAccountingPeriod gnc_period_select_get_active(GncPeriodSelect *period)
Get the currently selected accounting period from a GncPeriodSelect widget.
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_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...
#define ENTER(format, args...)
Print a function entry debugging message.
GKeyFile * gnc_state_get_current(void)
Returns a pointer to the most recently loaded state.
GDate * gnc_period_select_get_date(GncPeriodSelect *period)
Get the currently selected accounting period choice from a GncPeriodSelect widget.
Functions for adding content to a window.
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
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.
char * qof_print_date(time64 secs)
Convenience; calls through to qof_print_date_dmy_buff().
Functions providing a register page for the GnuCash UI.
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...
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...
gchar * gnc_list_formatter(GList *strings)
This function takes a GList of char*, and uses locale-sensitive list formatter.
time64 gnc_time64_get_today_start(void)
The gnc_time64_get_today_start() routine returns a time64 value corresponding to the first second of ...
void gnc_ppr_filter_update_register(GncPluginPage *plugin_page)
This function is called to update the register.
GncAccountingPeriod
This specifies a time interval.
void gnc_ppr_filter_status_select_all_cb(GtkButton *button, RegisterFilterDialog *rfd)
This function is called whenever the "select all" status button is clicked.
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
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_start_cb(GtkWidget *radio, RegisterFilterDialog *rfd)
This function is called when one of the start date radio buttons is selected.
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...
struct tm * gnc_localtime(const time64 *secs)
fill out a time struct from a 64-bit time value.
Generic api to store and retrieve preferences.
Query * gnc_plugin_page_register_get_query(GncPluginPage *plugin_page)
This function is called to get the query associated with this plugin page.
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.
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_today_end(void)
The gnc_time64_get_today_end() routine returns a time64 value corresponding to the last second of tod...
#define LEAVE(format, args...)
Print a function exit debugging message.
time64 gnc_time(time64 *tbuf)
get the current time
GtkWidget * gnc_period_select_new(gboolean starting_labels)
Create a new GncPeriodSelect widget which is used to select a accounting period like "previous month"...
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void gnc_plugin_page_register_query_update(GncPluginPageRegister *page, Query *query)
This updates the query after the filters have been applied.
void gnc_period_select_set_active(GncPeriodSelect *period, GncAccountingPeriod which)
Set which item in the GncPeriodSelect is initially selected.
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...
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...
SplitRegister * gnc_ledger_display_get_split_register(GNCLedgerDisplay *ld)
return the split register associated with a ledger display
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_plugin_page_register_update_for_search_query(GncPluginPageRegister *page)
This checks if the register is a search register and if so saves the query.
A custom widget for selecting accounting periods.
GNCSplitReg * gnc_plugin_page_register_get_gsr(GncPluginPage *plugin_page)
Get the GNCSplitReg data structure associated with this register page.
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_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_one_cb(GtkToggleButton *button, RegisterFilterDialog *rfd)
This function is called whenever one of the status entries is checked or unchecked.
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...