7 #ifndef _FCITX_CONFIG_OPTION_H_ 8 #define _FCITX_CONFIG_OPTION_H_ 16 #include <type_traits> 19 #include <fcitx-config/fcitxconfig_export.h> 20 #include <fcitx-config/marshallfunction.h> 21 #include <fcitx-config/option_details.h> 22 #include <fcitx-config/optiontypename.h> 23 #include <fcitx-config/rawconfig.h> 33 std::string description, std::string uri);
35 std::string typeString()
const override;
36 void reset()
override;
37 bool isDefault()
const override;
39 void marshall(
RawConfig &config)
const override;
40 bool unmarshall(
const RawConfig &config,
bool partial)
override;
41 std::unique_ptr<Configuration> subConfigSkeleton()
const override;
43 bool equalTo(
const OptionBase &other)
const override;
44 void copyFrom(
const OptionBase &other)
override;
46 bool skipDescription()
const override;
47 bool skipSave()
const override;
48 void dumpDescription(
RawConfig &config)
const override;
51 std::string externalUri_;
57 using ExternalOption::ExternalOption;
58 void dumpDescription(
RawConfig &config)
const override;
65 bool check(
const T & )
const {
return true; }
66 void dumpDescription(
RawConfig & )
const {}
71 bool skipDescription() {
return false; }
72 bool skipSave() {
return false; }
73 void dumpDescription(
RawConfig & )
const {}
80 bool skipDescription() {
return false; }
81 bool skipSave() {
return false; }
82 void dumpDescription(
RawConfig &config)
const {
93 : option_(std::move(option)) {}
95 bool skipDescription() {
return false; }
96 bool skipSave() {
return false; }
97 void dumpDescription(
RawConfig &config)
const {
109 bool skipDescription() {
return false; }
110 bool skipSave() {
return false; }
111 void dumpDescription(
RawConfig &config)
const {
123 bool skipDescription() {
return false; }
124 bool skipSave() {
return false; }
125 void dumpDescription(
RawConfig &config)
const {
138 bool skipDescription() {
return true; }
139 bool skipSave() {
return false; }
140 void dumpDescription(
RawConfig & )
const {}
143 template <
typename Annotation>
145 using Annotation::Annotation;
146 bool skipDescription() {
return true; }
147 using Annotation::dumpDescription;
148 using Annotation::skipSave;
154 template <
typename SubConstrain>
156 ListConstrain(SubConstrain sub = SubConstrain()) : sub_(std::move(sub)) {}
158 using ElementType =
typename SubConstrain::Type;
159 using Type = std::vector<ElementType>;
160 bool check(
const Type &value) {
161 return std::ranges::all_of(
162 value, [
this](
const ElementType &ele) {
return sub_.check(ele); });
165 void dumpDescription(
RawConfig &config)
const {
166 sub_.dumpDescription(*config.
get(
"ListConstrain",
true));
177 template <
typename SubConstrain>
180 : sub_(std::move(sub)) {}
182 using ElementType =
typename SubConstrain::Type;
183 using Type = std::optional<ElementType>;
184 bool check(
const Type &value) {
188 return sub_.check(*value);
190 void dumpDescription(
RawConfig &config)
const {
191 sub_.dumpDescription(*config.
get(
"OptionalConstrain",
true));
203 int max = std::numeric_limits<int>::max())
204 : min_(min), max_(max) {}
205 bool check(
int value)
const {
return value >= min_ && value <= max_; }
206 void dumpDescription(
RawConfig &config)
const {
207 if (min_ != std::numeric_limits<int>::min()) {
208 marshallOption(config[
"IntMin"], min_);
210 if (max_ != std::numeric_limits<int>::max()) {
211 marshallOption(config[
"IntMax"], max_);
229 using Type = std::string;
230 bool check(
const std::string &value)
const;
231 void dumpDescription(
RawConfig &config)
const;
235 enum class KeyConstrainFlag {
237 AllowModifierOnly = (1 << 0),
239 AllowModifierLess = (1 << 1),
250 bool check(
const Key &key)
const {
251 if (!flags_.test(KeyConstrainFlag::AllowModifierLess) &&
256 if (!flags_.test(KeyConstrainFlag::AllowModifierOnly) &&
264 void dumpDescription(
RawConfig &config)
const {
265 if (flags_.test(KeyConstrainFlag::AllowModifierLess)) {
266 config[
"AllowModifierLess"] =
"True";
268 if (flags_.test(KeyConstrainFlag::AllowModifierOnly)) {
269 config[
"AllowModifierOnly"] =
"True";
278 template <
typename T>
282 void marshall(
RawConfig &config,
const T &value)
const {
283 return marshallOption(config, value);
285 bool unmarshall(T &value,
const RawConfig &config,
bool partial)
const {
286 return unmarshallOption(value, config, partial);
291 template <
typename OptionType>
294 using value_type =
typename OptionType::value_type;
297 : option_(option), value_(option ? option->value() : value_type()) {}
301 option_->setValue(std::move(value_));
306 : option_(other.option_), value_(std::move(other.value_)) {
307 other.option_ =
nullptr;
311 option_ = other.option_;
312 value_ = std::move(other.value_);
313 other.option_ =
nullptr;
316 value_type &operator*() {
return value_; }
317 value_type *operator->() {
return &value_; }
324 template <
typename Constrain,
typename Marshaller,
typename Annotation,
329 std::string description;
331 Constrain constrain{};
332 Marshaller marshaller{};
333 Annotation annotation{};
340 template <
typename T,
typename Constrain = NoConstrain<T>,
341 typename Marshaller = DefaultMarshaller<T>,
342 typename Annotation = NoAnnotation>
345 using value_type = T;
346 using constrain_type = Constrain;
351 const T &defaultValue = T(), Constrain constrain = Constrain(),
352 Marshaller marshaller = Marshaller(),
353 Annotation annotation = Annotation())
354 :
OptionBaseV3(parent, std::move(path), std::move(description)),
355 defaultValue_(defaultValue), value_(defaultValue),
356 marshaller_(std::move(marshaller)), constrain_(std::move(constrain)),
357 annotation_(std::move(annotation)) {
358 if (!constrain_.check(defaultValue_)) {
359 throw std::invalid_argument(
360 "defaultValue doesn't satisfy constrain");
365 :
Option(params.parent, std::move(params.path),
366 std::move(params.description), std::move(params.defaultValue),
367 std::move(params.constrain), std::move(params.marshaller),
368 std::move(params.annotation)) {}
372 void dumpDescription(
RawConfig &config)
const override {
373 OptionBase::dumpDescription(config);
374 if constexpr (not std::is_base_of_v<Configuration, T>) {
375 marshaller_.marshall(config[
"DefaultValue"], defaultValue_);
377 constrain_.dumpDescription(config);
378 annotation_.dumpDescription(config);
379 using ::fcitx::dumpDescriptionHelper;
380 dumpDescriptionHelper(
381 config,
static_cast<typename RemoveVector<T>::type *
>(
nullptr));
384 std::unique_ptr<Configuration> subConfigSkeleton()
const override {
385 if constexpr (std::is_base_of_v<Configuration, T>) {
386 auto skeleton = std::make_unique<T>(defaultValue_);
387 skeleton->syncDefaultValueToCurrent();
391 typename RemoveVector<T>::type>) {
392 return std::make_unique<typename RemoveVector<T>::type>();
398 bool isDefault()
const override {
return defaultValue_ == value_; }
399 void reset()
override { value_ = defaultValue_; }
401 const T &value()
const {
return value_; }
403 const T &defaultValue()
const {
return defaultValue_; }
405 const T &operator*()
const {
return value(); }
406 const T *operator->()
const {
return &value_; }
408 template <
typename U>
409 bool setValue(U &&value) {
410 if (!constrain_.check(value)) {
413 value_ = std::forward<U>(value);
417 template <
typename Dummy = int,
418 std::enable_if_t<!std::is_same<Constrain, NoConstrain<T>>::value,
424 template <
typename Dummy = int,
425 std::enable_if_t<std::is_same<Constrain, NoConstrain<T>>::value,
431 void marshall(
RawConfig &config)
const override {
432 return marshaller_.marshall(config, value_);
434 bool unmarshall(
const RawConfig &config,
bool partial)
override {
439 if (!marshaller_.unmarshall(tempValue, config, partial)) {
442 return setValue(tempValue);
445 bool equalTo(
const OptionBase &other)
const override {
446 auto otherP =
static_cast<const Option *
>(&other);
447 return value_ == otherP->value_;
450 void copyFrom(
const OptionBase &other)
override {
451 auto otherP =
static_cast<const Option *
>(&other);
452 value_ = otherP->value_;
455 bool skipDescription()
const override {
456 return annotation_.skipDescription();
459 bool skipSave()
const override {
return annotation_.skipSave(); }
461 void syncDefaultValueToCurrent()
override {
462 defaultValue_ = value_;
463 if constexpr (std::is_base_of_v<Configuration, T>) {
464 value_.syncDefaultValueToCurrent();
465 defaultValue_.syncDefaultValueToCurrent();
469 auto &annotation()
const {
return annotation_; }
474 Marshaller marshaller_;
475 Constrain constrain_;
476 mutable Annotation annotation_;
480 template <
typename T,
typename Annotation>
485 template <
typename Annotation>
500 template <
typename T,
typename Constrain = NoConstrain<T>,
501 typename Marshaller = DefaultMarshaller<T>,
502 typename Annotation = NoAnnotation>
506 template <
bool h
idden,
typename T>
509 template <
typename T,
typename Constrain,
typename Marshaller,
512 Option<T, Constrain, Marshaller, Annotation>> {
516 template <
typename T,
typename Constrain,
typename Marshaller,
519 Option<T, Constrain, Marshaller, Annotation>> {
532 using SubConfigOption::SubConfigOption;
533 bool skipDescription()
const override {
return true; }
535 using OptionType = HiddenSubConfigOption;
538 template <
bool h
idden,
typename T>
539 using ConditionalHidden =
544 #endif // _FCITX_CONFIG_OPTION_H_ Optional Constrain that applies the constrain only when the value is not std::nullopt.
A helper class provide writing ability to option value.
Option that will not shown in UI.
Default Constrain with no actual constrain.
Annotation to be used against String type to indicate this is a Font.
List Constrain that applies the constrain to all element.
void setValueByPath(const std::string &path, std::string value)
Set a value by path, creating intermediate nodes if needed.
A raw configuration tree that stores key-value pairs in a hierarchical structure. ...
For a list of sub config, the field that should be used for display.
std::shared_ptr< RawConfig > get(const std::string &path, bool create=false)
Get a sub-item by path.
String constrain that requires the value to be a valid regular expression.
bool isModifier() const
Check if the key is a modifier press.
An option that launches external tool.
An option that launches external tool.
Annotation to be used against String type, for those type of string that should shown as a combobox...
Helper template class to make easier to use type safe enum flags.
Default marshaller that write the config RawConfig.
Class to represent a key.
Represent a Configuration option.
Default Annotation with no options.
Integer type constrain with a lower and a upper bound.