Fix color option handling.

Read and write color options the way legacy code does. Pass only values
with no alpha to gdk_rgba_parse because it fails if a hex-string has
alpha.
This commit is contained in:
John Ralls 2021-08-18 13:38:06 -07:00
parent 97a317b50c
commit 10381d42e0
5 changed files with 59 additions and 5 deletions

View File

@ -2140,8 +2140,12 @@ public:
void set_ui_item_from_option(GncOption& option) noexcept override
{
GdkRGBA color;
auto rgba_str{g_strdup_printf("#%s",
option.get_value<std::string>().c_str())};
/* gdk_rgba_parse uses pango_color_parse for hex color strings instead
* of pango_color_parse_with_alpha and that fails if the string length
* is 8.
*/
auto value{option.get_value<std::string>().substr(0,6)};
auto rgba_str{g_strdup_printf("#%s", value.c_str())};
if (gdk_rgba_parse(&color, rgba_str))
{
auto color_button = GTK_COLOR_CHOOSER(get_widget());

View File

@ -388,11 +388,16 @@ gnc_option_to_scheme (std::ostream& oss, const OptType& opt)
{
oss << ")";
}
return oss;
}
else
if constexpr (std::is_same_v<std::decay_t<decltype(value)>, std::string>)
{
oss << "\"" << qof_instance_to_string(value) << "\"";
if (type == GncOptionUIType::COLOR)
return output_color_value(oss, value);
}
oss << "\"" << qof_instance_to_string(value) << "\"";
return oss;
}

View File

@ -453,7 +453,12 @@ GncOption::to_scheme(std::ostream& oss) const
else if constexpr
(std::is_same_v<std::decay_t<decltype(option.get_value())>,
std::string>)
{
if (option.get_ui_type() == GncOptionUIType::COLOR)
output_color_value(oss, option.get_value());
else
oss << '"' << option << '"';
}
else if constexpr
(std::is_same_v<std::decay_t<decltype(option)>,
GncOptionRangeValue<int>> ||

View File

@ -28,6 +28,7 @@
#include <libguile.h>
#include <string>
#include <iostream>
#include <iomanip>
#include <variant>
#include <memory>
#include "gnc-option-ui.hpp"
@ -149,6 +150,24 @@ operator>>(std::istream& iss, GncOption& opt)
return opt.in_stream(iss);
}
inline std::ostream&
output_color_value(std::ostream& oss, const std::string& value)
{
oss << "'(";
oss << std::fixed << std::showpoint << std::setprecision(1);
auto len{value.length() > 8 ? 8 : value.length()};
for (size_t i{}; i < len; i += 2)
{
oss << static_cast<float>(stoi(value.substr(i, 2), nullptr, 16));
if (i < 6)
oss << " ";
}
if (len < 8)
oss << 256.0;
oss << ")";
return oss;
}
template<typename ValueType> GncOption*
gnc_make_option(const char* section, const char* name,
const char* key, const char* doc_string,

View File

@ -46,6 +46,8 @@ namespace std {
#include "gnc-optiondb.hpp"
#include "gnc-optiondb-impl.hpp"
#include "gnc-option-date.hpp"
#include <sstream>
#include <iomanip>
static const QofLogModule log_module = "gnc.optiondb";
@ -240,6 +242,24 @@ scm_from_value<GncOwner*>(GncOwner* value)
return scm_from_value<const GncOwner*>(value);
}
static std::string
scm_color_list_to_string(SCM list)
{
std::ostringstream oss{};
oss << std::hex << std::setfill('0');
SCM cdr = list;
while (scm_is_pair(cdr))
{
if (scm_is_rational(SCM_CAR(cdr)))
oss << std::setw(2) <<
static_cast<unsigned int>(scm_to_double(SCM_CAR(cdr)));
cdr = SCM_CDR(cdr);
}
if (scm_is_rational(cdr))
oss << std::setw(2) << static_cast<unsigned int>(scm_to_double(cdr));
return oss.str();
}
template <typename ValueType> inline ValueType
scm_to_value(SCM new_value)
{
@ -257,6 +277,8 @@ scm_to_value<bool>(SCM new_value)
template <> inline std::string
scm_to_value<std::string>(SCM new_value)
{
if (scm_is_true(scm_list_p(new_value)))
return scm_color_list_to_string(new_value);
auto strval = scm_to_utf8_stringn(new_value, nullptr);
std::string retval{strval};
free(strval);
@ -552,7 +574,6 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB);
#include <algorithm>
#include <array>
#include <string>
#include <sstream>
#include "gnc-option.hpp"
#include "gnc-option-ui.hpp"