30 #include "kvp-value.hpp" 31 #include "kvp-frame.hpp" 32 #include "qofbookslots.h" 37 #include "gnc-option-ui.hpp" 39 #include "gnc-session.h" 42 constexpr
auto stream_max = std::numeric_limits<std::streamsize>::max();
43 using AliasedOption = std::pair<const char*, const char*>;
44 using OptionAlias = std::pair<const char*, AliasedOption>;
45 using OptionAliases = std::vector<OptionAlias>;
48 static const OptionAliases c_option_aliases;
50 static const AliasedOption* find_alias (
const char* old_name)
52 if (!old_name)
return nullptr;
54 std::find_if(c_option_aliases.begin(), c_option_aliases.end(),
55 [old_name](
auto alias){
56 return std::strcmp(old_name, alias.first) == 0;
58 if (alias == c_option_aliases.end())
61 return &alias->second;
65 const OptionAliases Aliases::c_option_aliases
67 {
"Accounts to include", {
nullptr,
"Accounts"}},
68 {
"Exclude transactions between selected accounts?",
69 {
nullptr,
"Exclude transactions between selected accounts"}},
70 {
"Filter Accounts", {
nullptr,
"Filter By…"}},
71 {
"Flatten list to depth limit?",
72 {
nullptr,
"Flatten list to depth limit"}},
73 {
"From", {
nullptr,
"Start Date"}},
74 {
"Report Accounts", {
nullptr,
"Accounts"}},
75 {
"Report Currency", {
nullptr,
"Report's currency"}},
76 {
"Show Account Code?", {
nullptr,
"Show Account Code"}},
77 {
"Show Full Account Name?", {
nullptr,
"Show Full Account Name"}},
78 {
"Show Multi-currency Totals?",
79 {
nullptr,
"Show Multi-currency Totals"}},
80 {
"Show zero balance items?", {
nullptr,
"Show zero balance items"}},
81 {
"Sign Reverses?", {
nullptr,
"Sign Reverses"}},
82 {
"To", {
nullptr,
"End Date"}},
83 {
"Charge Type", {
nullptr,
"Action"}},
85 {
"Individual income columns", {
nullptr,
"Individual sales columns"}},
86 {
"Individual expense columns",
87 {
nullptr,
"Individual purchases columns"}},
88 {
"Remittance amount", {
nullptr,
"Gross Balance"}},
89 {
"Net Income", {
nullptr,
"Net Balance"}},
91 {
"Use Full Account Name?", {
nullptr,
"Use Full Account Name"}},
92 {
"Use Full Other Account Name?",
93 {
nullptr,
"Use Full Other Account Name"}},
94 {
"Void Transactions?", {
"Filter",
"Void Transactions"}},
95 {
"Void Transactions", {
"Filter",
"Void Transactions"}},
96 {
"Account Substring", {
"Filter",
"Account Name Filter"}},
97 {
"Enable links", {
nullptr,
"Enable Links"}},
99 {
"Common Currency", {
"Currency",
"Common Currency"}},
100 {
"Show original currency amount",
101 {
"Currency",
"Show original currency amount"}},
102 {
"Report's currency", {
"Currency",
"Report's currency"}},
103 {
"Reconcile Status", {
nullptr,
"Reconciled Status"}},
106 {
"Links", {
nullptr,
"Transaction Links"}},
108 {
"Individual Taxes", {
nullptr,
"Use Detailed Tax Summary"}},
109 {
"Show Accounts until level", {
nullptr,
"Levels of Subaccounts"}},
110 {
"Invoice number", {
nullptr,
"Invoice Number"}},
111 {
"Report title", {
nullptr,
"Report Title"}},
112 {
"Extra notes", {
nullptr,
"Extra Notes"}},
114 {
"default format", {
nullptr,
"Default Format"}},
115 {
"Report format", {
nullptr,
"Report Format"}},
117 {
"Filter By...", {
nullptr,
"Filter By…"}},
118 {
"Specify date to filter by...", {
nullptr,
"Specify date to filter by…"}},
120 {
"Running Balance", {
nullptr,
"Account Balance"}},
121 {
"Totals", {
nullptr,
"Grand Total"}},
125 operator==(
const std::string& str,
const char* cstr)
127 return strcmp(str.c_str(), cstr) == 0;
131 GncOptionSection::foreach_option(std::function<
void(
GncOption&)> func)
133 std::for_each(m_options.begin(), m_options.end(), func);
137 GncOptionSection::foreach_option(std::function<
void(
const GncOption&)> func)
const 139 std::for_each(m_options.begin(), m_options.end(), func);
143 GncOptionSection::add_option(
GncOption&& option)
145 m_options.push_back(std::move(option));
146 if (!std::is_sorted(m_options.begin(), m_options.end()))
147 std::sort(m_options.begin(), m_options.end());
151 GncOptionSection::remove_option(
const char* name)
153 m_options.erase(std::remove_if(m_options.begin(), m_options.end(),
154 [name](
const auto& option) ->
bool 156 return option.get_name() == name;
157 }), m_options.end());
161 GncOptionSection::find_option(
const char* name)
const 163 auto option = std::find_if(m_options.begin(), m_options.end(),
164 [name](
auto& option) ->
bool {
165 return option.get_name() == name;
167 if (option != m_options.end())
170 auto alias = Aliases::find_alias(name);
171 if (!alias || alias->first)
173 return find_option(alias->second);
176 GncOptionDB::GncOptionDB() : m_default_section{} {}
178 GncOptionDB::GncOptionDB(QofBook* book) :
GncOptionDB() {}
181 GncOptionDB::register_option(
const char* sectname,
GncOption&& option)
183 auto section = find_section(sectname);
187 section->add_option(std::move(option));
191 m_sections.push_back(std::make_shared<GncOptionSection>(sectname));
192 m_sections.back()->add_option(std::move(option));
193 if (!std::is_sorted(m_sections.begin(), m_sections.end()))
194 std::sort(m_sections.begin(), m_sections.end());
198 GncOptionDB::register_option(
const char* sectname,
GncOption* option)
200 register_option(sectname, std::move(*option));
205 GncOptionDB::unregister_option(
const char* sectname,
const char* name)
207 auto section = find_section(sectname);
209 section->remove_option(name);
213 GncOptionDB::set_default_section(
const char* sectname)
215 m_default_section = find_section(sectname);
219 GncOptionDB::get_default_section() const noexcept
221 return m_default_section;
225 GncOptionDB::find_section(
const std::string& section)
const 227 auto db_section = std::find_if(m_sections.begin(), m_sections.end(),
228 [§ion](
auto& sect) ->
bool 230 return section == sect->get_name();
232 return db_section == m_sections.end() ? nullptr : db_section->get();
236 GncOptionDB::find_option(
const std::string& section,
const char* name)
const 238 auto db_section =
const_cast<GncOptionDB*
>(
this)->find_section(section);
241 option = db_section->find_option(name);
244 auto alias = Aliases::find_alias(name);
249 if (alias && alias->first && section != alias->first)
250 return find_option(alias->first, alias->second);
255 GncOptionDB::lookup_string_option(
const char* section,
const char* name)
257 static const std::string empty_string{};
259 auto db_opt = find_option(section, name);
262 return db_opt->get_value<std::string>();
266 GncOptionDB::make_internal(
const char* section,
const char* name)
269 auto db_opt = find_option(section, name);
271 db_opt->make_internal();
275 GncOptionDB::save_option_key_value(std::ostream& oss,
276 const std::string& section,
277 const std::string& name)
const noexcept
280 auto db_opt = find_option(section, name.c_str());
281 if (!db_opt || !db_opt->is_changed())
283 oss << section.substr(0, classifier_size_max) <<
":" <<
284 name.substr(0, classifier_size_max) <<
"=" << *db_opt <<
";";
289 GncOptionDB::load_option_key_value(std::istream& iss)
292 char section[classifier_size_max], name[classifier_size_max];
293 iss.getline(section, classifier_size_max,
':');
294 iss.getline(name, classifier_size_max,
'=');
296 throw std::invalid_argument(
"Section or name delimiter not found or values too long");
297 auto option = find_option(section, name);
299 iss.ignore(stream_max,
';');
303 std::getline(iss, value,
';');
304 std::istringstream item_iss{value};
311 GncOptionDB::save_to_key_value(std::ostream& oss)
const noexcept
315 [&oss](
const GncOptionSectionPtr& section)
317 oss <<
"[Options]\n";
318 section->foreach_option(
319 [&oss, §ion](
auto& option)
322 oss << section->get_name().substr(0, classifier_size_max) <<
323 ':' << option.get_name().substr(0, classifier_size_max) <<
324 '=' << option <<
'\n';
331 GncOptionDB::load_from_key_value(std::istream& iss)
333 if (iss.peek() ==
'[')
335 char buf[classifier_size_max];
336 iss.getline(buf, classifier_size_max);
337 if (strcmp(buf,
"[Options]") != 0)
338 throw std::runtime_error(
"Wrong secion header for options.");
341 while (iss.peek() !=
'[')
343 load_option_key_value(iss);
349 GncOptionDB::register_callback(GncOptionDBChangeCallback cb,
void* data)
351 constexpr std::hash<GncOptionDBChangeCallback> cb_hash;
352 auto id{cb_hash(cb)};
353 if (std::find_if(m_callbacks.begin(), m_callbacks.end(),
354 [id](
auto&cb)->
bool{
return cb.m_id == id; }) == m_callbacks.end())
355 m_callbacks.emplace_back(
id, cb, data);
360 GncOptionDB::unregister_callback(
size_t id)
362 m_callbacks.erase(std::remove_if(m_callbacks.begin(), m_callbacks.end(),
363 [id](
auto& cb)->
bool {
return cb.m_id == id; }),
368 GncOptionDB::run_callbacks()
370 std::for_each(m_callbacks.begin(), m_callbacks.end(),
371 [](
auto& cb)->
void { cb.m_func(cb.m_data); });
375 counter_option_path(
const GncOption& option, GSList* list, std::string& name)
377 constexpr
const char* counters{
"counters"};
378 constexpr
const char* formats{
"counter_formats"};
379 auto key = option.get_key();
380 name = key.substr(0, key.size() - 1);
381 list->next->data = (
void*)name.c_str();
382 if (option.get_name().rfind(
"format")
383 != std::string::npos)
384 list->data = (
void*)formats;
386 list->data = (
void*)counters;
390 option_path(
const GncOption& option, GSList* list)
392 list->next->data = (
void*)option.get_name().c_str();
393 list->data = (
void*)option.get_section().c_str();
404 static inline KvpValue*
405 kvp_value_from_bool_option(
const GncOption& option)
407 auto val{option.template get_value<bool>()};
409 return new KvpValue(val ? g_strdup(
"t") : g_strdup(
"f"));
417 case GncOptionUIType::ACCOUNT_SEL:
418 case GncOptionUIType::BUDGET:
419 case GncOptionUIType::OWNER:
420 case GncOptionUIType::CUSTOMER:
421 case GncOptionUIType::VENDOR:
422 case GncOptionUIType::EMPLOYEE:
423 case GncOptionUIType::INVOICE:
424 case GncOptionUIType::TAX_TABLE:
425 case GncOptionUIType::QUERY:
432 static inline KvpValue*
433 kvp_value_from_qof_instance_option(
const GncOption& option)
435 const QofInstance* inst{QOF_INSTANCE(option.template get_value<const QofInstance*>())};
437 return new KvpValue(guid);
442 static const char* date_format_frame_key =
"Fancy Date Format";
443 static const char* date_format_custom_key =
"custom";
444 static const char* date_format_months_key =
"month";
445 static const char* date_format_years_key =
"years";
446 static const char *date_format_format_key =
"fmt";
448 static inline KvpValue *
449 kvp_frame_from_date_format_option(
const GncOption& option)
451 auto [format, months, years, custom] = option.get_value<GncOptionDateFormat>();
456 auto frame{
new KvpFrame};
458 frame->set({date_format_months_key},
new KvpValue(g_strdup(gnc_date_monthformat_to_string(months))));
459 frame->set({date_format_years_key},
new KvpValue(static_cast<int64_t>(years)));
460 frame->set({date_format_custom_key},
new KvpValue(g_strdup(custom.c_str())));
461 return new KvpValue(frame);
465 GncOptionDB::save_to_kvp(QofBook* book,
bool clear_options)
const noexcept
470 [book](GncOptionSectionPtr& section)
472 section->foreach_option(
482 GSList list_tail{}, list_head{
nullptr, &list_tail};
483 if (strcmp(section->get_name().c_str(),
"Counters") == 0)
484 counter_option_path(option, &list_head, name);
486 option_path(option, &list_head);
487 auto type{option.get_ui_type()};
489 if (type == GncOptionUIType::BOOLEAN)
490 kvp = kvp_value_from_bool_option(option);
491 else if (is_qofinstance_ui_type(type))
492 kvp = kvp_value_from_qof_instance_option(option);
493 else if (type == GncOptionUIType::NUMBER_RANGE)
495 if (option.is_alternate())
497 kvp =
new KvpValue(static_cast<int64_t>(option.template get_value<int>()));
501 kvp =
new KvpValue(option.template get_value<double>());
504 else if (type == GncOptionUIType::DATE_FORMAT)
505 kvp = kvp_frame_from_date_format_option(option);
508 auto str{option.template get_value<std::string>()};
509 kvp =
new KvpValue{g_strdup(str.c_str())};
519 fill_option_from_string_kvp(
GncOption& option, KvpValue* kvp)
521 auto str{kvp->get<
const char*>()};
522 if (option.get_ui_type() == GncOptionUIType::BOOLEAN)
523 option.set_value(*str ==
't' ?
true :
false);
525 option.set_value(std::string{str});
529 fill_option_from_guid_kvp(
GncOption& option, KvpValue* kvp)
531 auto guid{kvp->get<
GncGUID*>()};
533 (
const QofInstance*)qof_instance_from_guid(guid, option.get_ui_type()));
537 fill_option_from_date_format_kvp(
GncOption& option, KvpValue* kvp)
540 auto frame{kvp->get<KvpFrame*>()};
543 option.set_value(default_fmt);
546 auto format_str{frame->get_slot({date_format_format_key})->get<const char*>()};
550 option.set_value(default_fmt);
554 auto months_str{frame->get_slot({date_format_months_key})->get<const char*>()};
557 auto years_num{frame->get_slot({date_format_years_key})->get<int64_t>()};
558 bool years =
static_cast<bool>(years_num);
559 auto custom_str{frame->get_slot({date_format_custom_key})->get<const char*>()};
560 option.set_value<GncOptionDateFormat>({format, months, years, custom_str ? custom_str :
""});
564 GncOptionDB::load_from_kvp(QofBook* book) noexcept
567 [book](GncOptionSectionPtr& section)
569 section->foreach_option(
576 GSList list_tail{}, list_head{
nullptr, &list_tail};
577 if (strcmp(section->get_name().c_str(),
"Counters") == 0)
578 counter_option_path(option, &list_head, name);
580 option_path(option, &list_head);
585 auto set_double = [&option, kvp, &list_head]() {
591 constexpr
const char *counters{
"counters"};
592 auto value{kvp->get<
double>()};
593 if (strcmp(static_cast<char*>(list_head.data), counters) == 0)
594 option.set_value(static_cast<int>(value));
596 option.set_value(value);
599 switch (kvp->get_type())
601 case KvpValue::Type::DOUBLE:
604 case KvpValue::Type::INT64:
605 option.set_value(static_cast<int>(kvp->get<int64_t>()));
607 case KvpValue::Type::STRING:
608 fill_option_from_string_kvp(option, kvp);
610 case KvpValue::Type::GUID:
611 fill_option_from_guid_kvp(option, kvp);
613 case KvpValue::Type::FRAME:
614 if (g_strcmp0(option.get_name().c_str(), date_format_frame_key) == 0)
615 fill_option_from_date_format_kvp(option, kvp);
627 const char* name,
const char* key,
628 const char* doc_string, std::string value)
630 GncOption option{section, name, key, doc_string, value,
631 GncOptionUIType::STRING};
632 db->register_option(section, std::move(option));
637 const char* key,
const char* doc_string,
640 GncOption option{section, name, key, doc_string, value,
641 GncOptionUIType::TEXT};
642 db->register_option(section, std::move(option));
648 const char* name,
const char* key,
649 const char* doc_string, std::string value)
651 GncOption option{section, name, key, doc_string, value,
652 GncOptionUIType::FONT};
653 db->register_option(section, std::move(option));
658 const char* name,
const char* key,
659 const char* doc_string, GncBudget *value)
663 GncOptionUIType::BUDGET}};
664 db->register_option(section, std::move(option));
669 const char* name,
const char* key,
670 const char* doc_string, std::string value)
672 GncOption option{section, name, key, doc_string, value,
673 GncOptionUIType::COLOR};
674 db->register_option(section, std::move(option));
679 const char* name,
const char* key,
680 const char* doc_string, gnc_commodity *value)
684 GncOptionUIType::COMMODITY}};
685 db->register_option(section, std::move(option));
690 const char* name,
const char* key,
691 const char* doc_string,
const char* value)
693 gnc_commodity* commodity{};
697 for (
auto node = namespaces; node && commodity ==
nullptr;
698 node = g_list_next(node))
700 commodity = gnc_commodity_table_lookup(commodity_table,
701 (
const char*)(node->data),
708 GncOptionUIType::COMMODITY}};
709 db->register_option(section, std::move(option));
714 const char* section,
const char* name,
715 const char* key,
const char* doc_string,
718 GncOption option{section, name, key, doc_string, value,
719 GncOptionUIType::BOOLEAN};
720 db->register_option(section, std::move(option));
725 const char* name,
const char* key,
726 const char* doc_string, std::string value)
728 GncOption option{section, name, key, doc_string, value,
729 GncOptionUIType::PIXMAP};
730 db->register_option(section, std::move(option));
735 const char* name,
const char* key,
736 const char* doc_string,
737 const GncOptionAccountList& value)
740 GncOptionUIType::ACCOUNT_LIST, value}};
741 db->register_option(section, std::move(option));
746 const char* section,
const char* name,
748 const char* doc_string,
749 const GncOptionAccountList& value,
750 GncOptionAccountTypeList&& allowed)
755 GncOptionUIType::ACCOUNT_LIST, value, std::move(allowed)}};
756 db->register_option(section, std::move(option));
758 catch (
const std::invalid_argument& err)
760 PWARN(
"Account List Limited Option, value failed validation, option not registered.");
764 using AccountPair = std::pair<GncOptionAccountList&,
765 const GncOptionAccountTypeList&>;
767 find_children(
Account* account,
void* data)
771 GncOptionAccountList& list = datapair->first;
772 const GncOptionAccountTypeList& types = datapair->second;
773 if (std::find(types.begin(), types.end(),
780 const GncOptionAccountTypeList& types)
782 GncOptionAccountList list;
783 AccountPair funcdata{list, types};
784 Account* base_acct = gnc_book_get_root_account(book);
785 gnc_account_foreach_descendant(base_acct, (AccountCb)find_children,
793 const char* section,
const char* name,
794 const char* key,
const char* doc_string,
796 GncOptionAccountTypeList&& allowed)
801 GncOptionUIType::ACCOUNT_SEL, value, std::move(allowed)}};
802 db->register_option(section, std::move(option));
804 catch (
const std::invalid_argument& err)
806 PWARN(
"Account Sel Limited Option, value failed validation, option not registerd.");
812 const char* name,
const char* key,
813 const char* doc_string,
const char* default_val,
814 GncMultichoiceOptionChoices&& choices)
816 std::string defval{default_val};
817 auto found{std::find_if(choices.begin(), choices.end(),
818 [&defval](
auto& choice)->
bool {
819 return defval == std::get<0>(choice);
821 if (found == choices.end())
822 defval = (choices.empty() ? std::string{
"None"} :
823 std::get<0>(choices.at(0)));
825 defval.c_str(), std::move(choices)}};
826 db->register_option(section, std::move(option));
831 const char* name,
const char* key,
832 const char* doc_string,
const char* value,
833 GncMultichoiceOptionChoices&& list)
836 value, std::move(list), GncOptionUIType::LIST}};
837 db->register_option(section, std::move(option));
843 template <
typename ValueType>
void 845 const char* name,
const char* key,
846 const char* doc_string, ValueType value,
847 ValueType min, ValueType max, ValueType step)
852 doc_string, value, min,
854 db->register_option(section, std::move(option));
856 catch(
const std::invalid_argument& err)
858 PWARN(
"Number Range Option %s, option not registerd.",
865 const char* section,
const char* name,
866 const char* key,
const char* doc_string,
871 value, 10, UINT16_MAX, 1, GncOptionUIType::PLOT_SIZE}};
872 db->register_option(section, std::move(option));
877 const char* name,
const QofQuery* value)
879 GncOption option{section, name,
"",
"", value,
880 GncOptionUIType::INTERNAL};
881 db->register_option(section, std::move(option));
886 const char* name,
const char* key,
887 const char* doc_string,
const GncOwner* value,
893 case GNC_OWNER_CUSTOMER:
894 uitype = GncOptionUIType::CUSTOMER;
896 case GNC_OWNER_EMPLOYEE:
897 uitype = GncOptionUIType::EMPLOYEE;
900 uitype = GncOptionUIType::JOB;
902 case GNC_OWNER_VENDOR:
903 uitype = GncOptionUIType::VENDOR;
906 uitype = GncOptionUIType::INTERNAL;
910 db->register_option(section, std::move(option));
915 const char* name,
const char* key,
916 const char* doc_string, GncInvoice* value)
920 GncOptionUIType::INVOICE}};
921 db->register_option(section, std::move(option));
926 const char* name,
const char* key,
931 GncOptionUIType::TAX_TABLE}};
932 db->register_option(section, std::move(option));
937 const char* name,
const char* key,
938 const char* doc_string, std::string value)
940 GncOption option{section, name, key, doc_string,
941 value, GncOptionUIType::INV_REPORT};
942 db->register_option(section, std::move(option));
947 const char* name,
const char* key,
948 const char* doc_string,
int value)
951 value, 0, 999999999, 1}};
952 option.set_alternate(
true);
953 db->register_option(section, std::move(option));
958 const char* section,
const char* name,
959 const char* key,
const char* doc_string,
962 GncOption option{section, name, key, doc_string, value,
963 GncOptionUIType::STRING};
964 db->register_option(section, std::move(option));
969 const char* name,
const char* key,
970 const char* doc_string, GncOptionDateFormat&& value)
972 GncOption option{section, name, key, doc_string, std::move(value),
973 GncOptionUIType::DATE_FORMAT};
974 db->register_option(section, std::move(option));
979 const char* name,
const char* key,
980 const char* doc_string, gnc_commodity *value)
983 section, name, key, doc_string, value, GncOptionUIType::CURRENCY
985 db->register_option(section, std::move(option));
990 const char* name,
const char* key,
991 const char* doc_string,
const char* value)
995 const auto commodity = gnc_commodity_table_lookup(commodity_table,
999 section, name, key, doc_string, commodity, GncOptionUIType::CURRENCY
1001 db->register_option(section, std::move(option));
1006 const char* name,
const char* key,
1007 const char* doc_string,
time64 time,
1010 auto ui_type = ui == RelativeDateUI::BOTH ? GncOptionUIType::DATE_BOTH :
1011 ui == RelativeDateUI::RELATIVE ? GncOptionUIType::DATE_RELATIVE :
1012 GncOptionUIType::DATE_ABSOLUTE;
1015 db->register_option(section, std::move(option));
1020 const char* name,
const char* key,
1024 auto ui_type = ui == RelativeDateUI::BOTH ? GncOptionUIType::DATE_BOTH :
1025 ui == RelativeDateUI::RELATIVE ? GncOptionUIType::DATE_RELATIVE :
1026 GncOptionUIType::DATE_ABSOLUTE;
1029 db->register_option(section, std::move(option));
1034 const char* section,
const char* name,
1035 const char* key,
const char* doc_string,
1036 RelativeDatePeriodVec& period_set,
1039 auto is_absolute = period_set.size() == 1 &&
1040 period_set.front() == RelativeDatePeriod::ABSOLUTE;
1041 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1042 is_absolute ? GncOptionUIType::DATE_ABSOLUTE : GncOptionUIType::DATE_RELATIVE;
1044 ui_type, period_set)};
1046 option.set_default_value(
gnc_time(
nullptr));
1047 db->register_option(section, std::move(option));
1051 static const RelativeDatePeriodVec begin_dates
1053 RelativeDatePeriod::TODAY,
1054 RelativeDatePeriod::START_THIS_MONTH,
1055 RelativeDatePeriod::START_PREV_MONTH,
1056 RelativeDatePeriod::START_CURRENT_QUARTER,
1057 RelativeDatePeriod::START_PREV_QUARTER,
1058 RelativeDatePeriod::START_CAL_YEAR,
1059 RelativeDatePeriod::START_PREV_YEAR,
1060 RelativeDatePeriod::START_ACCOUNTING_PERIOD
1065 const char* name,
const char* key,
1066 const char* doc_string,
bool both)
1068 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1069 GncOptionUIType::DATE_RELATIVE;
1071 ui_type, begin_dates)};
1072 db->register_option(section, std::move(option));
1075 static const RelativeDatePeriodVec end_dates
1077 RelativeDatePeriod::TODAY,
1078 RelativeDatePeriod::END_THIS_MONTH,
1079 RelativeDatePeriod::END_PREV_MONTH,
1080 RelativeDatePeriod::END_CURRENT_QUARTER,
1081 RelativeDatePeriod::END_PREV_QUARTER,
1082 RelativeDatePeriod::END_CAL_YEAR,
1083 RelativeDatePeriod::END_PREV_YEAR,
1084 RelativeDatePeriod::END_ACCOUNTING_PERIOD
1089 const char* name,
const char* key,
1090 const char* doc_string,
bool both)
1092 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1093 GncOptionUIType::DATE_RELATIVE;
1095 ui_type, end_dates)};
1096 db->register_option(section, std::move(option));
1100 gnc_register_report_placement_option(GncOptionDBPtr& db,
1101 const char* section,
const char* name)
1106 GncOptionReportPlacementVec value;
1108 "no_key",
"nodoc_string",
1109 value,GncOptionUIType::REPORT_PLACEMENT}};
1110 db->register_option(section, std::move(option));
1114 gnc_register_internal_option(GncOptionDBPtr& db,
1115 const char* section,
const char* name,
1116 const std::string& value)
1120 GncOptionUIType::INTERNAL}};
1121 db->register_option(section, std::move(option));
1125 gnc_register_internal_option(GncOptionDBPtr& db,
1126 const char* section,
const char* name,
1131 GncOptionUIType::INTERNAL}};
1132 db->register_option(section, std::move(option));
1144 PWARN(
"Direct Destroy called on GncOptionDB %" G_GUINT64_FORMAT, (uint64_t)odb);
1151 odb->foreach_section(
1152 [&errors](GncOptionSectionPtr& section){
1153 section->foreach_option(
1157 option.set_option_from_ui_item();
1159 catch (
const std::invalid_argument& err)
1161 PWARN(
"Option %s:%s failed to set its value %s",
1162 option.get_section().c_str(),
1163 option.get_name().c_str(), err.what());
1164 errors = g_list_prepend(errors,
1165 (
void*)option.get_name().c_str());
1169 odb->run_callbacks();
1176 odb->foreach_section(
1177 [](GncOptionSectionPtr& section){
1178 section->foreach_option(
1180 option.set_ui_item_from_option();
1187 odb->load_from_kvp(book);
1192 gboolean clear_options)
1194 odb->save_to_kvp(book, static_cast<bool>(clear_options));
1200 constexpr
const char* business_section{N_(
"Business")};
1201 constexpr
const char* counter_section{N_(
"Counters")};
1202 static const std::string empty_string{
""};
1206 gnc_register_number_range_option<double>(odb, OPTION_SECTION_ACCOUNTS,
1207 OPTION_NAME_AUTO_READONLY_DAYS,
"a",
1208 N_(
"Choose the number of days after which transactions will be read-only and cannot be edited anymore. This threshold is marked by a red line in the account register windows. If zero, all transactions can be edited and none are read-only."),
1209 0.0, 0.0, 3650.0, 1.0);
1212 OPTION_NAME_NUM_FIELD_SOURCE,
"b",
1213 N_(
"Check to have split action field used in registers for 'Num' field in place of transaction number; transaction number shown as 'T-Num' on second line of register. Has corresponding effect on business features, reporting and imports/exports."),
1216 OPTION_NAME_TRADING_ACCOUNTS,
"a",
1217 N_(
"Check to have trading accounts used for transactions involving more than one currency or commodity."),
1223 OPTION_NAME_DEFAULT_BUDGET,
"a",
1224 N_(
"Budget to be used when none has been otherwise specified."),
1230 N_(
"Customer number"),
"gncCustomera",
1231 N_(
"The previous customer number generated. This number will be incremented to generate the next customer number."),
1234 N_(
"Customer number format"),
1236 N_(
"The format string to use for generating customer numbers. This is a printf-style format string."),
1239 N_(
"Employee number"),
"gncEmployeea",
1240 N_(
"The previous employee number generated. This number will be incremented to generate the next employee number."),
1243 N_(
"Employee number format"),
1245 N_(
"The format string to use for generating employee numbers. This is a printf-style format string."),
1248 N_(
"Invoice number"),
"gncInvoicea",
1249 N_(
"The previous invoice number generated. This number will be incremented to generate the next invoice number."),
1252 N_(
"Invoice number format"),
1254 N_(
"The format string to use for generating invoice numbers. This is a printf-style format string."),
1257 N_(
"Bill number"),
"gncBilla",
1258 N_(
"The previous bill number generated. This number will be incremented to generate the next bill number."),
1261 N_(
"Bill number format"),
"gncBillb",
1262 N_(
"The format string to use for generating bill numbers. This is a printf-style format string."),
1265 N_(
"Expense voucher number"),
"gncExpVouchera",
1266 N_(
"The previous expense voucher number generated. This number will be incremented to generate the next voucher number."),
1269 N_(
"Expense voucher number format"),
1271 N_(
"The format string to use for generating expense voucher numbers. This is a printf-style format string."),
1274 N_(
"Job number"),
"gncJoba",
1275 N_(
"The previous job number generated. This number will be incremented to generate the next job number."),
1278 N_(
"Job number format"),
"gncJobb",
1279 N_(
"The format string to use for generating job numbers. This is a printf-style format string."),
1282 N_(
"Order number"),
"gncOrdera",
1283 N_(
"The previous order number generated. This number will be incremented to generate the next order number."),
1286 N_(
"Order number format"),
"gncOrderb",
1287 N_(
"The format string to use for generating order numbers. This is a printf-style format string."),
1290 N_(
"Vendor number"),
"gncVendora",
1291 N_(
"The previous vendor number generated. This number will be incremented to generate the next vendor number."),
1294 N_(
"Vendor number format"),
"gncVendorb",
1295 N_(
"The format string to use for generating vendor numbers. This is a printf-style format string."),
1301 N_(
"The name of your business."),
1304 N_(
"The address of your business."),
1307 N_(
"Company Contact Person"),
"b2",
1308 N_(
"The contact person to print on invoices."),
1311 N_(
"Company Phone Number"),
"c1",
1312 N_(
"The contact person to print on invoices."),
1315 N_(
"Company Fax Number"),
"c2",
1316 N_(
"The fax number of your business."),
1319 N_(
"Company Email Address"),
"c3",
1320 N_ (
"The email address of your business."),
1323 N_(
"Company Website URL"),
"c4",
1324 N_(
"The URL address of your website."),
1327 N_(
"The ID for your company (eg 'Tax-ID: 00-000000)."),
1330 OPTION_NAME_DEFAULT_INVOICE_REPORT,
"e1",
1331 N_(
"The invoice report to be used for printing."),
1333 gnc_register_number_range_option<double>(odb, business_section,
1334 OPTION_NAME_DEFAULT_INVOICE_REPORT_TIMEOUT,
"e2",
1335 N_(
"Length of time to change the used invoice report. A value of 0 means disabled."),
1336 0.0, 0.0, 20.0, 1.0);
1338 N_(
"Default Customer TaxTable"),
"f1",
1339 N_(
"The default tax table to apply to customers."),
1342 N_(
"Default Vendor TaxTable"),
"f2",
1343 N_(
"The default tax table to apply to vendors."),
1347 N_(
"Fancy Date Format"),
"g",
1348 N_(
"The default date format used for fancy printed dates."),
1354 N_(
"The electronic tax number of your business"),
1361 auto option{odb->find_option(section, name)};
1370 const char* section,
const char* name,
1371 const char* key,
const char* doc_string,
1372 int value,
int min,
int max,
int step);
1374 const char* section,
const char* name,
1375 const char* key,
const char* doc_string,
1376 double value,
double min,
1377 double max,
double step);
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
void gnc_option_db_clean(GncOptionDB *odb)
Reset all ui_items to the option value.
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.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
void gnc_register_simple_boolean_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, bool value)
Create a new simple boolean option and register it in the options database.
KvpValue * qof_book_get_option(QofBook *book, GSList *path)
Read a single option value.
The generic option-value class.
gboolean gnc_date_string_to_monthformat(const gchar *format_string, GNCDateMonthFormat *format)
Converts the month format to a printable string.
const char * gnc_date_dateformat_to_string(QofDateFormat format)
The string->value versions return FALSE on success and TRUE on failure.
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
void mark_saved() noexcept
Mark the option as needing to be saved.
void gnc_register_invoice_print_report_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new print report option and register it in the options database.
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
void gnc_register_number_range_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, ValueType value, ValueType min, ValueType max, ValueType step)
Create a new number range option and register it in the options database.
No Fancy Date Format, use Global.
A legal date value is a pair of either a RelativeDatePeriod, the absolute flag and a time64...
void gnc_register_counter_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, int value)
Create a new counter option and register it in the options database.
bool is_changed() const noexcept
C public interface for the Options Database.
void gnc_option_db_save(GncOptionDB *odb, QofBook *book, gboolean clear_options)
Save the GncOptionDB contents into a book's options store.
void gnc_register_multichoice_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const char *default_val, GncMultichoiceOptionChoices &&choices)
Create a new multichoice option and register it in the options database.
Represents the public interface for an option.
Set one or more accounts on which to report, optionally restricted to certain account types...
#define PWARN(format, args...)
Log a warning.
void gnc_register_query_option(GncOptionDB *db, const char *section, const char *name, const QofQuery *value)
Create a new QofQuery option and register it in the options database.
void gnc_register_number_plot_size_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, int value)
Create a new plot-size option and register it in the options database.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
void gnc_register_date_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, time64 time, RelativeDateUI ui)
Create a new date option and register it in the options database.
Multichoice options have a vector of valid options (GncMultichoiceOptionChoices) and validate the sel...
void gnc_register_account_sel_limited_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const Account *value, GncOptionAccountTypeList &&allowed)
Create a limited account selection option and register it in the options database.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
void gnc_register_start_date_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, bool both)
Create a new start-date option and register it in the options database.
void gnc_option_db_load(GncOptionDB *odb, QofBook *book)
Load a book's options into the GncOptionDB.
void gnc_register_list_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const char *value, GncMultichoiceOptionChoices &&list)
Create a new list option and register it in the options database.
void gnc_option_db_destroy(GncOptionDB *odb)
Destruct and release a GncOptionDB.
RelativeDatePeriod
Reporting periods relative to the current date.
void gnc_register_color_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new color option and register it in the options database.
class GncOptionSection The upper-level classification implementation.
void gnc_register_string_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new string option and register it in the options database.
void gnc_register_account_list_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const GncOptionAccountList &value)
Create a new account list option and register it in the options database.
void gnc_register_commodity_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, gnc_commodity *value)
Create a new commodity option and register it in the options database.
class GncOptionCommodityValue Commodities are stored with their namespace and mnemonic instead of the...
Used for numeric ranges and plot sizes.
GNCDateMonthFormat
This is how to format the month, as a number, an abbreviated string, or the full name.
bool is_dirty() const noexcept
const GncGUID * qof_entity_get_guid(gconstpointer ent)
void gnc_register_end_date_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, bool both)
Create a new end-date option and register it in the options database.
The primary C++ interface to options for books, reports, and stylesheets.
GList * gnc_option_db_commit(GncOptionDB *odb)
Write all changed ui_item values to their options.
void gnc_register_taxtable_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, GncTaxTable *value)
Create a new taxtable option and register it in the options database.
void gnc_register_font_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new font option and register it in the options database.
time64 gnc_time(time64 *tbuf)
get the current time
Implementation details for GncOptionDB.
void gnc_register_pixmap_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new pixmap option and register it in the options database.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void gnc_register_budget_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, GncBudget *value)
Create a new budget option and register it in the options database.
void gnc_register_currency_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, gnc_commodity *value)
Create a new currency option and register it in the options database.
void qof_book_set_option(QofBook *book, KvpValue *value, GSList *path)
Save a single option value.
void gnc_register_dateformat_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, GncOptionDateFormat &&value)
Create a new date format option and register it in the options database.
void qof_book_options_delete(QofBook *book, GSList *path)
Delete the options.
gboolean gnc_date_string_to_dateformat(const gchar *format_string, QofDateFormat *format)
Converts the date format to a printable string.
void gnc_option_db_book_options(GncOptionDB *odb)
Register the standard option set for a QofBook.
The type used to store guids in C.
void gnc_register_invoice_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, GncInvoice *value)
Create a new invoice option and register it in the options database.
QofDateFormat
Enum for determining a date format.
GncOptionAccountList gnc_account_list_from_types(QofBook *book, const GncOptionAccountTypeList &types)
Extract a list of accounts in the book having one of the GNCAccountTypes in types.
void gnc_register_counter_format_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new counter format option and register it in the options database.
void gnc_register_text_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, std::string value)
Create a new text option and register it in the options database.
GncOptionUIType
Used by GncOptionClassifier to indicate to dialog-options what control should be displayed for the op...
modtime is the internal date of the last modtime See libgnucash/engine/TaxTableBillTermImmutability.txt for an explanation of the following Code that handles refcount, parent, child, invisible and children is identical to that in ::GncBillTerm
void gnc_register_owner_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const GncOwner *value, GncOwnerType type)
Create a new GncOwner option and register it in the options database.
GncOptionDB * gnc_option_db_new(void)
Create an empty option database.
void gnc_register_account_list_limited_option(GncOptionDB *db, const char *section, const char *name, const char *key, const char *doc_string, const GncOptionAccountList &value, GncOptionAccountTypeList &&allowed)
Create a new limited account list option and register it in the options database. ...