[c++options] Correctly implement handling Fancy Date Format.

It's not a simple string.
This commit is contained in:
John Ralls 2023-09-19 16:04:28 -07:00
parent 8150645b10
commit a49fd0bc09
8 changed files with 105 additions and 13 deletions

View File

@ -319,6 +319,12 @@ scm_from_value<GncOptionReportPlacementVec>(GncOptionReportPlacementVec value)
return scm_reverse(s_list);
}
template <> inline SCM
scm_from_value<GncOptionDateFormat>(GncOptionDateFormat value)
{
return SCM_BOOL_F;
}
static std::string
scm_color_list_to_string(SCM list)
{
@ -564,7 +570,6 @@ gnc_option_test_book_destroy(QofBook* book)
%ignore operator>>(std::istream&, GncOption&);
%ignore GncOption::_get_option();
%rename(gnc_register_date_option_set)
gnc_register_date_option(GncOptionDBPtr&, const char*, const char*,
const char*, const char*, RelativeDatePeriodVec&,
@ -804,7 +809,8 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB);
%ignore gnc_register_taxtable_option(GncOptionDB*, const char*, const char*, const char*, const char*, GncTaxTable*);
%ignore gnc_register_counter_option(GncOptionDB*, const char*, const char*, const char*, const char*, double);
%ignore gnc_register_counter_format_option(GncOptionDB*, const char*, const char*, const char*, const char*, std::string);
%ignore gnc_register_dateformat_option(GncOptionDB*, const char*, const char*, const char*, const char*, std::string);
%ignore gnc_register_dateformat_option(GncOptionDB*, const char*, const char*, const char*, const char*, GncOptionDateFormat&&);
%ignore gnc_register_dateformat_option(GncOptionDBPtr&, const char*, const char*, const char*, const char*, GncOptionDateFormat&&);
%ignore gnc_register_date_option(GncOptionDB*, const char*, const char*, const char*, const char*, RelativeDatePeriod, RelativeDateUI);
%ignore gnc_register_date_option(GncOptionDB*, const char*, const char*, const char*, const char*, time64, RelativeDateUI);
%ignore gnc_register_date_option(GncOptionDB*, const char*, const char*, const char*, const char*, RelativeDatePeriodVec, bool);

View File

@ -1682,13 +1682,21 @@ public:
void set_ui_item_from_option(GncOption& option) noexcept override
{
auto widget{GNC_DATE_FORMAT(get_widget())};
gnc_date_format_set_custom(widget,
option.get_value<std::string>().c_str());
auto [format, months, years, custom] = option.get_value<GncOptionDateFormat>();
gnc_date_format_set_format(widget, format);
gnc_date_format_set_months(widget, months);
gnc_date_format_set_years(widget, years);
gnc_date_format_set_custom(widget, custom.c_str());
}
void set_option_from_ui_item(GncOption& option) noexcept override
{
auto widget{GNC_DATE_FORMAT(get_widget())};
option.set_value(std::string{gnc_date_format_get_custom(widget)});
GncOptionDateFormat format{
gnc_date_format_get_format(widget),
gnc_date_format_get_months(widget),
gnc_date_format_get_years(widget),
gnc_date_format_get_custom(widget)};
option.set_value(format);
}
};

View File

