From d782e4851c47aed0ba65d9a73f137c2b44e74e77 Mon Sep 17 00:00:00 2001 From: GenevensiS <66968533+G-e-n-e-v-e-n-s-i-S@users.noreply.github.com> Date: Sun, 19 Apr 2026 19:06:52 +0200 Subject: [PATCH] add `is_default` script function --- doc/function/index.txt | 1 + doc/function/is_default.txt | 10 ++++++++++ src/data/field.cpp | 4 ++++ src/data/field.hpp | 4 +++- src/data/field/choice.cpp | 7 ++++++- src/data/field/choice.hpp | 4 +++- src/data/field/color.cpp | 5 +++++ src/data/field/color.hpp | 4 +++- src/data/field/image.cpp | 4 ++++ src/data/field/image.hpp | 4 +++- src/data/field/information.cpp | 5 +++++ src/data/field/information.hpp | 4 +++- src/data/field/multiple_choice.cpp | 4 ++++ src/data/field/multiple_choice.hpp | 4 +++- src/data/field/package_choice.cpp | 6 ++++++ src/data/field/package_choice.hpp | 4 +++- src/data/field/symbol.cpp | 4 ++++ src/data/field/symbol.hpp | 4 +++- src/data/field/text.cpp | 5 +++++ src/data/field/text.hpp | 4 +++- src/render/value/image.cpp | 7 ++++--- src/script/functions/editor.cpp | 8 ++++++++ 22 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 doc/function/is_default.txt diff --git a/doc/function/index.txt b/doc/function/index.txt index d41e3a93..6664e6b9 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -78,6 +78,7 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:exclusive_choice]] Require that at most one of the given choices is selected. | [[fun:require_exclusive_choice]] Require that exactly one of the given choices is selected. | [[fun:remove_choice]] Remove the given choices from a multiple choice value. +| [[fun:is_default]] Check if a field is in its default state. ! Images <<< | [[fun:linear_blend]] Blend two images together using a linear gradient. diff --git a/doc/function/is_default.txt b/doc/function/is_default.txt new file mode 100644 index 00000000..75d61b6a --- /dev/null +++ b/doc/function/is_default.txt @@ -0,0 +1,10 @@ +Function: is_default + +--Usage-- +> is_default(some_field) + +Returns true if the field is in its default state, that is, if the user hasn't modified the value yet, false otherwise. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:field]] Field to test. diff --git a/src/data/field.cpp b/src/data/field.cpp index 077db053..b6657b03 100644 --- a/src/data/field.cpp +++ b/src/data/field.cpp @@ -305,6 +305,10 @@ bool Value::equals(const Value* that) { return this == that; } +bool Value::isDefault() { + return false; +} + bool Value::update(Context& ctx) { updateAge(); updateSortValue(ctx); diff --git a/src/data/field.hpp b/src/data/field.hpp index 364a0b43..b546e523 100644 --- a/src/data/field.hpp +++ b/src/data/field.hpp @@ -255,7 +255,9 @@ public: virtual ValueP clone() const = 0; /// Convert this value to a string for use in tables - virtual String toString() const = 0; + virtual String toString() const = 0; + /// Check if this value is in the default state + virtual bool isDefault(); /// Apply scripts to this value, return true if the value has changed virtual bool update(Context& ctx); /// This value has been updated by an action diff --git a/src/data/field/choice.cpp b/src/data/field/choice.cpp index 87a03403..0ba57244 100644 --- a/src/data/field/choice.cpp +++ b/src/data/field/choice.cpp @@ -317,7 +317,12 @@ ChoiceValue::ChoiceValue(const ChoiceFieldP& field, bool initial_first_choice) String ChoiceValue::toString() const { return value(); -} +} + +bool ChoiceValue::isDefault() { + return value.isDefault(); +} + bool ChoiceValue::update(Context& ctx) { bool change = field().default_script.invokeOnDefault(ctx, value) | field(). script.invokeOn(ctx, value); diff --git a/src/data/field/choice.hpp b/src/data/field/choice.hpp index b8386cd5..1d914618 100644 --- a/src/data/field/choice.hpp +++ b/src/data/field/choice.hpp @@ -199,7 +199,9 @@ public: DECLARE_VALUE_TYPE(Choice, Defaultable); ValueType value; /// The name of the selected choice - + + bool isDefault() override; + bool update(Context&) override; }; diff --git a/src/data/field/color.cpp b/src/data/field/color.cpp index 6b17c992..2062c63f 100644 --- a/src/data/field/color.cpp +++ b/src/data/field/color.cpp @@ -110,7 +110,12 @@ String ColorValue::toString() const { if (value() == c->color) return c->name; } return _(""); +} + +bool ColorValue::isDefault() { + return value.isDefault(); } + bool ColorValue::update(Context& ctx) { bool change = field().default_script.invokeOnDefault(ctx, value) | field(). script.invokeOn(ctx, value); diff --git a/src/data/field/color.hpp b/src/data/field/color.hpp index 5707d18d..e42a453d 100644 --- a/src/data/field/color.hpp +++ b/src/data/field/color.hpp @@ -77,7 +77,9 @@ public: DECLARE_VALUE_TYPE(Color, Defaultable); ValueType value; ///< The value - + + bool isDefault() override; + bool update(Context&) override; }; diff --git a/src/data/field/image.cpp b/src/data/field/image.cpp index 84a0b121..cd385b3b 100644 --- a/src/data/field/image.cpp +++ b/src/data/field/image.cpp @@ -39,6 +39,10 @@ String ImageValue::toString() const { return filename.empty() ? _("") : _(""); } +bool ImageValue::isDefault() { + return filename.empty(); +} + // custom reflection: convert to ScriptImageP for scripting void ImageValue::reflect(Reader& handler) { diff --git a/src/data/field/image.hpp b/src/data/field/image.hpp index e126000b..40b45de4 100644 --- a/src/data/field/image.hpp +++ b/src/data/field/image.hpp @@ -47,7 +47,9 @@ public: } ValueType filename; ///< Filename of the image (in the current package), or "" - Age last_update; ///< When was the image last changed? + Age last_update; ///< When was the image last changed? + + bool isDefault() override; }; // ----------------------------------------------------------------------------- : ImageStyle diff --git a/src/data/field/information.cpp b/src/data/field/information.cpp index 9014b9d3..0e2f9275 100644 --- a/src/data/field/information.cpp +++ b/src/data/field/information.cpp @@ -62,7 +62,12 @@ IMPLEMENT_REFLECTION(InfoStyle) { String InfoValue::toString() const { return value; +} + +bool InfoValue::isDefault() { + return true; } + bool InfoValue::update(Context& ctx) { if (value.empty()) value = field().caption.get(); bool change = field().script.invokeOn(ctx, value); diff --git a/src/data/field/information.hpp b/src/data/field/information.hpp index f54eedee..9dd111f9 100644 --- a/src/data/field/information.hpp +++ b/src/data/field/information.hpp @@ -60,7 +60,9 @@ public: DECLARE_VALUE_TYPE(Info, String); ValueType value; - + + bool isDefault() override; + bool update(Context&) override; }; diff --git a/src/data/field/multiple_choice.cpp b/src/data/field/multiple_choice.cpp index 53b4443c..7619b6b7 100644 --- a/src/data/field/multiple_choice.cpp +++ b/src/data/field/multiple_choice.cpp @@ -52,6 +52,10 @@ IMPLEMENT_REFLECTION_NAMELESS(MultipleChoiceValue) { REFLECT_BASE(ChoiceValue); } +bool MultipleChoiceValue::isDefault() { + return value.isDefault(); +} + bool MultipleChoiceValue::update(Context& ctx) { String old_value = value(); ctx.setVariable(_("last_change"), to_script(last_change)); diff --git a/src/data/field/multiple_choice.hpp b/src/data/field/multiple_choice.hpp index 1318eb59..7afb647c 100644 --- a/src/data/field/multiple_choice.hpp +++ b/src/data/field/multiple_choice.hpp @@ -63,7 +63,9 @@ public: /// Splits the value, stores the selected choices in the out parameter void get(vector& out) const; - + + bool isDefault() override; + bool update(Context&) override; private: diff --git a/src/data/field/package_choice.cpp b/src/data/field/package_choice.cpp index 8047b8bc..385c8c7f 100644 --- a/src/data/field/package_choice.cpp +++ b/src/data/field/package_choice.cpp @@ -62,6 +62,12 @@ PackagedP PackageChoiceValue::getPackage() const { else return package_manager.openAny(package_name, true); } +bool PackageChoiceValue::isDefault() { + PackageChoiceFieldP packageFieldP = boost::dynamic_pointer_cast(fieldP); + if (packageFieldP) return package_name == packageFieldP->initial; + return false; +} + bool PackageChoiceValue::update(Context& ctx) { bool change = field().script.invokeOn(ctx, package_name); Value::update(ctx); diff --git a/src/data/field/package_choice.hpp b/src/data/field/package_choice.hpp index e204a49f..006a6545 100644 --- a/src/data/field/package_choice.hpp +++ b/src/data/field/package_choice.hpp @@ -61,7 +61,9 @@ public: /// Get the package (if it is set), otherwise return nullptr PackagedP getPackage() const; - + + bool isDefault() override; + bool update(Context&) override; }; diff --git a/src/data/field/symbol.cpp b/src/data/field/symbol.cpp index 1a27fe5d..0ec5ddf7 100644 --- a/src/data/field/symbol.cpp +++ b/src/data/field/symbol.cpp @@ -51,6 +51,10 @@ String SymbolValue::toString() const { return filename.empty() ? _("") : _(""); } +bool SymbolValue::isDefault() { + return filename.empty(); +} + IMPLEMENT_REFLECTION_NO_GET_MEMBER(SymbolValue) { if (fieldP->save_value || !handler.isWriting) REFLECT_NAMELESS(filename); } diff --git a/src/data/field/symbol.hpp b/src/data/field/symbol.hpp index fb4871a4..8be7ba8f 100644 --- a/src/data/field/symbol.hpp +++ b/src/data/field/symbol.hpp @@ -69,6 +69,8 @@ public: DECLARE_VALUE_TYPE(Symbol, LocalFileName); ValueType filename; ///< Filename of the symbol (in the current package) - Age last_update; ///< When was the symbol last changed? + Age last_update; ///< When was the symbol last changed? + + bool isDefault() override; }; diff --git a/src/data/field/text.cpp b/src/data/field/text.cpp index bc75a2bc..92edf73d 100644 --- a/src/data/field/text.cpp +++ b/src/data/field/text.cpp @@ -176,7 +176,12 @@ IMPLEMENT_REFLECTION(TextStyle) { String TextValue::toString() const { return untag_hide_sep(value()); +} + +bool TextValue::isDefault() { + return value.isDefault(); } + bool TextValue::update(Context& ctx) { updateAge(); WITH_DYNAMIC_ARG(last_update_age, last_update.get()); diff --git a/src/data/field/text.hpp b/src/data/field/text.hpp index f54c343e..71b5f51e 100644 --- a/src/data/field/text.hpp +++ b/src/data/field/text.hpp @@ -112,7 +112,9 @@ public: ValueType value; ///< The text of this value Age last_update; ///< When was the text last changed? - + + bool isDefault() override; + bool update(Context&) override; }; diff --git a/src/render/value/image.cpp b/src/render/value/image.cpp index 98b5a7a5..069456c1 100644 --- a/src/render/value/image.cpp +++ b/src/render/value/image.cpp @@ -116,14 +116,15 @@ Bitmap ImageValueViewer::imagePlaceholder(const Rotation& rot, UInt w, UInt h, c } // Draw text if (editing) { - // only when in editor mode + // only when in editor mode + String label = _LABEL_("load image"); for (UInt size = 12 ; size > 2 ; --size) { dc.SetFont(wxFont(size, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - RealSize rs = dc.GetTextExtent(_LABEL_("load image")); + RealSize rs = dc.GetTextExtent(label); if (rs.width <= w - 10 && rs.height < h - 10) { // text fits RealPoint pos = align_in_rect(ALIGN_MIDDLE_CENTER, rs, rect); - dc.DrawText(_LABEL_("load image"), pos, Color(255,255,255), 2, Color(0,0,0), 3); // stroked + dc.DrawText(label, pos, Color(255,255,255), 2, Color(0,0,0), 3); // stroked break; } } diff --git a/src/script/functions/editor.cpp b/src/script/functions/editor.cpp index 46916a71..8d4b7e7b 100644 --- a/src/script/functions/editor.cpp +++ b/src/script/functions/editor.cpp @@ -187,6 +187,13 @@ SCRIPT_FUNCTION_DEPENDENCIES(combined_editor) { } } return dependency_dummy; +} + +// ----------------------------------------------------------------------------- : Values + +SCRIPT_FUNCTION(is_default) { + SCRIPT_PARAM_C(ValueP,input); + SCRIPT_RETURN(input->isDefault()); } // ----------------------------------------------------------------------------- : Choice values @@ -389,6 +396,7 @@ SCRIPT_FUNCTION(count_chosen) { void init_script_editor_functions(Context& ctx) { ctx.setVariable(_("forward_editor"), script_combined_editor); // compatability ctx.setVariable(_("combined_editor"), script_combined_editor); + ctx.setVariable(_("is_default"), script_is_default); ctx.setVariable(_("primary_choice"), script_primary_choice); ctx.setVariable(_("chosen"), script_chosen); ctx.setVariable(_("count_chosen"), script_count_chosen);