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));
710 g_list_free (namespaces);
715 const char* section,
const char* name,
716 const char* key,
const char* doc_string,
719 GncOption option{section, name, key, doc_string, value,
720 GncOptionUIType::BOOLEAN};
721 db->register_option(section, std::move(option));
726 const char* name,
const char* key,
727 const char* doc_string, std::string value)
729 GncOption option{section, name, key, doc_string, value,
730 GncOptionUIType::PIXMAP};
731 db->register_option(section, std::move(option));
736 const char* name,
const char* key,
737 const char* doc_string,
738 const GncOptionAccountList& value)
741 GncOptionUIType::ACCOUNT_LIST, value}};
742 db->register_option(section, std::move(option));
747 const char* section,
const char* name,
749 const char* doc_string,
750 const GncOptionAccountList& value,
751 GncOptionAccountTypeList&& allowed)
756 GncOptionUIType::ACCOUNT_LIST, value, std::move(allowed)}};
757 db->register_option(section, std::move(option));
759 catch (
const std::invalid_argument& err)
761 PWARN(
"Account List Limited Option, value failed validation, option not registered.");
765 using AccountPair = std::pair<GncOptionAccountList&,
766 const GncOptionAccountTypeList&>;
768 find_children(
Account* account,
void* data)
772 GncOptionAccountList& list = datapair->first;
773 const GncOptionAccountTypeList& types = datapair->second;
774 if (std::find(types.begin(), types.end(),
781 const GncOptionAccountTypeList& types)
783 GncOptionAccountList list;
784 AccountPair funcdata{list, types};
785 Account* base_acct = gnc_book_get_root_account(book);
786 gnc_account_foreach_descendant(base_acct, (AccountCb)find_children,
794 const char* section,
const char* name,
795 const char* key,
const char* doc_string,
797 GncOptionAccountTypeList&& allowed)
802 GncOptionUIType::ACCOUNT_SEL, value, std::move(allowed)}};
803 db->register_option(section, std::move(option));
805 catch (
const std::invalid_argument& err)
807 PWARN(
"Account Sel Limited Option, value failed validation, option not registerd.");
813 const char* name,
const char* key,
814 const char* doc_string,
const char* default_val,
815 GncMultichoiceOptionChoices&& choices)
817 std::string defval{default_val};
818 auto found{std::find_if(choices.begin(), choices.end(),
819 [&defval](
auto& choice)->
bool {
820 return defval == std::get<0>(choice);
822 if (found == choices.end())
823 defval = (choices.empty() ? std::string{
"None"} :
824 std::get<0>(choices.at(0)));
826 defval.c_str(), std::move(choices)}};
827 db->register_option(section, std::move(option));
832 const char* name,
const char* key,
833 const char* doc_string,
const char* value,
834 GncMultichoiceOptionChoices&& list)
837 value, std::move(list), GncOptionUIType::LIST}};
838 db->register_option(section, std::move(option));
844 template <
typename ValueType>
void 846 const char* name,
const char* key,
847 const char* doc_string, ValueType value,
848 ValueType min, ValueType max, ValueType step)
853 doc_string, value, min,
855 db->register_option(section, std::move(option));
857 catch(
const std::invalid_argument& err)
859 PWARN(
"Number Range Option %s, option not registerd.",
866 const char* section,
const char* name,
867 const char* key,
const char* doc_string,
872 value, 10, UINT16_MAX, 1, GncOptionUIType::PLOT_SIZE}};
873 db->register_option(section, std::move(option));
878 const char* name,
const QofQuery* value)
880 GncOption option{section, name,
"",
"", value,
881 GncOptionUIType::INTERNAL};
882 db->register_option(section, std::move(option));
887 const char* name,
const char* key,
888 const char* doc_string,
const GncOwner* value,
894 case GNC_OWNER_CUSTOMER:
895 uitype = GncOptionUIType::CUSTOMER;
897 case GNC_OWNER_EMPLOYEE:
898 uitype = GncOptionUIType::EMPLOYEE;
901 uitype = GncOptionUIType::JOB;
903 case GNC_OWNER_VENDOR:
904 uitype = GncOptionUIType::VENDOR;
907 uitype = GncOptionUIType::INTERNAL;
911 db->register_option(section, std::move(option));
916 const char* name,
const char* key,
917 const char* doc_string, GncInvoice* value)
921 GncOptionUIType::INVOICE}};
922 db->register_option(section, std::move(option));
927 const char* name,
const char* key,
932 GncOptionUIType::TAX_TABLE}};
933 db->register_option(section, std::move(option));
938 const char* name,
const char* key,
939 const char* doc_string, std::string value)
941 GncOption option{section, name, key, doc_string,
942 value, GncOptionUIType::INV_REPORT};
943 db->register_option(section, std::move(option));
948 const char* name,
const char* key,
949 const char* doc_string,
int value)
952 value, 0, 999999999, 1}};
953 option.set_alternate(
true);
954 db->register_option(section, std::move(option));
959 const char* section,
const char* name,
960 const char* key,
const char* doc_string,
963 GncOption option{section, name, key, doc_string, value,
964 GncOptionUIType::STRING};
965 db->register_option(section, std::move(option));
970 const char* name,
const char* key,
971 const char* doc_string, GncOptionDateFormat&& value)
973 GncOption option{section, name, key, doc_string, std::move(value),
974 GncOptionUIType::DATE_FORMAT};
975 db->register_option(section, std::move(option));
980 const char* name,
const char* key,
981 const char* doc_string, gnc_commodity *value)
984 section, name, key, doc_string, value, GncOptionUIType::CURRENCY
986 db->register_option(section, std::move(option));
991 const char* name,
const char* key,
992 const char* doc_string,
const char* value)
996 const auto commodity = gnc_commodity_table_lookup(commodity_table,
1000 section, name, key, doc_string, commodity, GncOptionUIType::CURRENCY
1002 db->register_option(section, std::move(option));
1007 const char* name,
const char* key,
1008 const char* doc_string,
time64 time,
1011 auto ui_type = ui == RelativeDateUI::BOTH ? GncOptionUIType::DATE_BOTH :
1012 ui == RelativeDateUI::RELATIVE ? GncOptionUIType::DATE_RELATIVE :
1013 GncOptionUIType::DATE_ABSOLUTE;
1016 db->register_option(section, std::move(option));
1021 const char* name,
const char* key,
1025 auto ui_type = ui == RelativeDateUI::BOTH ? GncOptionUIType::DATE_BOTH :
1026 ui == RelativeDateUI::RELATIVE ? GncOptionUIType::DATE_RELATIVE :
1027 GncOptionUIType::DATE_ABSOLUTE;
1030 db->register_option(section, std::move(option));
1035 const char* section,
const char* name,
1036 const char* key,
const char* doc_string,
1037 RelativeDatePeriodVec& period_set,
1040 auto is_absolute = period_set.size() == 1 &&
1041 period_set.front() == RelativeDatePeriod::ABSOLUTE;
1042 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1043 is_absolute ? GncOptionUIType::DATE_ABSOLUTE : GncOptionUIType::DATE_RELATIVE;
1045 ui_type, period_set)};
1047 option.set_default_value(
gnc_time(
nullptr));
1048 db->register_option(section, std::move(option));
1052 static const RelativeDatePeriodVec begin_dates
1054 RelativeDatePeriod::TODAY,
1055 RelativeDatePeriod::START_THIS_MONTH,
1056 RelativeDatePeriod::START_PREV_MONTH,
1057 RelativeDatePeriod::START_CURRENT_QUARTER,
1058 RelativeDatePeriod::START_PREV_QUARTER,
1059 RelativeDatePeriod::START_CAL_YEAR,
1060 RelativeDatePeriod::START_PREV_YEAR,
1061 RelativeDatePeriod::START_ACCOUNTING_PERIOD
1066 const char* name,
const char* key,
1067 const char* doc_string,
bool both)
1069 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1070 GncOptionUIType::DATE_RELATIVE;
1072 ui_type, begin_dates)};
1073 db->register_option(section, std::move(option));
1076 static const RelativeDatePeriodVec end_dates
1078 RelativeDatePeriod::TODAY,
1079 RelativeDatePeriod::END_THIS_MONTH,
1080 RelativeDatePeriod::END_PREV_MONTH,
1081 RelativeDatePeriod::END_CURRENT_QUARTER,
1082 RelativeDatePeriod::END_PREV_QUARTER,
1083 RelativeDatePeriod::END_CAL_YEAR,
1084 RelativeDatePeriod::END_PREV_YEAR,
1085 RelativeDatePeriod::END_ACCOUNTING_PERIOD
1090 const char* name,
const char* key,
1091 const char* doc_string,
bool both)
1093 auto ui_type = both ? GncOptionUIType::DATE_BOTH :
1094 GncOptionUIType::DATE_RELATIVE;
1096 ui_type, end_dates)};
1097 db->register_option(section, std::move(option));
1101 gnc_register_report_placement_option(GncOptionDBPtr& db,
1102 const char* section,
const char* name)
1107 GncOptionReportPlacementVec value;
1109 "no_key",
"nodoc_string",
1110 value,GncOptionUIType::REPORT_PLACEMENT}};
1111 db->register_option(section, std::move(option));
1115 gnc_register_internal_option(GncOptionDBPtr& db,
1116 const char* section,
const char* name,
1117 const std::string& value)
1121 GncOptionUIType::INTERNAL}};
1122 db->register_option(section, std::move(option));
1126 gnc_register_internal_option(GncOptionDBPtr& db,
1127 const char* section,
const char* name,
1132 GncOptionUIType::INTERNAL}};
1133 db->register_option(section, std::move(option));
1145 PWARN(
"Direct Destroy called on GncOptionDB %" G_GUINT64_FORMAT, (uint64_t)odb);
1152 odb->foreach_section(
1153 [&errors](GncOptionSectionPtr& section){
1154 section->foreach_option(
1158 option.set_option_from_ui_item();
1160 catch (
const std::invalid_argument& err)
1162 PWARN(
"Option %s:%s failed to set its value %s",
1163 option.get_section().c_str(),
1164 option.get_name().c_str(), err.what());
1165 errors = g_list_prepend(errors,
1166 (
void*)option.get_name().c_str());
1170 odb->run_callbacks();
1177 odb->foreach_section(
1178 [](GncOptionSectionPtr& section){
1179 section->foreach_option(
1181 option.set_ui_item_from_option();
1188 odb->load_from_kvp(book);
1193 gboolean clear_options)
1195 odb->save_to_kvp(book, static_cast<bool>(clear_options));
1201 constexpr
const char* business_section{N_(
"Business")};
1202 constexpr
const char* counter_section{N_(
"Counters")};
1203 static const std::string empty_string{
""};
1207 gnc_register_number_range_option<double>(odb, OPTION_SECTION_ACCOUNTS,
1208 OPTION_NAME_AUTO_READONLY_DAYS,
"a",
1209 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."),
1210 0.0, 0.0, 3650.0, 1.0);
1213 OPTION_NAME_NUM_FIELD_SOURCE,
"b",
1214 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."),
1217 OPTION_NAME_TRADING_ACCOUNTS,
"a",
1218 N_(
"Check to have trading accounts used for transactions involving more than one currency or commodity."),
1224 OPTION_NAME_DEFAULT_BUDGET,
"a",
1225 N_(
"Budget to be used when none has been otherwise specified."),
1231 N_(
"Customer number"),
"gncCustomera",
1232 N_(
"The previous customer number generated. This number will be incremented to generate the next customer number."),
1235 N_(
"Customer number format"),
1237 N_(
"The format string to use for generating customer numbers. This is a printf-style format string."),
1240 N_(
"Employee number"),
"gncEmployeea",
1241 N_(
"The previous employee number generated. This number will be incremented to generate the next employee number."),
1244 N_(
"Employee number format"),
1246 N_(
"The format string to use for generating employee numbers. This is a printf-style format string."),
1249 N_(
"Invoice number"),
"gncInvoicea",
1250 N_(
"The previous invoice number generated. This number will be incremented to generate the next invoice number."),
1253 N_(
"Invoice number format"),
1255 N_(
"The format string to use for generating invoice numbers. This is a printf-style format string."),
1258 N_(
"Bill number"),
"gncBilla",
1259 N_(
"The previous bill number generated. This number will be incremented to generate the next bill number."),
1262 N_(
"Bill number format"),
"gncBillb",
1263 N_(
"The format string to use for generating bill numbers. This is a printf-style format string."),
1266 N_(
"Expense voucher number"),
"gncExpVouchera",
1267 N_(
"The previous expense voucher number generated. This number will be incremented to generate the next voucher number."),
1270 N_(
"Expense voucher number format"),
1272 N_(
"The format string to use for generating expense voucher numbers. This is a printf-style format string."),
1275 N_(
"Job number"),
"gncJoba",
1276 N_(
"The previous job number generated. This number will be incremented to generate the next job number."),
1279 N_(
"Job number format"),
"gncJobb",
1280 N_(
"The format string to use for generating job numbers. This is a printf-style format string."),
1283 N_(
"Order number"),
"gncOrdera",
1284 N_(
"The previous order number generated. This number will be incremented to generate the next order number."),
1287 N_(
"Order number format"),
"gncOrderb",
1288 N_(
"The format string to use for generating order numbers. This is a printf-style format string."),
1291 N_(
"Vendor number"),
"gncVendora",
1292 N_(
"The previous vendor number generated. This number will be incremented to generate the next vendor number."),
1295 N_(
"Vendor number format"),
"gncVendorb",
1296 N_(
"The format string to use for generating vendor numbers. This is a printf-style format string."),
1302 N_(
"The name of your business."),
1305 N_(
"The address of your business."),
1308 N_(
"Company Contact Person"),
"b2",
1309 N_(
"The contact person to print on invoices."),
1312 N_(
"Company Phone Number"),
"c1",
1313 N_(
"The contact person to print on invoices."),
1316 N_(
"Company Fax Number"),
"c2",
1317 N_(
"The fax number of your business."),
1320 N_(
"Company Email Address"),
"c3",
1321 N_ (
"The email address of your business."),
1324 N_(
"Company Website URL"),
"c4",
1325 N_(
"The URL address of your website."),
1328 N_(
"The ID for your company (eg 'Tax-ID: 00-000000)."),
1331 OPTION_NAME_DEFAULT_INVOICE_REPORT,
"e1",
1332 N_(
"The invoice report to be used for printing."),
1334 gnc_register_number_range_option<double>(odb, business_section,
1335 OPTION_NAME_DEFAULT_INVOICE_REPORT_TIMEOUT,
"e2",
1336 N_(
"Length of time to change the used invoice report. A value of 0 means disabled."),
1337 0.0, 0.0, 20.0, 1.0);
1339 N_(
"Default Customer TaxTable"),
"f1",
1340 N_(
"The default tax table to apply to customers."),
1343 N_(
"Default Vendor TaxTable"),
"f2",
1344 N_(
"The default tax table to apply to vendors."),
1348 N_(
"Fancy Date Format"),
"g",
1349 N_(
"The default date format used for fancy printed dates."),
1355 N_(
"The electronic tax number of your business"),
1362 auto option{odb->find_option(section, name)};
1371 const char* section,
const char* name,
1372 const char* key,
const char* doc_string,
1373 int value,
int min,
int max,
int step);
1375 const char* section,
const char* name,
1376 const char* key,
const char* doc_string,
1377 double value,
double min,
1378 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. ...