@ -1038,6 +1038,7 @@ template void GncOptionValue<uint16_t>::set_value(uint16_t);
template void GncOptionValue<GncOptionAccountList>::set_value(GncOptionAccountList);
template void GncOptionValue<GncMultichoiceOptionIndexVec>::set_value(GncMultichoiceOptionIndexVec);
template void GncOptionValue<GncOptionReportPlacementVec>::set_value(GncOptionReportPlacementVec);
template void GncOptionValue<GncOptionDateFormat>::set_value(GncOptionDateFormat);
template void GncOptionValue<bool>::set_default_value(bool);
template void GncOptionValue<int>::set_default_value(int);
template void GncOptionValue<int64_t>::set_default_value(int64_t);
@ -1052,6 +1053,7 @@ template void GncOptionValue<uint16_t>::set_default_value(uint16_t);
template void GncOptionValue<GncOptionAccountList>::set_default_value(GncOptionAccountList);
template void GncOptionValue<GncMultichoiceOptionIndexVec>::set_default_value(GncMultichoiceOptionIndexVec);
template void GncOptionValue<GncOptionReportPlacementVec>::set_default_value(GncOptionReportPlacementVec);
template void GncOptionValue<GncOptionDateFormat>::set_default_value(GncOptionDateFormat);
template void GncOptionValue<bool>::reset_default_value();
template void GncOptionValue<int>::reset_default_value();
template void GncOptionValue<int64_t>::reset_default_value();
@ -1066,6 +1068,7 @@ template void GncOptionValue<uint16_t>::reset_default_value();
template void GncOptionValue<GncOptionAccountList>::reset_default_value();
template void GncOptionValue<GncMultichoiceOptionIndexVec>::reset_default_value();
template void GncOptionValue<GncOptionReportPlacementVec>::reset_default_value();
template void GncOptionValue<GncOptionDateFormat>::reset_default_value();
template std::string GncOptionValue<bool>::serialize() const noexcept;
template std::string GncOptionValue<int>::serialize() const noexcept;
template std::string GncOptionValue<int64_t>::serialize() const noexcept;
@ -1076,6 +1079,7 @@ template std::string GncOptionValue<std::string>::serialize() const noexcept;
template std::string GncOptionValue<const QofQuery*>::serialize() const noexcept;
template std::string GncOptionValue<const GncOwner*>::serialize() const noexcept;
template std::string GncOptionValue<GncOptionReportPlacementVec>::serialize() const noexcept;
template std::string GncOptionValue<GncOptionDateFormat>::serialize() const noexcept;
template std::string GncOptionRangeValue<int>::serialize() const noexcept;
template std::string GncOptionRangeValue<double>::serialize() const noexcept;
template bool GncOptionValue<bool>::deserialize(const std::string&) noexcept;
@ -1088,5 +1092,6 @@ template bool GncOptionValue<std::string>::deserialize(const std::string&) noexc
template bool GncOptionValue<const QofQuery*>::deserialize(const std::string&) noexcept;
template bool GncOptionValue<const GncOwner*>::deserialize(const std::string&) noexcept;
template bool GncOptionValue<GncOptionReportPlacementVec>::deserialize(const std::string&) noexcept;
template bool GncOptionValue<GncOptionDateFormat>::deserialize(const std::string&) noexcept;
template bool GncOptionRangeValue<int>::deserialize(const std::string&) noexcept;
template bool GncOptionRangeValue<double>::deserialize(const std::string&) noexcept;

View File

