7 #ifndef _FCITX_CONFIG_OPTION_H_ 8 #define _FCITX_CONFIG_OPTION_H_ 15 #include <type_traits> 18 #include <fcitx-config/fcitxconfig_export.h> 19 #include <fcitx-config/marshallfunction.h> 20 #include <fcitx-config/option_details.h> 21 #include <fcitx-config/optiontypename.h> 22 #include <fcitx-config/rawconfig.h> 32 std::string description, std::string uri);
34 std::string typeString()
const override;
35 void reset()
override;
36 bool isDefault()
const override;
38 void marshall(
RawConfig &config)
const override;
39 bool unmarshall(
const RawConfig &config,
bool partial)
override;
40 std::unique_ptr<Configuration> subConfigSkeleton()
const override;
42 bool equalTo(
const OptionBase &other)
const override;
43 void copyFrom(
const OptionBase &other)
override;
45 bool skipDescription()
const override;
46 bool skipSave()
const override;
47 void dumpDescription(
RawConfig &config)
const override;
50 std::string externalUri_;
56 using ExternalOption::ExternalOption;
57 void dumpDescription(
RawConfig &config)
const override;
64 bool check(
const T & )
const {
return true; }
65 void dumpDescription(
RawConfig & )
const {}
70 bool skipDescription() {
return false; }
71 bool skipSave() {
return false; }
72 void dumpDescription(
RawConfig & )
const {}
79 bool skipDescription() {
return false; }
80 bool skipSave() {
return false; }
81 void dumpDescription(
RawConfig &config)
const {
82 config.setValueByPath(
"Tooltip", tooltip_);
92 : option_(std::move(option)) {}
94 bool skipDescription() {
return false; }
95 bool skipSave() {
return false; }
96 void dumpDescription(
RawConfig &config)
const {
97 config.setValueByPath(
"ListDisplayOption", option_);
108 bool skipDescription() {
return false; }
109 bool skipSave() {
return false; }
110 void dumpDescription(
RawConfig &config) {
111 config.setValueByPath(
"Font",
"True");
122 bool skipDescription() {
return false; }
123 bool skipSave() {
return false; }
124 void dumpDescription(
RawConfig &config)
const {
125 config.setValueByPath(
"IsEnum",
"True");
137 bool skipDescription() {
return true; }
138 bool skipSave() {
return false; }
139 void dumpDescription(
RawConfig & )
const {}
142 template <
typename Annotation>
144 using Annotation::Annotation;
145 bool skipDescription() {
return true; }
146 using Annotation::dumpDescription;
147 using Annotation::skipSave;
153 template <
typename SubConstrain>
155 ListConstrain(SubConstrain sub = SubConstrain()) : sub_(std::move(sub)) {}
157 using ElementType =
typename SubConstrain::Type;
158 using Type = std::vector<ElementType>;
159 bool check(
const Type &value) {
161 value.begin(), value.end(),
162 [
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_);
221 enum class KeyConstrainFlag {
223 AllowModifierOnly = (1 << 0),
225 AllowModifierLess = (1 << 1),
236 bool check(
const Key &key)
const {
237 if (!flags_.test(KeyConstrainFlag::AllowModifierLess) &&
242 if (!flags_.test(KeyConstrainFlag::AllowModifierOnly) &&
250 void dumpDescription(
RawConfig &config)
const {
251 if (flags_.test(KeyConstrainFlag::AllowModifierLess)) {
252 config[
"AllowModifierLess"] =
"True";
254 if (flags_.test(KeyConstrainFlag::AllowModifierOnly)) {
255 config[
"AllowModifierOnly"] =
"True";
264 template <
typename T>
268 void marshall(
RawConfig &config,
const T &value)
const {
269 return marshallOption(config, value);
271 bool unmarshall(T &value,
const RawConfig &config,
bool partial)
const {
272 return unmarshallOption(value, config, partial);
277 template <
typename OptionType>
280 using value_type =
typename OptionType::value_type;
283 : option_(option), value_(option ? option->value() : value_type()) {}
287 option_->setValue(std::move(value_));
292 : option_(other.option_), value_(std::move(other.value_)) {
293 other.option_ =
nullptr;
297 option_ = other.option_;
298 value_ = std::move(other.value_);
299 other.option_ =
nullptr;
302 value_type &operator*() {
return value_; }
303 value_type *operator->() {
return &value_; }
310 template <
typename Constrain,
typename Marshaller,
typename Annotation,
315 std::string description;
317 Constrain constrain{};
318 Marshaller marshaller{};
319 Annotation annotation{};
326 template <
typename T,
typename Constrain = NoConstrain<T>,
327 typename Marshaller = DefaultMarshaller<T>,
328 typename Annotation = NoAnnotation>
331 using value_type = T;
332 using constrain_type = Constrain;
337 const T &defaultValue = T(), Constrain constrain = Constrain(),
338 Marshaller marshaller = Marshaller(),
339 Annotation annotation = Annotation())
340 :
OptionBaseV3(parent, std::move(path), std::move(description)),
341 defaultValue_(defaultValue), value_(defaultValue),
342 marshaller_(std::move(marshaller)), constrain_(std::move(constrain)),
343 annotation_(std::move(annotation)) {
344 if (!constrain_.check(defaultValue_)) {
345 throw std::invalid_argument(
346 "defaultValue doesn't satisfy constrain");
351 :
Option(params.parent, std::move(params.path),
352 std::move(params.description), std::move(params.defaultValue),
353 std::move(params.constrain), std::move(params.marshaller),
354 std::move(params.annotation)) {}
358 void dumpDescription(
RawConfig &config)
const override {
359 OptionBase::dumpDescription(config);
360 if constexpr (not std::is_base_of_v<Configuration, T>) {
361 marshaller_.marshall(config[
"DefaultValue"], defaultValue_);
363 constrain_.dumpDescription(config);
364 annotation_.dumpDescription(config);
365 using ::fcitx::dumpDescriptionHelper;
366 dumpDescriptionHelper(
367 config,
static_cast<typename RemoveVector<T>::type *
>(
nullptr));
370 std::unique_ptr<Configuration> subConfigSkeleton()
const override {
371 if constexpr (std::is_base_of_v<Configuration, T>) {
372 auto skeleton = std::make_unique<T>(defaultValue_);
373 skeleton->syncDefaultValueToCurrent();
377 typename RemoveVector<T>::type>) {
378 return std::make_unique<typename RemoveVector<T>::type>();
384 bool isDefault()
const override {
return defaultValue_ == value_; }
385 void reset()
override { value_ = defaultValue_; }
387 const T &value()
const {
return value_; }
389 const T &defaultValue()
const {
return defaultValue_; }
391 const T &operator*()
const {
return value(); }
392 const T *operator->()
const {
return &value_; }
394 template <
typename U>
395 bool setValue(U &&value) {
396 if (!constrain_.check(value)) {
399 value_ = std::forward<U>(value);
403 template <
typename Dummy = int,
404 std::enable_if_t<!std::is_same<Constrain, NoConstrain<T>>::value,
410 template <
typename Dummy = int,
411 std::enable_if_t<std::is_same<Constrain, NoConstrain<T>>::value,
417 void marshall(
RawConfig &config)
const override {
418 return marshaller_.marshall(config, value_);
420 bool unmarshall(
const RawConfig &config,
bool partial)
override {
425 if (!marshaller_.unmarshall(tempValue, config, partial)) {
428 return setValue(tempValue);
431 bool equalTo(
const OptionBase &other)
const override {
432 auto otherP =
static_cast<const Option *
>(&other);
433 return value_ == otherP->value_;
436 void copyFrom(
const OptionBase &other)
override {
437 auto otherP =
static_cast<const Option *
>(&other);
438 value_ = otherP->value_;
441 bool skipDescription()
const override {
442 return annotation_.skipDescription();
445 bool skipSave()
const override {
return annotation_.skipSave(); }
447 void syncDefaultValueToCurrent()
override {
448 defaultValue_ = value_;
449 if constexpr (std::is_base_of_v<Configuration, T>) {
450 value_.syncDefaultValueToCurrent();
451 defaultValue_.syncDefaultValueToCurrent();
455 auto &annotation()
const {
return annotation_; }
460 Marshaller marshaller_;
461 Constrain constrain_;
462 mutable Annotation annotation_;
466 template <
typename T,
typename Annotation>
471 template <
typename Annotation>
486 template <
typename T,
typename Constrain = NoConstrain<T>,
487 typename Marshaller = DefaultMarshaller<T>,
488 typename Annotation = NoAnnotation>
492 template <
bool h
idden,
typename T>
495 template <
typename T,
typename Constrain,
typename Marshaller,
498 Option<T, Constrain, Marshaller, Annotation>> {
502 template <
typename T,
typename Constrain,
typename Marshaller,
505 Option<T, Constrain, Marshaller, Annotation>> {
518 using SubConfigOption::SubConfigOption;
519 bool skipDescription()
const override {
return true; }
521 using OptionType = HiddenSubConfigOption;
524 template <
bool h
idden,
typename T>
525 using ConditionalHidden =
530 #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.
For a list of sub config, the field that should be used for display.
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.