GnuCash  5.6-150-g038405b370+
gnc-option.hpp
Go to the documentation of this file.
1 /********************************************************************\
2  * gnc-option.hpp -- Application options system *
3  * Copyright (C) 2020 John Ralls <jralls@ceridwen.us> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
33 #ifndef GNC_OPTION_HPP_
34 #define GNC_OPTION_HPP_
35 
36 #include <glib.h>
37 #include <any>
38 #include <string>
39 #include <iostream>
40 #include <iomanip>
41 #include <type_traits>
42 #include <variant>
43 #include <memory>
44 #include <tuple>
45 #include <cstdint>
46 #include "gnc-option-ui.hpp"
47 #include "gnc-option-date.hpp"
48 #include "guid.hpp"
49 
50 struct OptionClassifier;
51 class GncOptionUIItem;
52 using GncOptionUIItemPtr = std::unique_ptr<GncOptionUIItem>;
53 #ifndef SWIG //SWIG pulls in GncOwner from swig-engine.
54 struct _gncOwner;
55 using GncOwner = _gncOwner;
56 struct _QofQuery;
58 #endif
59 struct QofInstance_s;
61 template <typename ValueType> class GncOptionValue;
67 template <typename ValueType> class GncOptionRangeValue;
69 class GncOptionDateValue;
70 using GncOptionDateFormat = std::tuple<QofDateFormat, GNCDateMonthFormat, bool, std::string>;
71 using GncOptionReportPlacement = std::tuple<uint32_t, uint32_t, uint32_t>;
72 using GncOptionReportPlacementVec = std::vector<GncOptionReportPlacement>;
73 template <typename T>
75 {
76  static constexpr bool value =
77  std::is_base_of_v<OptionClassifier, std::decay_t<T>>;
78 };
79 
80 template <typename T> inline constexpr bool
81 is_OptionClassifier_v = is_OptionClassifier<T>::value;
82 
83 template <typename T, typename U>
85 {
86  static constexpr bool value = std::is_same_v<std::decay_t<T>,
87  std::decay_t<U>>;
88 };
89 
90 template <typename T, typename U> inline constexpr bool
91 is_same_decayed_v = is_same_decayed<T, U>::value;
92 
93 template <typename T>
95 {
96  static constexpr bool value =
97  (is_same_decayed_v<T, GncOptionRangeValue<int>> ||
98  is_same_decayed_v<T, GncOptionRangeValue<double>>);
99 };
100 
101 template <typename T> inline constexpr bool
102 is_RangeValue_v = is_RangeValue<T>::value;
103 
104 
105 using GncOptionVariant = std::variant<GncOptionValue<std::string>,
120 
121 using GncOptionVariantPtr = std::unique_ptr<GncOptionVariant>;
122 
123 enum class GncOptionMultichoiceKeyType
124 {
125  SYMBOL,
126  STRING,
127  NUMBER,
128 };
129 
137 {
138 public:
139  template <typename OptionType,
140  typename std::enable_if_t<is_OptionClassifier_v<OptionType>,
141  int> = 0>
142 
143  GncOption(OptionType option) :
144  m_option{std::make_unique<GncOptionVariant>(option)} {}
145  template <typename ValueType,
146  typename std::enable_if_t<!is_OptionClassifier_v<ValueType>,
147  int> = 0>
148  GncOption(const char* section, const char* name,
149  const char* key, const char* doc_string,
150  ValueType value,
151  GncOptionUIType ui_type = GncOptionUIType::INTERNAL);
152  template <typename ValueType> void set_value(ValueType value);
153  template <typename ValueType> void set_default_value(ValueType value);
154  template <typename ValueType> ValueType get_default_value() const;
155  template <typename ValueType> ValueType get_value() const;
156  void reset_default_value();
157 
158  const std::string& get_section() const;
159  const std::string& get_name() const;
160  const std::string& get_key() const;
161  const std::string& get_docstring() const;
162  void set_ui_item(GncOptionUIItemPtr&& ui_elem);
163  const GncOptionUIType get_ui_type() const;
164  void set_ui_item_selectable(bool) const noexcept;
165  GncOptionUIItem* const get_ui_item() const;
166  void set_ui_item_from_option();
167  void set_option_from_ui_item();
168  void make_internal();
169  bool is_internal();
171  void mark_saved() noexcept;
173  bool is_dirty() const noexcept;
175  bool is_changed() const noexcept;
179  bool is_multiselect() const noexcept;
181  template <typename ValueType> void get_limits(ValueType&, ValueType&,
182  ValueType&) const noexcept;
184  template <typename ValueType> bool validate(ValueType value) const;
186  uint16_t num_permissible_values() const;
188  uint16_t permissible_value_index(const char* value) const;
190  const char* permissible_value(uint16_t index) const;
192  const char* permissible_value_name(uint16_t index) const;
194  GList* account_type_list() const noexcept;
195  bool is_alternate() const noexcept;
196  void set_alternate(bool) noexcept;
200  std::string serialize() const;
205  bool deserialize(const std::string& str);
210  std::istream& in_stream(std::istream& iss);
211  friend GncOptionVariant& swig_get_option(GncOption*);
212  void set_widget_changed (std::any cb) { m_widget_changed = cb; }
213  std::any& get_widget_changed () { return m_widget_changed; }
214 private:
215  inline static const std::string c_empty_string{""};
216  GncOptionVariantPtr m_option;
217  GncOptionUIItemPtr m_ui_item{nullptr};
218  std::any m_widget_changed{};
219 };
220 
221 inline bool
222 operator<(const GncOption& right, const GncOption& left)
223 {
224  return right.get_key() < left.get_key();
225 }
226 
227 inline std::ostream&
228 operator<<(std::ostream& oss, const GncOption& opt)
229 {
230  oss << opt.serialize();
231  return oss;
232 }
233 
234 inline std::istream&
235 operator>>(std::istream& iss, GncOption& opt)
236 {
237  return opt.in_stream(iss);
238 }
239 
240 inline std::ostream&
241 output_color_value(std::ostream& oss, const std::string& value)
242 {
243  oss << "'(";
244  oss << std::fixed << std::showpoint << std::setprecision(1);
245  auto len{value.length() > 8 ? 8 : value.length()};
246  for (size_t i{}; i < len; i += 2)
247  {
248  oss << static_cast<float>(stoi(value.substr(i, 2), nullptr, 16));
249  if (i < 6)
250  oss << " ";
251  }
252  if (len < 8)
253  oss << 256.0;
254  oss << ")";
255  return oss;
256 }
257 
263 template<typename ValueType> GncOption*
264 gnc_make_option(const char* section, const char* name,
265  const char* key, const char* doc_string,
266  ValueType value, GncOptionUIType ui_type)
267 {
268  return new GncOption(section, name, key, doc_string, value, ui_type);
269 }
270 
271 #endif //GNC_OPTION_HPP_
272 
bool is_multiselect() const noexcept
Definition: gnc-option.cpp:322
The generic option-value class.
void mark_saved() noexcept
Mark the option as needing to be saved.
Definition: gnc-option.cpp:298
bool deserialize(const std::string &str)
Set the option&#39;s value from a character sequence.
Definition: gnc-option.cpp:455
uint16_t permissible_value_index(const char *value) const
Implemented only for GncOptionMultiselectValue.
Definition: gnc-option.cpp:371
A legal date value is a pair of either a RelativeDatePeriod, the absolute flag and a time64...
bool is_changed() const noexcept
Definition: gnc-option.cpp:314
Represents the public interface for an option.
Definition: gnc-option.hpp:136
Set one or more accounts on which to report, optionally restricted to certain account types...
This class is the parent of all option implementations.
bool validate(ValueType value) const
Not implemented for GncOptionValue.
Definition: gnc-option.cpp:335
Multichoice options have a vector of valid options (GncMultichoiceOptionChoices) and validate the sel...
uint16_t num_permissible_values() const
Implemented only for GncOptionMultiselectValue.
Definition: gnc-option.cpp:356
std::string serialize() const
Get a string suitable for storage representing the option&#39;s value.
Definition: gnc-option.cpp:445
class GncOptionCommodityValue Commodities are stored with their namespace and mnemonic instead of the...
Used for numeric ranges and plot sizes.
bool is_dirty() const noexcept
Definition: gnc-option.cpp:306
Holds a pointer to the UI item which will control the option and an enum representing the type of the...
const char * permissible_value(uint16_t index) const
Implemented only for GncOptionMultiselectValue.
Definition: gnc-option.cpp:386
GncOption * gnc_make_option(const char *section, const char *name, const char *key, const char *doc_string, ValueType value, GncOptionUIType ui_type)
Free function wrapping GncOption&#39;s constructor.
Definition: gnc-option.hpp:264
void get_limits(ValueType &, ValueType &, ValueType &) const noexcept
Implemented only for GncOptionNumericRange.
Definition: gnc-option.cpp:177
const char * permissible_value_name(uint16_t index) const
Implemented only for GncOptionMultiselectValue.
Definition: gnc-option.cpp:400
A Query.
Definition: qofquery.cpp:74
GncOptionUIType
Used by GncOptionClassifier to indicate to dialog-options what control should be displayed for the op...
std::istream & in_stream(std::istream &iss)
Set the option&#39;s value from an input stream.
Definition: gnc-option.cpp:463
GList * account_type_list() const noexcept
Implemented only for GncOptionAccountListValue.
Definition: gnc-option.cpp:414
Relative date enumeration and manipulation functions.