@ -341,7 +341,8 @@ template<class OptType,
std::istream& operator>>(std::istream& iss, OptType& opt)
{
if constexpr (std::is_same_v<std::decay_t<decltype(opt.get_value())>, const _gncOwner*> ||
std::is_same_v<std::decay_t<decltype(opt.get_value())>, const _QofQuery*>)
std::is_same_v<std::decay_t<decltype(opt.get_value())>, const _QofQuery*> ||
std::is_same_v<std::decay_t<decltype(opt.get_value())>, GncOptionDateFormat>)
return iss;
else
{

View File

@ -115,6 +115,7 @@ GncOption::set_value(ValueType value)
[value](auto& option) {
if constexpr
(is_same_decayed_v<decltype(option.get_value()), ValueType> ||
is_same_decayed_v<decltype(option), GncOptionDateFormat> ||
(is_same_decayed_v<decltype(option),
GncOptionDateValue> &&
(is_same_decayed_v<ValueType, RelativeDatePeriod> ||
@ -146,6 +147,7 @@ GncOption::set_default_value(ValueType value)
[value](auto& option) {
if constexpr
(is_same_decayed_v<decltype(option.get_value()), ValueType>||
is_same_decayed_v<decltype(option), GncOptionDateFormat> ||
(is_same_decayed_v<decltype(option), GncOptionDateValue> &&
(is_same_decayed_v<ValueType, RelativeDatePeriod> ||
std::is_same_v<ValueType, time64> ||
@ -486,6 +488,10 @@ template GncOption::GncOption(const char*, const char*, const char*,
template GncOption::GncOption(const char*, const char*, const char*,
const char*, const QofQuery*, GncOptionUIType);
template GncOption::GncOption(const char *, const char*, const char*,
const char *, GncOptionDateFormat,
GncOptionUIType);
template bool GncOption::get_value<bool>() const;
template int GncOption::get_value<int>() const;
template int64_t GncOption::get_value<int64_t>() const;
@ -501,6 +507,7 @@ template RelativeDatePeriod GncOption::get_value<RelativeDatePeriod>() const;
template GncOptionAccountList GncOption::get_value<GncOptionAccountList>() const;
template GncMultichoiceOptionIndexVec GncOption::get_value<GncMultichoiceOptionIndexVec>() const;
template GncOptionReportPlacementVec GncOption::get_value<GncOptionReportPlacementVec>() const;
template GncOptionDateFormat GncOption::get_value<GncOptionDateFormat>() const;
template bool GncOption::get_default_value<bool>() const;
template int GncOption::get_default_value<int>() const;
@ -515,6 +522,7 @@ template RelativeDatePeriod GncOption::get_default_value<RelativeDatePeriod>() c
template GncOptionAccountList GncOption::get_default_value<GncOptionAccountList>() const;
template GncMultichoiceOptionIndexVec GncOption::get_default_value<GncMultichoiceOptionIndexVec>() const;
template GncOptionReportPlacementVec GncOption::get_default_value<GncOptionReportPlacementVec>() const;
template GncOptionDateFormat GncOption::get_default_value<GncOptionDateFormat>() const;
template void GncOption::set_value(bool);
template void GncOption::set_value(int);
@ -532,6 +540,7 @@ template void GncOption::set_value(uint16_t);
template void GncOption::set_value(GncOptionAccountList);
template void GncOption::set_value(GncMultichoiceOptionIndexVec);
template void GncOption::set_value(GncOptionReportPlacementVec);
template void GncOption::set_value(GncOptionDateFormat);
template void GncOption::set_default_value(bool);
template void GncOption::set_default_value(int);
@ -547,6 +556,7 @@ template void GncOption::set_default_value(uint16_t);
template void GncOption::set_default_value(GncOptionAccountList);
template void GncOption::set_default_value(GncMultichoiceOptionIndexVec);
template void GncOption::set_default_value(GncOptionReportPlacementVec);
template void GncOption::set_default_value(GncOptionDateFormat);
template void GncOption::get_limits(double&, double&, double&) const noexcept;
template void GncOption::get_limits(int&, int&, int&) const noexcept;
@ -563,6 +573,7 @@ template bool GncOption::validate(const QofQuery*) const;
template bool GncOption::validate(RelativeDatePeriod) const;
template bool GncOption::validate(GncMultichoiceOptionIndexVec) const;
template bool GncOption::validate(GncOptionReportPlacementVec) const;
template bool GncOption::validate(GncOptionDateFormat) const;
template GncOption* gnc_make_option<const std::string&>(const char*,
const char*,

View File

@ -66,6 +66,7 @@ class GncOptionMultichoiceValue;
template <typename ValueType> class GncOptionRangeValue;
class GncOptionCommodityValue;
class GncOptionDateValue;
using GncOptionDateFormat = std::tuple<QofDateFormat, GNCDateMonthFormat, bool, std::string>;
using GncOptionReportPlacement = std::tuple<uint32_t, uint32_t, uint32_t>;
using GncOptionReportPlacementVec = std::vector<GncOptionReportPlacement>;
template <typename T>
@ -113,7 +114,8 @@ using GncOptionVariant = std::variant<GncOptionValue<std::string>,
GncOptionRangeValue<int>,
GncOptionRangeValue<double>,
GncOptionCommodityValue,
GncOptionDateValue>;
GncOptionDateValue,
GncOptionValue<GncOptionDateFormat>>;
using GncOptionVariantPtr = std::unique_ptr<GncOptionVariant>;

View File

@ -28,6 +28,7 @@
#include <sstream>
#include "gnc-option-uitype.hpp"
#include "kvp-value.hpp"
#include "kvp-frame.hpp"
#include "qofbookslots.h"
#include "guid.hpp"
#include "gnc-optiondb.h"
@ -436,6 +437,30 @@ kvp_value_from_qof_instance_option(const GncOption& option)
return new KvpValue(guid);
}
/* GncOptionDateFormat Constants and support functions. These are frozen for backwards compatibility. */
static const char* date_format_frame_key = "Fancy Date Format";
static const char* date_format_custom_key ="custom";
static const char* date_format_months_key = "month";
static const char* date_format_years_key = "years";
static const char *date_format_format_key = "fmt";
static inline KvpValue *
kvp_frame_from_date_format_option(const GncOption& option)
{
auto [format, months, years, custom] = option.get_value<GncOptionDateFormat>();
if (format == QOF_DATE_FORMAT_UNSET)
return nullptr;
auto frame{new KvpFrame};
frame->set({date_format_format_key}, new KvpValue(g_strdup(gnc_date_dateformat_to_string(format))));
frame->set({date_format_months_key}, new KvpValue(g_strdup(gnc_date_monthformat_to_string(months))));
frame->set({date_format_years_key}, new KvpValue(static_cast<int64_t>(years)));
frame->set({date_format_custom_key}, new KvpValue(g_strdup(custom.c_str())));
return new KvpValue(frame);
};
void
GncOptionDB::save_to_kvp(QofBook* book, bool clear_options) const noexcept
{
@ -476,6 +501,8 @@ GncOptionDB::save_to_kvp(QofBook* book, bool clear_options) const noexcept
kvp = new KvpValue(option.template get_value<double>());
}
}
else if (type == GncOptionUIType::DATE_FORMAT)
kvp = kvp_frame_from_date_format_option(option);
else
{
auto str{option.template get_value<std::string>()};
@ -506,6 +533,33 @@ fill_option_from_guid_kvp(GncOption& option, KvpValue* kvp)
(const QofInstance*)qof_instance_from_guid(guid, option.get_ui_type()));
}
static inline void
fill_option_from_date_format_kvp(GncOption& option, KvpValue* kvp)
{
GncOptionDateFormat default_fmt{QOF_DATE_FORMAT_UNSET, GNCDATE_MONTH_NUMBER, true, ""};
auto frame{kvp->get<KvpFrame*>()};
if (!frame)
{
option.set_value(default_fmt);
return;
}
auto format_str{frame->get_slot({date_format_format_key})->get<const char*>()};
QofDateFormat format;
if (!format_str || gnc_date_string_to_dateformat(format_str, &format))
{
option.set_value(default_fmt);
return;
}
GNCDateMonthFormat months = GNCDATE_MONTH_NUMBER;
auto months_str{frame->get_slot({date_format_months_key})->get<const char*>()};
if (months_str)
gnc_date_string_to_monthformat(months_str, &months);
auto years_num{frame->get_slot({date_format_years_key})->get<int64_t>()};
bool years = static_cast<bool>(years_num);
auto custom_str{frame->get_slot({date_format_custom_key})->get<const char*>()};
option.set_value<GncOptionDateFormat>({format, months, years, custom_str ? custom_str : ""});
}
void
GncOptionDB::load_from_kvp(QofBook* book) noexcept
{
@ -556,6 +610,10 @@ GncOptionDB::load_from_kvp(QofBook* book) noexcept
case KvpValue::Type::GUID:
fill_option_from_guid_kvp(option, kvp);
break;
case KvpValue::Type::FRAME:
if (g_strcmp0(option.get_name().c_str(), date_format_frame_key) == 0)
fill_option_from_date_format_kvp(option, kvp);
break;
default:
return;
break;
@ -909,9 +967,9 @@ gnc_register_counter_format_option(GncOptionDB* db,
void
gnc_register_dateformat_option(GncOptionDB* db, const char* section,
const char* name, const char* key,
const char* doc_string, std::string value)
const char* doc_string, GncOptionDateFormat&& value)
{
GncOption option{section, name, key, doc_string, value,
GncOption option{section, name, key, doc_string, std::move(value),
GncOptionUIType::DATE_FORMAT};
db->register_option(section, std::move(option));
}
@ -1284,10 +1342,11 @@ gnc_option_db_book_options(GncOptionDB* odb)
N_("Default Vendor TaxTable"), "f2",
N_("The default tax table to apply to vendors."),
nullptr);
gnc_register_dateformat_option(odb, business_section,
N_("Fancy Date Format"), "g",
N_("The default date format used for fancy printed dates."),
empty_string);
{QOF_DATE_FORMAT_UNSET, GNCDATE_MONTH_NUMBER, true, ""});
//Tax Tab

View File

@ -806,7 +806,7 @@ inline void gnc_register_counter_format_option(GncOptionDBPtr& db,
void gnc_register_dateformat_option(GncOptionDB* db,
const char* section, const char* name,
const char* key, const char* doc_string,
std::string value);
GncOptionDateFormat&& value);
/**
* As above but takes a const GncOptionDBPtr& (const std::unique_ptr<GncOptionDB>&) for calling from C++.
@ -815,10 +815,10 @@ inline void gnc_register_dateformat_option(GncOptionDBPtr& db,
const char* section,
const char* name, const char* key,
const char* doc_string,
std::string value)
GncOptionDateFormat&& value)
{
gnc_register_dateformat_option(db.get(), section, name, key,
doc_string, value);
doc_string, std::move(value));
}
enum RelativeDateUI : uint8_t