[
  {
    "path": ".clang-format",
    "content": "---\nIndentWidth:     4\nTabWidth:        4\nColumnLimit:     80\n\n---\nLanguage:        Cpp\nAccessModifierOffset: -4\nAlignAfterOpenBracket: false\nAlignConsecutiveAssignments: false\nAlignConsecutiveDeclarations: false\nAlignEscapedNewlines: DontAlign\nAlignOperands: false\nAlignTrailingComments: false\nAllowAllParametersOfDeclarationOnNextLine: true\nAllowShortBlocksOnASingleLine: false\nAllowShortCaseLabelsOnASingleLine: false\nAllowShortFunctionsOnASingleLine: Empty\nAllowShortIfStatementsOnASingleLine: false\nAllowShortLoopsOnASingleLine: false\nAlwaysBreakBeforeMultilineStrings: false\nAlwaysBreakTemplateDeclarations: true\nBinPackArguments: true\nBinPackParameters: true\nBraceWrapping:\n  AfterStruct: true\n  AfterClass: true\n  AfterControlStatement: true\n  AfterEnum: true\n  AfterFunction: true\n  AfterNamespace: true\n  AfterUnion: true\n  BeforeCatch: false\n  BeforeElse: false\n  IndentBraces: false\n  SplitEmptyFunction: true\n  SplitEmptyRecord: true\n  SplitEmptyNamespace: true\nBreakBeforeBinaryOperators: None\nBreakBeforeBraces: Custom\nBreakBeforeInheritanceComma: true\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializers: BeforeComma\nBreakStringLiterals: true\nCompactNamespaces: false\nConstructorInitializerIndentWidth: 4\nContinuationIndentWidth: 4\nCpp11BracedListStyle: false\nDerivePointerAlignment: false\nExperimentalAutoDetectBinPacking: false\nFixNamespaceComments: true\nForEachMacros: ['foreach']\nIncludeIsMainRegex: ''\nIndentCaseLabels: true\nIndentWrappedFunctionNames: false\nKeepEmptyLinesAtTheStartOfBlocks: false\nNamespaceIndentation: None\nPointerAlignment: Right\nReflowComments: false\nSortIncludes: false\nSortUsingDeclarations: false\nSpaceAfterCStyleCast: true\nSpaceAfterTemplateKeyword: true\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeParens: ControlStatements\nSpaceInEmptyParentheses: false\nSpacesInAngles: false\nSpacesInCStyleCastParentheses: false\nSpacesInContainerLiterals: true\nSpacesInParentheses: false\nSpacesInSquareBrackets: false\nStandard: Cpp11\nUseTab: Always\n\n\n"
  },
  {
    "path": ".gitignore",
    "content": "/tmp/\r\n/bin*/\r\nbuild*/\r\n/workdir/\r\n*.pro.user\r\n*.lexer.*\r\n*.parser.*\r\n*~\r\n*.directory\r\n*.autosave\r\n*Thumbs.db\r\n*.qm\r\n*.orig\r\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: cpp\ndist: trusty\n\ncompiler:\n  - gcc\n\nbranches:\n  only:\n    - master\n    - develop\n\nos:\n  - linux\n\nbefore_install:\n  - sudo add-apt-repository ppa:beineri/opt-qt593-trusty -y\n  - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y\n  - sudo apt-get update -q\n\ninstall:\n  - sudo apt-get install flex bison\n  - sudo apt-get install qt59base qt59script qt59tools\n  - source /opt/qt59/bin/qt59-env.sh\n  - sudo apt-get install -qq g++-4.8\n  - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90\n\nscript:\n    - qmake\n    - make\n    - ./bin-linux-gcc-x86_64/QtnPropertyTests\n"
  },
  {
    "path": "AUTHORS",
    "content": "Original author:\n\nAlexey Zhondin  <qtinuum.dev@gmail.com>\n\n\nModifications/Extensions by:\n\nAlexandra Cherdantseva <neluhus.vagus@gmail.com>\n"
  },
  {
    "path": "CHANGELOG",
    "content": "QtnProperty\n===========\n\nv2.0.3  23.12.2020\n    [FIX] Register QVariant property delegate\n\nv2.0.2  18.12.2020\n    [FIX] Don't break property view splitter with drag action\n\nv2.0.1  30.11.2020\n    [REFINE] Show splitter line and change mouse cursor only for splittable property delegates\n    [FIX] Correct stripping redundant digits after decimal point when converting floating-point value to locale string\n    [FIX] Fixed compilation with Qt 5.15\n\nv2.0.0  20.11.2020\n    [NEW] Multi-property set with QtnMultiProperty (Used in QObjectPropertyWidget if multiple objects selected)\n    [NEW] Delegate attributes for floating-point properties:\n        multiplier, precision\n    [NEW] Delegate attributes for numeric properties:\n        min, max, step, suffix\n    [NEW] Delegate attributes for string properties:\n        placeholder, multiline_edit\n    [NEW] Apply delegate attributes for sub-properties (see QPoint, QSize etc.)\n    [NEW] QtnDoubleSpinBox - trailing zeros removed (used in floating-point properties)\n    [NEW] QtnInt64SpinBox - used in uint and int64 properties\n    [NEW] QtnCompleterLineEdit - autocomplete popup view with input text highlighted (used in QtnPropertyDelegateQStringCallback)\n    [NEW] Property delegates for:\n        int64, uint64, QPointF, QSizeF, QRectF,\n        QVector3D, Button, QBrush, QPen, QVariant, QKeySequence\n    [NEW] Editing QVariant with CustomProperyEditorDialog and CustomPropertyWidget\n    [NEW] Ability to set custom property delegate factory for QtnPropertyView with delegateFactory()->setSuperFactory(factory)\n    [NEW] QtnPropertyDelegateMetaEnum - property delegate for registered enums (Register with QtnPropertyDelegateMetaEnum::Register, and use custom delegate factory)\n    [NEW] QtnPropertyStateResettable and Reset button\n    [NEW] QtnPropertyStateUnlockable and Lock/Unlock button\n    [NEW] Update delegate with QtnPropertyChangeReasonUpdateDelegate\n    [NEW] Support dark theme on MacOS\n    [FIX] QColor property delegate with circle shape draws valid color\n    [FIX] Update property view when changing QObject property values outside property editor\n    [FIX] SliderBox delegate works with huge value range\n"
  },
  {
    "path": "Demo/AB/PropertyABColor.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyABColor.h\"\n\nvoid QtnPropertyABColor::invokeClick()\n{\n\temit click(this);\n}\n\nvoid QtnPropertyABColor::setClickHandler(\n\tconst std::function<void(const QtnPropertyABColor *)> &clickHandler)\n{\n\tQObject::connect(this, &QtnPropertyABColor::click, clickHandler);\n}\n\nbool QtnPropertyMyColor::fromActualValue(ValueType actualValue, BaseValueTypeStore& baseValue) const\n{\n    baseValue = QColor::fromRgb(actualValue.red, actualValue.green, actualValue.blue);\n    return true;\n}\n\nbool QtnPropertyMyColor::toActualValue(ValueTypeStore& actualValue, BaseValueType baseValue) const\n{\n    actualValue.red = baseValue.red();\n    actualValue.green = baseValue.green();\n    actualValue.blue = baseValue.blue();\n    return true;\n}\n"
  },
  {
    "path": "Demo/AB/PropertyABColor.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_AB_COLOR_H\n#define PROPERTY_AB_COLOR_H\n\n#include \"QtnProperty/GUI/PropertyQColor.h\"\n\nclass QtnPropertyABColor : public QtnPropertyQColor\n{\n\tQ_OBJECT\n\tQtnPropertyABColor(const QtnPropertyABColor &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyABColor(QObject *parent)\n\t\t: QtnPropertyQColor(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyABColor, QtnPropertyQColor)\n\n\tvoid invokeClick();\n\tvoid setClickHandler(\n\t\tconst std::function<void(const QtnPropertyABColor *)> &clickHandler);\n\nQ_SIGNALS:\n\tvoid click(const QtnPropertyABColor *property);\n};\n\nstruct MyColor\n{\n    int red = 0;\n    int green = 0;\n    int blue = 0;\n};\n\nusing QtnPropertyMyColorBase = QtnSinglePropertyBaseAs<QtnPropertyQColorBase, MyColor>;\n\nclass QtnPropertyMyColor : public QtnSinglePropertyValue<QtnPropertyMyColorBase>\n{\n    Q_OBJECT\n\nprivate:\n    QtnPropertyMyColor(const QtnPropertyMyColor &other) Q_DECL_EQ_DELETE;\n\npublic:\n    explicit QtnPropertyMyColor(QObject *parent = nullptr)\n        : QtnSinglePropertyValue<QtnPropertyMyColorBase>(parent)\n    {\n    }\n\nprotected:\n    bool fromActualValue(ValueType actualValue, BaseValueTypeStore& baseValue) const override;\n    bool toActualValue(ValueTypeStore& actualValue, BaseValueType baseValue) const override;\n\n    P_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyMyColor, QtnPropertyMyColorBase)\n};\n\n#endif // PROPERTY_AB_COLOR_H\n"
  },
  {
    "path": "Demo/AB/PropertyDelegateABColor.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateABColor.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"PropertyABColor.h\"\n\nvoid regABColorDelegates()\n{\n\tQtnPropertyDelegateFactory::staticInstance().registerDelegateDefault(\n\t\t&QtnPropertyABColor::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateABColor, QtnPropertyABColor>,\n\t\t\"LineEditBttn\");\n}\n\nQtnPropertyDelegateABColor::QtnPropertyDelegateABColor(\n\tQtnPropertyABColor &owner)\n\t: QtnPropertyDelegateQColor(owner)\n\t, m_owner(owner)\n{\n}\n\nQWidget *QtnPropertyDelegateABColor::createValueEditorImpl(QWidget * /*parent*/,\n\tconst QRect & /*rect*/, QtnInplaceInfo * /*inplaceInfo*/)\n{\n\tm_owner.invokeClick();\n\treturn nullptr;\n}\n"
  },
  {
    "path": "Demo/AB/PropertyDelegateABColor.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_AB_COLOR_H\n#define PROPERTY_DELEGATE_AB_COLOR_H\n\n#include \"QtnProperty/Delegates/GUI/PropertyDelegateQColor.h\"\n\nclass QtnPropertyABColor;\n\nclass QtnPropertyDelegateABColor : public QtnPropertyDelegateQColor\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateABColor)\n\npublic:\n\tQtnPropertyDelegateABColor(QtnPropertyABColor &owner);\n\nprotected:\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\nprivate:\n\tQtnPropertyABColor &m_owner;\n};\n\n#endif // PROPERTY_DELEGATE_AB_COLOR_H\n"
  },
  {
    "path": "Demo/Demo.pef",
    "content": "#include \"QtnProperty/PropertyCore.h\"\n#include \"QtnProperty/PropertyGUI.h\"\n#include \"QtnProperty/PropertyInt64.h\"\n#include \"QtnProperty/PropertyUInt64.h\"\n#include \"AB/PropertyABColor.h\"\n#include \"Layer/PropertyLayer.h\"\n#include \"PenWidth/PropertyPenWidth.h\"\n#include \"Freq/PropertyFreq.h\"\n\n#include_cpp <QFileDialog>\n#include_cpp <QDebug>\n\nenum COLOR\n{\n    red (1, \"red\"),\n    blue (2, \"blue\"),\n    green (3, \"green\")\n}\n\nenum FLAGS\n{\n    opt1(1, \"Option1\"),\n    opt2(2, \"Option2\"),\n    opt3(4, \"Option3\")\n}\n\nproperty_set SamplePS\n{\n\tMyColor myColor\n\t{\n        description = \"Property to hold MyColor values.\";\n\t}\n\t\n    Bool BoolProperty\n    {\n        description = \"Property to hold boolean values.\";\n        value = false;\n    }\n\n    Button ButtonProperty\n    {\n        description = \"Start calculate a long operation.\";\n\n        clickHandler = [](const QtnPropertyButton* bttn) {\n            qDebug() << Q_FUNC_INFO << \"Button has clicked: \" << bttn;\n        };\n\n        delegate { title = \"Click me\"; }\n    }\n\n    Button ButtonLinkProperty\n    {\n        clickHandler = [](const QtnPropertyButton* bttn) {\n            qDebug() << Q_FUNC_INFO << \"Link has clicked: \" << bttn;\n        };\n\n        delegate Link { title = \"Click on me\"; }\n    }\n\n    ABColor RGBColor\n    {\n        description = \"ABColor property with RGB components\";\n        value = QColor(123, 150, 10);\n\n        clickHandler = [this](const QtnPropertyABColor* color) {\n            qDebug() << Q_FUNC_INFO << \"Color has clicked: \" << color;\n            RGBColor = QColor::fromRgb(qrand()%255, qrand()%255, qrand()%255);\n        };\n\n        delegate { rgbSubItems = true; }\n    }\n\n    QColor ColorSolidDelegate\n    {\n        description = \"QColor property with Solid delegate\";\n        value = QColor(13, 150, 10);\n\n        delegate Solid;\n    }\n\n    Float FloatPropertySliderBox\n    {\n        displayName = \"Float Property Slider Box\";\n        description = \"Property to hold float values in range [0, 10].\";\n        value = 1.f;\n        minValue = 0;\n        maxValue = 10.f;\n        stepValue = 0.1f;\n\n        delegate SliderBox\n        {\n            fillColor = QColor::fromRgb(170, 170, 255);\n            drawBorder = false;\n        }\n    }\n\n    Float FloatPercent\n    {\n    \tdescription = \"Property to hold float values in range [0-1] visible as [0%-100%].\";\n    \tvalue = 0.5f;\n    \tminValue = 0.f;\n    \tmaxValue = 1.f;\n\n    \tdelegate\n    \t{\n    \t\tmultiplier = 100.0;\n    \t\tsuffix = \"%\";\n    \t}\n    }\n\n    Double DoublePercent\n    {\n    \tdescription = \"Property to hold double values in range [0-1] visible as [0%-100%].\";\n    \tvalue = 0.5;\n    \tminValue = 0.0;\n    \tmaxValue = 1.0;\n\n    \tdelegate\n    \t{\n    \t\tmultiplier = 100.0;\n    \t\tprecision = 10;\n    \t\tsuffix = \"%\";\n    \t}\n    }\n\n    Float FloatIntRangeSliderBox\n    {\n        description = \"Property to hold float values in full range.\";\n        value = 111.f;\n        minValue = -float(1 << std::numeric_limits<float>::digits);\n        maxValue = float(1 << std::numeric_limits<float>::digits);\n\n        delegate SliderBox\n        {\n            fillColor = QColor::fromRgb(170, 170, 255);\n            drawBorder = false;\n        }\n    }\n\n    Double DoubleFullRangeSliderBox\n    {\n        description = \"Property to hold double values in full range.\";\n        value = 1111.0;\n        minValue = -double(1LL << std::numeric_limits<double>::digits);\n        maxValue = double(1LL << std::numeric_limits<double>::digits);\n\n        delegate SliderBox\n        {\n            fillColor = QColor::fromRgb(170, 170, 255);\n            drawBorder = false;\n        }\n    }\n\n    Double DoubleProperty\n    {\n        description = \"Property to hold double values in range [10, 20].\";\n        value = 12.3;\n        minValue = 10;\n        maxValue = 20;\n        stepValue = 0.5;\n    }\n\n    Float FloatProperty\n    {\n        description = \"Property to hold float values in range [-10, 0].\";\n        value = -3.5;\n        minValue = -10;\n        maxValue = 0;\n        stepValue = 0.5;\n    }\n\n    Int IntProperty\n    {\n        description = \"Property to hold integer values with changing step 15.\";\n        value = 10;\n        stepValue = 15;\n    }\n\n    Int IntPropertyComboBox\n    {\n        description = \"Property to hold integer values with changing step 15.\";\n        value = 10;\n        stepValue = 15;\n        delegate IntList\n        {\n            values = QVariant::fromValue(QList<int>() << 10 << 12 << 15);\n        }\n    }\n\n    UInt UIntProperty\n    {\n        description = \"Property to hold unsigned integer values in range [100, 200].\";\n        value = 100;\n        minValue = 100;\n        maxValue = 200;\n    }\n\n    Int64 Int64Property\n    {\n    \tdescription = \"Property to hold signed integer 64-bit value\";\n    \tvalue = -(1LL << 35);\n    \tdelegate\n    \t{\n    \t\tstep = 100000;\n    \t}\n    }\n\n    UInt64 UInt64Property\n    {\n    \tdescription = \"Property to hold signed integer 64-bit value\";\n    \tvalue = 1ULL << 63;\n    }\n\n    Int64 Int64SliderBox\n    {\n    \tdescription = \"Property to hold signed integer 64-bit value with slider box\";\n    \tvalue = -(1LL << 34);\n    \tdelegate SliderBox\n    \t{\n    \t}\n    }\n\n    UInt64 UInt64SliderBox\n    {\n    \tdescription = \"Property to hold unsigned integer 64-bit value with slider box\";\n    \tvalue = 1ULL << 58;\n    \tdelegate SliderBox\n    \t{\n    \t}\n    }\n\n    Enum EnumProperty\n    {\n        description = \"Property to hold enum value (color).\";\n        enumInfo = &COLOR::info();\n        value = COLOR::red;\n    }\n\n    EnumFlags EnumFlagsProperty\n    {\n        description = \"Property to hold combination of enum values (options).\";\n        enumInfo = &FLAGS::info();\n        value = FLAGS::opt2;\n    }\n\n    QString QStringValue\n    {\n        description = \"Property to hold QString value.\";\n        value = \"Hello world!\";\n    }\n\n    Bool EnableSubPropertySet\n    {\n        description = \"Enable/Disable Sub-PropertySet.\";\n        value = false;\n\n        slot propertyDidChange\n        {\n            SubPropertySet.switchState(QtnPropertyStateImmutable, !EnableSubPropertySet);\n        }\n    }\n\n    property_set SubPropertySetType SubPropertySet\n    {\n        description = \"This property set is part of the root property set.\";\n        state = QtnPropertyStateImmutable;\n\n        Bool SwitchProperty\n        {\n            description = \"Boolean property with customized True/False values.\";\n            value = true;\n\n            delegate ComboBox\n            {\n                labelTrue = \"On\";\n                labelFalse = \"Off\";\n            }\n        }\n\n        QStringCallback ReadOnlyString\n        {\n            description = \"This property is callback and read-only.\";\n            state = QtnPropertyStateImmutable;\n            callbackValueGet = [this] ()->QString {\n                if (SwitchProperty)\n                    return \"Switch is on\";\n                else\n                    return \"Switch is off\";\n            };\n        }\n\n        QString FileNameProperty\n        {\n            description = \"QString property tuned to handle file names.\";\n            value = \"~/test_file.txt\";\n            delegate File\n            {\n                invalidColor = QColor(Qt::red);\n                acceptMode = QFileDialog::AcceptSave;\n                nameFilters = QStringList() << \"Text files (*.txt)\" << \"All files (*)\";\n            }\n        }\n\n        QString FolderNameProperty\n        {\n            description = \"QString property tuned to handle folder names.\";\n            value = \"/var\";\n            delegate File\n            {\n                invalidColor = QColor(Qt::blue);\n                fileMode = QFileDialog::DirectoryOnly;\n            }\n        }\n\n        QString StringFromList\n        {\n            description = \"QString property with list of acepted values (one, two, three, four).\";\n            value = \"two\";\n            delegate ComboBox\n            {\n                items = QStringList() << \"one\" << \"two\" << \"three\" << \"four\";\n            }\n        }\n\n        QColor CircleShapeColor\n        {\n            description = \"QColor property with delegate tuned to draw circle\";\n            value = QColor(255, 100, 100);\n            delegate { shape = QtnColorDelegateShapeCircle; }\n        }\n    }\n\n    QPoint QPointProperty\n    {\n        description = \"Property to hold QPoint value.\";\n        value = QPoint(-10, 10);\n    }\n\n    QSize QSizeProperty\n    {\n        description = \"Property to hold QSize value.\";\n        value = QSize(100, 200);\n    }\n\n    QRect QRectProperty\n    {\n        description = \"Property to hold QRect value.\";\n        value = QRect(10, 10, 200, 200);\n    }\n\n    QPointF QPointFProperty\n    {\n        description = \"Property to hold QPointF value.\";\n        value = QPointF(-10.5, 10.2);\n    }\n\n    QSizeF QSizeFProperty\n    {\n        description = \"Property to hold QSizeF value.\";\n        value = QSizeF(100.0, 200.1);\n    }\n\n    QRectF QRectFProperty\n    {\n        description = \"Property to hold QRectF value.\";\n        value = QRectF(10.23, 10.4, 200.2, 200.6);\n    }\n\n    QVector3D QVector3DProperty\n    {\n    \tdescription = \"Property to hold QVector3D value.\";\n    \tvalue = QVector3D(5, 6, 7);\n    \tdelegate {\n    \t\tmultiplier = 100.0 / 255.0;\n    \t\tmin = 0;\n    \t\tmax = 255;\n    \t\tprecision = 5;\n    \t\tsuffix = \"%\";\n    \t\tz = QVariantMap({\n    \t\t\t{ QString(\"name\"), QString(\"SliderBox\")},\n    \t\t\t{ QString(\"precision\"), 3 },\n    \t\t});\n    \t}\n    }\n\n    QColor QColorProperty\n    {\n        description = \"Property to hold QColor value.\";\n        value = Qt::blue;\n        slot propertyDidChange\n        {\n            qDebug() << Q_FUNC_INFO << \"Property has changed: \" << &QColorProperty;\n        }\n    }\n\n    QFont QFontProperty\n    {\n        description = \"Property to hold QFont value.\";\n        value = QFont(\"Sans Serif\", 14);\n    }\n\n        Freq FreqProperty\n    {\n        description = \"Property to hold frequency values.\";\n        value = 15;\n        unit = FreqUnit::KHz;\n    }\n\n    Layer LayerProperty\n    {\n        description = \"Property to hold layer.\";\n        value = 0;\n    }\n\n\tQBrushStyle BrushStyleProperty\n\t{\n        description = \"Property to hold QBrushStyle enum.\";\n        value = Qt::HorPattern;\n\t}\n\n\tPenWidth PenWidthProperty\n\t{\n        description = \"Property to hold PenWidth enum.\";\n        value = PenWidth::Middle;\n\t}\n\n    QPenStyle PenStyleProperty\n    {\n        description = \"Property to hold pen style values.\";\n        value = Qt::DashLine;\n    }\n\n    QPen PenProperty\n    {\n        description = \"Property to hold QPen values.\";\n        delegate\n        {\n            editColor = true;\n            editStyle = true;\n            editWidth = true;\n        }\n    }\n\n\tQString QStringCallbackProperty\n\t{\n        description = \"Property to hold QString values with candidates.\";\n\t}\n\n    extern property_set SubPropertySetType SubPropertySet2\n    {\n        state = QtnPropertyStateCollapsed;\n    }\n}\n"
  },
  {
    "path": "Demo/Demo.peg.cpp",
    "content": "#include \"Demo.peg.h\"\n\n#include <QFileDialog>\n#include <QDebug>\nstatic QtnEnumInfo& create_COLOR_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(COLOR::red, \"red\", \"red\"));\n    staticValues.append(QtnEnumValueInfo(COLOR::blue, \"blue\", \"blue\"));\n    staticValues.append(QtnEnumValueInfo(COLOR::green, \"green\", \"green\"));\n    \n    static QtnEnumInfo enumInfo(\"COLOR\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& COLOR::info()\n{\n    static QtnEnumInfo& enumInfo = create_COLOR_info();\n    return enumInfo;\n}\nstatic QtnEnumInfo& create_FLAGS_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(FLAGS::opt1, \"opt1\", \"Option1\"));\n    staticValues.append(QtnEnumValueInfo(FLAGS::opt2, \"opt2\", \"Option2\"));\n    staticValues.append(QtnEnumValueInfo(FLAGS::opt3, \"opt3\", \"Option3\"));\n    \n    static QtnEnumInfo enumInfo(\"FLAGS\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& FLAGS::info()\n{\n    static QtnEnumInfo& enumInfo = create_FLAGS_info();\n    return enumInfo;\n}\n\nQtnPropertySetSubPropertySetType::QtnPropertySetSubPropertySetType(QObject* parent)\n    : QtnPropertySet(parent)\n    , SwitchProperty(*qtnCreateProperty<QtnPropertyBool>(this))\n    , ReadOnlyString(*qtnCreateProperty<QtnPropertyQStringCallback>(this))\n    , FileNameProperty(*qtnCreateProperty<QtnPropertyQString>(this))\n    , FolderNameProperty(*qtnCreateProperty<QtnPropertyQString>(this))\n    , StringFromList(*qtnCreateProperty<QtnPropertyQString>(this))\n    , CircleShapeColor(*qtnCreateProperty<QtnPropertyQColor>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetSubPropertySetType::~QtnPropertySetSubPropertySetType()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetSubPropertySetType& QtnPropertySetSubPropertySetType::operator=(const QtnPropertySetSubPropertySetType& other)\n{\n    Q_UNUSED(other);\n\n    SwitchProperty = other.SwitchProperty;\n    ReadOnlyString = other.ReadOnlyString;\n    FileNameProperty = other.FileNameProperty;\n    FolderNameProperty = other.FolderNameProperty;\n    StringFromList = other.StringFromList;\n    CircleShapeColor = other.CircleShapeColor;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetSubPropertySetType::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetSubPropertySetType(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetSubPropertySetType::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetSubPropertySetType* p = new QtnPropertySetSubPropertySetType(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetSubPropertySetType::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetSubPropertySetType*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->SwitchProperty.state() & ignoreMask))\n    {\n        SwitchProperty = theCopyFrom->SwitchProperty;\n    }\n\n    if (!(theCopyFrom->ReadOnlyString.state() & ignoreMask))\n    {\n        ReadOnlyString = theCopyFrom->ReadOnlyString;\n    }\n\n    if (!(theCopyFrom->FileNameProperty.state() & ignoreMask))\n    {\n        FileNameProperty = theCopyFrom->FileNameProperty;\n    }\n\n    if (!(theCopyFrom->FolderNameProperty.state() & ignoreMask))\n    {\n        FolderNameProperty = theCopyFrom->FolderNameProperty;\n    }\n\n    if (!(theCopyFrom->StringFromList.state() & ignoreMask))\n    {\n        StringFromList = theCopyFrom->StringFromList;\n    }\n\n    if (!(theCopyFrom->CircleShapeColor.state() & ignoreMask))\n    {\n        CircleShapeColor = theCopyFrom->CircleShapeColor;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetSubPropertySetType::init()\n{\n    static QString SubPropertySet_name = QStringLiteral(\"SubPropertySet\");\n    setName(SubPropertySet_name);\n    static QString description = \"This property set is part of the root property set.\";\n    setDescription(description);\n    setState(QtnPropertyStateImmutable);\n    \n    // start children initialization\n    static QString SwitchProperty_name = QStringLiteral(\"SwitchProperty\");\n    SwitchProperty.setName(SwitchProperty_name);\n    static QString SwitchProperty_description = \"Boolean property with customized True/False values.\";\n    SwitchProperty.setDescription(SwitchProperty_description);\n    SwitchProperty.setValue(true);\n    static QString ReadOnlyString_name = QStringLiteral(\"ReadOnlyString\");\n    ReadOnlyString.setName(ReadOnlyString_name);\n    ReadOnlyString.setCallbackValueGet([this] ()->QString {\n                if (SwitchProperty)\n                    return \"Switch is on\";\n                else\n                    return \"Switch is off\";\n            });\n    static QString ReadOnlyString_description = \"This property is callback and read-only.\";\n    ReadOnlyString.setDescription(ReadOnlyString_description);\n    ReadOnlyString.setState(QtnPropertyStateImmutable);\n    static QString FileNameProperty_name = QStringLiteral(\"FileNameProperty\");\n    FileNameProperty.setName(FileNameProperty_name);\n    static QString FileNameProperty_description = \"QString property tuned to handle file names.\";\n    FileNameProperty.setDescription(FileNameProperty_description);\n    FileNameProperty.setValue(\"~/test_file.txt\");\n    static QString FolderNameProperty_name = QStringLiteral(\"FolderNameProperty\");\n    FolderNameProperty.setName(FolderNameProperty_name);\n    static QString FolderNameProperty_description = \"QString property tuned to handle folder names.\";\n    FolderNameProperty.setDescription(FolderNameProperty_description);\n    FolderNameProperty.setValue(\"/var\");\n    static QString StringFromList_name = QStringLiteral(\"StringFromList\");\n    StringFromList.setName(StringFromList_name);\n    static QString StringFromList_description = \"QString property with list of acepted values (one, two, three, four).\";\n    StringFromList.setDescription(StringFromList_description);\n    StringFromList.setValue(\"two\");\n    static QString CircleShapeColor_name = QStringLiteral(\"CircleShapeColor\");\n    CircleShapeColor.setName(CircleShapeColor_name);\n    static QString CircleShapeColor_description = \"QColor property with delegate tuned to draw circle\";\n    CircleShapeColor.setDescription(CircleShapeColor_description);\n    CircleShapeColor.setValue(QColor(255, 100, 100));\n    // end children initialization\n}\n\nvoid QtnPropertySetSubPropertySetType::connectSlots()\n{\n}\n\nvoid QtnPropertySetSubPropertySetType::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetSubPropertySetType::connectDelegates()\n{\n    SwitchProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"ComboBox\";\n        info.attributes[\"labelFalse\"] = \"Off\";\n        info.attributes[\"labelTrue\"] = \"On\";\n        return info;\n    });\n    FileNameProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"File\";\n        info.attributes[\"acceptMode\"] = QFileDialog::AcceptSave;\n        info.attributes[\"invalidColor\"] = QColor(Qt::red);\n        info.attributes[\"nameFilters\"] = QStringList() << \"Text files (*.txt)\" << \"All files (*)\";\n        return info;\n    });\n    FolderNameProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"File\";\n        info.attributes[\"fileMode\"] = QFileDialog::DirectoryOnly;\n        info.attributes[\"invalidColor\"] = QColor(Qt::blue);\n        return info;\n    });\n    StringFromList.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"ComboBox\";\n        info.attributes[\"items\"] = QStringList() << \"one\" << \"two\" << \"three\" << \"four\";\n        return info;\n    });\n    CircleShapeColor.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"shape\"] = QtnColorDelegateShapeCircle;\n        return info;\n    });\n}\n\nQtnPropertySetSamplePS::QtnPropertySetSamplePS(QObject* parent)\n    : QtnPropertySet(parent)\n    , myColor(*qtnCreateProperty<QtnPropertyMyColor>(this))\n    , BoolProperty(*qtnCreateProperty<QtnPropertyBool>(this))\n    , ButtonProperty(*qtnCreateProperty<QtnPropertyButton>(this))\n    , ButtonLinkProperty(*qtnCreateProperty<QtnPropertyButton>(this))\n    , RGBColor(*qtnCreateProperty<QtnPropertyABColor>(this))\n    , ColorSolidDelegate(*qtnCreateProperty<QtnPropertyQColor>(this))\n    , FloatPropertySliderBox(*qtnCreateProperty<QtnPropertyFloat>(this))\n    , FloatPercent(*qtnCreateProperty<QtnPropertyFloat>(this))\n    , DoublePercent(*qtnCreateProperty<QtnPropertyDouble>(this))\n    , FloatIntRangeSliderBox(*qtnCreateProperty<QtnPropertyFloat>(this))\n    , DoubleFullRangeSliderBox(*qtnCreateProperty<QtnPropertyDouble>(this))\n    , DoubleProperty(*qtnCreateProperty<QtnPropertyDouble>(this))\n    , FloatProperty(*qtnCreateProperty<QtnPropertyFloat>(this))\n    , IntProperty(*qtnCreateProperty<QtnPropertyInt>(this))\n    , IntPropertyComboBox(*qtnCreateProperty<QtnPropertyInt>(this))\n    , UIntProperty(*qtnCreateProperty<QtnPropertyUInt>(this))\n    , Int64Property(*qtnCreateProperty<QtnPropertyInt64>(this))\n    , UInt64Property(*qtnCreateProperty<QtnPropertyUInt64>(this))\n    , Int64SliderBox(*qtnCreateProperty<QtnPropertyInt64>(this))\n    , UInt64SliderBox(*qtnCreateProperty<QtnPropertyUInt64>(this))\n    , EnumProperty(*qtnCreateProperty<QtnPropertyEnum>(this))\n    , EnumFlagsProperty(*qtnCreateProperty<QtnPropertyEnumFlags>(this))\n    , QStringValue(*qtnCreateProperty<QtnPropertyQString>(this))\n    , EnableSubPropertySet(*qtnCreateProperty<QtnPropertyBool>(this))\n    , SubPropertySet(*qtnCreateProperty<QtnPropertySetSubPropertySetType>(this))\n    , QPointProperty(*qtnCreateProperty<QtnPropertyQPoint>(this))\n    , QSizeProperty(*qtnCreateProperty<QtnPropertyQSize>(this))\n    , QRectProperty(*qtnCreateProperty<QtnPropertyQRect>(this))\n    , QPointFProperty(*qtnCreateProperty<QtnPropertyQPointF>(this))\n    , QSizeFProperty(*qtnCreateProperty<QtnPropertyQSizeF>(this))\n    , QRectFProperty(*qtnCreateProperty<QtnPropertyQRectF>(this))\n    , QVector3DProperty(*qtnCreateProperty<QtnPropertyQVector3D>(this))\n    , QColorProperty(*qtnCreateProperty<QtnPropertyQColor>(this))\n    , QFontProperty(*qtnCreateProperty<QtnPropertyQFont>(this))\n    , FreqProperty(*qtnCreateProperty<QtnPropertyFreq>(this))\n    , LayerProperty(*qtnCreateProperty<QtnPropertyLayer>(this))\n    , BrushStyleProperty(*qtnCreateProperty<QtnPropertyQBrushStyle>(this))\n    , PenWidthProperty(*qtnCreateProperty<QtnPropertyPenWidth>(this))\n    , PenStyleProperty(*qtnCreateProperty<QtnPropertyQPenStyle>(this))\n    , PenProperty(*qtnCreateProperty<QtnPropertyQPen>(this))\n    , QStringCallbackProperty(*qtnCreateProperty<QtnPropertyQString>(this))\n    , SubPropertySet2(*qtnCreateProperty<QtnPropertySetSubPropertySetType>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetSamplePS::~QtnPropertySetSamplePS()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetSamplePS& QtnPropertySetSamplePS::operator=(const QtnPropertySetSamplePS& other)\n{\n    Q_UNUSED(other);\n\n    myColor = other.myColor;\n    BoolProperty = other.BoolProperty;\n    ButtonProperty = other.ButtonProperty;\n    ButtonLinkProperty = other.ButtonLinkProperty;\n    RGBColor = other.RGBColor;\n    ColorSolidDelegate = other.ColorSolidDelegate;\n    FloatPropertySliderBox = other.FloatPropertySliderBox;\n    FloatPercent = other.FloatPercent;\n    DoublePercent = other.DoublePercent;\n    FloatIntRangeSliderBox = other.FloatIntRangeSliderBox;\n    DoubleFullRangeSliderBox = other.DoubleFullRangeSliderBox;\n    DoubleProperty = other.DoubleProperty;\n    FloatProperty = other.FloatProperty;\n    IntProperty = other.IntProperty;\n    IntPropertyComboBox = other.IntPropertyComboBox;\n    UIntProperty = other.UIntProperty;\n    Int64Property = other.Int64Property;\n    UInt64Property = other.UInt64Property;\n    Int64SliderBox = other.Int64SliderBox;\n    UInt64SliderBox = other.UInt64SliderBox;\n    EnumProperty = other.EnumProperty;\n    EnumFlagsProperty = other.EnumFlagsProperty;\n    QStringValue = other.QStringValue;\n    EnableSubPropertySet = other.EnableSubPropertySet;\n    SubPropertySet = other.SubPropertySet;\n    QPointProperty = other.QPointProperty;\n    QSizeProperty = other.QSizeProperty;\n    QRectProperty = other.QRectProperty;\n    QPointFProperty = other.QPointFProperty;\n    QSizeFProperty = other.QSizeFProperty;\n    QRectFProperty = other.QRectFProperty;\n    QVector3DProperty = other.QVector3DProperty;\n    QColorProperty = other.QColorProperty;\n    QFontProperty = other.QFontProperty;\n    FreqProperty = other.FreqProperty;\n    LayerProperty = other.LayerProperty;\n    BrushStyleProperty = other.BrushStyleProperty;\n    PenWidthProperty = other.PenWidthProperty;\n    PenStyleProperty = other.PenStyleProperty;\n    PenProperty = other.PenProperty;\n    QStringCallbackProperty = other.QStringCallbackProperty;\n    SubPropertySet2 = other.SubPropertySet2;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetSamplePS::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetSamplePS(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetSamplePS::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetSamplePS* p = new QtnPropertySetSamplePS(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetSamplePS::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetSamplePS*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->myColor.state() & ignoreMask))\n    {\n        myColor = theCopyFrom->myColor;\n    }\n\n    if (!(theCopyFrom->BoolProperty.state() & ignoreMask))\n    {\n        BoolProperty = theCopyFrom->BoolProperty;\n    }\n\n    if (!(theCopyFrom->ButtonProperty.state() & ignoreMask))\n    {\n        ButtonProperty = theCopyFrom->ButtonProperty;\n    }\n\n    if (!(theCopyFrom->ButtonLinkProperty.state() & ignoreMask))\n    {\n        ButtonLinkProperty = theCopyFrom->ButtonLinkProperty;\n    }\n\n    if (!(theCopyFrom->RGBColor.state() & ignoreMask))\n    {\n        RGBColor = theCopyFrom->RGBColor;\n    }\n\n    if (!(theCopyFrom->ColorSolidDelegate.state() & ignoreMask))\n    {\n        ColorSolidDelegate = theCopyFrom->ColorSolidDelegate;\n    }\n\n    if (!(theCopyFrom->FloatPropertySliderBox.state() & ignoreMask))\n    {\n        FloatPropertySliderBox = theCopyFrom->FloatPropertySliderBox;\n    }\n\n    if (!(theCopyFrom->FloatPercent.state() & ignoreMask))\n    {\n        FloatPercent = theCopyFrom->FloatPercent;\n    }\n\n    if (!(theCopyFrom->DoublePercent.state() & ignoreMask))\n    {\n        DoublePercent = theCopyFrom->DoublePercent;\n    }\n\n    if (!(theCopyFrom->FloatIntRangeSliderBox.state() & ignoreMask))\n    {\n        FloatIntRangeSliderBox = theCopyFrom->FloatIntRangeSliderBox;\n    }\n\n    if (!(theCopyFrom->DoubleFullRangeSliderBox.state() & ignoreMask))\n    {\n        DoubleFullRangeSliderBox = theCopyFrom->DoubleFullRangeSliderBox;\n    }\n\n    if (!(theCopyFrom->DoubleProperty.state() & ignoreMask))\n    {\n        DoubleProperty = theCopyFrom->DoubleProperty;\n    }\n\n    if (!(theCopyFrom->FloatProperty.state() & ignoreMask))\n    {\n        FloatProperty = theCopyFrom->FloatProperty;\n    }\n\n    if (!(theCopyFrom->IntProperty.state() & ignoreMask))\n    {\n        IntProperty = theCopyFrom->IntProperty;\n    }\n\n    if (!(theCopyFrom->IntPropertyComboBox.state() & ignoreMask))\n    {\n        IntPropertyComboBox = theCopyFrom->IntPropertyComboBox;\n    }\n\n    if (!(theCopyFrom->UIntProperty.state() & ignoreMask))\n    {\n        UIntProperty = theCopyFrom->UIntProperty;\n    }\n\n    if (!(theCopyFrom->Int64Property.state() & ignoreMask))\n    {\n        Int64Property = theCopyFrom->Int64Property;\n    }\n\n    if (!(theCopyFrom->UInt64Property.state() & ignoreMask))\n    {\n        UInt64Property = theCopyFrom->UInt64Property;\n    }\n\n    if (!(theCopyFrom->Int64SliderBox.state() & ignoreMask))\n    {\n        Int64SliderBox = theCopyFrom->Int64SliderBox;\n    }\n\n    if (!(theCopyFrom->UInt64SliderBox.state() & ignoreMask))\n    {\n        UInt64SliderBox = theCopyFrom->UInt64SliderBox;\n    }\n\n    if (!(theCopyFrom->EnumProperty.state() & ignoreMask))\n    {\n        EnumProperty = theCopyFrom->EnumProperty;\n    }\n\n    if (!(theCopyFrom->EnumFlagsProperty.state() & ignoreMask))\n    {\n        EnumFlagsProperty = theCopyFrom->EnumFlagsProperty;\n    }\n\n    if (!(theCopyFrom->QStringValue.state() & ignoreMask))\n    {\n        QStringValue = theCopyFrom->QStringValue;\n    }\n\n    if (!(theCopyFrom->EnableSubPropertySet.state() & ignoreMask))\n    {\n        EnableSubPropertySet = theCopyFrom->EnableSubPropertySet;\n    }\n\n    SubPropertySet.copyValues(&theCopyFrom->SubPropertySet, ignoreMask);\n\n    if (!(theCopyFrom->QPointProperty.state() & ignoreMask))\n    {\n        QPointProperty = theCopyFrom->QPointProperty;\n    }\n\n    if (!(theCopyFrom->QSizeProperty.state() & ignoreMask))\n    {\n        QSizeProperty = theCopyFrom->QSizeProperty;\n    }\n\n    if (!(theCopyFrom->QRectProperty.state() & ignoreMask))\n    {\n        QRectProperty = theCopyFrom->QRectProperty;\n    }\n\n    if (!(theCopyFrom->QPointFProperty.state() & ignoreMask))\n    {\n        QPointFProperty = theCopyFrom->QPointFProperty;\n    }\n\n    if (!(theCopyFrom->QSizeFProperty.state() & ignoreMask))\n    {\n        QSizeFProperty = theCopyFrom->QSizeFProperty;\n    }\n\n    if (!(theCopyFrom->QRectFProperty.state() & ignoreMask))\n    {\n        QRectFProperty = theCopyFrom->QRectFProperty;\n    }\n\n    if (!(theCopyFrom->QVector3DProperty.state() & ignoreMask))\n    {\n        QVector3DProperty = theCopyFrom->QVector3DProperty;\n    }\n\n    if (!(theCopyFrom->QColorProperty.state() & ignoreMask))\n    {\n        QColorProperty = theCopyFrom->QColorProperty;\n    }\n\n    if (!(theCopyFrom->QFontProperty.state() & ignoreMask))\n    {\n        QFontProperty = theCopyFrom->QFontProperty;\n    }\n\n    if (!(theCopyFrom->FreqProperty.state() & ignoreMask))\n    {\n        FreqProperty = theCopyFrom->FreqProperty;\n    }\n\n    if (!(theCopyFrom->LayerProperty.state() & ignoreMask))\n    {\n        LayerProperty = theCopyFrom->LayerProperty;\n    }\n\n    if (!(theCopyFrom->BrushStyleProperty.state() & ignoreMask))\n    {\n        BrushStyleProperty = theCopyFrom->BrushStyleProperty;\n    }\n\n    if (!(theCopyFrom->PenWidthProperty.state() & ignoreMask))\n    {\n        PenWidthProperty = theCopyFrom->PenWidthProperty;\n    }\n\n    if (!(theCopyFrom->PenStyleProperty.state() & ignoreMask))\n    {\n        PenStyleProperty = theCopyFrom->PenStyleProperty;\n    }\n\n    if (!(theCopyFrom->PenProperty.state() & ignoreMask))\n    {\n        PenProperty = theCopyFrom->PenProperty;\n    }\n\n    if (!(theCopyFrom->QStringCallbackProperty.state() & ignoreMask))\n    {\n        QStringCallbackProperty = theCopyFrom->QStringCallbackProperty;\n    }\n\n    SubPropertySet2.copyValues(&theCopyFrom->SubPropertySet2, ignoreMask);\n\n    return true;\n}\n\nvoid QtnPropertySetSamplePS::init()\n{\n    static QString SamplePS_name = QStringLiteral(\"SamplePS\");\n    setName(SamplePS_name);\n    \n    // start children initialization\n    static QString myColor_name = QStringLiteral(\"myColor\");\n    myColor.setName(myColor_name);\n    static QString myColor_description = \"Property to hold MyColor values.\";\n    myColor.setDescription(myColor_description);\n    static QString BoolProperty_name = QStringLiteral(\"BoolProperty\");\n    BoolProperty.setName(BoolProperty_name);\n    static QString BoolProperty_description = \"Property to hold boolean values.\";\n    BoolProperty.setDescription(BoolProperty_description);\n    BoolProperty.setValue(false);\n    static QString ButtonProperty_name = QStringLiteral(\"ButtonProperty\");\n    ButtonProperty.setName(ButtonProperty_name);\n    ButtonProperty.setClickHandler([](const QtnPropertyButton* bttn) {\n            qDebug() << Q_FUNC_INFO << \"Button has clicked: \" << bttn;\n        });\n    static QString ButtonProperty_description = \"Start calculate a long operation.\";\n    ButtonProperty.setDescription(ButtonProperty_description);\n    static QString ButtonLinkProperty_name = QStringLiteral(\"ButtonLinkProperty\");\n    ButtonLinkProperty.setName(ButtonLinkProperty_name);\n    ButtonLinkProperty.setClickHandler([](const QtnPropertyButton* bttn) {\n            qDebug() << Q_FUNC_INFO << \"Link has clicked: \" << bttn;\n        });\n    static QString RGBColor_name = QStringLiteral(\"RGBColor\");\n    RGBColor.setName(RGBColor_name);\n    RGBColor.setClickHandler([this](const QtnPropertyABColor* color) {\n            qDebug() << Q_FUNC_INFO << \"Color has clicked: \" << color;\n            RGBColor = QColor::fromRgb(qrand()%255, qrand()%255, qrand()%255);\n        });\n    static QString RGBColor_description = \"ABColor property with RGB components\";\n    RGBColor.setDescription(RGBColor_description);\n    RGBColor.setValue(QColor(123, 150, 10));\n    static QString ColorSolidDelegate_name = QStringLiteral(\"ColorSolidDelegate\");\n    ColorSolidDelegate.setName(ColorSolidDelegate_name);\n    static QString ColorSolidDelegate_description = \"QColor property with Solid delegate\";\n    ColorSolidDelegate.setDescription(ColorSolidDelegate_description);\n    ColorSolidDelegate.setValue(QColor(13, 150, 10));\n    static QString FloatPropertySliderBox_name = QStringLiteral(\"FloatPropertySliderBox\");\n    FloatPropertySliderBox.setName(FloatPropertySliderBox_name);\n    static QString FloatPropertySliderBox_description = \"Property to hold float values in range [0, 10].\";\n    FloatPropertySliderBox.setDescription(FloatPropertySliderBox_description);\n    FloatPropertySliderBox.setDisplayName(\"Float Property Slider Box\");\n    FloatPropertySliderBox.setMaxValue(10.f);\n    FloatPropertySliderBox.setMinValue(0);\n    FloatPropertySliderBox.setStepValue(0.1f);\n    FloatPropertySliderBox.setValue(1.f);\n    static QString FloatPercent_name = QStringLiteral(\"FloatPercent\");\n    FloatPercent.setName(FloatPercent_name);\n    static QString FloatPercent_description = \"Property to hold float values in range [0-1] visible as [0%-100%].\";\n    FloatPercent.setDescription(FloatPercent_description);\n    FloatPercent.setMaxValue(1.f);\n    FloatPercent.setMinValue(0.f);\n    FloatPercent.setValue(0.5f);\n    static QString DoublePercent_name = QStringLiteral(\"DoublePercent\");\n    DoublePercent.setName(DoublePercent_name);\n    static QString DoublePercent_description = \"Property to hold double values in range [0-1] visible as [0%-100%].\";\n    DoublePercent.setDescription(DoublePercent_description);\n    DoublePercent.setMaxValue(1.0);\n    DoublePercent.setMinValue(0.0);\n    DoublePercent.setValue(0.5);\n    static QString FloatIntRangeSliderBox_name = QStringLiteral(\"FloatIntRangeSliderBox\");\n    FloatIntRangeSliderBox.setName(FloatIntRangeSliderBox_name);\n    static QString FloatIntRangeSliderBox_description = \"Property to hold float values in full range.\";\n    FloatIntRangeSliderBox.setDescription(FloatIntRangeSliderBox_description);\n    FloatIntRangeSliderBox.setMaxValue(float(1 << std::numeric_limits<float>::digits));\n    FloatIntRangeSliderBox.setMinValue(-float(1 << std::numeric_limits<float>::digits));\n    FloatIntRangeSliderBox.setValue(111.f);\n    static QString DoubleFullRangeSliderBox_name = QStringLiteral(\"DoubleFullRangeSliderBox\");\n    DoubleFullRangeSliderBox.setName(DoubleFullRangeSliderBox_name);\n    static QString DoubleFullRangeSliderBox_description = \"Property to hold double values in full range.\";\n    DoubleFullRangeSliderBox.setDescription(DoubleFullRangeSliderBox_description);\n    DoubleFullRangeSliderBox.setMaxValue(double(1LL << std::numeric_limits<double>::digits));\n    DoubleFullRangeSliderBox.setMinValue(-double(1LL << std::numeric_limits<double>::digits));\n    DoubleFullRangeSliderBox.setValue(1111.0);\n    static QString DoubleProperty_name = QStringLiteral(\"DoubleProperty\");\n    DoubleProperty.setName(DoubleProperty_name);\n    static QString DoubleProperty_description = \"Property to hold double values in range [10, 20].\";\n    DoubleProperty.setDescription(DoubleProperty_description);\n    DoubleProperty.setMaxValue(20);\n    DoubleProperty.setMinValue(10);\n    DoubleProperty.setStepValue(0.5);\n    DoubleProperty.setValue(12.3);\n    static QString FloatProperty_name = QStringLiteral(\"FloatProperty\");\n    FloatProperty.setName(FloatProperty_name);\n    static QString FloatProperty_description = \"Property to hold float values in range [-10, 0].\";\n    FloatProperty.setDescription(FloatProperty_description);\n    FloatProperty.setMaxValue(0);\n    FloatProperty.setMinValue(-10);\n    FloatProperty.setStepValue(0.5);\n    FloatProperty.setValue(-3.5);\n    static QString IntProperty_name = QStringLiteral(\"IntProperty\");\n    IntProperty.setName(IntProperty_name);\n    static QString IntProperty_description = \"Property to hold integer values with changing step 15.\";\n    IntProperty.setDescription(IntProperty_description);\n    IntProperty.setStepValue(15);\n    IntProperty.setValue(10);\n    static QString IntPropertyComboBox_name = QStringLiteral(\"IntPropertyComboBox\");\n    IntPropertyComboBox.setName(IntPropertyComboBox_name);\n    static QString IntPropertyComboBox_description = \"Property to hold integer values with changing step 15.\";\n    IntPropertyComboBox.setDescription(IntPropertyComboBox_description);\n    IntPropertyComboBox.setStepValue(15);\n    IntPropertyComboBox.setValue(10);\n    static QString UIntProperty_name = QStringLiteral(\"UIntProperty\");\n    UIntProperty.setName(UIntProperty_name);\n    static QString UIntProperty_description = \"Property to hold unsigned integer values in range [100, 200].\";\n    UIntProperty.setDescription(UIntProperty_description);\n    UIntProperty.setMaxValue(200);\n    UIntProperty.setMinValue(100);\n    UIntProperty.setValue(100);\n    static QString Int64Property_name = QStringLiteral(\"Int64Property\");\n    Int64Property.setName(Int64Property_name);\n    static QString Int64Property_description = \"Property to hold signed integer 64-bit value\";\n    Int64Property.setDescription(Int64Property_description);\n    Int64Property.setValue(-(1LL << 35));\n    static QString UInt64Property_name = QStringLiteral(\"UInt64Property\");\n    UInt64Property.setName(UInt64Property_name);\n    static QString UInt64Property_description = \"Property to hold signed integer 64-bit value\";\n    UInt64Property.setDescription(UInt64Property_description);\n    UInt64Property.setValue(1ULL << 63);\n    static QString Int64SliderBox_name = QStringLiteral(\"Int64SliderBox\");\n    Int64SliderBox.setName(Int64SliderBox_name);\n    static QString Int64SliderBox_description = \"Property to hold signed integer 64-bit value with slider box\";\n    Int64SliderBox.setDescription(Int64SliderBox_description);\n    Int64SliderBox.setValue(-(1LL << 34));\n    static QString UInt64SliderBox_name = QStringLiteral(\"UInt64SliderBox\");\n    UInt64SliderBox.setName(UInt64SliderBox_name);\n    static QString UInt64SliderBox_description = \"Property to hold unsigned integer 64-bit value with slider box\";\n    UInt64SliderBox.setDescription(UInt64SliderBox_description);\n    UInt64SliderBox.setValue(1ULL << 58);\n    static QString EnumProperty_name = QStringLiteral(\"EnumProperty\");\n    EnumProperty.setName(EnumProperty_name);\n    static QString EnumProperty_description = \"Property to hold enum value (color).\";\n    EnumProperty.setDescription(EnumProperty_description);\n    EnumProperty.setEnumInfo(&COLOR::info());\n    EnumProperty.setValue(COLOR::red);\n    static QString EnumFlagsProperty_name = QStringLiteral(\"EnumFlagsProperty\");\n    EnumFlagsProperty.setName(EnumFlagsProperty_name);\n    static QString EnumFlagsProperty_description = \"Property to hold combination of enum values (options).\";\n    EnumFlagsProperty.setDescription(EnumFlagsProperty_description);\n    EnumFlagsProperty.setEnumInfo(&FLAGS::info());\n    EnumFlagsProperty.setValue(FLAGS::opt2);\n    static QString QStringValue_name = QStringLiteral(\"QStringValue\");\n    QStringValue.setName(QStringValue_name);\n    static QString QStringValue_description = \"Property to hold QString value.\";\n    QStringValue.setDescription(QStringValue_description);\n    QStringValue.setValue(\"Hello world!\");\n    static QString EnableSubPropertySet_name = QStringLiteral(\"EnableSubPropertySet\");\n    EnableSubPropertySet.setName(EnableSubPropertySet_name);\n    static QString EnableSubPropertySet_description = \"Enable/Disable Sub-PropertySet.\";\n    EnableSubPropertySet.setDescription(EnableSubPropertySet_description);\n    EnableSubPropertySet.setValue(false);\n    static QString SubPropertySet_name = QStringLiteral(\"SubPropertySet\");\n    SubPropertySet.setName(SubPropertySet_name);\n    static QString SubPropertySet_description = \"This property set is part of the root property set.\";\n    SubPropertySet.setDescription(SubPropertySet_description);\n    SubPropertySet.setState(QtnPropertyStateImmutable);\n    static QString QPointProperty_name = QStringLiteral(\"QPointProperty\");\n    QPointProperty.setName(QPointProperty_name);\n    static QString QPointProperty_description = \"Property to hold QPoint value.\";\n    QPointProperty.setDescription(QPointProperty_description);\n    QPointProperty.setValue(QPoint(-10, 10));\n    static QString QSizeProperty_name = QStringLiteral(\"QSizeProperty\");\n    QSizeProperty.setName(QSizeProperty_name);\n    static QString QSizeProperty_description = \"Property to hold QSize value.\";\n    QSizeProperty.setDescription(QSizeProperty_description);\n    QSizeProperty.setValue(QSize(100, 200));\n    static QString QRectProperty_name = QStringLiteral(\"QRectProperty\");\n    QRectProperty.setName(QRectProperty_name);\n    static QString QRectProperty_description = \"Property to hold QRect value.\";\n    QRectProperty.setDescription(QRectProperty_description);\n    QRectProperty.setValue(QRect(10, 10, 200, 200));\n    static QString QPointFProperty_name = QStringLiteral(\"QPointFProperty\");\n    QPointFProperty.setName(QPointFProperty_name);\n    static QString QPointFProperty_description = \"Property to hold QPointF value.\";\n    QPointFProperty.setDescription(QPointFProperty_description);\n    QPointFProperty.setValue(QPointF(-10.5, 10.2));\n    static QString QSizeFProperty_name = QStringLiteral(\"QSizeFProperty\");\n    QSizeFProperty.setName(QSizeFProperty_name);\n    static QString QSizeFProperty_description = \"Property to hold QSizeF value.\";\n    QSizeFProperty.setDescription(QSizeFProperty_description);\n    QSizeFProperty.setValue(QSizeF(100.0, 200.1));\n    static QString QRectFProperty_name = QStringLiteral(\"QRectFProperty\");\n    QRectFProperty.setName(QRectFProperty_name);\n    static QString QRectFProperty_description = \"Property to hold QRectF value.\";\n    QRectFProperty.setDescription(QRectFProperty_description);\n    QRectFProperty.setValue(QRectF(10.23, 10.4, 200.2, 200.6));\n    static QString QVector3DProperty_name = QStringLiteral(\"QVector3DProperty\");\n    QVector3DProperty.setName(QVector3DProperty_name);\n    static QString QVector3DProperty_description = \"Property to hold QVector3D value.\";\n    QVector3DProperty.setDescription(QVector3DProperty_description);\n    QVector3DProperty.setValue(QVector3D(5, 6, 7));\n    static QString QColorProperty_name = QStringLiteral(\"QColorProperty\");\n    QColorProperty.setName(QColorProperty_name);\n    static QString QColorProperty_description = \"Property to hold QColor value.\";\n    QColorProperty.setDescription(QColorProperty_description);\n    QColorProperty.setValue(Qt::blue);\n    static QString QFontProperty_name = QStringLiteral(\"QFontProperty\");\n    QFontProperty.setName(QFontProperty_name);\n    static QString QFontProperty_description = \"Property to hold QFont value.\";\n    QFontProperty.setDescription(QFontProperty_description);\n    QFontProperty.setValue(QFont(\"Sans Serif\", 14));\n    static QString FreqProperty_name = QStringLiteral(\"FreqProperty\");\n    FreqProperty.setName(FreqProperty_name);\n    static QString FreqProperty_description = \"Property to hold frequency values.\";\n    FreqProperty.setDescription(FreqProperty_description);\n    FreqProperty.setUnit(FreqUnit::KHz);\n    FreqProperty.setValue(15);\n    static QString LayerProperty_name = QStringLiteral(\"LayerProperty\");\n    LayerProperty.setName(LayerProperty_name);\n    static QString LayerProperty_description = \"Property to hold layer.\";\n    LayerProperty.setDescription(LayerProperty_description);\n    LayerProperty.setValue(0);\n    static QString BrushStyleProperty_name = QStringLiteral(\"BrushStyleProperty\");\n    BrushStyleProperty.setName(BrushStyleProperty_name);\n    static QString BrushStyleProperty_description = \"Property to hold QBrushStyle enum.\";\n    BrushStyleProperty.setDescription(BrushStyleProperty_description);\n    BrushStyleProperty.setValue(Qt::HorPattern);\n    static QString PenWidthProperty_name = QStringLiteral(\"PenWidthProperty\");\n    PenWidthProperty.setName(PenWidthProperty_name);\n    static QString PenWidthProperty_description = \"Property to hold PenWidth enum.\";\n    PenWidthProperty.setDescription(PenWidthProperty_description);\n    PenWidthProperty.setValue(PenWidth::Middle);\n    static QString PenStyleProperty_name = QStringLiteral(\"PenStyleProperty\");\n    PenStyleProperty.setName(PenStyleProperty_name);\n    static QString PenStyleProperty_description = \"Property to hold pen style values.\";\n    PenStyleProperty.setDescription(PenStyleProperty_description);\n    PenStyleProperty.setValue(Qt::DashLine);\n    static QString PenProperty_name = QStringLiteral(\"PenProperty\");\n    PenProperty.setName(PenProperty_name);\n    static QString PenProperty_description = \"Property to hold QPen values.\";\n    PenProperty.setDescription(PenProperty_description);\n    static QString QStringCallbackProperty_name = QStringLiteral(\"QStringCallbackProperty\");\n    QStringCallbackProperty.setName(QStringCallbackProperty_name);\n    static QString QStringCallbackProperty_description = \"Property to hold QString values with candidates.\";\n    QStringCallbackProperty.setDescription(QStringCallbackProperty_description);\n    static QString SubPropertySet2_name = QStringLiteral(\"SubPropertySet2\");\n    SubPropertySet2.setName(SubPropertySet2_name);\n    SubPropertySet2.setState(QtnPropertyStateCollapsed);\n    // end children initialization\n}\n\nvoid QtnPropertySetSamplePS::connectSlots()\n{\n    QObject::connect(&EnableSubPropertySet, &QtnProperty::propertyDidChange, this, &QtnPropertySetSamplePS::on_EnableSubPropertySet_propertyDidChange);\n    QObject::connect(&QColorProperty, &QtnProperty::propertyDidChange, this, &QtnPropertySetSamplePS::on_QColorProperty_propertyDidChange);\n}\n\nvoid QtnPropertySetSamplePS::disconnectSlots()\n{\n    QObject::disconnect(&EnableSubPropertySet, &QtnProperty::propertyDidChange, this, &QtnPropertySetSamplePS::on_EnableSubPropertySet_propertyDidChange);\n    QObject::disconnect(&QColorProperty, &QtnProperty::propertyDidChange, this, &QtnPropertySetSamplePS::on_QColorProperty_propertyDidChange);\n}\n\nvoid QtnPropertySetSamplePS::on_EnableSubPropertySet_propertyDidChange(QtnPropertyChangeReason reason)\n{\n    Q_UNUSED(reason);\n    \n            SubPropertySet.switchState(QtnPropertyStateImmutable, !EnableSubPropertySet);\n        \n}\n\nvoid QtnPropertySetSamplePS::on_QColorProperty_propertyDidChange(QtnPropertyChangeReason reason)\n{\n    Q_UNUSED(reason);\n    \n            qDebug() << Q_FUNC_INFO << \"Property has changed: \" << &QColorProperty;\n        \n}\n\nvoid QtnPropertySetSamplePS::connectDelegates()\n{\n    ButtonProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"title\"] = \"Click me\";\n        return info;\n    });\n    ButtonLinkProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"Link\";\n        info.attributes[\"title\"] = \"Click on me\";\n        return info;\n    });\n    RGBColor.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"rgbSubItems\"] = true;\n        return info;\n    });\n    ColorSolidDelegate.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"Solid\";\n        return info;\n    });\n    FloatPropertySliderBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"SliderBox\";\n        info.attributes[\"drawBorder\"] = false;\n        info.attributes[\"fillColor\"] = QColor::fromRgb(170, 170, 255);\n        return info;\n    });\n    FloatPercent.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"multiplier\"] = 100.0;\n        info.attributes[\"suffix\"] = \"%\";\n        return info;\n    });\n    DoublePercent.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"multiplier\"] = 100.0;\n        info.attributes[\"precision\"] = 10;\n        info.attributes[\"suffix\"] = \"%\";\n        return info;\n    });\n    FloatIntRangeSliderBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"SliderBox\";\n        info.attributes[\"drawBorder\"] = false;\n        info.attributes[\"fillColor\"] = QColor::fromRgb(170, 170, 255);\n        return info;\n    });\n    DoubleFullRangeSliderBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"SliderBox\";\n        info.attributes[\"drawBorder\"] = false;\n        info.attributes[\"fillColor\"] = QColor::fromRgb(170, 170, 255);\n        return info;\n    });\n    IntPropertyComboBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"IntList\";\n        info.attributes[\"values\"] = QVariant::fromValue(QList<int>() << 10 << 12 << 15);\n        return info;\n    });\n    Int64Property.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"step\"] = 100000;\n        return info;\n    });\n    Int64SliderBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"SliderBox\";\n        return info;\n    });\n    UInt64SliderBox.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"SliderBox\";\n        return info;\n    });\n    QVector3DProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"max\"] = 255;\n        info.attributes[\"min\"] = 0;\n        info.attributes[\"multiplier\"] = 100.0 / 255.0;\n        info.attributes[\"precision\"] = 5;\n        info.attributes[\"suffix\"] = \"%\";\n        info.attributes[\"z\"] = QVariantMap({\n    \t\t\t{ QString(\"name\"), QString(\"SliderBox\")},\n    \t\t\t{ QString(\"precision\"), 3 },\n    \t\t});\n        return info;\n    });\n    PenProperty.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.attributes[\"editColor\"] = true;\n        info.attributes[\"editStyle\"] = true;\n        info.attributes[\"editWidth\"] = true;\n        return info;\n    });\n}\n"
  },
  {
    "path": "Demo/Demo.peg.h",
    "content": "#ifndef DEMO_H\n#define DEMO_H\n\n#include \"QtnProperty/PropertyCore.h\"\n#include \"QtnProperty/PropertyGUI.h\"\n#include \"QtnProperty/PropertyInt64.h\"\n#include \"QtnProperty/PropertyUInt64.h\"\n#include \"AB/PropertyABColor.h\"\n#include \"Layer/PropertyLayer.h\"\n#include \"PenWidth/PropertyPenWidth.h\"\n#include \"Freq/PropertyFreq.h\"\n\nclass COLOR\n{\npublic:\n    enum Enum\n    {\n        red = 1,\n        blue = 2,\n        green = 3\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 3;\n};\n\nclass FLAGS\n{\npublic:\n    enum Enum\n    {\n        opt1 = 1,\n        opt2 = 2,\n        opt3 = 4\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 3;\n};\n\nclass QtnPropertySetSubPropertySetType: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetSubPropertySetType)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetSubPropertySetType(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetSubPropertySetType() override;\n    // assignment declaration\n    QtnPropertySetSubPropertySetType& operator=(const QtnPropertySetSubPropertySetType& other);\n    \n    // start children declarations\n    QtnPropertyBool& SwitchProperty;\n    QtnPropertyQStringCallback& ReadOnlyString;\n    QtnPropertyQString& FileNameProperty;\n    QtnPropertyQString& FolderNameProperty;\n    QtnPropertyQString& StringFromList;\n    QtnPropertyQColor& CircleShapeColor;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\nclass QtnPropertySetSamplePS: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetSamplePS)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetSamplePS(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetSamplePS() override;\n    // assignment declaration\n    QtnPropertySetSamplePS& operator=(const QtnPropertySetSamplePS& other);\n    \n    // start children declarations\n    QtnPropertyMyColor& myColor;\n    QtnPropertyBool& BoolProperty;\n    QtnPropertyButton& ButtonProperty;\n    QtnPropertyButton& ButtonLinkProperty;\n    QtnPropertyABColor& RGBColor;\n    QtnPropertyQColor& ColorSolidDelegate;\n    QtnPropertyFloat& FloatPropertySliderBox;\n    QtnPropertyFloat& FloatPercent;\n    QtnPropertyDouble& DoublePercent;\n    QtnPropertyFloat& FloatIntRangeSliderBox;\n    QtnPropertyDouble& DoubleFullRangeSliderBox;\n    QtnPropertyDouble& DoubleProperty;\n    QtnPropertyFloat& FloatProperty;\n    QtnPropertyInt& IntProperty;\n    QtnPropertyInt& IntPropertyComboBox;\n    QtnPropertyUInt& UIntProperty;\n    QtnPropertyInt64& Int64Property;\n    QtnPropertyUInt64& UInt64Property;\n    QtnPropertyInt64& Int64SliderBox;\n    QtnPropertyUInt64& UInt64SliderBox;\n    QtnPropertyEnum& EnumProperty;\n    QtnPropertyEnumFlags& EnumFlagsProperty;\n    QtnPropertyQString& QStringValue;\n    QtnPropertyBool& EnableSubPropertySet;\n    QtnPropertySetSubPropertySetType& SubPropertySet;\n    QtnPropertyQPoint& QPointProperty;\n    QtnPropertyQSize& QSizeProperty;\n    QtnPropertyQRect& QRectProperty;\n    QtnPropertyQPointF& QPointFProperty;\n    QtnPropertyQSizeF& QSizeFProperty;\n    QtnPropertyQRectF& QRectFProperty;\n    QtnPropertyQVector3D& QVector3DProperty;\n    QtnPropertyQColor& QColorProperty;\n    QtnPropertyQFont& QFontProperty;\n    QtnPropertyFreq& FreqProperty;\n    QtnPropertyLayer& LayerProperty;\n    QtnPropertyQBrushStyle& BrushStyleProperty;\n    QtnPropertyPenWidth& PenWidthProperty;\n    QtnPropertyQPenStyle& PenStyleProperty;\n    QtnPropertyQPen& PenProperty;\n    QtnPropertyQString& QStringCallbackProperty;\n    QtnPropertySetSubPropertySetType& SubPropertySet2;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n    \n    // start slot declarations\n    void on_EnableSubPropertySet_propertyDidChange(QtnPropertyChangeReason reason);\n    void on_QColorProperty_propertyDidChange(QtnPropertyChangeReason reason);\n    // end slot declarations\n};\n\n#endif // DEMO_H\n"
  },
  {
    "path": "Demo/Demo.pro",
    "content": "include(../QtnPropertyDepend.pri)\ninclude(../Internal/TargetConfig.pri)\ninclude(../PEG/PEG.pri)\n\nQT += core gui widgets script scripttools\n\nTARGET = QtnPropertyDemo\nTEMPLATE = app\n\nSOURCES +=  main.cpp\\\n            MainWindow.cpp \\\n            mydialog.cpp \\\n            AB/PropertyABColor.cpp \\\n            AB/PropertyDelegateABColor.cpp \\\n            Int/PropertyDelegateIntList.cpp \\\n            Layer/PropertyLayer.cpp \\\n            Layer/PropertyDelegateLayer.cpp \\\n            PenWidth/PropertyPenWidth.cpp \\\n            PenWidth/PropertyDelegatePenWidth.cpp \\\n            Freq/PropertyFreq.cpp \\\n            Freq/PropertyDelegateFreq.cpp\n\nHEADERS  += MainWindow.h \\\n            mydialog.h \\\n            AB/PropertyABColor.h \\\n            AB/PropertyDelegateABColor.h \\\n            Int/PropertyDelegateIntList.h \\\n            Layer/PropertyLayer.h \\\n            Layer/PropertyDelegateLayer.h \\\n            PenWidth/PropertyPenWidth.h \\\n            PenWidth/PropertyDelegatePenWidth.h \\\n            Freq/PropertyFreq.h \\\n            Freq/PropertyDelegateFreq.h\n\nFORMS    += MainWindow.ui \\\n            mydialog.ui\n\nPEG_SOURCES += Demo.pef\n\nOTHER_FILES += \\\n    Demo.pef\n\nQMAKE_BUNDLE_DATA += DYNAMIC_LIBS\n\nunix:QMAKE_LFLAGS += -Wl,-rpath,\\'\\$$ORIGIN\\'\n\n"
  },
  {
    "path": "Demo/Freq/PropertyDelegateFreq.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateFreq.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"PropertyFreq.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n\n#include <QComboBox>\n#include <QLineEdit>\n#include <QStyledItemDelegate>\n#include <QPaintEvent>\n\nvoid regFreqDelegates()\n{\n\tQtnPropertyDelegateFactory::staticInstance().registerDelegateDefault(\n\t\t&QtnPropertyFreqBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateFreq, QtnPropertyFreqBase>);\n}\n\nstatic QString freqUnit2Str(FreqUnit unit)\n{\n\tswitch (unit)\n\t{\n\t\tcase FreqUnit::Hz:\n\t\t\treturn \"Hz\";\n\t\tcase FreqUnit::KHz:\n\t\t\treturn \"KHz\";\n\t\tcase FreqUnit::MHz:\n\t\t\treturn \"MHz\";\n\t\tdefault:\n\t\t\treturn \"NA\";\n\t}\n}\n\nvoid QtnPropertyDelegateFreq::createSubItemValuesImpl(\n\tQtnDrawContext &context, const QRect &rect, QList<QtnSubItem> &subItems)\n{\n\tauto unitWidth = context.painter->fontMetrics().width(\"MHz\");\n\tauto spaceWidth = context.painter->fontMetrics().width(\" \");\n\n\tauto valueRect = rect;\n\tvalueRect.setRight(valueRect.right() - unitWidth - spaceWidth);\n\n\tauto unitRect = rect;\n\tunitRect.setLeft(valueRect.right() + spaceWidth);\n\n\tif (valueRect.isValid())\n\t\taddValueSubItem(context, valueRect, subItems);\n\n\tif (unitRect.isValid())\n\t\taddUnitSubItem(context, unitRect, subItems);\n}\n\nvoid QtnPropertyDelegateFreq::addValueSubItem(QtnDrawContext & /*context*/,\n\tconst QRect &rect, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem subItem(rect);\n\tsubItem.drawHandler = [this](\n\t\t\t\t\t\t\t  QtnDrawContext &context, const QtnSubItem &item) {\n\t\tauto text = qtnElidedText(*context.painter,\n\t\t\tQString::number(owner().value()), item.rect, nullptr);\n\t\tcontext.painter->drawText(\n\t\t\titem.rect, Qt::AlignRight | Qt::AlignVCenter, text);\n\t};\n\n\tsubItems.append(subItem);\n}\n\nvoid QtnPropertyDelegateFreq::addUnitSubItem(QtnDrawContext & /*context*/,\n\tconst QRect &rect, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem subItem(rect);\n\tsubItem.drawHandler = [this](\n\t\t\t\t\t\t\t  QtnDrawContext &context, const QtnSubItem &item) {\n\t\tqtnDrawValueText(freqUnit2Str(owner().unit()), *context.painter,\n\t\t\titem.rect, context.style());\n\t};\n\n\tsubItems.append(subItem);\n}\n"
  },
  {
    "path": "Demo/Freq/PropertyDelegateFreq.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_FREQ_H\n#define PROPERTY_DELEGATE_FREQ_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n\nclass QtnPropertyFreqBase;\n\nclass QtnPropertyDelegateFreq\n\t: public QtnPropertyDelegateTyped<QtnPropertyFreqBase,\n\t\t  QtnPropertyDelegateWithValues>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateFreq)\n\npublic:\n\tQtnPropertyDelegateFreq(QtnPropertyFreqBase &owner)\n\t\t: QtnPropertyDelegateTyped<QtnPropertyFreqBase,\n\t\t\t  QtnPropertyDelegateWithValues>(owner)\n\t{\n\t}\n\nprotected:\n\tvoid createSubItemValuesImpl(QtnDrawContext &context, const QRect &rect,\n\t\tQList<QtnSubItem> &subItems) override;\n\nprivate:\n\tvoid addValueSubItem(QtnDrawContext &context, const QRect &rect,\n\t\tQList<QtnSubItem> &subItems);\n\tvoid addUnitSubItem(QtnDrawContext &context, const QRect &rect,\n\t\tQList<QtnSubItem> &subItems);\n};\n\n#endif // PROPERTY_DELEGATE_FREQ_H\n"
  },
  {
    "path": "Demo/Freq/PropertyFreq.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyFreq.h\"\n\nvoid QtnPropertyFreqBase::setUnit(FreqUnit unit)\n{\n\tif (m_unit == unit)\n\t\treturn;\n\n\tQ_EMIT propertyWillChange(QtnPropertyChangeReasonValue, &unit, 0);\n\n\tm_unit = unit;\n\n\tQ_EMIT propertyDidChange(QtnPropertyChangeReasonValue);\n}\n\nbool QtnPropertyFreqBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tQ_UNUSED(str);\n\tQ_UNUSED(reason);\n\treturn false;\n}\n\nbool QtnPropertyFreqBase::toStrImpl(QString &str) const\n{\n\tQ_UNUSED(str);\n\treturn false;\n}\n"
  },
  {
    "path": "Demo/Freq/PropertyFreq.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_FREQ_H\n#define PROPERTY_FREQ_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nenum class FreqUnit\n{\n\tHz,\n\tKHz,\n\tMHz\n};\n\nclass QtnPropertyFreqBase : public QtnSinglePropertyBase<int>\n{\n\tQ_OBJECT\n\tQtnPropertyFreqBase(const QtnPropertyFreqBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyFreqBase(QObject *parent)\n\t\t: QtnSinglePropertyBase<int>(parent)\n\t\t, m_unit(FreqUnit::Hz)\n\t{\n\t}\n\n\tFreqUnit unit() const\n\t{\n\t\treturn m_unit;\n\t}\n\tvoid setUnit(FreqUnit unit);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\nprivate:\n\tFreqUnit m_unit;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyFreqBase)\n};\n\nclass QtnPropertyFreqCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyFreqBase>\n{\n\tQ_OBJECT\n\tQtnPropertyFreqCallback(\n\t\tconst QtnPropertyFreqCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyFreqCallback(QObject *parent)\n\t\t: QtnSinglePropertyCallback<QtnPropertyFreqBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyFreqCallback, QtnPropertyFreqBase)\n};\n\nclass QtnPropertyFreq : public QtnSinglePropertyValue<QtnPropertyFreqBase>\n{\n\tQ_OBJECT\n\tQtnPropertyFreq(const QtnPropertyFreq &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyFreq(QObject *parent)\n\t\t: QtnSinglePropertyValue<QtnPropertyFreqBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyFreq, QtnPropertyFreqBase)\n};\n\n#endif // PROPERTY_FREQ_H\n"
  },
  {
    "path": "Demo/Int/PropertyDelegateIntList.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateIntList.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Core/PropertyInt.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include <QLineEdit>\n\nvoid regIntListDelegates()\n{\n\tQtnPropertyDelegateFactory::staticInstance().registerDelegate(\n\t\t&QtnPropertyIntBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateIntList, QtnPropertyIntBase>,\n\t\t\"IntList\");\n}\n\nclass QtnPropertyIntComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyIntBase, QComboBox>\n{\npublic:\n\tQtnPropertyIntComboBoxHandler(\n\t\tQtnPropertyDelegateIntList *delegate, QComboBox &editor)\n\t\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t{\n\t\tupdateEditor();\n\n\t\tQObject::connect(&editor,\n\t\t\tstatic_cast<void (QComboBox::*)(int)>(\n\t\t\t\t&QComboBox::currentIndexChanged),\n\t\t\tthis, &QtnPropertyIntComboBoxHandler::onCurrentIndexChanged);\n\t}\n\nprivate:\n\tvoid updateEditor() override\n\t{\n\t\tupdating++;\n\n\t\teditor().setEnabled(stateProperty()->isEditableByUser());\n\t\tif (stateProperty()->isMultiValue())\n\t\t\teditor().setCurrentIndex(-1);\n\t\telse\n\t\t{\n\t\t\tint index = editor().findData((int) property());\n\t\t\teditor().setCurrentIndex(index);\n\t\t}\n\t\tupdating--;\n\t}\n\n\tvoid onCurrentIndexChanged(int index)\n\t{\n\t\tif (index >= 0)\n\t\t{\n\t\t\tQVariant data = editor().itemData(index);\n\t\t\tif (data.canConvert<int>())\n\t\t\t\tonValueChanged(data.toInt());\n\t\t}\n\t}\n};\n\nQtnPropertyDelegateIntList::QtnPropertyDelegateIntList(\n\tQtnPropertyIntBase &owner)\n\t: QtnPropertyDelegateInt(owner)\n{\n}\n\nQWidget *QtnPropertyDelegateIntList::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQComboBox *comboBox = new QtnPropertyComboBox(this, parent);\n\n\tauto delegate = owner().delegateInfo();\n\tif (delegate)\n\t{\n\t\tQList<int> values;\n\t\tdelegate->loadAttribute(\"values\", values);\n\t\tfor (auto value : values)\n\t\t{\n\t\t\tcomboBox->addItem(QString::number(value), value);\n\t\t}\n\t}\n\n\tcomboBox->setGeometry(rect);\n\n\t// connect widget and property\n\tnew QtnPropertyIntComboBoxHandler(this, *comboBox);\n\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcomboBox->showPopup();\n\n\treturn comboBox;\n}\n"
  },
  {
    "path": "Demo/Int/PropertyDelegateIntList.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_INT_LIST_H\n#define PROPERTY_DELEGATE_INT_LIST_H\n\n#include \"QtnProperty/Delegates/Core/PropertyDelegateInt.h\"\n\nclass QtnPropertyIntBase;\n\nclass QtnPropertyDelegateIntList : public QtnPropertyDelegateInt\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateIntList)\n\npublic:\n\tQtnPropertyDelegateIntList(QtnPropertyIntBase &owner);\n\nprotected:\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n};\n\n#endif // PROPERTY_DELEGATE_INT_LIST_H\n"
  },
  {
    "path": "Demo/Layer/PropertyDelegateLayer.cpp",
    "content": "/*\n   Copyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n#include \"PropertyDelegateLayer.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"PropertyLayer.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n\n#include <QComboBox>\n#include <QLineEdit>\n#include <QStyledItemDelegate>\n#include <QPaintEvent>\n\nvoid regLayerDelegates()\n{\n\tQtnPropertyDelegateFactory::staticInstance().registerDelegateDefault(\n\t\t&QtnPropertyLayerBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateLayer, QtnPropertyLayerBase>);\n}\n\nstatic void drawLayer(\n\tQStyle *style, const LayerInfo &layer, QPainter &painter, const QRect &rect)\n{\n\tQRect textRect = rect;\n\n\tQRect colorRect = rect;\n\tcolorRect.setWidth(colorRect.height());\n\tcolorRect.adjust(2, 2, -2, -2);\n\n\tpainter.fillRect(colorRect, Qt::black);\n\tcolorRect.adjust(1, 1, -1, -1);\n\tpainter.fillRect(colorRect, layer.color);\n\n\ttextRect.setLeft(colorRect.right() + 5);\n\n\tif (textRect.isValid())\n\t{\n\t\tqtnDrawValueText(layer.name, painter, textRect, style);\n\t}\n}\n\nclass QtnPropertyLayerComboBox : public QComboBox\n{\npublic:\n\texplicit QtnPropertyLayerComboBox(\n\t\tQtnPropertyDelegateLayer *delegate, QWidget *parent = Q_NULLPTR)\n\t\t: QComboBox(parent)\n\t\t, m_delegate(delegate)\n\t\t, m_property(static_cast<QtnPropertyLayerBase *>(delegate->property()))\n\t\t, m_updating(0)\n\t{\n\t\tm_layers = m_property->layers();\n\t\tsetLineEdit(nullptr);\n\t\tsetItemDelegate(new ItemDelegate(m_layers, this));\n\t\tfor (const auto &layer : m_layers)\n\t\t{\n\t\t\tQ_UNUSED(layer);\n\t\t\taddItem(QString());\n\t\t}\n\n\t\tupdateEditor();\n\n\t\tQObject::connect(m_property, &QtnPropertyBase::propertyDidChange, this,\n\t\t\t&QtnPropertyLayerComboBox::onPropertyDidChange);\n\t\tQObject::connect(this,\n\t\t\tstatic_cast<void (QComboBox::*)(int)>(\n\t\t\t\t&QComboBox::currentIndexChanged),\n\t\t\tthis, &QtnPropertyLayerComboBox::onCurrentIndexChanged);\n\t}\n\nprotected:\n\tvoid paintEvent(QPaintEvent *event) override\n\t{\n\t\tQComboBox::paintEvent(event);\n\n\t\tQPainter painter(this);\n\n\t\tauto index = currentIndex();\n\t\tif (index != -1)\n\t\t{\n\t\t\tQ_ASSERT(index < m_layers.size());\n\t\t\tdrawLayer(style(), m_layers[index], painter, event->rect());\n\t\t}\n\t}\n\n\tvoid updateEditor()\n\t{\n\t\tm_updating++;\n\t\tsetEnabled(m_delegate->stateProperty()->isEditableByUser());\n\t\tsetCurrentIndex(m_property->value());\n\t\tm_updating--;\n\t}\n\n\tvoid onPropertyDidChange(QtnPropertyChangeReason reason)\n\t{\n\t\tif ((reason & QtnPropertyChangeReasonValue))\n\t\t\tupdateEditor();\n\t}\n\n\tvoid onCurrentIndexChanged(int index)\n\t{\n\t\tif (m_updating)\n\t\t\treturn;\n\n\t\tif (index >= 0)\n\t\t{\n\t\t\tQ_ASSERT(index < m_layers.size());\n\t\t\tm_property->setValue(index, m_delegate->editReason());\n\t\t}\n\t}\n\nprivate:\n\tQtnPropertyDelegateLayer *m_delegate;\n\tQtnPropertyLayerBase *m_property;\n\tQList<LayerInfo> m_layers;\n\tunsigned m_updating;\n\n\tclass ItemDelegate : public QStyledItemDelegate\n\t{\n\tpublic:\n\t\tItemDelegate(const QList<LayerInfo> &layers, QComboBox *owner)\n\t\t\t: m_layers(layers)\n\t\t\t, m_owner(owner)\n\t\t{\n\t\t}\n\n\t\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\t\tconst QModelIndex &index) const override\n\t\t{\n\t\t\tQStyledItemDelegate::paint(painter, option, index);\n\n\t\t\tQ_ASSERT(index.row() < m_layers.size());\n\t\t\tdrawLayer(\n\t\t\t\tm_owner->style(), m_layers[index.row()], *painter, option.rect);\n\t\t}\n\n\tprivate:\n\t\tconst QList<LayerInfo> &m_layers;\n\t\tQComboBox *m_owner;\n\t};\n};\n\nvoid QtnPropertyDelegateLayer::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tauto layer = owner().valueLayer();\n\tif (layer)\n\t\tdrawLayer(painter.style(), *layer, painter, rect);\n}\n\nQWidget *QtnPropertyDelegateLayer::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto combo = new QtnPropertyLayerComboBox(this, parent);\n\tcombo->setGeometry(rect);\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcombo->showPopup();\n\n\treturn combo;\n}\n"
  },
  {
    "path": "Demo/Layer/PropertyDelegateLayer.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_LAYER_H\n#define PROPERTY_DELEGATE_LAYER_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n\nclass QtnPropertyLayerBase;\n\nclass QtnPropertyDelegateLayer\n\t: public QtnPropertyDelegateTyped<QtnPropertyLayerBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateLayer)\n\npublic:\n\tQtnPropertyDelegateLayer(QtnPropertyLayerBase &owner)\n\t\t: QtnPropertyDelegateTyped<QtnPropertyLayerBase>(owner)\n\t{\n\t}\n\nprotected:\n\tvoid drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n};\n\n#endif // PROPERTY_DELEGATE_LAYER_H\n"
  },
  {
    "path": "Demo/Layer/PropertyLayer.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyLayer.h\"\n\nconst LayerInfo *QtnPropertyLayerBase::valueLayer() const\n{\n\tconst auto &layerValues = layers();\n\tauto layerIndex = value();\n\tif (layerIndex < 0 || layerIndex >= layerValues.size())\n\t\treturn nullptr;\n\n\treturn &layerValues[layerIndex];\n}\n\nLayerInfo *QtnPropertyLayerBase::valueLayer()\n{\n\treturn const_cast<LayerInfo *>(\n\t\t((const QtnPropertyLayerBase *) this)->valueLayer());\n}\n\nconst QList<LayerInfo> &QtnPropertyLayerBase::layers() const\n{\n\treturn m_layers;\n}\n\nvoid QtnPropertyLayerBase::setLayers(QList<LayerInfo> layers)\n{\n\tQ_EMIT propertyWillChange(QtnPropertyChangeReasonValue, nullptr, 0);\n\n\tm_layers = layers;\n\n\tQ_EMIT propertyDidChange(QtnPropertyChangeReasonValue);\n}\n\nbool QtnPropertyLayerBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tint index = 0;\n\tfor (const auto &layer : layers())\n\t{\n\t\tif (layer.name == str)\n\t\t{\n\t\t\treturn setValue(index, reason);\n\t\t}\n\t\t++index;\n\t}\n\n\treturn false;\n}\n\nbool QtnPropertyLayerBase::toStrImpl(QString &str) const\n{\n\tauto layer = valueLayer();\n\tif (layer)\n\t\tstr = layer->name;\n\treturn true;\n}\n"
  },
  {
    "path": "Demo/Layer/PropertyLayer.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_LAYER_H\n#define PROPERTY_LAYER_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include <QColor>\n\nstruct LayerInfo\n{\n\tQString name;\n\tQColor color;\n\tqintptr data = 0;\n\n\tLayerInfo() {}\n\tLayerInfo(QString name, QColor color, qintptr data = 0)\n\t\t: name(name)\n\t\t, color(color)\n\t\t, data(data)\n\t{\n\t}\n};\n\n/*\ninline bool operator== (const LayerInfo& left, const LayerInfo& right) { return left.name == right.name; }\ninline bool operator != (const LayerInfo& left, const LayerInfo& right) { return !(left == right); }\n\nQDataStream& operator<< (QDataStream& stream, const LayerInfo& layer);\nQDataStream& operator>> (QDataStream& stream, LayerInfo& layer);\n\nQ_DECLARE_METATYPE(LayerInfo)\n*/\n\nclass QtnPropertyLayerBase : public QtnSinglePropertyBase<int>\n{\n\tQ_OBJECT\n\tQtnPropertyLayerBase(const QtnPropertyLayerBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyLayerBase(QObject *parent)\n\t\t: QtnSinglePropertyBase<int>(parent)\n\t{\n\t}\n\n\tconst LayerInfo *valueLayer() const;\n\tLayerInfo *valueLayer();\n\n\tconst QList<LayerInfo> &layers() const;\n\tvoid setLayers(QList<LayerInfo> layers);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\nprivate:\n\tQList<LayerInfo> m_layers;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyLayerBase)\n};\n\nclass QtnPropertyLayerCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyLayerBase>\n{\n\tQ_OBJECT\n\tQtnPropertyLayerCallback(\n\t\tconst QtnPropertyLayerCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyLayerCallback(QObject *parent)\n\t\t: QtnSinglePropertyCallback<QtnPropertyLayerBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyLayerCallback, QtnPropertyLayerBase)\n};\n\nclass QtnPropertyLayer : public QtnSinglePropertyValue<QtnPropertyLayerBase>\n{\n\tQ_OBJECT\n\tQtnPropertyLayer(const QtnPropertyLayer &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyLayer(QObject *parent)\n\t\t: QtnSinglePropertyValue<QtnPropertyLayerBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyLayer, QtnPropertyLayerBase)\n};\n\n#endif // PROPERTY_LAYER_H\n"
  },
  {
    "path": "Demo/MainWindow.cpp",
    "content": "#include \"MainWindow.h\"\n#include \"ui_MainWindow.h\"\n#include \"mydialog.h\"\n#include <QMessageBox>\n#include <QDesktopWidget>\n#include <QInputDialog>\n\n#include \"QtnProperty/QObjectPropertySet.h\"\n#include \"Demo.peg.h\"\n#include \"QtnProperty/FunctionalHelpers.h\"\n\n// this is required for QStringCallbackProperty delegate parameters\n#include \"QtnProperty/Delegates/Core/PropertyDelegateQString.h\"\n\nMainWindow::MainWindow(QWidget *parent)\n\t: QMainWindow(parent)\n\t, ui(new Ui::MainWindow)\n\t, m_candidates({ \"one\", \"two\", \"three\" })\n{\n\tui->setupUi(this);\n\n\tui->pw->setParts(QtnPropertyWidgetPartsDescriptionPanel);\n\n\tauto ps = new QtnPropertySetSamplePS(this);\n\n\tps->LayerProperty.setLayers(\n\t\t{ { \"Top\", Qt::red, 0 }, { \"Left\", Qt::blue, 1 },\n\t\t\t{ \"Right\", Qt::green, 2 }, { \"Bottom\", Qt::gray, 3 } });\n\n\tps->QStringCallbackProperty.setDelegateInfo({ \"Callback\" });\n\tQVariant attr;\n\tattr.setValue(qtnMemFn(this, &MainWindow::getCandidates));\n\tps->QStringCallbackProperty.setDelegateAttribute(\"GetCandidatesFn\", attr);\n\tattr.setValue(qtnMemFn(this, &MainWindow::createCandidate));\n\tps->QStringCallbackProperty.setDelegateAttribute(\"CreateCandidateFn\", attr);\n\n\tui->pw->setPropertySet(ps);\n\n\tqtnScriptRegisterPropertyTypes(&jsEngine);\n\tjsEngine.globalObject().setProperty(\"samplePS\", jsEngine.newQObject(ps));\n\n\tdbg.attachTo(&jsEngine);\n\n\tmove(QApplication::desktop()->availableGeometry().center() -\n\t\trect().center());\n}\n\nMainWindow::~MainWindow()\n{\n\tdelete ui;\n}\n\nvoid MainWindow::on_editButton_clicked()\n{\n\tQtnPropertySet *properties = ui->pw->propertySet();\n\n\tif (!properties)\n\t{\n\t\tQMessageBox::warning(this, \"Demo\", \"Property is not set.\");\n\t\treturn;\n\t}\n\n\t// copy of properties\n\tQtnPropertySet *cpy = properties->createCopy(this);\n\tQ_ASSERT(cpy);\n\t// defaults\n\tQtnPropertySet *dft = properties->createNew(this);\n\tMyDialog dlg(this, *cpy, dft);\n\tif (dlg.exec() == QDialog::Accepted)\n\t{\n\t\tproperties->copyValues(\n\t\t\tcpy, QtnPropertyStateImmutable | QtnPropertyStateInvisible);\n\t}\n}\n\nvoid MainWindow::on_dbgButton_clicked()\n{\n\tQMainWindow *dbgWindow = dbg.standardWindow();\n\tdbgWindow->show();\n}\n\nvoid MainWindow::on_pushButton_clicked()\n{\n\tQtnPropertySet *properties = ui->pw->propertySet();\n\n\tif (!properties)\n\t{\n\t\tQMessageBox::warning(this, \"Demo\", \"Property is not set.\");\n\t\treturn;\n\t}\n\n\tQString txt = ui->plainTextEdit->toPlainText();\n\n\tif (!properties->fromStr(txt))\n\t{\n\t\tQMessageBox::warning(\n\t\t\tthis, \"Demo\", \"Cannot apply string to Propertyset.\");\n\t\treturn;\n\t}\n\n\tui->plainTextEdit->clear();\n}\n\nvoid MainWindow::on_pushButton_3_clicked()\n{\n\tQtnPropertySet *properties = ui->pw->propertySet();\n\n\tif (!properties)\n\t{\n\t\tQMessageBox::warning(this, \"Demo\", \"Property is not set.\");\n\t\treturn;\n\t}\n\n\tQString text;\n\tif (!properties->toStr(text))\n\t{\n\t\tQMessageBox::warning(\n\t\t\tthis, \"Demo\", \"Cannot get string from Propertyset.\");\n\t\treturn;\n\t}\n\n\tui->plainTextEdit->setPlainText(text);\n}\n\nvoid MainWindow::on_pushButton_2_clicked()\n{\n\tQtnPropertySet *bttnProperties =\n\t\tqtnCreateQObjectPropertySet(ui->pushButton_2);\n\tQtnPropertySet *editProperties =\n\t\tqtnCreateQObjectPropertySet(ui->plainTextEdit);\n\tQtnPropertySet properties(this);\n\n\tif (bttnProperties)\n\t\tproperties.addChildProperty(bttnProperties);\n\n\tif (editProperties)\n\t\tproperties.addChildProperty(editProperties);\n\n\tMyDialog dlg(this, properties);\n\tdlg.exec();\n}\n\nQString MainWindow::createCandidate(QWidget *parent, QString candidate)\n{\n\tbool ok;\n\tQString text = QInputDialog::getText(\n\t\tparent, \"Create item\", \"Name:\", QLineEdit::Normal, candidate, &ok);\n\tif (ok && !text.isEmpty())\n\t{\n\t\tif (m_candidates.indexOf(text) < 0)\n\t\t\tm_candidates.append(text);\n\t\telse\n\t\t\tQMessageBox::warning(\n\t\t\t\tparent, \"Create item\", \"Cannot create duplicate.\");\n\n\t\treturn text;\n\t}\n\n\treturn QString();\n}\n"
  },
  {
    "path": "Demo/MainWindow.h",
    "content": "#ifndef MAINWINDOW_H\n#define MAINWINDOW_H\n\n#include <QMainWindow>\n#include <QScriptEngine>\n#include <QScriptEngineDebugger>\n\n#include \"QtnProperty/Property.h\"\n\nnamespace Ui\n{\nclass MainWindow;\n}\n\nclass MainWindow : public QMainWindow\n{\n\tQ_OBJECT\n\npublic:\n\texplicit MainWindow(QWidget *parent = 0);\n\t~MainWindow();\n\nprivate slots:\n\tvoid on_editButton_clicked();\n\tvoid on_dbgButton_clicked();\n\n\tvoid on_pushButton_clicked();\n\n\tvoid on_pushButton_2_clicked();\n\n\tvoid on_pushButton_3_clicked();\n\nprivate:\n\tQStringList getCandidates() const\n\t{\n\t\treturn m_candidates;\n\t}\n\tQString createCandidate(QWidget *parent, QString candidate);\n\n\tUi::MainWindow *ui;\n\n\tQScriptEngineDebugger dbg;\n\tQScriptEngine jsEngine;\n\n\tQStringList m_candidates;\n};\n\n#endif // MAINWINDOW_H\n"
  },
  {
    "path": "Demo/MainWindow.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\"MainWindow\">\n  <property name=\"enabled\">\n   <bool>true</bool>\n  </property>\n  <property name=\"geometry\">\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>675</width>\n    <height>468</height>\n   </rect>\n  </property>\n  <property name=\"font\">\n   <font>\n    <pointsize>10</pointsize>\n   </font>\n  </property>\n  <property name=\"windowTitle\">\n   <string>PropertyWidget Demo</string>\n  </property>\n  <property name=\"iconSize\">\n   <size>\n    <width>24</width>\n    <height>24</height>\n   </size>\n  </property>\n  <widget class=\"QWidget\" name=\"centralWidget\">\n   <property name=\"sizePolicy\">\n    <sizepolicy hsizetype=\"Expanding\" vsizetype=\"Expanding\">\n     <horstretch>0</horstretch>\n     <verstretch>0</verstretch>\n    </sizepolicy>\n   </property>\n   <layout class=\"QHBoxLayout\" name=\"horizontalLayout\">\n    <item>\n     <widget class=\"QtnPropertyWidget\" name=\"pw\" native=\"true\">\n      <property name=\"sizePolicy\">\n       <sizepolicy hsizetype=\"Expanding\" vsizetype=\"Expanding\">\n        <horstretch>0</horstretch>\n        <verstretch>0</verstretch>\n       </sizepolicy>\n      </property>\n      <property name=\"minimumSize\">\n       <size>\n        <width>150</width>\n        <height>0</height>\n       </size>\n      </property>\n     </widget>\n    </item>\n    <item>\n     <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\n      <item>\n       <widget class=\"QPushButton\" name=\"editButton\">\n        <property name=\"text\">\n         <string>Edit in modal dialog...</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QLabel\" name=\"label\">\n        <property name=\"sizePolicy\">\n         <sizepolicy hsizetype=\"Preferred\" vsizetype=\"Preferred\">\n          <horstretch>0</horstretch>\n          <verstretch>0</verstretch>\n         </sizepolicy>\n        </property>\n        <property name=\"text\">\n         <string>Script examples:\nsamplePS.IntProperty.value = 15;\nprint(samplePS.SubPropertySet.SwitchProperty.state);\nsamplePS.UIntProperty.propertyDidChange.connect(\n    function(p1, p2) {\n        print(p2.name+&quot; is &quot;+p2.value+&quot; now&quot;);\n});</string>\n        </property>\n        <property name=\"textFormat\">\n         <enum>Qt::PlainText</enum>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QPushButton\" name=\"dbgButton\">\n        <property name=\"enabled\">\n         <bool>true</bool>\n        </property>\n        <property name=\"text\">\n         <string>Show script debugger</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QLabel\" name=\"label_2\">\n        <property name=\"text\">\n         <string>String examples:\nEnumProperty = blue\nEnableSubPropertySet = true\nSubPropertySet.FolderNameProperty = &quot;/home/my&quot;</string>\n        </property>\n        <property name=\"textFormat\">\n         <enum>Qt::PlainText</enum>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QPlainTextEdit\" name=\"plainTextEdit\"/>\n      </item>\n      <item>\n       <widget class=\"QPushButton\" name=\"pushButton\">\n        <property name=\"text\">\n         <string>from string</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QPushButton\" name=\"pushButton_3\">\n        <property name=\"text\">\n         <string>to string</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QPushButton\" name=\"pushButton_2\">\n        <property name=\"text\">\n         <string>edit QObject properties</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <spacer name=\"verticalSpacer\">\n        <property name=\"orientation\">\n         <enum>Qt::Vertical</enum>\n        </property>\n        <property name=\"sizeHint\" stdset=\"0\">\n         <size>\n          <width>20</width>\n          <height>40</height>\n         </size>\n        </property>\n       </spacer>\n      </item>\n     </layout>\n    </item>\n   </layout>\n  </widget>\n </widget>\n <layoutdefault spacing=\"6\" margin=\"11\"/>\n <customwidgets>\n  <customwidget>\n   <class>QtnPropertyWidget</class>\n   <extends>QWidget</extends>\n   <header>QtnProperty/PropertyWidget.h</header>\n   <container>1</container>\n  </customwidget>\n </customwidgets>\n <resources/>\n <connections/>\n</ui>\n"
  },
  {
    "path": "Demo/PenWidth/PropertyDelegatePenWidth.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegatePenWidth.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"PropertyPenWidth.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n\n#include <QComboBox>\n#include <QLineEdit>\n#include <QStyledItemDelegate>\n#include <QPaintEvent>\n\nvoid regPenWidthDelegates()\n{\n\tQtnPropertyDelegateFactory::staticInstance().registerDelegateDefault(\n\t\t&QtnPropertyPenWidthBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegatePenWidth,\n\t\t\tQtnPropertyPenWidthBase>);\n}\n\nstatic void drawPenWidth(\n\tQStyle *style, PenWidth penWidth, QPainter &painter, QRect rect)\n{\n\trect.adjust(2, 2, -2, -2);\n\n\tQPen pen = painter.pen();\n\n\tswitch (penWidth)\n\t{\n\t\tcase PenWidth::Default:\n\t\t\tqtnDrawValueText(\"Default\", painter, rect, style);\n\t\t\treturn;\n\t\tcase PenWidth::Thin:\n\t\t\tpen.setWidth(1);\n\t\t\tbreak;\n\t\tcase PenWidth::Middle:\n\t\t\tpen.setWidth(2);\n\t\t\tbreak;\n\t\tcase PenWidth::Thick:\n\t\t\tpen.setWidth(3);\n\t\t\tbreak;\n\t}\n\n\tpainter.save();\n\tpainter.setPen(pen);\n\tauto midY = rect.center().y();\n\tpainter.drawLine(rect.left(), midY, rect.right(), midY);\n\tpainter.restore();\n}\n\nclass QtnPropertyPenWidthComboBox : public QComboBox\n{\npublic:\n\texplicit QtnPropertyPenWidthComboBox(\n\t\tQtnPropertyDelegatePenWidth *delegate, QWidget *parent = Q_NULLPTR)\n\t\t: QComboBox(parent)\n\t\t, m_delegate(delegate)\n\t\t, m_property(\n\t\t\t  *static_cast<QtnPropertyPenWidthBase *>(delegate->property()))\n\t\t, m_updating(0)\n\t{\n\t\tsetLineEdit(nullptr);\n\t\tsetItemDelegate(new ItemDelegate(this));\n\n\t\taddItem(QString(), QVariant::fromValue(PenWidth::Default));\n\t\taddItem(QString(), QVariant::fromValue(PenWidth::Thin));\n\t\taddItem(QString(), QVariant::fromValue(PenWidth::Middle));\n\t\taddItem(QString(), QVariant::fromValue(PenWidth::Thick));\n\n\t\tupdateEditor();\n\n\t\tQObject::connect(&m_property, &QtnPropertyBase::propertyDidChange, this,\n\t\t\t&QtnPropertyPenWidthComboBox::onPropertyDidChange,\n\t\t\tQt::QueuedConnection);\n\t\tQObject::connect(this,\n\t\t\tstatic_cast<void (QComboBox::*)(int)>(\n\t\t\t\t&QComboBox::currentIndexChanged),\n\t\t\tthis, &QtnPropertyPenWidthComboBox::onCurrentIndexChanged);\n\t}\n\nprotected:\n\tvoid paintEvent(QPaintEvent *event) override\n\t{\n\t\tQComboBox::paintEvent(event);\n\n\t\tQPainter painter(this);\n\n\t\tauto index = currentIndex();\n\t\tif (index != -1)\n\t\t{\n\t\t\tauto penWidth = currentData().value<PenWidth>();\n\t\t\tdrawPenWidth(style(), penWidth, painter,\n\t\t\t\tevent->rect().adjusted(0, 0, -event->rect().height(), 0));\n\t\t}\n\t}\n\n\tvoid updateEditor()\n\t{\n\t\tm_updating++;\n\t\tsetEnabled(m_delegate->stateProperty()->isEditableByUser());\n\t\tfor (int i = 0; i < count(); ++i)\n\t\t{\n\t\t\tif (itemData(i).value<PenWidth>() == m_property.value())\n\t\t\t\tsetCurrentIndex(i);\n\t\t}\n\t\tm_updating--;\n\t}\n\n\tvoid onPropertyDidChange(QtnPropertyChangeReason reason)\n\t{\n\t\tif ((reason & QtnPropertyChangeReasonValue))\n\t\t\tupdateEditor();\n\t}\n\n\tvoid onCurrentIndexChanged(int index)\n\t{\n\t\tif (index >= 0)\n\t\t{\n\t\t\tm_property.setValue(\n\t\t\t\titemData(index).value<PenWidth>(), m_delegate->editReason());\n\t\t}\n\t}\n\nprivate:\n\tQtnPropertyDelegatePenWidth *m_delegate;\n\tQtnPropertyPenWidthBase &m_property;\n\tunsigned m_updating;\n\n\tclass ItemDelegate : public QStyledItemDelegate\n\t{\n\t\tQComboBox *m_owner;\n\n\tpublic:\n\t\tItemDelegate(QComboBox *owner)\n\t\t\t: m_owner(owner)\n\t\t{\n\t\t}\n\n\t\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\t\tconst QModelIndex &index) const override\n\t\t{\n\t\t\tQStyledItemDelegate::paint(painter, option, index);\n\t\t\tdrawPenWidth(m_owner->style(),\n\t\t\t\tindex.data(Qt::UserRole).value<PenWidth>(), *painter,\n\t\t\t\toption.rect);\n\t\t}\n\t};\n};\n\nbool QtnPropertyDelegatePenWidth::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\treturn owner().toStr(strValue);\n}\n\nvoid QtnPropertyDelegatePenWidth::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tdrawPenWidth(painter.style(), owner().value(), painter, rect);\n}\n\nQWidget *QtnPropertyDelegatePenWidth::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto combo = new QtnPropertyPenWidthComboBox(this, parent);\n\tcombo->setGeometry(rect);\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcombo->showPopup();\n\n\treturn combo;\n}\n"
  },
  {
    "path": "Demo/PenWidth/PropertyDelegatePenWidth.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_PEN_WIDTH_H\n#define PROPERTY_DELEGATE_PEN_WIDTH_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n\nclass QtnPropertyPenWidthBase;\n\nclass QtnPropertyDelegatePenWidth\n\t: public QtnPropertyDelegateTyped<QtnPropertyPenWidthBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegatePenWidth)\n\npublic:\n\tQtnPropertyDelegatePenWidth(QtnPropertyPenWidthBase &owner)\n\t\t: QtnPropertyDelegateTyped<QtnPropertyPenWidthBase>(owner)\n\t{\n\t}\n\nprotected:\n\tbool propertyValueToStrImpl(QString &strValue) const override;\n\tvoid drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n};\n\n#endif // PROPERTY_DELEGATE_PEN_WIDTH_H\n"
  },
  {
    "path": "Demo/PenWidth/PropertyPenWidth.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyPenWidth.h\"\n\nQDataStream &operator<<(QDataStream &stream, const PenWidth penWidth)\n{\n\tstream << (qint64) penWidth;\n\treturn stream;\n}\n\nQDataStream &operator>>(QDataStream &stream, PenWidth &penWidth)\n{\n\tqint64 data = 0;\n\tstream >> data;\n\n\tpenWidth = (PenWidth) data;\n\n\treturn stream;\n}\n\nbool QtnPropertyPenWidthBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QMap<QString, PenWidth> str2PenWidth = {\n\t\t{ \"Default\", PenWidth::Default }, { \"Thin\", PenWidth::Thin },\n\t\t{ \"Middle\", PenWidth::Middle }, { \"Thick\", PenWidth::Thick }\n\t};\n\n\tsetValue(str2PenWidth.value(str, PenWidth::Default), reason);\n\treturn true;\n}\n\nbool QtnPropertyPenWidthBase::toStrImpl(QString &str) const\n{\n\tswitch (value())\n\t{\n\t\tcase PenWidth::Default:\n\t\t\tstr = \"Default\";\n\t\t\treturn true;\n\t\tcase PenWidth::Thin:\n\t\t\tstr = \"Thin\";\n\t\t\treturn true;\n\t\tcase PenWidth::Middle:\n\t\t\tstr = \"Middle\";\n\t\t\treturn true;\n\t\tcase PenWidth::Thick:\n\t\t\tstr = \"Thick\";\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "Demo/PenWidth/PropertyPenWidth.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_PEN_WIDTH_H\n#define PROPERTY_PEN_WIDTH_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include <QColor>\n\nenum class PenWidth\n{\n\tDefault = 0,\n\tThin = 1,\n\tMiddle = 2,\n\tThick = 3\n};\n\nQDataStream &operator<<(QDataStream &stream, const PenWidth penWidth);\nQDataStream &operator>>(QDataStream &stream, PenWidth &penWidth);\n\nQ_DECLARE_METATYPE(PenWidth)\n\nclass QtnPropertyPenWidthBase : public QtnSinglePropertyBase<PenWidth>\n{\n\tQ_OBJECT\n\tQtnPropertyPenWidthBase(\n\t\tconst QtnPropertyPenWidthBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyPenWidthBase(QObject *parent)\n\t\t: QtnSinglePropertyBase<PenWidth>(parent)\n\t{\n\t}\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\nprivate:\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyPenWidthBase)\n};\n\nclass QtnPropertyPenWidthCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyPenWidthBase>\n{\n\tQ_OBJECT\n\tQtnPropertyPenWidthCallback(\n\t\tconst QtnPropertyPenWidthCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyPenWidthCallback(QObject *parent)\n\t\t: QtnSinglePropertyCallback<QtnPropertyPenWidthBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyPenWidthCallback, QtnPropertyPenWidthBase)\n};\n\nclass QtnPropertyPenWidth\n\t: public QtnSinglePropertyValue<QtnPropertyPenWidthBase>\n{\n\tQ_OBJECT\n\tQtnPropertyPenWidth(const QtnPropertyPenWidth &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyPenWidth(QObject *parent)\n\t\t: QtnSinglePropertyValue<QtnPropertyPenWidthBase>(parent)\n\t{\n\t}\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyPenWidth, QtnPropertyPenWidthBase)\n};\n\n#endif // PROPERTY_PEN_WIDTH_H\n"
  },
  {
    "path": "Demo/main.cpp",
    "content": "#include \"MainWindow.h\"\n#include <QApplication>\n\nvoid regABColorDelegates();\nvoid regIntListDelegates();\nvoid regLayerDelegates();\nvoid regPenWidthDelegates();\nvoid regFreqDelegates();\n\nint main(int argc, char *argv[])\n{\n    regABColorDelegates();\n    regIntListDelegates();\n    regLayerDelegates();\n    regPenWidthDelegates();\n    regFreqDelegates();\n\n    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);\n    QApplication a(argc, argv);\n    MainWindow w;\n    w.show();\n    \n    return a.exec();\n}\n"
  },
  {
    "path": "Demo/mydialog.cpp",
    "content": "#include \"mydialog.h\"\n#include \"ui_mydialog.h\"\n\nMyDialog::MyDialog(QWidget* parent, QtnPropertySet& propertySet, const QtnPropertySet* defaultProperty) :\n    QDialog(parent),\n    ui(new Ui::MyDialog),\n    m_defaultProperty(defaultProperty)\n{\n    ui->setupUi(this);\n\n    ui->widget->setPropertySet(&propertySet);\n}\n\nMyDialog::~MyDialog()\n{\n    delete ui;\n}\n"
  },
  {
    "path": "Demo/mydialog.h",
    "content": "#ifndef MYDIALOG_H\n#define MYDIALOG_H\n\n#include <QDialog>\n#include \"QtnProperty/Property.h\"\n\nnamespace Ui\n{\nclass MyDialog;\n}\n\nclass MyDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tMyDialog(QWidget *parent, QtnPropertySet &properties,\n\t\tconst QtnPropertySet *defaultProperties = nullptr);\n\t~MyDialog();\n\nprivate:\n\tUi::MyDialog *ui;\n\tconst QtnPropertySet *m_defaultProperty;\n};\n\n#endif // MYDIALOG_H\n"
  },
  {
    "path": "Demo/mydialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MyDialog</class>\n <widget class=\"QDialog\" name=\"MyDialog\">\n  <property name=\"geometry\">\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>666</width>\n    <height>300</height>\n   </rect>\n  </property>\n  <property name=\"windowTitle\">\n   <string>Dialog</string>\n  </property>\n  <layout class=\"QHBoxLayout\" name=\"horizontalLayout\">\n   <item>\n    <widget class=\"QtnPropertyWidgetEx\" name=\"widget\" native=\"true\"/>\n   </item>\n   <item>\n    <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\n     <property name=\"sizeConstraint\">\n      <enum>QLayout::SetDefaultConstraint</enum>\n     </property>\n     <item>\n      <widget class=\"QDialogButtonBox\" name=\"buttonBox\">\n       <property name=\"sizePolicy\">\n        <sizepolicy hsizetype=\"Preferred\" vsizetype=\"Maximum\">\n         <horstretch>0</horstretch>\n         <verstretch>0</verstretch>\n        </sizepolicy>\n       </property>\n       <property name=\"locale\">\n        <locale language=\"English\" country=\"UnitedStates\"/>\n       </property>\n       <property name=\"orientation\">\n        <enum>Qt::Vertical</enum>\n       </property>\n       <property name=\"standardButtons\">\n        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>\n       </property>\n       <property name=\"centerButtons\">\n        <bool>false</bool>\n       </property>\n      </widget>\n     </item>\n     <item>\n      <spacer name=\"verticalSpacer\">\n       <property name=\"orientation\">\n        <enum>Qt::Vertical</enum>\n       </property>\n       <property name=\"sizeType\">\n        <enum>QSizePolicy::MinimumExpanding</enum>\n       </property>\n       <property name=\"sizeHint\" stdset=\"0\">\n        <size>\n         <width>0</width>\n         <height>0</height>\n        </size>\n       </property>\n      </spacer>\n     </item>\n    </layout>\n   </item>\n  </layout>\n </widget>\n <customwidgets>\n  <customwidget>\n   <class>QtnPropertyWidgetEx</class>\n   <extends>QWidget</extends>\n   <header>QtnProperty/PropertyWidgetEx.h</header>\n   <container>1</container>\n  </customwidget>\n </customwidgets>\n <resources/>\n <connections>\n  <connection>\n   <sender>buttonBox</sender>\n   <signal>accepted()</signal>\n   <receiver>MyDialog</receiver>\n   <slot>accept()</slot>\n   <hints>\n    <hint type=\"sourcelabel\">\n     <x>248</x>\n     <y>254</y>\n    </hint>\n    <hint type=\"destinationlabel\">\n     <x>157</x>\n     <y>274</y>\n    </hint>\n   </hints>\n  </connection>\n  <connection>\n   <sender>buttonBox</sender>\n   <signal>rejected()</signal>\n   <receiver>MyDialog</receiver>\n   <slot>reject()</slot>\n   <hints>\n    <hint type=\"sourcelabel\">\n     <x>316</x>\n     <y>260</y>\n    </hint>\n    <hint type=\"destinationlabel\">\n     <x>286</x>\n     <y>274</y>\n    </hint>\n   </hints>\n  </connection>\n </connections>\n</ui>\n"
  },
  {
    "path": "Docs/Doxyfile",
    "content": "# Doxyfile 1.8.3.1\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project\n#\n# All text after a hash (#) is considered a comment and will be ignored\n# The format is:\n#       TAG = value [value, ...]\n# For lists items can also be appended using:\n#       TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\" \")\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file \n# that follow. The default is UTF-8 which is also the encoding used for all \n# text before the first occurrence of this tag. Doxygen uses libiconv (or the \n# iconv built into libc) for the transcoding. See \n# http://www.gnu.org/software/libiconv for the list of possible encodings.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or sequence of words) that should \n# identify the project. Note that if you do not use Doxywizard you need \n# to put quotes around the project name if it contains spaces.\n\nPROJECT_NAME           = QtnProperty\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \n# This could be handy for archiving the generated documentation or \n# if some version control system is used.\n\nPROJECT_NUMBER         = \n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description \n# for a project that appears at the top of each page and should give viewer \n# a quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is \n# included in the documentation. The maximum height of the logo should not \n# exceed 55 pixels and the maximum width should not exceed 200 pixels. \n# Doxygen will copy the logo to the output directory.\n\nPROJECT_LOGO           = \n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \n# base path where the generated documentation will be put. \n# If a relative path is entered, it will be relative to the location \n# where doxygen was started. If left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = .\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create \n# 4096 sub-directories (in 2 levels) under the output directory of each output \n# format and will distribute the generated files over these directories. \n# Enabling this option can be useful when feeding doxygen a huge amount of \n# source files, where putting all generated files in the same directory would \n# otherwise cause performance problems for the file system.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \n# documentation generated by doxygen is written. Doxygen will use this \n# information to generate all constant output in the proper language. \n# The default language is English, other supported languages are: \n# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, \n# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, \n# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English \n# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, \n# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, \n# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \n# include brief member descriptions after the members that are listed in \n# the file and class documentation (similar to JavaDoc). \n# Set to NO to disable this.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \n# the brief description of a member or function before the detailed description. \n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \n# brief descriptions will be completely suppressed.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator \n# that is used to form the text in various listings. Each string \n# in this list, if found as the leading text of the brief description, will be \n# stripped from the text and the result after processing the whole list, is \n# used as the annotated text. Otherwise, the brief description is used as-is. \n# If left blank, the following values are used (\"$name\" is automatically \n# replaced with the name of the entity): \"The $name class\" \"The $name widget\" \n# \"The $name file\" \"is\" \"provides\" \"specifies\" \"contains\" \n# \"represents\" \"a\" \"an\" \"the\"\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \n# Doxygen will generate a detailed section even if there is only a brief \n# description.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all \n# inherited members of a class in the documentation of that class as if those \n# members were ordinary class members. Constructors, destructors and assignment \n# operators of the base classes will not be shown.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \n# path before files name in the file list and in the header files. If set \n# to NO the shortest path that makes the file name unique will be used.\n\nFULL_PATH_NAMES        = YES\n\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \n# can be used to strip a user-defined part of the path. Stripping is \n# only done if one of the specified strings matches the left-hand part of \n# the path. The tag can be used to show relative paths in the file list. \n# If left blank the directory from which doxygen is run is used as the \n# path to strip. Note that you specify absolute paths here, but also \n# relative paths, which will be relative from the directory where doxygen is \n# started.\n\nSTRIP_FROM_PATH        = \n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of \n# the path mentioned in the documentation of a class, which tells \n# the reader which header file to include in order to use a class. \n# If left blank only the name of the header file containing the class \n# definition is used. Otherwise one should specify the include paths that \n# are normally passed to the compiler using the -I flag.\n\nSTRIP_FROM_INC_PATH    = \n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \n# (but less readable) file names. This can be useful if your file system \n# doesn't support long names like on DOS, Mac, or CD-ROM.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \n# will interpret the first line (until the first dot) of a JavaDoc-style \n# comment as the brief description. If set to NO, the JavaDoc \n# comments will behave just like regular Qt-style comments \n# (thus requiring an explicit @brief command for a brief description.)\n\nJAVADOC_AUTOBRIEF      = NO\n\n# If the QT_AUTOBRIEF tag is set to YES then Doxygen will \n# interpret the first line (until the first dot) of a Qt-style \n# comment as the brief description. If set to NO, the comments \n# will behave just like regular Qt-style comments (thus requiring \n# an explicit \\brief command for a brief description.)\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \n# comments) as a brief description. This used to be the default behaviour. \n# The new default is to treat a multi-line C++ comment block as a detailed \n# description. Set this tag to YES if you prefer the old behaviour instead.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \n# member inherits the documentation from any documented member that it \n# re-implements.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce \n# a new page for each member. If set to NO, the documentation of a member will \n# be part of the file/class/namespace that contains it.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \n# Doxygen uses this value to replace tabs by spaces in code fragments.\n\nTAB_SIZE               = 8\n\n# This tag can be used to specify a number of aliases that acts \n# as commands in the documentation. An alias has the form \"name=value\". \n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \n# put the command \\sideeffect (or @sideeffect) in the documentation, which \n# will result in a user-defined paragraph with heading \"Side Effects:\". \n# You can put \\n's in the value part of an alias to insert newlines.\n\nALIASES                = \n\n# This tag can be used to specify a number of word-keyword mappings (TCL only). \n# A mapping has the form \"name=value\". For example adding \n# \"class=itcl::class\" will allow you to use the command class in the \n# itcl::class meaning.\n\nTCL_SUBST              = \n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C \n# sources only. Doxygen will then generate output that is more tailored for C. \n# For instance, some of the names that are used will be different. The list \n# of all members will be omitted, etc.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java \n# sources only. Doxygen will then generate output that is more tailored for \n# Java. For instance, namespaces will be presented as packages, qualified \n# scopes will look different, etc.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran \n# sources only. Doxygen will then generate output that is more tailored for \n# Fortran.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL \n# sources. Doxygen will then generate output that is tailored for \n# VHDL.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it \n# parses. With this tag you can assign which parser to use for a given \n# extension. Doxygen has a built-in mapping, but you can override or extend it \n# using this tag. The format is ext=language, where ext is a file extension, \n# and language is one of the parsers supported by doxygen: IDL, Java, \n# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, \n# C++. For instance to make doxygen treat .inc files as Fortran files (default \n# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note \n# that for custom extensions you also need to set FILE_PATTERNS otherwise the \n# files are not read by doxygen.\n\nEXTENSION_MAPPING      = \n\n# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all \n# comments according to the Markdown format, which allows for more readable \n# documentation. See http://daringfireball.net/projects/markdown/ for details. \n# The output of markdown processing is further processed by doxygen, so you \n# can mix doxygen, HTML, and XML commands with Markdown formatting. \n# Disable only in case of backward compatibilities issues.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented classes, \n# or namespaces to their corresponding documentation. Such a link can be \n# prevented in individual cases by by putting a % sign in front of the word or \n# globally by setting AUTOLINK_SUPPORT to NO.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want \n# to include (a tag file for) the STL sources as input, then you should \n# set this tag to YES in order to let doxygen match functions declarations and \n# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. \n# func(std::string) {}). This also makes the inheritance and collaboration \n# diagrams that involve STL classes more complete and accurate.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to \n# enable parsing support.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. \n# Doxygen will parse them like normal C++ but will assume all classes use public \n# instead of private inheritance when no explicit protection keyword is present.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate \n# getter and setter methods for a property. Setting this option to YES (the \n# default) will make doxygen replace the get and set methods by a property in \n# the documentation. This will only work if the methods are indeed getting or \n# setting a simple type. If this is not the case, or you want to show the \n# methods anyway, you should set this option to NO.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \n# tag is set to YES, then doxygen will reuse the documentation of the first \n# member in the group (if any) for the other members of the group. By default \n# all members of a group must be documented explicitly.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES (the default) to allow class member groups of \n# the same type (for instance a group of public functions) to be put as a \n# subgroup of that type (e.g. under the Public Functions section). Set it to \n# NO to prevent subgrouping. Alternatively, this can be done per class using \n# the \\nosubgrouping command.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and \n# unions are shown inside the group in which they are included (e.g. using \n# @ingroup) instead of on a separate page (for HTML and Man pages) or \n# section (for LaTeX and RTF).\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and \n# unions with only public data fields will be shown inline in the documentation \n# of the scope in which they are defined (i.e. file, namespace, or group \n# documentation), provided this scope is documented. If set to NO (the default), \n# structs, classes, and unions are shown on a separate page (for HTML and Man \n# pages) or section (for LaTeX and RTF).\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum \n# is documented as struct, union, or enum with the name of the typedef. So \n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct \n# with name TypeT. When disabled the typedef will appear as a member of a file, \n# namespace, or class. And the struct will be named TypeS. This can typically \n# be useful for C code in case the coding convention dictates that all compound \n# types are typedef'ed and only the typedef is referenced, never the tag name.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to \n# determine which symbols to keep in memory and which to flush to disk. \n# When the cache is full, less often used symbols will be written to disk. \n# For small to medium size projects (<1000 input files) the default value is \n# probably good enough. For larger projects a too small cache size can cause \n# doxygen to be busy swapping symbols to and from disk most of the time \n# causing a significant performance penalty. \n# If the system has enough physical memory increasing the cache will improve the \n# performance by keeping more symbols in memory. Note that the value works on \n# a logarithmic scale so increasing the size by one will roughly double the \n# memory usage. The cache size is given by this formula: \n# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, \n# corresponding to a cache size of 2^16 = 65536 symbols.\n\nSYMBOL_CACHE_SIZE      = 0\n\n# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be \n# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given \n# their name and scope. Since this can be an expensive process and often the \n# same symbol appear multiple times in the code, doxygen keeps a cache of \n# pre-resolved symbols. If the cache is too small doxygen will become slower. \n# If the cache is too large, memory is wasted. The cache size is given by this \n# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, \n# corresponding to a cache size of 2^16 = 65536 symbols.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \n# documentation are documented, even if no documentation was available. \n# Private class members and static file members will be hidden unless \n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \n# will be included in the documentation.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal \n# scope will be included in the documentation.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \n# will be included in the documentation.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \n# defined locally in source files will be included in the documentation. \n# If set to NO only classes defined in header files are included.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. When set to YES local \n# methods, which are defined in the implementation section but not in \n# the interface are included in the documentation. \n# If set to NO (the default) only methods in the interface are included.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be \n# extracted and appear in the documentation as a namespace called \n# 'anonymous_namespace{file}', where file will be replaced with the base \n# name of the file that contains the anonymous namespace. By default \n# anonymous namespaces are hidden.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n# undocumented members of documented classes, files or namespaces. \n# If set to NO (the default) these members will be included in the \n# various overviews, but no documentation section is generated. \n# This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \n# undocumented classes that are normally visible in the class hierarchy. \n# If set to NO (the default) these classes will be included in the various \n# overviews. This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \n# friend (class|struct|union) declarations. \n# If set to NO (the default) these declarations will be included in the \n# documentation.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \n# documentation blocks found inside the body of a function. \n# If set to NO (the default) these blocks will be appended to the \n# function's detailed documentation block.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation \n# that is typed after a \\internal command is included. If the tag is set \n# to NO (the default) then the documentation will be excluded. \n# Set it to YES to include the internal documentation.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \n# file names in lower-case letters. If set to YES upper-case letters are also \n# allowed. This is useful if you have classes or files whose names only differ \n# in case and if your file system supports case sensitive file names. Windows \n# and Mac users are advised to set this option to NO.\n\nCASE_SENSE_NAMES       = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \n# will show members with their full class and namespace scopes in the \n# documentation. If set to YES the scope will be hidden.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n# will put a list of the files that are included by a file in the documentation \n# of that file.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen \n# will list include files with double quotes in the documentation \n# rather than with sharp brackets.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \n# is inserted in the documentation for inline members.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \n# will sort the (detailed) documentation of file and class members \n# alphabetically by member name. If set to NO the members will appear in \n# declaration order.\n\nSORT_MEMBER_DOCS       = NO\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the \n# brief documentation of file, namespace and class members alphabetically \n# by member name. If set to NO (the default) the members will appear in \n# declaration order.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen \n# will sort the (brief and detailed) documentation of class members so that \n# constructors and destructors are listed first. If set to NO (the default) \n# the constructors will appear in the respective orders defined by \n# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. \n# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO \n# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the \n# hierarchy of group names into alphabetical order. If set to NO (the default) \n# the group names will appear in their defined order.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be \n# sorted by fully-qualified names, including namespaces. If set to \n# NO (the default), the class list will be sorted only by class name, \n# not including the namespace part. \n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. \n# Note: This option applies only to the class list, not to the \n# alphabetical list.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to \n# do proper type resolution of all parameters of a function it will reject a \n# match between the prototype and the implementation of a member function even \n# if there is only one candidate or it is obvious which candidate to choose \n# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen \n# will still accept a match between prototype and implementation in such cases.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \n# disable (NO) the todo list. This list is created by putting \\todo \n# commands in the documentation.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \n# disable (NO) the test list. This list is created by putting \\test \n# commands in the documentation.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \n# disable (NO) the bug list. This list is created by putting \\bug \n# commands in the documentation.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \n# disable (NO) the deprecated list. This list is created by putting \n# \\deprecated commands in the documentation.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional \n# documentation sections, marked by \\if section-label ... \\endif \n# and \\cond section-label ... \\endcond blocks.\n\nENABLED_SECTIONS       = \n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \n# the initial value of a variable or macro consists of for it to appear in \n# the documentation. If the initializer consists of more lines than specified \n# here it will be hidden. Use a value of 0 to hide initializers completely. \n# The appearance of the initializer of individual variables and macros in the \n# documentation can be controlled using \\showinitializer or \\hideinitializer \n# command in the documentation regardless of this setting.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n# at the bottom of the documentation of classes and structs. If set to YES the \n# list will mention the files that were used to generate the documentation.\n\nSHOW_USED_FILES        = YES\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. \n# This will remove the Files entry from the Quick Index and from the \n# Folder Tree View (if specified). The default is YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the \n# Namespaces page.  This will remove the Namespaces entry from the Quick Index \n# and from the Folder Tree View (if specified). The default is YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that \n# doxygen should invoke to get the current version for each file (typically from \n# the version control system). Doxygen will invoke the program by executing (via \n# popen()) the command <command> <input-file>, where <command> is the value of \n# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file \n# provided by doxygen. Whatever the program writes to standard output \n# is used as the file version. See the manual for examples.\n\nFILE_VERSION_FILTER    = \n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed \n# by doxygen. The layout file controls the global structure of the generated \n# output files in an output format independent way. To create the layout file \n# that represents doxygen's defaults, run doxygen with the -l option. \n# You can optionally specify a file name after the option, if omitted \n# DoxygenLayout.xml will be used as the name of the layout file.\n\nLAYOUT_FILE            = \n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files \n# containing the references data. This must be a list of .bib files. The \n# .bib extension is automatically appended if omitted. Using this command \n# requires the bibtex tool to be installed. See also \n# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style \n# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this \n# feature you need bibtex and perl available in the search path. Do not use \n# file names with spaces, bibtex cannot handle them.\n\nCITE_BIB_FILES         = \n\n#---------------------------------------------------------------------------\n# configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated \n# by doxygen. Possible values are YES and NO. If left blank NO is used.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are \n# generated by doxygen. Possible values are YES and NO. If left blank \n# NO is used.\n\nWARNINGS               = YES\n\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \n# automatically be disabled.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \n# potential errors in the documentation, such as not documenting some \n# parameters in a documented function, or documenting parameters that \n# don't exist or using markup commands wrongly.\n\nWARN_IF_DOC_ERROR      = YES\n\n# The WARN_NO_PARAMDOC option can be enabled to get warnings for \n# functions that are documented, but have no documentation for their parameters \n# or return value. If set to NO (the default) doxygen will only warn about \n# wrong or incomplete parameter documentation, but not about the absence of \n# documentation.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that \n# doxygen can produce. The string should contain the $file, $line, and $text \n# tags, which will be replaced by the file and line number from which the \n# warning originated and the warning text. Optionally the format may contain \n# $version, which will be replaced by the version of the file (if it could \n# be obtained via FILE_VERSION_FILTER)\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning \n# and error messages should be written. If left blank the output is written \n# to stderr.\n\nWARN_LOGFILE           = \n\n#---------------------------------------------------------------------------\n# configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag can be used to specify the files and/or directories that contain \n# documented source files. You may enter file names like \"myfile.cpp\" or \n# directories like \"/usr/src/myproject\". Separate the files or directories \n# with spaces.\n\nINPUT                  = .. \\\n                         ../../Utils\n\n# This tag can be used to specify the character encoding of the source files \n# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is \n# also the default input encoding. Doxygen uses libiconv (or the iconv built \n# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for \n# the list of possible encodings.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the \n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank the following patterns are tested: \n# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh \n# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py \n# *.f90 *.f *.for *.vhd *.vhdl\n\nFILE_PATTERNS          = *.c \\\n                         *.cc \\\n                         *.cxx \\\n                         *.cpp \\\n                         *.c++ \\\n                         *.d \\\n                         *.java \\\n                         *.ii \\\n                         *.ixx \\\n                         *.ipp \\\n                         *.i++ \\\n                         *.inl \\\n                         *.h \\\n                         *.hh \\\n                         *.hxx \\\n                         *.hpp \\\n                         *.h++ \\\n                         *.idl \\\n                         *.odl \\\n                         *.cs \\\n                         *.php \\\n                         *.php3 \\\n                         *.inc \\\n                         *.m \\\n                         *.markdown \\\n                         *.md \\\n                         *.mm \\\n                         *.dox \\\n                         *.py \\\n                         *.f90 \\\n                         *.f \\\n                         *.for \\\n                         *.vhd \\\n                         *.vhdl\n\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \n# should be searched for input files as well. Possible values are YES and NO. \n# If left blank NO is used.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be \n# excluded from the INPUT source files. This way you can easily exclude a \n# subdirectory from a directory tree whose root is specified with the INPUT tag. \n# Note that relative paths are relative to the directory from which doxygen is \n# run.\n\nEXCLUDE                = ../Demo \\\n                         ../Tests \\\n                         ../PEG\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or \n# directories that are symbolic links (a Unix file system feature) are excluded \n# from the input.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the \n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \n# certain files from those directories. Note that the wildcards are matched \n# against the file with absolute path, so to exclude all test directories \n# for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       = \n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names \n# (namespaces, classes, functions, etc.) that should be excluded from the \n# output. The symbol name can be a fully qualified name, a word, or if the \n# wildcard * is used, a substring. Examples: ANamespace, AClass, \n# AClass::ANamespace, ANamespace::*Test\n\nEXCLUDE_SYMBOLS        = \n\n# The EXAMPLE_PATH tag can be used to specify one or more files or \n# directories that contain example code fragments that are included (see \n# the \\include command).\n\nEXAMPLE_PATH           = \n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank all files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \n# searched for input files to be used with the \\include or \\dontinclude \n# commands irrespective of the value of the RECURSIVE tag. \n# Possible values are YES and NO. If left blank NO is used.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or \n# directories that contain image that are included in the documentation (see \n# the \\image command).\n\nIMAGE_PATH             = ./img\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \n# invoke to filter for each input file. Doxygen will invoke the filter program \n# by executing (via popen()) the command <filter> <input-file>, where <filter> \n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \n# input file. Doxygen will then use the output that the filter program writes \n# to standard output.  If FILTER_PATTERNS is specified, this tag will be \n# ignored.\n\nINPUT_FILTER           = \n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern \n# basis.  Doxygen will compare the file name with each pattern and apply the \n# filter if there is a match.  The filters are a list of the form: \n# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further \n# info on how filters are used. If FILTER_PATTERNS is empty or if \n# non of the patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        = \n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \n# INPUT_FILTER) will be used to filter the input files when producing source \n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file \n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) \n# and it is also possible to disable source filtering for a specific pattern \n# using *.ext= (so without naming a filter). This option only has effect when \n# FILTER_SOURCE_FILES is enabled.\n\nFILTER_SOURCE_PATTERNS = \n\n# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that \n# is part of the input, its contents will be placed on the main page (index.html). \n# This can be useful if you have a project on for instance GitHub and want reuse \n# the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE = \n\n#---------------------------------------------------------------------------\n# configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \n# be generated. Documented entities will be cross-referenced with these sources. \n# Note: To get rid of all source code in the generated output, make sure also \n# VERBATIM_HEADERS is set to NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body \n# of functions and classes directly in the documentation.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \n# doxygen to hide any special comment blocks from generated source code \n# fragments. Normal C, C++ and Fortran comments will always remain visible.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES \n# then for each documented function all documented \n# functions referencing it will be listed.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES \n# then for each documented function all documented entities \n# called/used by that function will be listed.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) \n# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from \n# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will \n# link to the source code.  Otherwise they will link to the documentation.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code \n# will point to the HTML generated by the htags(1) tool instead of doxygen \n# built-in source browser. The htags tool is part of GNU's global source \n# tagging system (see http://www.gnu.org/software/global/global.html). You \n# will need version 4.8.6 or higher.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \n# will generate a verbatim copy of the header file for each class for \n# which an include is specified. Set to NO to disable this.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \n# of all compounds will be generated. Enable this if the project \n# contains a lot of classes, structs, unions or interfaces.\n\nALPHABETICAL_INDEX     = YES\n\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \n# in which this list will be split (can be a number in the range [1..20])\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all \n# classes will be put under the same header in the alphabetical index. \n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \n# should be ignored while generating the index headers.\n\nIGNORE_PREFIX          = \n\n#---------------------------------------------------------------------------\n# configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \n# generate HTML output.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `html' will be used as the default path.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \n# doxygen will generate files with .html extension.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a personal HTML header for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard header. Note that when using a custom header you are responsible  \n# for the proper inclusion of any scripts and style sheets that doxygen \n# needs, which is dependent on the configuration options used. \n# It is advised to generate a default header using \"doxygen -w html \n# header.html footer.html stylesheet.css YourConfigFile\" and then modify \n# that header. Note that the header is subject to change so you typically \n# have to redo this when upgrading to a newer version of doxygen or when \n# changing the value of configuration settings such as GENERATE_TREEVIEW!\n\nHTML_HEADER            = \n\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard footer.\n\nHTML_FOOTER            = \n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading \n# style sheet that is used by each HTML page. It can be used to \n# fine-tune the look of the HTML output. If left blank doxygen will \n# generate a default style sheet. Note that it is recommended to use \n# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this \n# tag will in the future become obsolete.\n\nHTML_STYLESHEET        = \n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional \n# user-defined cascading style sheet that is included after the standard \n# style sheets created by doxygen. Using this option one can overrule \n# certain style aspects. This is preferred over using HTML_STYLESHEET \n# since it does not replace the standard style sheet and is therefor more \n# robust against future updates. Doxygen will copy the style sheet file to \n# the output directory.\n\nHTML_EXTRA_STYLESHEET  = \n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or \n# other source files which should be copied to the HTML output directory. Note \n# that these files will be copied to the base HTML output directory. Use the \n# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these \n# files. In the HTML_STYLESHEET file, use the file name only. Also note that \n# the files will be copied as-is; there are no commands or markers available.\n\nHTML_EXTRA_FILES       = \n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. \n# Doxygen will adjust the colors in the style sheet and background images \n# according to this color. Hue is specified as an angle on a colorwheel, \n# see http://en.wikipedia.org/wiki/Hue for more information. \n# For instance the value 0 represents red, 60 is yellow, 120 is green, \n# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. \n# The allowed range is 0 to 359.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of \n# the colors in the HTML output. For a value of 0 the output will use \n# grayscales only. A value of 255 will produce the most vivid colors.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to \n# the luminance component of the colors in the HTML output. Values below \n# 100 gradually make the output lighter, whereas values above 100 make \n# the output darker. The value divided by 100 is the actual gamma applied, \n# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, \n# and 100 does not change the gamma.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML \n# page will contain the date and time when the page was generated. Setting \n# this to NO can help when comparing the output of multiple runs.\n\nHTML_TIMESTAMP         = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n# documentation will contain sections that can be hidden and shown after the \n# page has loaded.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of \n# entries shown in the various tree structured indices initially; the user \n# can expand and collapse entries dynamically later on. Doxygen will expand \n# the tree to such a level that at most the specified number of entries are \n# visible (unless a fully collapsed tree already exceeds this amount). \n# So setting the number of entries 1 will produce a full collapsed tree by \n# default. 0 is a special value representing an infinite number of entries \n# and will result in a full expanded tree by default.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files \n# will be generated that can be used as input for Apple's Xcode 3 \n# integrated development environment, introduced with OSX 10.5 (Leopard). \n# To create a documentation set, doxygen will generate a Makefile in the \n# HTML output directory. Running make will produce the docset in that \n# directory and running \"make install\" will install the docset in \n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find \n# it at startup. \n# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html \n# for more information.\n\nGENERATE_DOCSET        = NO\n\n# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the \n# feed. A documentation feed provides an umbrella under which multiple \n# documentation sets from a single provider (such as a company or product suite) \n# can be grouped.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that \n# should uniquely identify the documentation set bundle. This should be a \n# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen \n# will append .docset to the name.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely \n# identify the documentation publisher. This should be a reverse domain-name \n# style string, e.g. com.mycompany.MyDocSet.documentation.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \n# will be generated that can be used as input for tools like the \n# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) \n# of the generated HTML documentation.\n\nGENERATE_HTMLHELP      = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \n# be used to specify the file name of the resulting .chm file. You \n# can add a path in front of the file if the result should not be \n# written to the html output directory.\n\nCHM_FILE               = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \n# be used to specify the location (absolute path including file name) of \n# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run \n# the HTML help compiler on the generated index.hhp.\n\nHHC_LOCATION           = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \n# controls if a separate .chi index file is generated (YES) or that \n# it should be included in the master .chm file (NO).\n\nGENERATE_CHI           = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING \n# is used to encode HtmlHelp index (hhk), content (hhc) and project file \n# content.\n\nCHM_INDEX_ENCODING     = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \n# controls whether a binary table of contents is generated (YES) or a \n# normal table of contents (NO) in the .chm file.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \n# to the contents of the HTML help documentation and to the tree view.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and \n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated \n# that can be used as input for Qt's qhelpgenerator to generate a \n# Qt Compressed Help (.qch) of the generated HTML documentation.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can \n# be used to specify the file name of the resulting .qch file. \n# The path specified is relative to the HTML output folder.\n\nQCH_FILE               = \n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating \n# Qt Help Project output. For more information please see \n# http://doc.trolltech.com/qthelpproject.html#namespace\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating \n# Qt Help Project output. For more information please see \n# http://doc.trolltech.com/qthelpproject.html#virtual-folders\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to \n# add. For more information please see \n# http://doc.trolltech.com/qthelpproject.html#custom-filters\n\nQHP_CUST_FILTER_NAME   = \n\n# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the \n# custom filter to add. For more information please see \n# <a href=\"http://doc.trolltech.com/qthelpproject.html#custom-filters\"> \n# Qt Help Project / Custom Filters</a>.\n\nQHP_CUST_FILTER_ATTRS  = \n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this \n# project's \n# filter section matches. \n# <a href=\"http://doc.trolltech.com/qthelpproject.html#filter-attributes\"> \n# Qt Help Project / Filter Attributes</a>.\n\nQHP_SECT_FILTER_ATTRS  = \n\n# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can \n# be used to specify the location of Qt's qhelpgenerator. \n# If non-empty doxygen will try to run qhelpgenerator on the generated \n# .qhp file.\n\nQHG_LOCATION           = \n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  \n# will be generated, which together with the HTML files, form an Eclipse help \n# plugin. To install this plugin and make it available under the help contents \n# menu in Eclipse, the contents of the directory containing the HTML and XML \n# files needs to be copied into the plugins directory of eclipse. The name of \n# the directory within the plugins directory should be the same as \n# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before \n# the help appears.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the eclipse help plugin. When installing the plugin \n# the directory name containing the HTML and XML files should also have \n# this name.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) \n# at top of each HTML page. The value NO (the default) enables the index and \n# the value YES disables it. Since the tabs have the same information as the \n# navigation tree you can set this option to NO if you already set \n# GENERATE_TREEVIEW to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index \n# structure should be generated to display hierarchical information. \n# If the tag value is set to YES, a side panel will be generated \n# containing a tree-like index structure (just like the one that \n# is generated for HTML Help). For this to work a browser that supports \n# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). \n# Windows users are probably better off using the HTML help feature. \n# Since the tree basically has the same information as the tab index you \n# could consider to set DISABLE_INDEX to NO when enabling this option.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values \n# (range [0,1..20]) that doxygen will group on one line in the generated HTML \n# documentation. Note that a value of 0 will completely suppress the enum \n# values from appearing in the overview section.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n# used to set the initial width (in pixels) of the frame in which the tree \n# is shown.\n\nTREEVIEW_WIDTH         = 250\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open \n# links to external symbols imported via tag files in a separate window.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of Latex formulas included \n# as images in the HTML documentation. The default is 10. Note that \n# when you change the font size after a successful doxygen run you need \n# to manually remove any form_*.png images from the HTML output directory \n# to force them to be regenerated.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images \n# generated for formulas are transparent PNGs. Transparent PNGs are \n# not supported properly for IE 6.0, but are supported on all modern browsers. \n# Note that when changing this option you need to delete any form_*.png files \n# in the HTML output before the changes have effect.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax \n# (see http://www.mathjax.org) which uses client side Javascript for the \n# rendering instead of using prerendered bitmaps. Use this if you do not \n# have LaTeX installed or if you want to formulas look prettier in the HTML \n# output. When enabled you may also need to install MathJax separately and \n# configure the path to it using the MATHJAX_RELPATH option.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for \n# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and \n# SVG. The default value is HTML-CSS, which is slower, but has the best \n# compatibility.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the \n# HTML output directory using the MATHJAX_RELPATH option. The destination \n# directory should contain the MathJax.js script. For instance, if the mathjax \n# directory is located at the same level as the HTML output directory, then \n# MATHJAX_RELPATH should be ../mathjax. The default value points to \n# the MathJax Content Delivery Network so you can quickly see the result without \n# installing MathJax.  However, it is strongly recommended to install a local \n# copy of MathJax from http://www.mathjax.org before deployment.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension \n# names that should be enabled during MathJax rendering.\n\nMATHJAX_EXTENSIONS     = \n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box \n# for the HTML output. The underlying search engine uses javascript \n# and DHTML and should work on any modern browser. Note that when using \n# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets \n# (GENERATE_DOCSET) there is already a search function so this one should \n# typically be disabled. For large projects the javascript based search engine \n# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be \n# implemented using a web server instead of a web client using Javascript. \n# There are two flavours of web server based search depending on the \n# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for \n# searching and an index file used by the script. When EXTERNAL_SEARCH is \n# enabled the indexing and searching needs to be provided by external tools. \n# See the manual for details.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP \n# script for searching. Instead the search results are written to an XML file \n# which needs to be processed by an external indexer. Doxygen will invoke an \n# external search engine pointed to by the SEARCHENGINE_URL option to obtain \n# the search results. Doxygen ships with an example indexer (doxyindexer) and \n# search engine (doxysearch.cgi) which are based on the open source search engine \n# library Xapian. See the manual for configuration details.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server \n# which will returned the search results when EXTERNAL_SEARCH is enabled. \n# Doxygen ships with an example search engine (doxysearch) which is based on \n# the open source search engine library Xapian. See the manual for configuration \n# details.\n\nSEARCHENGINE_URL       = \n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed \n# search data is written to a file for indexing by an external tool. With the \n# SEARCHDATA_FILE tag the name of this file can be specified.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the \n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is \n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple \n# projects and redirect the results back to the right project.\n\nEXTERNAL_SEARCH_ID     = \n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen \n# projects other than the one defined by this configuration file, but that are \n# all added to the same external search index. Each project needs to have a \n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id \n# of to a relative location where the documentation can be found. \n# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...\n\nEXTRA_SEARCH_MAPPINGS  = \n\n#---------------------------------------------------------------------------\n# configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \n# generate Latex output.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `latex' will be used as the default path.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \n# invoked. If left blank `latex' will be used as the default command name. \n# Note that when enabling USE_PDFLATEX this option is only used for \n# generating bitmaps for formulas in the HTML output, but not in the \n# Makefile that is written to the output directory.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \n# generate index for LaTeX. If left blank `makeindex' will be used as the \n# default command name.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \n# LaTeX documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used \n# by the printer. Possible values are: a4, letter, legal and \n# executive. If left blank a4wide will be used.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \n# packages that should be included in the LaTeX output.\n\nEXTRA_PACKAGES         = \n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \n# the generated latex document. The header should contain everything until \n# the first chapter. If it is left blank doxygen will generate a \n# standard header. Notice: only use this tag if you know what you are doing!\n\nLATEX_HEADER           = \n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for \n# the generated latex document. The footer should contain everything after \n# the last chapter. If it is left blank doxygen will generate a \n# standard footer. Notice: only use this tag if you know what you are doing!\n\nLATEX_FOOTER           = \n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \n# contain links (just like the HTML output) instead of page references \n# This makes the output suitable for online browsing using a pdf viewer.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \n# plain latex in the generated Makefile. Set this option to YES to get a \n# higher quality PDF documentation.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \n# command to the generated LaTeX files. This will instruct LaTeX to keep \n# running if errors occur, instead of asking the user for help. \n# This option is also used when generating formulas in HTML.\n\nLATEX_BATCHMODE        = NO\n\n# If LATEX_HIDE_INDICES is set to YES then doxygen will not \n# include the index chapters (such as File Index, Compound Index, etc.) \n# in the output.\n\nLATEX_HIDE_INDICES     = NO\n\n# If LATEX_SOURCE_CODE is set to YES then doxygen will include \n# source code with syntax highlighting in the LaTeX output. \n# Note that which sources are shown also depends on other settings \n# such as SOURCE_BROWSER.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the \n# bibliography, e.g. plainnat, or ieeetr. The default style is \"plain\". See \n# http://en.wikipedia.org/wiki/BibTeX for more info.\n\nLATEX_BIB_STYLE        = plain\n\n#---------------------------------------------------------------------------\n# configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \n# The RTF output is optimized for Word 97 and may not look very pretty with \n# other RTF readers or editors.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `rtf' will be used as the default path.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \n# RTF documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \n# will contain hyperlink fields. The RTF file will \n# contain links (just like the HTML output) instead of page references. \n# This makes the output suitable for online browsing using WORD or other \n# programs which support those fields. \n# Note: wordpad (write) and others do not support links.\n\nRTF_HYPERLINKS         = NO\n\n# Load style sheet definitions from file. Syntax is similar to doxygen's \n# config file, i.e. a series of assignments. You only have to provide \n# replacements, missing definitions are set to their default value.\n\nRTF_STYLESHEET_FILE    = \n\n# Set optional variables used in the generation of an rtf document. \n# Syntax is similar to doxygen's config file.\n\nRTF_EXTENSIONS_FILE    = \n\n#---------------------------------------------------------------------------\n# configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \n# generate man pages\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `man' will be used as the default path.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to \n# the generated man pages (default is the subroutine's section .3)\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \n# then it will generate one additional man file for each entity \n# documented in the real man page(s). These additional files \n# only source the real man page, but without them the man command \n# would be unable to find the correct page. The default is NO.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES Doxygen will \n# generate an XML file that captures the structure of \n# the code including all documentation.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `xml' will be used as the default path.\n\nXML_OUTPUT             = xml\n\n# The XML_SCHEMA tag can be used to specify an XML schema, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_SCHEMA             = \n\n# The XML_DTD tag can be used to specify an XML DTD, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_DTD                = \n\n# If the XML_PROGRAMLISTING tag is set to YES Doxygen will \n# dump the program listings (including syntax highlighting \n# and cross-referencing information) to the XML output. Note that \n# enabling this will significantly increase the size of the XML output.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \n# generate an AutoGen Definitions (see autogen.sf.net) file \n# that captures the structure of the code including all \n# documentation. Note that this feature is still experimental \n# and incomplete at the moment.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \n# generate a Perl module file that captures the structure of \n# the code including all documentation. Note that this \n# feature is still experimental and incomplete at the \n# moment.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \n# to generate PDF and DVI output from the Perl module output.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \n# nicely formatted so it can be parsed by a human reader.  This is useful \n# if you want to understand what is going on.  On the other hand, if this \n# tag is set to NO the size of the Perl module output will be much smaller \n# and Perl will parse it just the same.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file \n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \n# This is useful so different doxyrules.make files included by the same \n# Makefile don't overwrite each other's variables.\n\nPERLMOD_MAKEVAR_PREFIX = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \n# evaluate all C-preprocessor directives found in the sources and include \n# files.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \n# names in the source code. If set to NO (the default) only conditional \n# compilation will be performed. Macro expansion can be done in a controlled \n# way by setting EXPAND_ONLY_PREDEF to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \n# then the macro expansion is limited to the macros specified with the \n# PREDEFINED and EXPAND_AS_DEFINED tags.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \n# pointed to by INCLUDE_PATH will be searched when a #include is found.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that \n# contain include files that are not input files but should be processed by \n# the preprocessor.\n\nINCLUDE_PATH           = \n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \n# patterns (like *.h and *.hpp) to filter out the header-files in the \n# directories. If left blank, the patterns specified with FILE_PATTERNS will \n# be used.\n\nINCLUDE_FILE_PATTERNS  = \n\n# The PREDEFINED tag can be used to specify one or more macro names that \n# are defined before the preprocessor is started (similar to the -D option of \n# gcc). The argument of the tag is a list of macros of the form: name \n# or name=definition (no spaces). If the definition and the = are \n# omitted =1 is assumed. To prevent a macro definition from being \n# undefined via #undef or recursively expanded use the := operator \n# instead of the = operator.\n\nPREDEFINED             = \n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \n# this tag can be used to specify a list of macro names that should be expanded. \n# The macro definition that is found in the sources will be used. \n# Use the PREDEFINED tag if you want to use a different macro definition that \n# overrules the definition found in the source code.\n\nEXPAND_AS_DEFINED      = \n\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \n# doxygen's preprocessor will remove all references to function-like macros \n# that are alone on a line, have an all uppercase name, and do not end with a \n# semicolon, because these will confuse the parser if not removed.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration::additions related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES option can be used to specify one or more tagfiles. For each \n# tag file the location of the external documentation should be added. The \n# format of a tag file without this location is as follows: \n#   TAGFILES = file1 file2 ... \n# Adding location for the tag files is done as follows: \n#   TAGFILES = file1=loc1 \"file2 = loc2\" ... \n# where \"loc1\" and \"loc2\" can be relative or absolute paths \n# or URLs. Note that each tag file must have a unique name (where the name does \n# NOT include the path). If a tag file is not located in the directory in which \n# doxygen is run, you must also specify the path to the tagfile here.\n\nTAGFILES               = \n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \n# a tag file that is based on the input files it reads.\n\nGENERATE_TAGFILE       = \n\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \n# in the class index. If set to NO only the inherited external classes \n# will be listed.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \n# in the modules index. If set to NO, only the current project's groups will \n# be listed.\n\nEXTERNAL_GROUPS        = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script \n# interpreter (i.e. the result of `which perl').\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \n# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base \n# or super classes. Setting the tag to NO turns the diagrams off. Note that \n# this option also works with HAVE_DOT disabled, but it is recommended to \n# install and use dot, since it yields more powerful graphs.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc \n# command. Doxygen will then run the mscgen tool (see \n# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the \n# documentation. The MSCGEN_PATH tag allows you to specify the directory where \n# the mscgen tool resides. If left empty the tool is assumed to be found in the \n# default search path.\n\nMSCGEN_PATH            = \n\n# If set to YES, the inheritance and collaboration graphs will hide \n# inheritance and usage relations if the target is undocumented \n# or is not a class.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \n# available from the path. This tool is part of Graphviz, a graph visualization \n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \n# have no effect if this option is set to NO (the default)\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is \n# allowed to run in parallel. When set to 0 (the default) doxygen will \n# base this on the number of processors available in the system. You can set it \n# explicitly to a value larger than 0 to get control over the balance \n# between CPU load and processing speed.\n\nDOT_NUM_THREADS        = 0\n\n# By default doxygen will use the Helvetica font for all dot files that \n# doxygen generates. When you want a differently looking font you can specify \n# the font name using DOT_FONTNAME. You need to make sure dot is able to find \n# the font, which can be done by putting it in a standard location or by setting \n# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the \n# directory containing the font.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. \n# The default size is 10pt.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the Helvetica font. \n# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to \n# set the path where dot can find it.\n\nDOT_FONTPATH           = \n\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect inheritance relations. Setting this tag to YES will force the \n# CLASS_DIAGRAMS tag to NO.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect implementation dependencies (inheritance, containment, and \n# class references variables) of the class with other documented classes.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for groups, showing the direct groups dependencies\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and \n# collaboration diagrams in a style similar to the OMG's Unified Modeling \n# Language.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside \n# the class node. If there are many fields or methods and many nodes the \n# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS \n# threshold limits the number of items for each type to make the size more \n# managable. Set this to 0 for no limit. Note that the threshold may be \n# exceeded by 50% before the limit is enforced.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If set to YES, the inheritance and collaboration graphs will show the \n# relations between templates and their instances.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n# tags are set to YES then doxygen will generate a graph for each documented \n# file showing the direct and indirect include dependencies of the file with \n# other documented files.\n\nINCLUDE_GRAPH          = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n# documented header file showing the documented files that directly or \n# indirectly include this file.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH and HAVE_DOT options are set to YES then \n# doxygen will generate a call dependency graph for every global function \n# or class method. Note that enabling this option will significantly increase \n# the time of a run. So in most cases it will be better to enable call graphs \n# for selected functions only using the \\callgraph command.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then \n# doxygen will generate a caller dependency graph for every global function \n# or class method. Note that enabling this option will significantly increase \n# the time of a run. So in most cases it will be better to enable caller \n# graphs for selected functions only using the \\callergraph command.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \n# will generate a graphical hierarchy of all classes instead of a textual one.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES \n# then doxygen will show the dependencies a directory has on other directories \n# in a graphical way. The dependency relations are determined by the #include \n# relations between the files in the directories.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \n# generated by dot. Possible values are svg, png, jpg, or gif. \n# If left blank png will be used. If you choose svg you need to set \n# HTML_FILE_EXTENSION to xhtml in order to make the SVG files \n# visible in IE 9+ (other browsers do not have this requirement).\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to \n# enable generation of interactive SVG images that allow zooming and panning. \n# Note that this requires a modern browser other than Internet Explorer. \n# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you \n# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files \n# visible. Older versions of IE do not have SVG support.\n\nINTERACTIVE_SVG        = NO\n\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \n# found. If left blank, it is assumed the dot tool can be found in the path.\n\nDOT_PATH               = \n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \n# contain dot files that are included in the documentation (see the \n# \\dotfile command).\n\nDOTFILE_DIRS           = \n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that \n# contain msc files that are included in the documentation (see the \n# \\mscfile command).\n\nMSCFILE_DIRS           = \n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of \n# nodes that will be shown in the graph. If the number of nodes in a graph \n# becomes larger than this value, doxygen will truncate the graph, which is \n# visualized by representing a node as a red box. Note that doxygen if the \n# number of direct children of the root node in a graph is already larger than \n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note \n# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the \n# graphs generated by dot. A depth value of 3 means that only nodes reachable \n# from the root by following a path via at most 3 edges will be shown. Nodes \n# that lay further from the root node will be omitted. Note that setting this \n# option to 1 or 2 may greatly reduce the computation time needed for large \n# code bases. Also note that the size of a graph can be further restricted by \n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent \n# background. This is disabled by default, because dot on Windows does not \n# seem to support this out of the box. Warning: Depending on the platform used, \n# enabling this option may lead to badly anti-aliased labels on the edges of \n# a graph (i.e. they become hard to read).\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output \n# files in one run (i.e. multiple -o and -T options on the command line). This \n# makes dot run faster, but since only newer versions of dot (>1.8.10) \n# support this, this feature is disabled by default.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \n# generate a legend page explaining the meaning of the various boxes and \n# arrows in the dot generated graphs.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \n# remove the intermediate dot files that are used to generate \n# the various graphs.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "Docs/Example/TextAttributes.pef",
    "content": "#include \"QtnProperty/PropertyCore.h\"\n#include \"QtnProperty/PropertyGUI.h\"\n\nproperty_set TextAttributes\n{\n    Bool WordWrap\n    {\n        description = \"Text word wrapping\";\n        value = true;\n    }\n    Int Height\n    {\n        description = \"Text height\";\n        value = 16;\n        minValue = 1;\n        maxValue = 100;\n        stepValue = 1;\n    }\n    QColor Color\n    {\n        description = \"Foreground text color\";\n        value = QColor(0, 0, 0);\n    }\n}"
  },
  {
    "path": "Docs/Example/TextAttributes.peg.cpp",
    "content": "#include \"TextAttributes.peg.h\"\n\n\nQtnPropertySetTextAttributes::QtnPropertySetTextAttributes(QObject* parent)\n    : QtnPropertySet(parent)\n    , WordWrap(*qtnCreateProperty<QtnPropertyBool>(this))\n    , Height(*qtnCreateProperty<QtnPropertyInt>(this))\n    , Color(*qtnCreateProperty<QtnPropertyQColor>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetTextAttributes::~QtnPropertySetTextAttributes()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetTextAttributes& QtnPropertySetTextAttributes::operator=(const QtnPropertySetTextAttributes& other)\n{\n    Q_UNUSED(other);\n\n    WordWrap = other.WordWrap;\n    Height = other.Height;\n    Color = other.Color;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetTextAttributes::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetTextAttributes(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetTextAttributes::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetTextAttributes* p = new QtnPropertySetTextAttributes(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetTextAttributes::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetTextAttributes*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->WordWrap.state() & ignoreMask))\n    {\n        WordWrap = theCopyFrom->WordWrap;\n    }\n\n    if (!(theCopyFrom->Height.state() & ignoreMask))\n    {\n        Height = theCopyFrom->Height;\n    }\n\n    if (!(theCopyFrom->Color.state() & ignoreMask))\n    {\n        Color = theCopyFrom->Color;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetTextAttributes::init()\n{\n    static QString TextAttributes_name = QStringLiteral(\"TextAttributes\");\n    setName(TextAttributes_name);\n    \n    // start children initialization\n    static QString WordWrap_name = QStringLiteral(\"WordWrap\");\n    WordWrap.setName(WordWrap_name);\n    static QString WordWrap_description = \"Text word wrapping\";\n    WordWrap.setDescription(WordWrap_description);\n    WordWrap.setValue(true);\n    static QString Height_name = QStringLiteral(\"Height\");\n    Height.setName(Height_name);\n    static QString Height_description = \"Text height\";\n    Height.setDescription(Height_description);\n    Height.setMaxValue(100);\n    Height.setMinValue(1);\n    Height.setStepValue(1);\n    Height.setValue(16);\n    static QString Color_name = QStringLiteral(\"Color\");\n    Color.setName(Color_name);\n    static QString Color_description = \"Foreground text color\";\n    Color.setDescription(Color_description);\n    Color.setValue(QColor(0, 0, 0));\n    // end children initialization\n}\n\nvoid QtnPropertySetTextAttributes::connectSlots()\n{\n}\n\nvoid QtnPropertySetTextAttributes::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetTextAttributes::connectDelegates()\n{\n}\n"
  },
  {
    "path": "Docs/Example/TextAttributes.peg.h",
    "content": "#ifndef TEXTATTRIBUTES_H\n#define TEXTATTRIBUTES_H\n\n#include \"QtnProperty/PropertyCore.h\"\n#include \"QtnProperty/PropertyGUI.h\"\n\nclass QtnPropertySetTextAttributes: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetTextAttributes)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetTextAttributes(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetTextAttributes() override;\n    // assignment declaration\n    QtnPropertySetTextAttributes& operator=(const QtnPropertySetTextAttributes& other);\n    \n    // start children declarations\n    QtnPropertyBool& WordWrap;\n    QtnPropertyInt& Height;\n    QtnPropertyQColor& Color;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\n#endif // TEXTATTRIBUTES_H\n"
  },
  {
    "path": "Internal/BaseConfig.pri",
    "content": "QTNPROPERTY_BIN_PREFIX = $$PWD/..\n\nQTNPROPERTY_BIN = $$QTNPROPERTY_BIN_PREFIX/bin\n\nwin32 {\n    QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-win32\n    msvc:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-msvc$$QMAKE_MSC_VER\n}\n\nemscripten:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-emscripten\nelse:macx:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-osx\nelse:linux:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-linux\n\nisEmpty(QTNPROPERTY_BIN) {\n    message(\"Only mac/win32/linux/emscripten supported\")\n    QTNPROPERTY_BIN = \"FAIL\"\n} else {\n    clang:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-clang\n    else:gcc:QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-gcc\n\n    QTNPROPERTY_BIN = $$QTNPROPERTY_BIN-$$QT_ARCH\n    CONFIG(debug, debug|release) {\n        QTNPROPERTY_BIN = $$QTNPROPERTY_BIN/debug\n    }\n}\n"
  },
  {
    "path": "Internal/TargetConfig.pri",
    "content": "isEmpty(QTNPROPERTY_BIN) {\n    include($$PWD/BaseConfig.pri)\n}\n\nDESTDIR = $$QTNPROPERTY_BIN\n\nCONFIG += c++11\n\nmsvc {\n    DEFINES += _CRT_SECURE_NO_WARNINGS\n}\n\nclang:QMAKE_CXXFLAGS_WARN_ON += \\\n    -Wno-deprecated-copy \\\n    -Wno-unknown-warning-option \\\n    -Wno-deprecated-declarations\n\nmacx:DYNAMIC_LIBS.path = \"Contents/MacOS\"\n\nCONFIG(debug, debug|release) {\n    DEFINES += DEBUG\n} else {\n    DEFINES += NDEBUG\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "NOTICE",
    "content": "Apache QtnProperty\nCopyright 2012-2020 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/)."
  },
  {
    "path": "PEG/Bison.pri",
    "content": "bison.name = Bison ${QMAKE_FILE_IN}\nbison.input = BISON_SOURCES\nbison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp\n\nwin32:bison.commands = win_bison -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}\nunix::bison.commands = bison -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}\n\n#-Wmidrule-value -t\n\nbison.CONFIG += targets_predeps\nbison.variable_out = GENERATED_SOURCES\nsilent:bison.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands\nQMAKE_EXTRA_COMPILERS += bison\n"
  },
  {
    "path": "PEG/Flex.pri",
    "content": "flex.name = Flex ${QMAKE_FILE_IN}\nflex.input = FLEX_SOURCES\nflex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp\n\nwin32:flex.commands = win_flex --wincompat -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}\nunix:flex.commands = flex -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}\n\nflex.CONFIG += target_predeps\nflex.variable_out = GENERATED_SOURCES\nsilent:flex.commands = @echo Lex ${QMAKE_FILE_IN} && $$flex.commands\nQMAKE_EXTRA_COMPILERS += flex\n"
  },
  {
    "path": "PEG/PEG.pri",
    "content": "# To use *.pef files in your project you should:\n# 1. Include this PEG.pri file to your project file\n# 2. List your *.pef files in PEG_SOURCES variable\n# 3. Define PEG_TOOL to point to QtnPEG before including\n# PEG.pri file in your pro file\n\nisEmpty(QTNPROPERTY_BIN) {\n    include($$PWD/../Internal/BaseConfig.pri)\n}\n\nisEmpty(PEG_TOOL) {\nwin32:PEG_TOOL = $$QTNPROPERTY_BIN/QtnPEG.exe\nelse:PEG_TOOL = $$QTNPROPERTY_BIN/QtnPEG\n}\n\npeg.name = PropertyEnum generator ${QMAKE_FILE_IN}\npeg.input = PEG_SOURCES\npeg.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.peg.cpp\npeg.commands = $$PEG_TOOL ${QMAKE_FILE_IN}\npeg.CONFIG += target_predeps\npeg.variable_out = SOURCES\nsilent:peg.commands = @echo PEG ${QMAKE_FILE_IN} && $$peg.commands\nQMAKE_EXTRA_COMPILERS += peg\n\npeg_header.name = PEG Headers ${QMAKE_FILE_IN}\npeg_header.input = PEG_SOURCES\npeg_header.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.peg.h\npeg_header.commands = $$escape_expand(\\\\n) # empty command\npeg_header.CONFIG += target_predeps no_link\npeg_header.variable_out = PEG_MOC_HEADERS\nQMAKE_EXTRA_COMPILERS += peg_header\n\nload(moc)\npeg_moc.name = my_moc_header\npeg_moc.output = $$moc_header.output\npeg_moc.input = PEG_MOC_HEADERS\npeg_moc.commands = $$moc_header.commands\npeg_moc.variable_out = GENERATED_SOURCES\nQMAKE_EXTRA_COMPILERS += peg_moc\n"
  },
  {
    "path": "PEG/PEG.pro",
    "content": "include(../Internal/TargetConfig.pri)\ninclude(Bison.pri)\ninclude(Flex.pri)\n\nQT += core\nQT -= gui\n\nclang:QMAKE_CXXFLAGS_WARN_ON += \\\n    -Wno-deprecated-register \\\n    -Wno-unneeded-internal-declaration \\\n    -Wno-unused-const-variable\n\ngcc:QMAKE_CXXFLAGS_WARN_ON += \\\n    -Wno-unused-function\n\nTARGET = QtnPEG\n\nCONFIG += cmdline\nCONFIG -= app_bundle\n\nTEMPLATE = app\nVERSION = 2.0.0\n\nSOURCES += main.cpp \\\n    PropertyEnumGenerator.cpp\n\nBISON_SOURCES += PropertyEnum.y\nFLEX_SOURCES += PropertyEnum.l\n\nOTHER_FILES += \\\n    PropertyEnum.l \\\n    PropertyEnum.y\n\nHEADERS += \\\n    PropertyEnumGeneratorCommon.h \\\n    PropertyEnumGenerator.h\n\nmsvc:QMAKE_CXXFLAGS += /wd4065 /wd4267 /wd4005\n"
  },
  {
    "path": "PEG/PropertyEnum.l",
    "content": "%option 8bit\n%option warn\n%option yylineno\n%option noyywrap\n%option stack\n%option bison-bridge bison-locations\n\n%x ASSIGN_STATE\n%x LINE_COMMENT_STATE\n%x CPP_COMMENT_STATE\n%x CPP_STRING_STATE\n%x CPP_CHAR_STATE\n%x INCLUDE_STATE\n%x CPP_CODE_STATE\n%x CPP_CODE_STATE2\n%x STRING_STATE\n%x INITIALIZATION_LIST_STATE\n\n%{\n#include \"PropertyEnumGeneratorCommon.h\"\n#include \"PropertyEnum.parser.hpp\"\n\nint yycolumn = 1;\nint yy_bracket_count = 0;\n\nextern void yyerror(/*YYLTYPE *yylloc,*/ char const *s);\n\n#define YY_USER_ACTION yylloc->first_line = yylloc->last_line = yylineno; \\\n    yylloc->first_column = yycolumn; yylloc->last_column = yycolumn + yyleng - 1; \\\n    yycolumn += yyleng;\n%}\n\n%%\n\n[ \\t]+                      /* skip whitespaces */\n[\\r\\n]                      { yycolumn = 1; }\n\n#include|#include_h         { yy_push_state(INCLUDE_STATE); return INCLUDE_H; }\n#include_cpp                { yy_push_state(INCLUDE_STATE); return INCLUDE_CPP; }\ncode_h                      { return CODE_H; }\ncode_cpp                    { return CODE_CPP; }\nproperty_set                { return PROPERTY_SET; }\nproperty                    { return PROPERTY; }\nextern                      { return EXTERN; }\nslot                        { return SLOT; }\ndelegate                    { return DELEGATE; }\nenum                        { return ENUM; }\npublic|protected|private    { *yylval = yytext; return ACCESS_ID; }\n[[:alpha:]_]+[[:alnum:]_]*  { *yylval = yytext; return ID; }\n\"{\"                         { return CPP_BRACKET_OPEN; }\n\"}\"                         { return CPP_BRACKET_CLOSE; }\n\"(\"                         { return '('; }\n\")\"                         { return ')'; }\n\";\"                         { return SEMICOLON; }\n\":\"                         { return COLON; }\n\"::\"                        { return DBL_COLON; }\n\",\"                         { return COMMA; }\n\".\"                         { return DOT; }\n\"~\"                         { return TILDE; }\n\"=\"                         { yy_push_state(ASSIGN_STATE); return ASSIGN; }\n[+-]?[[:digit:]]+           { *yylval = yytext; return NUMBER; }\n[LR]?\\\"                     { yymore(); yy_push_state(STRING_STATE); yy_push_state(CPP_STRING_STATE); }\n\n.                           {\n    printf( \"Unrecognized character: %s\\n\", yytext ); yyerror(\"scan error\"); exit(1);\n}\n\n<STRING_STATE>{\n.                           {\n                                yy_pop_state();\n                                char lastChar = yytext[yyleng-1];\n                                yytext[yyleng-1] = '\\0';\n                                *yylval = yytext;\n                                unput(lastChar);\n                                return STR;\n                            }\n}\n\n<INCLUDE_STATE>{\n[^\\n]*                      {\n                                yy_pop_state();\n                                *yylval = yytext;\n                                return INCLUDE_NAME;\n                            }\n}\n\n<ASSIGN_STATE>{\n\"/*\"                        { yy_push_state(CPP_COMMENT_STATE); }\n\"}\"                         { printf( \"Unbalanced } bracket\\n\"); yyerror(\"scan error\"); exit(1); }\n\"{\"                         { yymore(); yy_push_state(CPP_CODE_STATE2); yy_bracket_count = 1; }\n[^\\\";{}]+                   { yymore(); }\n[LR]?\\\"                     { yymore(); yy_push_state(CPP_STRING_STATE); }\n;                           {\n                                yy_pop_state();\n                                // skip ';' char\n                                yytext[yyleng-1] = '\\0';\n                                *yylval = yytext;\n                                *yylval = yylval->trimmed();\n                                return VALUE_TO_ASSIGN;\n                            }\n}\n\n<CPP_STRING_STATE>{\n[^\\\\\\\"]+                    { yymore(); }\n\"\\\\\\\"\"                      { yymore(); }\n\"\\\\\"[^\\\"]                   { yymore(); }\n\"\\\"\"[ \\t]*\"\\\"\"              { yymore(); }\n\"\\\"\"[\\r\\n]*\"\\\"\"             { yycolumn = 1; yymore(); }\n\\\"                          { yymore(); yy_pop_state(); }\n}\n\n<INITIAL,CPP_CODE_STATE,CPP_CODE_STATE2,ASSIGN_STATE>\"//\" { yy_push_state(LINE_COMMENT_STATE); }\n\n<LINE_COMMENT_STATE>{\n[^\\r\\n]*                    { /* skip line comment */ yy_pop_state(); }\n}\n\n<INITIAL,CPP_CODE_STATE,CPP_CODE_STATE2,ASSIGN_STATE,INITIALIZATION_LIST_STATE>\"/*\" { yy_push_state(CPP_COMMENT_STATE); }\n\n<CPP_COMMENT_STATE>{\n[^*]*                       { /* skip cpp comment */ }\n\"*\"+[^/]                    { /* skip cpp comment */ }\n\"*\"+\"/\"                     { yy_pop_state(); }\n}\n\n<CPP_CODE_STATE>{\n[^{}]*                      { yymore(); }\n\"{\"                         { yymore(); ++yy_bracket_count; }\n\"}\"                         {\n                                --yy_bracket_count;\n                                if (yy_bracket_count == 0) {\n                                    yy_pop_state();\n                                    // skip close bracked\n                                    yytext[yyleng-1] = '\\0';\n                                    *yylval = yytext;\n                                    return CPP_CODE;\n                                } else {\n                                    yymore();\n                                }\n                            }\n}\n\n<CPP_CODE_STATE2>{\n[^{}]*                      { yymore(); }\n\"{\"                         { yymore(); ++yy_bracket_count; }\n\"}\"                         {\n                                yymore();\n                                --yy_bracket_count;\n                                if (yy_bracket_count == 0)\n                                    yy_pop_state();\n                            }\n}\n\n<INITIALIZATION_LIST_STATE>{\n[^{]*                       { yymore(); }\n\"{\"                         {\n                                yy_pop_state();\n                                // skip open bracked\n                                yytext[yyleng-1] = '\\0';\n                                *yylval = yytext;\n                                unput('{');\n                                return INITIALIZATION_LIST;\n                            }\n}\n\n%%\n\nvoid yy_push_state_cpp_code()\n{\n    yy_push_state(CPP_CODE_STATE);\n    yy_bracket_count = 1;\n}\n\nvoid yy_push_state_initialization_list()\n{\n    yy_push_state(INITIALIZATION_LIST_STATE);\n    yy_bracket_count = 1;\n}\n"
  },
  {
    "path": "PEG/PropertyEnum.y",
    "content": "%{\n#include \"PropertyEnumGeneratorCommon.h\"\n#include \"PropertyEnumGenerator.h\"\n#include <stdio.h>\n\nvoid yyerror(/*YYLTYPE *yylloc, */char const *);\n#define YYLEX_PARAM &yylval, &yylloc\n#define YYPRINT(File, Type, Value) fprintf ((File), \"%s\", (Value).toLatin1().data())\n\nextern void yy_push_state_cpp_code();\nextern void yy_push_state_initialization_list();\n\n%}\n\n%locations\n//%define parse.error verbose\n//%define api.pure full\n%lex-param {YYLEX_PARAM}\n\n\n%token  PROPERTY_SET\n        PROPERTY\n        INCLUDE_H\n        INCLUDE_CPP\n        INCLUDE_NAME\n        EXTERN\n        ID\n        CPP_BRACKET_OPEN\n        CPP_BRACKET_CLOSE\n        ASSIGN\n        SEMICOLON\n        COLON\n        DBL_COLON\n        COMMA\n        DOT\n        TILDE\n        VALUE_TO_ASSIGN\n        ACCESS_ID\n        SLOT\n        DELEGATE\n        CODE_H\n        CODE_CPP\n        CPP_CODE\n        ENUM\n        NUMBER\n        STR\n        INITIALIZATION_LIST\n\n%%\n\npef_body:         /* empty */\n                | pef_body include_h\n                | pef_body include_cpp\n                | pef_body source_code\n                | pef_body property_set\n                | pef_body enum\n;\n\ninclude_h:      INCLUDE_H INCLUDE_NAME      {\n    peg.code.append(QSharedPointer<Code>(new IncludeCode($2, true)));\n}\n;\n\ninclude_cpp:    INCLUDE_CPP INCLUDE_NAME    {\n    peg.code.append(QSharedPointer<Code>(new IncludeCode($2, false)));\n}\n;\n\nsource_code:      CODE_H CPP_BRACKET_OPEN { yy_push_state_cpp_code(); }\n                    CPP_CODE    {\n    QSharedPointer<SourceCode> code(new SourceCode($4, true));\n    if (pegContext.currPropertySet)\n        pegContext.currPropertySet->sourceCodes.append(code);\n    else\n        peg.code.append(code);\n}\n                | CODE_CPP CPP_BRACKET_OPEN { yy_push_state_cpp_code(); }\n                    CPP_CODE   {\n    QSharedPointer<SourceCode> code(new SourceCode($4, false));\n    if (pegContext.currPropertySet)\n        pegContext.currPropertySet->sourceCodes.append(code);\n    else\n        peg.code.append(code);\n}\n;\n\nproperty_set:   property_set_head property_set_body { pegContext.commitPropertySet(); }\n;\n\nproperty_set_head:  PROPERTY_SET ID   {\n    pegContext.startPropertySet();\n    pegContext.currPropertySet->setName($2);\n}\n;\n\ntype_decl:    ID                                { pegContext.currType.namespaceName = \"\";\n                                                  pegContext.currType.name = $1; }\n            | namespace_name DBL_COLON ID       { pegContext.currType.namespaceName = $1;\n                                                  pegContext.currType.name = $3; }\n;\n\nnamespace_name:   ID\n                | namespace_name DBL_COLON ID\n;\n\noptional_semicolon: /* empty */\n                    | SEMICOLON\n;\n\nproperty_set_body: CPP_BRACKET_OPEN property_set_declarations CPP_BRACKET_CLOSE optional_semicolon {\n}\n;\n\nproperty_set_declarations:    /* empty */\n                            | property_set_declarations property_declaration\n                            | property_set_declarations value_declaration\n                            | property_set_declarations slot_declaration\n                            | property_set_declarations sub_property_set\n                            | property_set_declarations source_code\n                            | property_set_declarations delegate_declaration\n                            | property_set_declarations constructor\n                            | property_set_declarations destructor\n;\n\nsub_property_set:     property_set\n                    | property_set_with_id\n                    | property_set_extern\n;\n\nproperty_set_with_id:   property_set_head ID property_set_body  {\n    pegContext.currPropertySet->name = $2;\n    pegContext.commitPropertySet();\n    // add sub property set as member\n    pegContext.currPropertySet->members.push_back(pegContext.currPropertySet->subPropertySets.last());\n}\n;\n\nproperty_set_extern:    property_set_extern_head property_set_extern_tail\n;\n\nproperty_set_extern_head:    EXTERN PROPERTY_SET type_decl ID   {\n    pegContext.startPropertySet();\n    pegContext.currPropertySet->_extern = true;\n    pegContext.currPropertySet->selfType = pegContext.currentPropertySetType();\n    pegContext.currPropertySet->name = $4;\n}\n;\n\nproperty_set_extern_tail:   sub_item_body           {\n    pegContext.commitPropertySet();\n    // add sub property set as member\n    pegContext.currPropertySet->members.push_back(pegContext.currPropertySet->subPropertySets.last());\n}\n                            | SEMICOLON             {\n    pegContext.commitPropertySet();\n    // add sub property set as member\n    pegContext.currPropertySet->members.push_back(pegContext.currPropertySet->subPropertySets.last());\n}\n;\n\nproperty_declaration:   property_declaration_head property_declaration_tail\n;\n\nproperty_declaration_head:   type_decl ID               {\n    pegContext.startProperty();\n    pegContext.currProperty->selfType = pegContext.currentPropertyType();\n    pegContext.currProperty->name = $2;\n}\n;\n\nproperty_declaration_tail:    sub_item_body {\n    pegContext.commitProperty();\n}\n                            | SEMICOLON     {\n    pegContext.commitProperty();\n}\n;\n\nsub_item_body:  CPP_BRACKET_OPEN sub_item_declarations CPP_BRACKET_CLOSE {\n}\n;\n\nsub_item_declarations:    /* empty */\n                        | sub_item_declarations value_declaration\n                        | sub_item_declarations slot_declaration\n                        | sub_item_declarations delegate_declaration\n;\n\nvalue_declaration:      name_to_assign ASSIGN VALUE_TO_ASSIGN   {\n    AssignInfo info;\n    info.member = pegContext.currAssignMember;\n    info.value = $3;\n    pegContext.current()->assignments.insert(pegContext.currAssignFunc, info);\n}\n;\n\nname_to_assign:   ID                        {\n    pegContext.currAssignFunc = $1;\n    pegContext.currAssignMember = \"\";\n}\n                | name_to_assign DOT ID     {\n    pegContext.currAssignFunc = $3;\n    pegContext.currAssignMember = $1;\n}\n;\n\nslot_declaration:   SLOT name_to_assign            {\n    if (!pegContext.checkSlotName(pegContext.currAssignFunc)) {\n        QString error = QString(\"Unrecognized slot name <%1>.\").arg(pegContext.currAssignFunc);\n        yyerror(error.toLatin1().data());\n        exit(1);\n    }\n}\n                        CPP_BRACKET_OPEN    { yy_push_state_cpp_code(); }\n                        CPP_CODE            {\n    AssignInfo info;\n    info.member = pegContext.currAssignMember;\n    info.value = $6;\n    pegContext.current()->slots_code.insert(pegContext.currAssignFunc, info);\n}\n;\n\ndelegate_declaration:     DELEGATE {\n    if (pegContext.current()->delegateInfo.data()) {\n        QString error = QString(\"Delegate for object <%1> already defined.\").arg(pegContext.current()->name);\n        yyerror(error.toLatin1().data());\n        exit(1);\n    }\n\n    pegContext.current()->delegateInfo.reset(new DelegateInfo());\n}\n                                delegate_tail\n;\n\ndelegate_tail:            ID delegate_body {\n    pegContext.current()->delegateInfo->name = $1;\n}\n                        | delegate_body\n;\n\ndelegate_body:       SEMICOLON\n                    | CPP_BRACKET_OPEN delegate_attributes CPP_BRACKET_CLOSE\n;\n\ndelegate_attributes:      /*empty*/\n                        | delegate_attributes delegate_attribute\n;\n\ndelegate_attribute:      ID ASSIGN VALUE_TO_ASSIGN {\n    pegContext.current()->delegateInfo->attributes[$1] = $3;\n}\n\nconstructor: ID '(' ')'\n                        initialization_list\n                        CPP_BRACKET_OPEN { yy_push_state_cpp_code(); } CPP_CODE {\n    pegContext.currPropertySet->setConstructorCode($1, $4, $7);\n}\n;\n\ninitialization_list:      /*empty*/\n                        | COLON { yy_push_state_initialization_list(); }\n                          INITIALIZATION_LIST {\n    $$ = $3;\n}\n;\n\ndestructor: TILDE ID '(' ')' CPP_BRACKET_OPEN { yy_push_state_cpp_code(); }\n                        CPP_CODE {\n    pegContext.currPropertySet->setDestructorCode($2, $7);\n}\n;\n\nenum:   ENUM ID             {\n    pegContext.enumCode.reset(new EnumCode($2));\n}\n            CPP_BRACKET_OPEN\n            enum_values_list CPP_BRACKET_CLOSE optional_semicolon {\n    peg.code.append(pegContext.enumCode);\n    pegContext.enumCode.reset();\n}\n;\n\nenum_values_list:        /* none */\n                        | enum_values_list2\n;\n\nenum_values_list2:        enum_value\n                        | enum_values_list2 COMMA enum_value\n;\n\nenum_value:         ID '(' NUMBER COMMA STR ')'     {\n    EnumCode::EnumItemCode item;\n    item.name = $1;\n    bool success = false;\n    item.id = $3.toInt(&success);\n    if (!success) {\n        QString error = QString(\"Unrecognized enum item id <%1>.\").arg($3);\n        yyerror(error.toLatin1().data());\n        exit(1);\n    }\n    item.text = $5;\n\n    pegContext.enumCode->items.append(item);\n}\n                 enum_states_list\n;\n\nenum_states_list:         /* none */\n                        | enum_states_list ID   {\n    pegContext.enumCode->items.last().states.append($2);\n}\n;\n\n%%\n\nvoid yyerror(/*YYLTYPE *yylloc, */char const *s)\n{\n    fprintf(stderr, \"Parser error: (%d,%d)-(%d,%d) '%s'\\n\"\n                    ,yylloc.first_line\n                    ,yylloc.first_column\n                    ,yylloc.last_line\n                    ,yylloc.last_column\n                    ,s);\n}\n\n"
  },
  {
    "path": "PEG/PropertyEnumGenerator.cpp",
    "content": "/*\n   Copyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n#include \"PropertyEnumGenerator.h\"\n\n#include <QFile>\n#include <QFileInfo>\n#include <QSet>\n#include <QStack>\n\nPEG &peg = PEG::instance();\n\n// special values that initialized in constructor\nstatic Exceptions createSetExceptions()\n{\n\tExceptions exceptions;\n\texceptions.insert(\"parent\");\n\treturn exceptions;\n}\nstatic Exceptions setExceptions = createSetExceptions();\n\nstatic Signatures createSlotSignatures()\n{\n\tSignatures _slots;\n\t_slots.insert(\"propertyWillChange\",\n\t\t{ \"QtnPropertyChangeReason reason, \"\n\t\t  \"QtnPropertyValuePtr newValue, \"\n\t\t  \"int typeId\",\n\n\t\t\t\"Q_UNUSED(reason); \"\n\t\t\t\"Q_UNUSED(newValue);\"\n\t\t\t\"Q_UNUSED(typeId);\" });\n\n\t_slots.insert(\"propertyDidChange\",\n\t\t{ \"QtnPropertyChangeReason reason\",\n\n\t\t\t\"Q_UNUSED(reason);\" });\n\n\t_slots.insert(\"propertyValueAccept\",\n\t\t{ \"QtnPropertyValuePtr valueToAccept, \"\n\t\t  \"bool* accept\",\n\n\t\t\t\"Q_UNUSED(valueToAccept); \"\n\t\t\t\"Q_UNUSED(accept);\" });\n\treturn _slots;\n}\nstatic Signatures slotsSignatures = createSlotSignatures();\n\nstatic QString slotSignature(const QString &name)\n{\n\tauto it = slotsSignatures.find(name);\n\tif (it == slotsSignatures.end())\n\t\tpeg.fatalError(\"Cannot recognize slot \" + name);\n\n\treturn it.value().arguments;\n}\n\nstatic QString slotUnusedCode(const QString &name)\n{\n\tauto it = slotsSignatures.find(name);\n\tif (it == slotsSignatures.end())\n\t\tpeg.fatalError(\"Cannot recognize slot \" + name);\n\n\treturn it.value().unusedCode;\n}\n\nstatic QString valueByName(const Assignments &assignments, const QString &name,\n\tconst QString &defaultValue)\n{\n\tauto it = assignments.find(name);\n\tif (it == assignments.end())\n\t\treturn defaultValue;\n\n\tif (!it->member.isEmpty())\n\t\treturn defaultValue;\n\n\treturn it->value;\n}\n\nstatic QString capitalize(QString text)\n{\n\treturn text.left(1).toUpper() + text.mid(1);\n}\n\nstatic void assignmentSetCode(\n\tQString prefix, Assignments::ConstIterator assignment, TextStreamIndent &s)\n{\n\tQString name;\n\tif (!prefix.isEmpty())\n\t\tname += prefix + \".\";\n\tif (!assignment.value().member.isEmpty())\n\t\tname += assignment.value().member + \".\";\n\n\tif (assignment.key() != \"description\")\n\t{\n\t\ts.newLine() << QString(\"%1set%2(%3);\")\n\t\t\t\t\t\t   .arg(name, capitalize(assignment.key()),\n\t\t\t\t\t\t\t   assignment.value().value);\n\t} else\n\t{\n\t\tQString var = name + assignment.key();\n\t\tvar.replace(\".\", \"_\");\n\t\ts.newLine() << QString(\"static QString %1 = %2;\")\n\t\t\t\t\t\t   .arg(var, assignment.value().value);\n\t\ts.newLine() << QString(\"%1set%2(%3);\")\n\t\t\t\t\t\t   .arg(name, capitalize(assignment.key()), var);\n\t}\n}\n\nstatic void assignmentsSetCode(QString prefix, const Assignments &assignments,\n\tconst Exceptions &exceptions, TextStreamIndent &s)\n{\n\tfor (auto it = assignments.cbegin(); it != assignments.cend(); ++it)\n\t{\n\t\tif (!exceptions.contains(it.key()))\n\t\t\tassignmentSetCode(prefix, it, s);\n\t}\n}\n\nstatic QString slotName(\n\tconst QString &name, const QString *member1, const QString *member2)\n{\n\tQString slotName = \"on_\";\n\tif (member1 && !member1->isEmpty())\n\t{\n\t\tQString s = *member1;\n\t\tslotName += s.replace(QChar('.'), QChar('_')) + \"_\";\n\t}\n\n\tif (member2 && !member2->isEmpty())\n\t{\n\t\tQString s = *member2;\n\t\tslotName += s.replace(QChar('.'), QChar('_')) + \"_\";\n\t}\n\n\treturn slotName + name;\n}\n\nvoid DelegateInfo::generateCode(TextStreamIndent &s) const\n{\n\ts.newLine() << QString(\"QtnPropertyDelegateInfo info;\");\n\n\tif (!name.isEmpty())\n\t\ts.newLine() << QString(\"info.name = \\\"%1\\\";\").arg(name);\n\n\tfor (auto it = attributes.begin(); it != attributes.end(); ++it)\n\t{\n\t\ts.newLine() << QString(\"info.attributes[\\\"%1\\\"] = %2;\")\n\t\t\t\t\t\t   .arg(it.key(), it.value());\n\t}\n\n\ts.newLine() << \"return info;\";\n}\n\nIncludeCode::IncludeCode(QString name, bool isHeader)\n\t: name(name.trimmed())\n\t, isHeader(isHeader)\n{\n}\n\nvoid IncludeCode::generateHFile(TextStreamIndent &s) const\n{\n\tif (!isHeader)\n\t\treturn;\n\tgenerate(s);\n}\n\nvoid IncludeCode::generateCppFile(TextStreamIndent &s) const\n{\n\tif (isHeader)\n\t\treturn;\n\tgenerate(s);\n}\n\nSourceCode::SourceCode(const QString &code, bool code_h)\n\t: code(code)\n\t, code_h(code_h)\n{\n}\n\nvoid SourceCode::generateHFile(TextStreamIndent &s) const\n{\n\tif (!code_h)\n\t\treturn;\n\ts.newLine() << code;\n}\n\nvoid SourceCode::generateCppFile(TextStreamIndent &s) const\n{\n\tif (code_h)\n\t\treturn;\n\ts.newLine() << code;\n}\n\nPropertySetCode::PropertySetCode() {}\n\nvoid PropertySetCode::setName(QString _name)\n{\n\tname = _name;\n\tselfType = \"QtnPropertySet\" + name;\n}\n\nvoid PropertySetCode::setSuperType(const PropertySetCode *parent)\n{\n\tif (parent->superType.isEmpty())\n\t\tsuperType = parent->selfType;\n\telse\n\t\tsuperType = parent->superType + \"::\" + parent->selfType;\n}\n\nvoid PropertySetCode::setConstructorCode(\n\tQString _name, QString _initialization_list, QString _code)\n{\n\tif (_name != name)\n\t\tpeg.fatalError(\n\t\t\tQString(\"Cannot recognize as constructor '%1'.\").arg(_name));\n\n\tif (constructor)\n\t\tpeg.fatalError(\n\t\t\tQString(\"Constructor for '%1' already defined.\").arg(_name));\n\n\tconstructor.reset(new Constructor());\n\tconstructor->initialization_list = _initialization_list.trimmed();\n\tconstructor->code = _code;\n}\n\nvoid PropertySetCode::setDestructorCode(QString _name, QString _code)\n{\n\tif (_name != name)\n\t\tpeg.fatalError(\n\t\t\tQString(\"Cannot recognize as destructor '%1'.\").arg(_name));\n\n\tif (destructor)\n\t\tpeg.fatalError(\n\t\t\tQString(\"Destructor for '%1' already defined.\").arg(_name));\n\n\tdestructor.reset(new Destructor());\n\tdestructor->code = _code;\n}\n\nvoid PropertySetCode::generateHFile(TextStreamIndent &s) const\n{\n\tgenerateSubPropertySetsDeclarations(s);\n\ts << endl;\n\ts.newLine() << QString(\"class %1: public QtnPropertySet\").arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << \"Q_OBJECT\";\n\ts.newLine() << QString(\"//Q_DISABLE_COPY(%1)\").arg(selfType);\n\ts << endl;\n\ts.newLine(-1) << \"public:\";\n\ts.newLine() << \"// constructor declaration\";\n\ts.newLine() << QString(\"explicit %1(QObject* parent = %2);\")\n\t\t\t\t\t   .arg(selfType,\n\t\t\t\t\t\t   valueByName(assignments, \"parent\", \"nullptr\"));\n\ts.newLine() << \"// destructor declaration\";\n\ts.newLine() << QString(\"virtual ~%1() override;\").arg(selfType);\n\ts.newLine() << \"// assignment declaration\";\n\ts.newLine() << QString(\"%1& operator=(const %1& other);\").arg(selfType);\n\tgenerateChildrenDeclaration(s);\n\ts << endl;\n\ts.newLine(-1) << \"protected:\";\n\ts.newLine() << \"// cloning implementation\";\n\ts.newLine() << QString(\n\t\t\"QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\");\n\ts.newLine() << QString(\"QtnPropertySet* createCopyImpl(QObject* \"\n\t\t\t\t\t\t   \"parentForCopy) const override;\");\n\ts.newLine() << \"// copy values implementation\";\n\ts.newLine() << QString(\"bool copyValuesImpl(QtnPropertySet* \"\n\t\t\t\t\t\t   \"propertySetCopyFrom, QtnPropertyState ignoreMask) \"\n\t\t\t\t\t\t   \"override;\");\n\ts << endl;\n\ts.newLine(-1) << \"private:\";\n\ts.newLine() << \"void init();\";\n\ts.newLine() << \"void connectSlots();\";\n\ts.newLine() << \"void disconnectSlots();\";\n\ts.newLine() << \"void connectDelegates();\";\n\tgenerateSlotsDeclaration(s);\n\ts.delIndent();\n\tgenerateHSourceCode(s);\n\ts.newLine() << \"};\";\n}\n\nvoid PropertySetCode::generateCppFile(TextStreamIndent &s) const\n{\n\tgenerateSubPropertySetsImplementations(s);\n\n\t// constructor implementation\n\ts << endl;\n\ts.newLine() << QString(\"%1::%1(QObject* parent)\").arg(selfType);\n\ts.addIndent();\n\ts.newLine() << QString(\": QtnPropertySet(parent)\");\n\tgenerateChildrenInitialization(s);\n\tgenerateConstructorInitializationList(s);\n\ts.delIndent();\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\tif (constructor)\n\t\ts.newLine() << constructor->code;\n\ts.newLine() << \"init();\";\n\ts.newLine() << \"connectSlots();\";\n\ts.newLine() << \"connectDelegates();\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// destructor implementation\n\ts << endl;\n\ts.newLine() << selfType << \"::~\" << selfType << \"()\";\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\tif (destructor)\n\t\ts.newLine() << destructor->code;\n\ts.newLine() << \"disconnectSlots();\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// assignment implementation\n\ts << endl;\n\ts.newLine() << QString(\"%1& %1::operator=(const %1& other)\").arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << \"Q_UNUSED(other);\" << endl;\n\tgenerateChildrenCopy(s);\n\ts << endl;\n\ts.newLine() << \"return *this;\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// cloning implementation\n\ts << endl;\n\ts.newLine() << QString(\n\t\t\"QtnPropertySet* %1::createNewImpl(QObject* parentForNew) const\")\n\t\t\t\t\t   .arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << QString(\"return new %1(parentForNew);\").arg(selfType);\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\ts << endl;\n\ts.newLine() << QString(\n\t\t\"QtnPropertySet* %1::createCopyImpl(QObject* parentForCopy) const\")\n\t\t\t\t\t   .arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << QString(\"%1* p = new %1(parentForCopy);\").arg(selfType);\n\ts.newLine() << \"*p = *this;\";\n\ts.newLine() << \"return p;\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// copy values implementation\n\ts << endl;\n\ts.newLine() << QString(\"bool %1::copyValuesImpl(QtnPropertySet* \"\n\t\t\t\t\t\t   \"propertySetCopyFrom, QtnPropertyState ignoreMask)\")\n\t\t\t\t\t   .arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << \"Q_UNUSED(ignoreMask);\" << endl;\n\tgenerateCopyValues(s);\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// initialization\n\ts << endl;\n\ts.newLine() << \"void \" << selfType << \"::init()\";\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << QString(\"static QString %1_name = QStringLiteral(\\\"%1\\\");\")\n\t\t\t\t\t   .arg(name);\n\ts.newLine() << QString(\"setName(%1_name);\").arg(name);\n\tassignmentsSetCode(\"\", assignments, setExceptions, s);\n\tgenerateChildrenAssignment(s);\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// slots connect/disconnect\n\ts << endl;\n\ts.newLine() << QString(\"void %1::connectSlots()\").arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\tgenerateSlotsConnections(s, \"connect\");\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\ts << endl;\n\ts.newLine() << QString(\"void %1::disconnectSlots()\").arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\tgenerateSlotsConnections(s, \"disconnect\");\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\tgenerateSlotsImplementation(s);\n\n\t// delegates connects\n\ts << endl;\n\ts.newLine() << QString(\"void %1::connectDelegates()\").arg(selfType);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\tgenerateDelegatesConnection(s);\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\n\t// custom code\n\tgenerateCppSourceCode(s);\n}\n\nvoid PropertySetCode::generateChildrenDeclaration(TextStreamIndent &s) const\n{\n\tif (members.isEmpty())\n\t\treturn;\n\n\ts.pushWrapperLines(\n\t\t\"// start children declarations\", \"// end children declarations\");\n\tforeach (auto p, members)\n\t{\n\t\ts.newLine() << p->selfType << \"& \" << p->name << \";\";\n\t}\n\ts.popWrapperLines();\n}\n\nvoid PropertySetCode::generateChildrenInitialization(TextStreamIndent &s) const\n{\n\tif (members.isEmpty())\n\t\treturn;\n\n\tfor (auto it = members.cbegin(); it != members.cend(); ++it)\n\t{\n\t\tconst PropertySetMemberCode &p = **it;\n\t\ts.newLine() << \", \" << p.name << \"(*qtnCreateProperty<\" << p.selfType\n\t\t\t\t\t<< \">(this))\";\n\t}\n}\n\nvoid PropertySetCode::generateChildrenAssignment(TextStreamIndent &s) const\n{\n\tif (members.isEmpty())\n\t\treturn;\n\n\ts.pushWrapperLines(\n\t\t\"// start children initialization\", \"// end children initialization\");\n\tforeach (auto p, members)\n\t{\n\t\ts.newLine() << QString(\n\t\t\t\"static QString %1_name = QStringLiteral(\\\"%1\\\");\")\n\t\t\t\t\t\t   .arg(p->name);\n\t\ts.newLine() << QString(\"%1.setName(%1_name);\").arg(p->name);\n\t\tassignmentsSetCode(p->name, p->assignments, setExceptions, s);\n\t}\n\ts.popWrapperLines();\n}\n\nvoid PropertySetCode::generateChildrenCopy(TextStreamIndent &s) const\n{\n\tforeach (auto p, members)\n\t{\n\t\ts.newLine() << QString(\"%1 = other.%1;\").arg(p->name);\n\t}\n}\n\nvoid PropertySetCode::generateSubPropertySetsDeclarations(\n\tTextStreamIndent &s) const\n{\n\tQVector<const PropertySetCode *> _subPropertySets = getSubpropertySets();\n\tif (_subPropertySets.isEmpty())\n\t\treturn;\n\n\tfor (auto it = _subPropertySets.begin(); it != _subPropertySets.end(); ++it)\n\t{\n\t\t(*it)->generateHFile(s);\n\t}\n}\n\nvoid PropertySetCode::generateSubPropertySetsImplementations(\n\tTextStreamIndent &s) const\n{\n\tQVector<const PropertySetCode *> _subPropertySets = getSubpropertySets();\n\tif (_subPropertySets.isEmpty())\n\t\treturn;\n\n\tfor (auto it = _subPropertySets.begin(); it != _subPropertySets.end(); ++it)\n\t{\n\t\t(*it)->generateCppFile(s);\n\t}\n}\n\nvoid PropertySetCode::generateSlotsDeclaration(TextStreamIndent &s) const\n{\n\ts.pushWrapperLines(\n\t\t\"// start slot declarations\", \"// end slot declarations\");\n\tfor (auto it = slots_code.begin(); it != slots_code.end(); ++it)\n\t{\n\t\ts.newLine() << QString(\"void %1(%2);\")\n\t\t\t\t\t\t   .arg(slotName(it.key(), &it.value().member, nullptr),\n\t\t\t\t\t\t\t   slotSignature(it.key()));\n\t}\n\n\tfor (auto it = members.begin(); it != members.end(); ++it)\n\t{\n\t\tif (!(*it)->_extern)\n\t\t\tcontinue;\n\n\t\tfor (auto jt = (*it)->slots_code.begin(); jt != (*it)->slots_code.end();\n\t\t\t ++jt)\n\t\t{\n\t\t\ts.newLine() << QString(\"void %1(%2);\")\n\t\t\t\t\t\t\t   .arg(slotName(jt.key(), &(*it)->name,\n\t\t\t\t\t\t\t\t\t\t&jt.value().member),\n\t\t\t\t\t\t\t\t   slotSignature(jt.key()));\n\t\t}\n\t}\n\ts.popWrapperLines();\n}\n\nvoid PropertySetCode::generateSlotsImplementation(TextStreamIndent &s) const\n{\n\tfor (auto it = slots_code.begin(); it != slots_code.end(); ++it)\n\t{\n\t\ts << endl;\n\t\ts.newLine() << QString(\"void %1::%2(%3)\")\n\t\t\t\t\t\t   .arg(selfType,\n\t\t\t\t\t\t\t   slotName(it.key(), &it.value().member, nullptr),\n\t\t\t\t\t\t\t   slotSignature(it.key()));\n\t\ts.newLine() << \"{\";\n\t\ts.addIndent();\n\t\ts.newLine() << slotUnusedCode(it.key());\n\t\ts.newLine() << it.value().value;\n\t\ts.delIndent();\n\t\ts.newLine() << \"}\";\n\t}\n\n\tfor (auto it = members.begin(); it != members.end(); ++it)\n\t{\n\t\tif (!(*it)->_extern)\n\t\t\tcontinue;\n\n\t\tfor (auto jt = (*it)->slots_code.begin(); jt != (*it)->slots_code.end();\n\t\t\t ++jt)\n\t\t{\n\t\t\ts << endl;\n\t\t\ts.newLine() << QString(\"void %1::%2(%3)\")\n\t\t\t\t\t\t\t   .arg(selfType,\n\t\t\t\t\t\t\t\t   slotName(jt.key(), &(*it)->name,\n\t\t\t\t\t\t\t\t\t   &jt.value().member),\n\t\t\t\t\t\t\t\t   slotSignature(jt.key()));\n\t\t\ts.newLine() << \"{\";\n\t\t\ts.addIndent();\n\t\t\ts.newLine() << slotUnusedCode(jt.key());\n\t\t\ts.newLine() << jt.value().value;\n\t\t\ts.delIndent();\n\t\t\ts.newLine() << \"}\";\n\t\t}\n\t}\n}\n\nvoid PropertySetCode::generateHSourceCode(TextStreamIndent &s) const\n{\n\tfor (auto it = sourceCodes.begin(); it != sourceCodes.end(); ++it)\n\t{\n\t\tif (!(*it)->code_h)\n\t\t\tcontinue;\n\n\t\t(*it)->generateHFile(s);\n\t}\n}\n\nvoid PropertySetCode::generateCppSourceCode(TextStreamIndent &s) const\n{\n\tfor (auto it = sourceCodes.begin(); it != sourceCodes.end(); ++it)\n\t{\n\t\tif ((*it)->code_h)\n\t\t\tcontinue;\n\n\t\t(*it)->generateCppFile(s);\n\t}\n}\n\nvoid PropertySetCode::generateDelegatesConnection(TextStreamIndent &s) const\n{\n\tif (!delegateInfo.isNull())\n\t{\n\t\ts.newLine() << QString(\n\t\t\t\"setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\");\n\t\ts.addIndent();\n\t\tdelegateInfo->generateCode(s);\n\t\ts.delIndent();\n\t\ts.newLine() << \"});\";\n\t}\n\n\tforeach (auto p, members)\n\t{\n\t\tif (!p->delegateInfo.isNull())\n\t\t{\n\t\t\ts.newLine() << QString(\n\t\t\t\t\"%1.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\")\n\t\t\t\t\t\t\t   .arg(p->name);\n\t\t\ts.addIndent();\n\t\t\tp->delegateInfo->generateCode(s);\n\t\t\ts.delIndent();\n\t\t\ts.newLine() << \"});\";\n\t\t}\n\t}\n}\n\nvoid PropertySetCode::generateConstructorInitializationList(\n\tTextStreamIndent &s) const\n{\n\tif (!constructor || constructor->initialization_list.isEmpty())\n\t\treturn;\n\n\ts.newLine() << \", \" << constructor->initialization_list;\n}\n\nvoid PropertySetCode::generateCopyValues(TextStreamIndent &s) const\n{\n\ts.newLine() << QString(\n\t\t\"auto theCopyFrom = qobject_cast<%1*>(propertySetCopyFrom);\")\n\t\t\t\t\t   .arg(selfType);\n\ts.newLine() << \"if (!theCopyFrom)\";\n\ts.newLine(1) << \"return false;\";\n\ts << endl;\n\n\tQ_ASSERT(members.size() >= subPropertySets.size());\n\tauto mIt = members.begin();\n\tauto sIt = subPropertySets.begin();\n\tauto sEnd = subPropertySets.end();\n\n\tfor (auto mEnd = members.end(); mIt != mEnd; ++mIt)\n\t{\n\t\tif ((sIt != sEnd) && (*mIt)->name == (*sIt)->name)\n\t\t{\n\t\t\ts.newLine() << QString(\n\t\t\t\t\"%1.copyValues(&theCopyFrom->%1, ignoreMask);\")\n\t\t\t\t\t\t\t   .arg((*mIt)->name);\n\t\t\t++sIt;\n\t\t} else\n\t\t{\n\t\t\ts.newLine() << QString(\n\t\t\t\t\"if (!(theCopyFrom->%1.state() & ignoreMask))\")\n\t\t\t\t\t\t\t   .arg((*mIt)->name);\n\t\t\ts.newLine() << \"{\";\n\t\t\ts.newLine(1) << QString(\"%1 = theCopyFrom->%1;\").arg((*mIt)->name);\n\t\t\ts.newLine() << \"}\";\n\t\t}\n\n\t\ts << endl;\n\t}\n\n\ts.newLine() << \"return true;\";\n}\n\nQString PropertySetCode::slotMember(const QString &name)\n{\n\tif (!name.isEmpty())\n\t\treturn \"&\" + name;\n\telse\n\t\treturn \"this\";\n}\n\nQString PropertySetCode::slotMember(\n\tconst QString &name, const QString &subMember)\n{\n\tif (subMember.isEmpty())\n\t\treturn \"&\" + name;\n\telse\n\t\treturn \"&\" + name + \".\" + subMember;\n}\n\nvoid PropertySetCode::generateSlotsConnections(\n\tTextStreamIndent &s, const QString &name) const\n{\n\tfor (auto it = slots_code.begin(); it != slots_code.end(); ++it)\n\t{\n\t\ts.newLine() << QString(\n\t\t\t\"QObject::%1(%2, &QtnProperty::%3, this, &%4::%5);\")\n\t\t\t\t\t\t   .arg(name, slotMember(it.value().member), it.key(),\n\t\t\t\t\t\t\t   selfType,\n\t\t\t\t\t\t\t   slotName(it.key(), &it.value().member, nullptr));\n\t}\n\n\tfor (auto it = members.begin(); it != members.end(); ++it)\n\t{\n\t\tif (!(*it)->_extern)\n\t\t\tcontinue;\n\n\t\tfor (auto jt = (*it)->slots_code.begin(); jt != (*it)->slots_code.end();\n\t\t\t ++jt)\n\t\t{\n\t\t\ts.newLine() << QString(\n\t\t\t\t\"QObject::%1(%2, &QtnProperty::%3, this, &%4::%5);\")\n\t\t\t\t\t\t\t   .arg(name,\n\t\t\t\t\t\t\t\t   slotMember((*it)->name, jt.value().member),\n\t\t\t\t\t\t\t\t   jt.key(), selfType,\n\t\t\t\t\t\t\t\t   slotName(jt.key(), &(*it)->name,\n\t\t\t\t\t\t\t\t\t   &jt.value().member));\n\t\t}\n\t}\n}\n\nQVector<const PropertySetCode *> PropertySetCode::getSubpropertySets() const\n{\n\tQVector<const PropertySetCode *> _subPropertySets;\n\tQVectorIterator<QSharedPointer<PropertySetCode>> it(subPropertySets);\n\twhile (it.hasNext())\n\t{\n\t\tconst QSharedPointer<PropertySetCode> &ps = it.next();\n\t\tif (!ps->_extern)\n\t\t\t_subPropertySets.append(ps.data());\n\t}\n\n\treturn _subPropertySets;\n}\n\nEnumCode::EnumCode(const QString &name)\n\t: name(name)\n{\n}\n\nvoid EnumCode::generateHFile(TextStreamIndent &s) const\n{\n\ts.newLine();\n\ts.newLine() << QString(\"class %1\").arg(name);\n\ts.newLine() << \"{\";\n\ts.newLine() << \"public:\";\n\ts.addIndent();\n\tif (!items.isEmpty())\n\t{\n\t\ts.newLine() << \"enum Enum\";\n\t\ts.newLine() << \"{\";\n\t\ts.addIndent();\n\t\tfor (int i = 0, n = items.size(); i < n; ++i)\n\t\t{\n\t\t\tconst EnumItemCode &enumItem = items[i];\n\t\t\ts.newLine()\n\t\t\t\t<< QString(\"%1 = %2\").arg(enumItem.name).arg(enumItem.id);\n\t\t\tif ((i + 1) != n)\n\t\t\t\ts << \",\";\n\t\t}\n\t\ts.delIndent();\n\t\ts.newLine() << \"};\";\n\t}\n\ts.newLine();\n\ts.newLine() << \"static const QtnEnumInfo& info();\";\n\ts.newLine() << QString(\"static const unsigned int values_count = %1;\")\n\t\t\t\t\t   .arg(items.size());\n\ts.delIndent();\n\ts.newLine() << \"};\";\n}\n\nvoid EnumCode::generateCppFile(TextStreamIndent &s) const\n{\n\ts.newLine() << QString(\"static QtnEnumInfo& create_%1_info()\").arg(name);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << \"QVector<QtnEnumValueInfo> staticValues;\";\n\tforeach (const EnumItemCode &enumItem, items)\n\t{\n\t\tQString states;\n\t\tif (!enumItem.states.isEmpty())\n\t\t{\n\t\t\tstates += \", \";\n\t\t\tfor (int i = 0, n = enumItem.states.size(); i < n; ++i)\n\t\t\t{\n\t\t\t\tconst QString &state = enumItem.states[i];\n\t\t\t\tif (i != 0)\n\t\t\t\t\tstates += \" | \";\n\t\t\t\tstates += \"QtnEnumValueState\";\n\t\t\t\tstates += capitalize(state);\n\t\t\t}\n\t\t}\n\t\ts.newLine() << QString(\n\t\t\t\"staticValues.append(QtnEnumValueInfo(%1::%2, \\\"%2\\\", %3%4));\")\n\t\t\t\t\t\t   .arg(name, enumItem.name, enumItem.text, states);\n\t}\n\ts.newLine();\n\ts.newLine() << QString(\"static QtnEnumInfo enumInfo(\\\"%1\\\", staticValues);\")\n\t\t\t\t\t   .arg(name);\n\ts.newLine() << \"return enumInfo;\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n\ts.newLine();\n\ts.newLine() << QString(\"const QtnEnumInfo& %1::info()\").arg(name);\n\ts.newLine() << \"{\";\n\ts.addIndent();\n\ts.newLine() << QString(\"static QtnEnumInfo& enumInfo = create_%1_info();\")\n\t\t\t\t\t   .arg(name);\n\ts.newLine() << \"return enumInfo;\";\n\ts.delIndent();\n\ts.newLine() << \"}\";\n}\n\nPegContext::PegContext()\n\t: currPropertySet(nullptr)\n\t, currProperty(nullptr)\n{\n}\n\nPropertySetMemberCode *PegContext::current()\n{\n\tif (currProperty)\n\t\treturn currProperty;\n\telse\n\t{\n\t\tif (!currPropertySet)\n\t\t\tpeg.fatalError(\"No current object.\");\n\n\t\treturn currPropertySet;\n\t}\n}\n\nQString PegContext::currentType() const\n{\n\tif (currType.namespaceName.isEmpty())\n\t\treturn currType.name;\n\telse\n\t\treturn currType.namespaceName + \"::\" + currType.name;\n}\n\nQString PegContext::currentPropertyType() const\n{\n\tQString res = \"QtnProperty\" + currType.name;\n\n\tif (!currType.namespaceName.isEmpty())\n\t\tres = currType.namespaceName + \"::\" + res;\n\n\treturn res;\n}\n\nQString PegContext::currentPropertySetType() const\n{\n\tQString res = \"QtnPropertySet\" + currType.name;\n\n\tif (!currType.namespaceName.isEmpty())\n\t\tres = currType.namespaceName + \"::\" + res;\n\n\treturn res;\n}\n\nvoid PegContext::startPropertySet()\n{\n\tQSharedPointer<PropertySetCode> newPropertySet(new PropertySetCode());\n\n\tif (!propertySet)\n\t{\n\t\tpropertySet = newPropertySet;\n\t\tsubPropertySets.push(propertySet.data());\n\t} else\n\t{\n\t\tQ_ASSERT(!subPropertySets.isEmpty());\n\t\tPropertySetCode *currentPropertySet = subPropertySets.top();\n\t\tnewPropertySet->setSuperType(currentPropertySet);\n\t\tcurrentPropertySet->subPropertySets.append(newPropertySet);\n\t\tsubPropertySets.push(newPropertySet.data());\n\t}\n\n\tcurrPropertySet = subPropertySets.top();\n}\n\nvoid PegContext::commitPropertySet()\n{\n\tsubPropertySets.pop();\n\n\tif (subPropertySets.isEmpty())\n\t{\n\t\tpeg.code.append(propertySet);\n\t\tpropertySet.reset();\n\t\tcurrPropertySet = nullptr;\n\t} else\n\t{\n\t\tcurrPropertySet = subPropertySets.top();\n\t}\n}\n\nvoid PegContext::startProperty()\n{\n\tQSharedPointer<PropertyCode> newProperty(new PropertyCode());\n\tcurrPropertySet->members.append(newProperty);\n\tcurrProperty = newProperty.data();\n}\n\nvoid PegContext::commitProperty()\n{\n\tcurrProperty = nullptr;\n}\n\nbool PegContext::checkSlotName(const QString &name)\n{\n\treturn slotsSignatures.contains(name);\n}\nPegContext pegContext;\n\nPEG &PEG::instance()\n{\n\tstatic PEG peg;\n\treturn peg;\n}\n\nPEG::PEG()\n\t: m_isValid(false)\n\t, m_errStream(stderr)\n{\n}\n\nbool PEG::start(QString hFileName, QString cppFileName)\n{\n\tif (m_isValid)\n\t{\n\t\tprintError(\"PEG initialized already\");\n\t\treturn false;\n\t}\n\n\tQScopedPointer<QFile> hFile(new QFile(hFileName, this));\n\tif (!hFile->open(QFile::WriteOnly | QFile::Truncate))\n\t{\n\t\tprintError(\n\t\t\tQString(\"Cannot open '%1' file for writting\").arg(hFileName));\n\t\treturn false;\n\t}\n\n\tQScopedPointer<QFile> cppFile(new QFile(cppFileName, this));\n\tif (!cppFile->open(QFile::WriteOnly | QFile::Truncate))\n\t{\n\t\tprintError(\n\t\t\tQString(\"Cannot open '%1' file for writting\").arg(cppFileName));\n\t\treturn false;\n\t}\n\n\tQFileInfo fi(*hFile);\n\tm_hFileName = fi.completeBaseName() + \".\" + fi.suffix();\n\tm_hDefine = fi.baseName().toUpper() + \"_\" + fi.suffix().toUpper();\n\n\tm_hStream.setDevice(hFile.take());\n\tm_cppStream.setDevice(cppFile.take());\n\n\tm_isValid = true;\n\treturn true;\n}\n\nvoid PEG::stop()\n{\n\tgenerateOutputs();\n\n\tcode.clear();\n\tm_isValid = false;\n}\n\nvoid PEG::printError(QString error)\n{\n\tm_errStream << error << endl;\n}\n\nvoid PEG::fatalError(QString error)\n{\n\tprintError(error);\n\texit(1);\n}\n\nvoid PEG::generateOutputs()\n{\n\tgenerateHFile();\n\tgenerateCppFile();\n}\n\nvoid PEG::generateHFile()\n{\n\tm_hStream << \"#ifndef \" << m_hDefine << endl;\n\tm_hStream << \"#define \" << m_hDefine << endl;\n\n\tfor (auto it = code.begin(); it != code.end(); ++it)\n\t{\n\t\t(*it)->generateHFile(m_hStream);\n\t}\n\n\tm_hStream << endl << endl;\n\tm_hStream << \"#endif // \" << m_hDefine << endl;\n}\n\nvoid PEG::generateCppFile()\n{\n\tm_cppStream << \"#include \\\"\" << m_hFileName << \"\\\"\" << endl;\n\tfor (auto it = code.begin(); it != code.end(); ++it)\n\t{\n\t\t(*it)->generateCppFile(m_cppStream);\n\t}\n\tm_cppStream << endl;\n}\n/*\nvoid PEG::addIncludeH(QString name)\n{\n    QSharedPointer<Code> code(new IncludeCode(name, true));\n    m_code.push_back(code);\n}\n\nvoid PEG::addIncludeCpp(QString name)\n{\n    QSharedPointer<Code> code(new IncludeCode(name, false));\n    m_code.push_back(code);\n}\n\nvoid PEG::startPropertySet(QString name, QString parentType)\n{\n    Q_ASSERT(!m_context->propertySet);\n\n    m_context->propertySet.reset(new PropertySetCode(name, parentType));\n}\n\nvoid PEG::commitPropertySet()\n{\n    Q_ASSERT(m_context->propertySet);\n\n    m_code.push_back(m_context->propertySet);\n    m_context->propertySet.reset();\n}\n\nvoid PEG::startProperty(QString name, QString type)\n{\n    Q_ASSERT(!m_context->property);\n    Q_ASSERT(m_context->propertySet);\n\n    m_context->property.reset(new PropertyCode());\n    m_context->property->name = name;\n    m_context->property->type = type;\n}\n\nvoid PEG::commitProperty()\n{\n    Q_ASSERT(m_context->propertySet);\n    Q_ASSERT(m_context->property);\n\n    m_context->propertySet->properties.push_back(m_context->property);\n    m_context->property.reset();\n}\n\nvoid PEG::addAssignment(QString name, QString value)\n{\n    if (name.isEmpty())\n        fatalError(\"Assignment name is empty.\");\n\n    if (value.isEmpty())\n        fatalError(\"Assignment value is empty\");\n\n    if (m_context->property)\n        m_context->property->assignments.insert(name.trimmed(), value.trimmed());\n    else if (m_context->propertySet)\n        m_context->propertySet->assignments.insert(name.trimmed(), value.trimmed());\n    else fatalError(\"Assignment is out of scope.\");\n}\n\n\n*/\n"
  },
  {
    "path": "PEG/PropertyEnumGenerator.h",
    "content": "/*\n   Copyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n#ifndef PROPERTY_ENUM_GENERATOR_H\n#define PROPERTY_ENUM_GENERATOR_H\n\n#include <QObject>\n#include <QString>\n#include <QVector>\n#include <QStack>\n#include <QSharedPointer>\n#include <QTextStream>\n\nclass TextStreamIndent: public QTextStream\n{\npublic:\n    TextStreamIndent()\n        : m_indent(0)\n    {\n    }\n\n    QTextStream& newLine(int indentOffset = 0)\n    {\n        if (!m_wrapperLines.isEmpty())\n        {\n            auto& info = m_wrapperLines.top();\n            if (!info.active)\n            {\n                info.active = true;\n                newLine();\n                newLine(info.indentOffset) << info.firstLine;\n            }\n        }\n\n        return *this << endl << QString(TAB_LEN*(m_indent+indentOffset), ' ');\n    }\n\n    void addIndent() { ++m_indent; }\n    void delIndent() { --m_indent; }\n\n    void pushWrapperLines(const QString& firstLine, const QString& lastLine, int indentOffset = 0)\n    {\n        WrapperLinesInfo info;\n        info.firstLine = firstLine;\n        info.lastLine = lastLine;\n        info.indentOffset = indentOffset;\n        m_wrapperLines.push(info);\n    }\n\n    bool popWrapperLines()\n    {\n        Q_ASSERT(!m_wrapperLines.isEmpty());\n        auto info = m_wrapperLines.pop();\n        if (info.active && !info.lastLine.isEmpty())\n            newLine(info.indentOffset) << info.lastLine;\n        return info.active;\n    }\n\nprivate:\n    int m_indent;\n    static const int TAB_LEN = 4;\n\n    struct WrapperLinesInfo\n    {\n        QString firstLine;\n        QString lastLine;\n        int indentOffset;\n        bool active;\n\n        WrapperLinesInfo(): indentOffset(0), active(false) {}\n    };\n\n    QStack<WrapperLinesInfo> m_wrapperLines;\n};\n\nclass Code\n{\n    Q_DISABLE_COPY(Code)\n\npublic:\n    Code() {}\n    virtual ~Code() {}\n\n    virtual void generateHFile(TextStreamIndent& s) const = 0;\n    virtual void generateCppFile(TextStreamIndent& s) const = 0;\n};\n\nclass PEG: public QObject\n{\n    Q_OBJECT\n    Q_DISABLE_COPY(PEG)\n\npublic:\n    ~PEG() {}\n\n    static PEG& instance();\n\n    bool start(QString hFileName, QString cppFileName);\n    void stop();\n\n    void fatalError(QString error);\n\n    QVector<QSharedPointer<Code> > code;\n\nprivate:\n    PEG();\n\n    bool isValid() const { return m_isValid; }\n    void printError(QString error);\n\n    void generateOutputs();\n    void generateHFile();\n    void generateCppFile();\n\n     bool m_isValid;\n\n    QString m_hFileName;\n    QString m_hDefine;\n\n    TextStreamIndent m_hStream;\n    TextStreamIndent m_cppStream;\n    QTextStream m_errStream;\n};\n\nQString propertyType(QString type);\nextern PEG& peg;\n\n// types\nstruct AssignInfo\n{\n    QString member;\n    QString value;\n};\n\nstruct SignatureInfo\n{\n    QString arguments;\n    QString unusedCode;\n};\n\n// key - setter name (without set)\n// value - setter parameter\ntypedef QMap<QString, AssignInfo> Assignments;\n// key - slot name\n// values - slot code\ntypedef QMap<QString, AssignInfo> Slots;\ntypedef QMap<QString, SignatureInfo> Signatures;\n// key - name exception\ntypedef QSet<QString> Exceptions;\n\nstruct DelegateInfo\n{\n    QString name;\n    QMap<QString, QString> attributes;\n\n    void generateCode(TextStreamIndent& s) const;\n};\n\n// code for #include constructions\nstruct IncludeCode: public Code\n{\n    QString name;\n    bool isHeader;\n\n    IncludeCode(QString name, bool isHeader);\n\n    void generateHFile(TextStreamIndent& s) const override;\n    void generateCppFile(TextStreamIndent& s) const override;\n\nprivate:\n    void generate(TextStreamIndent& s) const { s.newLine() << \"#include \" << name; }\n\n    Q_DISABLE_COPY(IncludeCode)\n};\n\n// code for plain C++ code\nstruct SourceCode: public Code\n{\n    QString code;\n    bool code_h;\n\n    SourceCode(const QString& code, bool code_h);\n\n    void generateHFile(TextStreamIndent& s) const override;\n    void generateCppFile(TextStreamIndent& s) const override;\n};\n\nstruct PropertySetMemberCode\n{\n    PropertySetMemberCode(): _extern(false) {}\n    virtual ~PropertySetMemberCode() {}\n\n    QString name;\n    QString selfType;\n    Assignments assignments;\n    Slots slots_code;\n    bool _extern;\n\n    QScopedPointer<DelegateInfo> delegateInfo;\n};\n\n// code for property\nstruct PropertyCode: public PropertySetMemberCode\n{\n    PropertyCode() { _extern = true; }\n};\n\n// code for property_set\nstruct PropertySetCode: public Code, public PropertySetMemberCode\n{\n    QVector<QSharedPointer<PropertySetMemberCode>> members;\n    QVector<QSharedPointer<PropertySetCode>> subPropertySets;\n    QVector<QSharedPointer<SourceCode>> sourceCodes;\n    QString superType;\n\n    struct Constructor\n    {\n        QString code;\n        QString initialization_list;\n    };\n    QScopedPointer<Constructor> constructor;\n\n    struct Destructor\n    {\n        QString code;\n    };\n    QScopedPointer<Destructor> destructor;\n\n\n    PropertySetCode();\n\n    void setName(QString _name);\n    void setSuperType(const PropertySetCode* parent);\n    void setConstructorCode(QString _name,QString _initialization_list, QString _code);\n    void setDestructorCode(QString _name, QString _code);\n\n    void generateHFile(TextStreamIndent& s) const override;\n    void generateCppFile(TextStreamIndent& s) const override;\n\nprivate:\n    QString constructorParamsList() const;\n\n    void generateChildrenDeclaration(TextStreamIndent& s) const;\n    void generateChildrenInitialization(TextStreamIndent& s) const;\n    void generateChildrenAssignment(TextStreamIndent& s) const;\n    void generateChildrenCopy(TextStreamIndent& s) const;\n    void generateSubPropertySetsDeclarations(TextStreamIndent& s) const;\n    void generateSubPropertySetsImplementations(TextStreamIndent& s) const;\n    void generateSlotsDeclaration(TextStreamIndent& s) const;\n    void generateSlotsImplementation(TextStreamIndent& s) const;\n    void generateHSourceCode(TextStreamIndent& s) const;\n    void generateCppSourceCode(TextStreamIndent& s) const;\n    void generateDelegatesConnection(TextStreamIndent& s) const;\n    void generateConstructorInitializationList(TextStreamIndent& s) const;\n    void generateCopyValues(TextStreamIndent& s) const;\n\n    static QString slotMember(const QString& name);\n    static QString slotMember(const QString& name, const QString& subMember);\n\n    void generateSlotsConnections(TextStreamIndent& s, const QString& name) const;\n    QVector<const PropertySetCode*> getSubpropertySets() const;\n};\n\n// code for enums\nstruct EnumCode: public Code\n{\n    QString name;\n\n    struct EnumItemCode\n    {\n        QString name;\n        int id;\n        QString text;\n        QVector<QString> states;\n    };\n\n    QVector<EnumItemCode> items;\n\n    EnumCode(const QString& name);\n\n    void generateHFile(TextStreamIndent& s) const override;\n    void generateCppFile(TextStreamIndent& s) const override;\n};\n\nstruct PegContext\n{\n    QSharedPointer<PropertySetCode> propertySet;\n    QStack<PropertySetCode*> subPropertySets;\n\n    PropertySetCode *currPropertySet;\n    PropertyCode *currProperty;\n\n    QString currAssignMember;\n    QString currAssignFunc;\n\n    QSharedPointer<EnumCode> enumCode;\n\n    struct TypeInfo\n    {\n        QString namespaceName;\n        QString name;\n    };\n    TypeInfo currType;\n\n    PegContext();\n\n    PropertySetMemberCode *current();\n    QString currentType() const;\n    QString currentPropertyType() const;\n    QString currentPropertySetType() const;\n\n    void startPropertySet();\n    void commitPropertySet();\n\n    void startProperty();\n    void commitProperty();\n\n    bool checkSlotName(const QString& name);\n\nprivate:\n    Q_DISABLE_COPY(PegContext)\n};\nextern PegContext pegContext;\n\n\n#endif // PROPERTY_ENUM_GENERATOR_H\n"
  },
  {
    "path": "PEG/PropertyEnumGeneratorCommon.h",
    "content": "/*\n   Copyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n#ifndef PROPERTY_ENUM_GENERATOR_COMMON_H\n#define PROPERTY_ENUM_GENERATOR_COMMON_H\n\n#include <QString>\n#define YYSTYPE QString\n\nstruct YYLTYPE;\n\nextern int yylex(YYSTYPE* yylval_param, YYLTYPE* yylloc_param);\n\n#endif // PROPERTY_ENUM_GENERATOR_COMMON_H\n"
  },
  {
    "path": "PEG/main.cpp",
    "content": "/*\n   Copyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n#include \"PropertyEnumGenerator.h\"\n\n#include <QCoreApplication>\n#include <QFileInfo>\n#include <QRegExp>\n\nextern int yyparse();\nextern FILE *yyin;\nextern int yydebug;\n\nint main(int argc, char *argv[])\n{\n\t//yydebug = 1;\n\n\t// Qt application\n\tQCoreApplication app(argc, argv);\n\tapp.setAttribute(Qt::AA_Use96Dpi, true);\n\n\t// check argument\n\tif (argc < 2 || argc > 4)\n\t{\n\t\tQTextStream(stdout) << QString(\"peg usage: peg <input file> [<cpp \"\n\t\t\t\t\t\t\t\t\t   \"output file> [h output file]]\")\n\t\t\t\t\t\t\t<< endl;\n\t\treturn 0;\n\t}\n\n\t// generate output file names\n\tconst char *inputFileName = argv[1];\n\tQFileInfo fi(inputFileName);\n\tif (!fi.exists())\n\t{\n\t\tQTextStream(stderr) << QString(\"Error: file '%1' doesn't exist\")\n\t\t\t\t\t\t\t\t   .arg(fi.absoluteFilePath())\n\t\t\t\t\t\t\t<< endl;\n\t\treturn 1;\n\t}\n\n\tQString cppFileName;\n\tif (argc < 3)\n\t{\n\t\tcppFileName = fi.path() + \"/\" + fi.completeBaseName() + \".peg.cpp\";\n\t} else\n\t{\n\t\tcppFileName = argv[2];\n\t}\n\n\tQString hFileName;\n\tif (argc < 3)\n\t{\n\t\thFileName = fi.path() + \"/\" + fi.completeBaseName() + \".peg.h\";\n\t} else if (argc < 4)\n\t{\n\t\thFileName = cppFileName;\n\t\thFileName.replace(QRegExp(\".cpp$\"), \".h\");\n\t} else\n\t{\n\t\thFileName = argv[3];\n\t}\n\n\tPEG &peg = PEG::instance();\n\n\tif (!peg.start(hFileName, cppFileName))\n\t\treturn 1;\n\n\t// open source file for reading\n\tFILE *input_file = fopen(inputFileName, \"r\");\n\tif (!input_file)\n\t{\n\t\tQTextStream(stderr)\n\t\t\t<< QString(\"Error: cannot open file '%1' for reading\")\n\t\t\t\t   .arg(inputFileName)\n\t\t\t<< endl;\n\t\treturn 1;\n\t}\n\n\tyyin = input_file;\n\n\tint result = yyparse();\n\n\tyyin = stdin;\n\tfclose(input_file);\n\n\tpeg.stop();\n\n\treturn result;\n}\n"
  },
  {
    "path": "QtnProperty/Auxiliary/PropertyAux.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_AUX_H\n#define QTN_PROPERTY_AUX_H\n\n#include \"QtnProperty/Config.h\"\n#include <QObject>\n\n// forward declarations\nclass QtnPropertyBase;\nclass QtnProperty;\nclass QtnPropertySet;\n\nenum QtnPropertyStateFlag\n{\n\tQtnPropertyStateNone = 0x0000,\n\tQtnPropertyStateNonSimple = 0x0001,\n\tQtnPropertyStateInvisible = 0x0002,\n\tQtnPropertyStateImmutable = 0x0004,\n\tQtnPropertyStateCollapsed = 0x0008,\n\tQtnPropertyStateNonSerialized = 0x0010,\n\tQtnPropertyStateMultiValue = 0x0020,\n\tQtnPropertyStateModifiedValue = 0x0040,\n\tQtnPropertyStateIgnoreDirectParentState = 0x80,\n\tQtnPropertyStateResettable = 0x100,\n\tQtnPropertyStateUnlockable = 0x200\n};\n\nQ_DECLARE_FLAGS(QtnPropertyState, QtnPropertyStateFlag)\nQ_DECLARE_OPERATORS_FOR_FLAGS(QtnPropertyState)\n\nenum QtnPropertyChangeReasonFlag\n{\n\tQtnPropertyChangeReasonNewValue = 0x0001,\n\tQtnPropertyChangeReasonLoadedValue = 0x0002,\n\tQtnPropertyChangeReasonName = 0x0004,\n\tQtnPropertyChangeReasonDisplayName = 0x0008,\n\tQtnPropertyChangeReasonDescription = 0x0010,\n\tQtnPropertyChangeReasonId = 0x0020,\n\tQtnPropertyChangeReasonStateLocal = 0x0040,\n\tQtnPropertyChangeReasonStateInherited = 0x0080,\n\tQtnPropertyChangeReasonChildPropertyAdd = 0x0100,\n\tQtnPropertyChangeReasonChildPropertyRemove = 0x0200,\n\tQtnPropertyChangeReasonEdit = 0x0400,\n\tQtnPropertyChangeReasonResetValue = 0x0800,\n\tQtnPropertyChangeReasonMultiEdit = 0x1000,\n\tQtnPropertyChangeReasonLockToggled = 0x2000,\n\tQtnPropertyChangeReasonUpdateDelegate = 0x4000,\n\tQtnPropertyChangeReasonState = QtnPropertyChangeReasonStateLocal |\n\t\tQtnPropertyChangeReasonStateInherited,\n\tQtnPropertyChangeReasonChildren = QtnPropertyChangeReasonChildPropertyAdd |\n\t\tQtnPropertyChangeReasonChildPropertyRemove,\n\tQtnPropertyChangeReasonValue = QtnPropertyChangeReasonNewValue |\n\t\tQtnPropertyChangeReasonLoadedValue | QtnPropertyChangeReasonResetValue,\n};\n\nQ_DECLARE_FLAGS(QtnPropertyChangeReason, QtnPropertyChangeReasonFlag)\nQ_DECLARE_OPERATORS_FOR_FLAGS(QtnPropertyChangeReason)\n\ntypedef qint32 QtnPropertyID;\nextern QTN_IMPORT_EXPORT const qint32 QtnPropertyIDInvalid;\n\ntypedef void *QtnPropertyValuePtr;\n\ntemplate <typename T>\ninline T *qtnCastPropertyValue(QtnPropertyValuePtr value)\n{\n\treturn reinterpret_cast<T *>(value);\n}\n\ntemplate <typename T>\ninline const T *qtnConstCastPropertyValue(QtnPropertyValuePtr value)\n{\n\treturn reinterpret_cast<const T *>(value);\n}\n\nQ_DECLARE_METATYPE(QtnPropertyID)\nQ_DECLARE_METATYPE(QtnPropertyState)\nQ_DECLARE_METATYPE(QtnPropertyChangeReason)\nQ_DECLARE_METATYPE(QtnPropertyValuePtr)\n\n#endif // QTN_PROPERTY_AUX_H\n"
  },
  {
    "path": "QtnProperty/Auxiliary/PropertyDelegateInfo.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateInfo.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"PropertyMacro.h\"\n\nQtnPropertyDelegateInfo::QtnPropertyDelegateInfo(\n\tconst QtnPropertyDelegateInfo &other)\n\t: name(other.name)\n\t, attributes(other.attributes)\n{\n}\n\nQtnPropertyDelegateInfo::QtnPropertyDelegateInfo(\n\tconst QByteArray &name, const Attributes &attributes)\n\t: name(name)\n\t, attributes(attributes)\n{\n}\n\nQByteArray qtnComboBoxDelegate()\n{\n\treturn QByteArrayLiteral(\"ComboBox\");\n}\n\nQByteArray qtnCheckBoxDelegate()\n{\n\treturn QByteArrayLiteral(\"CheckBox\");\n}\n\nQByteArray qtnFieldDelegateNameAttr()\n{\n\treturn QByteArrayLiteral(\"fieldDelegateName\");\n}\n\ndouble qtnHundredPercent(double value)\n{\n\treturn std::max(0.0, std::min(100.0, value));\n}\n"
  },
  {
    "path": "QtnProperty/Auxiliary/PropertyDelegateInfo.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_INFO_H\n#define QTN_PROPERTY_DELEGATE_INFO_H\n\n#include \"QtnProperty/Config.h\"\n#include <QMap>\n#include <QVariant>\n\nstruct QTN_IMPORT_EXPORT QtnPropertyDelegateInfo\n{\n\tQByteArray name;\n\tusing Attributes = QMap<QByteArray, QVariant>;\n\tAttributes attributes;\n\n\tQtnPropertyDelegateInfo() = default;\n\tQtnPropertyDelegateInfo(const QtnPropertyDelegateInfo &other);\n\tQtnPropertyDelegateInfo(\n\t\tconst QByteArray &name, const Attributes &attributes = Attributes());\n\n\ttemplate <typename T>\n\tinline T getAttribute(\n\t\tconst QByteArray &attributeName, const T &defaultValue = T()) const\n\t{\n\t\tauto it = attributes.find(attributeName);\n\n\t\tif (it == attributes.end())\n\t\t\treturn defaultValue;\n\n\t\treturn it.value().value<T>();\n\t}\n\n\ttemplate <typename T>\n\tinline bool loadAttribute(const QByteArray &name, T &to) const\n\t{\n\t\tauto it = attributes.find(name);\n\n\t\tif (it == attributes.end())\n\t\t\treturn false;\n\n\t\tto = it.value().value<T>();\n\t\treturn true;\n\t}\n\n\ttemplate <typename OBJ_T, typename ATTR_T_RET, typename ATTR_T_ARG>\n\tinline void storeAttributeValue(const QByteArray &name, OBJ_T *to,\n\t\tATTR_T_RET (OBJ_T::*get)() const, void (OBJ_T::*set)(ATTR_T_ARG)) const\n\t{\n\t\tQ_ASSERT(to);\n\t\t(to->*set)(getAttribute(name, (to->*get)()));\n\t}\n};\n\nstruct QTN_IMPORT_EXPORT QtnSubPropertyInfo\n{\n\tint id;\n\tQString key;\n\tQByteArray displayNameAttr;\n\tQByteArray descriptionAttr;\n};\n\n#endif // QTN_PROPERTY_DELEGATE_INFO_H\n"
  },
  {
    "path": "QtnProperty/Auxiliary/PropertyMacro.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYMACRO_H\n#define PROPERTYMACRO_H\n\n#define P_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, Op) \\\n\tinline bool operator Op(const ClassName &left, const ClassName &right) \\\n\t{ \\\n\t\treturn left.value() Op right.value(); \\\n\t} \\\n\tinline bool operator Op(const ClassName &left, ValueType right) \\\n\t{ \\\n\t\treturn left.value() Op right; \\\n\t} \\\n\tinline bool operator Op(ValueType left, const ClassName &right) \\\n\t{ \\\n\t\treturn left Op right.value(); \\\n\t}\n\n#define P_PROPERTY_DECL_EQ_OPERATORS(ClassName, ValueType) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, ==) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, !=)\n\n#define P_PROPERTY_DECL_ALL_OPERATORS(ClassName, ValueType) \\\n\tP_PROPERTY_DECL_EQ_OPERATORS(ClassName, ValueType) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, <) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, <=) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, >) \\\n\tP_PROPERTY_DECL_CMP_OPERATOR(ClassName, ValueType, >=)\n\n#define P_PROPERTY_DECL_MEMBER_OPERATORS(ClassName) \\\npublic: \\\n\toperator ValueType() const \\\n\t{ \\\n\t\treturn value(); \\\n\t} \\\n\tClassName &operator=(const ClassName &newValue) \\\n\t{ \\\n\t\tsetValue(newValue.value()); \\\n\t\treturn *this; \\\n\t} \\\n\tClassName &operator=(ValueType newValue) \\\n\t{ \\\n\t\tsetValue(newValue); \\\n\t\treturn *this; \\\n\t}\n\n#define P_PROPERTY_DECL_MEMBER_OPERATORS2(ClassName, BaseClassName) \\\npublic: \\\n\toperator ValueType() const \\\n\t{ \\\n\t\treturn value(); \\\n\t} \\\n\tClassName &operator=(const ClassName &newValue) \\\n\t{ \\\n\t\tsetValue(newValue.value()); \\\n\t\treturn *this; \\\n\t} \\\n\tClassName &operator=(const BaseClassName &newValue) \\\n\t{ \\\n\t\tsetValue(newValue.value()); \\\n\t\treturn *this; \\\n\t} \\\n\tClassName &operator=(ValueType newValue) \\\n\t{ \\\n\t\tsetValue(newValue); \\\n\t\treturn *this; \\\n\t}\n\n#endif // PROPERTYMACRO_H\n"
  },
  {
    "path": "QtnProperty/Auxiliary/PropertyTemplates.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_TEMPLATES_H\n#define PROPERTY_TEMPLATES_H\n\n#include \"QtnProperty/Property.h\"\n#include \"PropertyMacro.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <limits>\n#include <functional>\n\ntemplate <typename T>\nstruct PropertyValueTag {};\n\ntemplate <typename T, typename EqPred = std::equal_to<T>>\nclass QtnSinglePropertyBase : public QtnProperty\n{\npublic:\n\tusing ValueType = T;\n\tusing ValueTypeStore = typename std::decay<ValueType>::type;\n\tusing ValueTag = PropertyValueTag<QtnSinglePropertyBase<T, EqPred>>;\n\n\tinline ValueType value() const\n\t{\n\t\treturn valueImpl(ValueTag());\n\t}\n\n\tbool setValue(ValueType newValue,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReason())\n\t{\n\t\tif ((reason & QtnPropertyChangeReasonEdit) && !isEditableByUser())\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!isWritable() || !isValueAcceptedImpl(newValue))\n\t\t\treturn false;\n\n\t\tif (!(reason & QtnPropertyChangeReasonMultiEdit) &&\n\t\t\tisValueEqualImpl(newValue))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tbool accept = true;\n\t\temit propertyValueAccept(QtnPropertyValuePtr(&newValue), &accept);\n\n\t\tif (!accept)\n\t\t\treturn false;\n\n\t\tif (!(reason & QtnPropertyChangeReasonValue))\n\t\t{\n\t\t\treason |= QtnPropertyChangeReasonNewValue;\n\t\t}\n\n\t\temit propertyWillChange(reason, QtnPropertyValuePtr(&newValue),\n\t\t\tqMetaTypeId<ValueTypeStore>());\n\t\tsetValueImpl(newValue, reason);\n\t\temit propertyDidChange(reason);\n\n\t\treturn true;\n\t}\n\n\tinline operator ValueType() const\n\t{\n\t\treturn value();\n\t}\n\n\tinline QtnSinglePropertyBase<ValueType> &operator=(ValueType newValue)\n\t{\n\t\tsetValue(newValue);\n\t\treturn *this;\n\t}\n\n\tinline QtnSinglePropertyBase<ValueType> &operator=(\n\t\tconst QtnSinglePropertyBase<ValueType> &newValue)\n\t{\n\t\tsetValue(newValue.value());\n\t\treturn *this;\n\t}\n\n\tinline bool readDefaultValue(ValueTypeStore &to) const\n\t{\n\t\treturn defaultValueImpl(to);\n\t}\n\nprotected:\n\texplicit QtnSinglePropertyBase(QObject *parent)\n\t\t: QtnProperty(parent)\n\t{\n\t}\n\n\tvirtual void doReset(QtnPropertyChangeReason reason) override\n\t{\n\t\tQ_ASSERT(reason & QtnPropertyChangeReasonResetValue);\n\t\tValueTypeStore defaultValue;\n\t\tif (defaultValueImpl(defaultValue))\n\t\t{\n\t\t\tsetValue(defaultValue, reason);\n\t\t} else\n\t\t{\n\t\t\tQtnProperty::doReset(reason);\n\t\t}\n\t}\n\n\tvirtual ValueType valueImpl(ValueTag) const = 0;\n\tvirtual void setValueImpl(\n\t\tValueType newValue, QtnPropertyChangeReason reason) = 0;\n\tvirtual bool isValueAcceptedImpl(ValueType)\n\t{\n\t\treturn true;\n\t}\n\n\tvirtual bool defaultValueImpl(ValueTypeStore &to) const\n\t{\n\t\tQ_UNUSED(to);\n\t\treturn false;\n\t}\n\n\tvirtual bool isValueEqualImpl(ValueType valueToCompare)\n\t{\n\t\treturn EqPred()(valueToCompare, value());\n\t}\n\n\t// serialization implementation\n\tvirtual bool loadImpl(QDataStream &stream) override\n\t{\n\t\tif (!QtnProperty::loadImpl(stream))\n\t\t\treturn false;\n\n\t\tValueTypeStore newValue;\n\t\tstream >> newValue;\n\n\t\tif (stream.status() != QDataStream::Ok)\n\t\t\treturn false;\n\n\t\tsetValue(newValue, QtnPropertyChangeReasonLoadedValue);\n\n\t\treturn stream.status() == QDataStream::Ok;\n\t}\n\n\tvirtual bool saveImpl(QDataStream &stream) const override\n\t{\n\t\tif (!QtnProperty::saveImpl(stream))\n\t\t\treturn false;\n\n\t\tstream << value();\n\n\t\treturn stream.status() == QDataStream::Ok;\n\t}\n\n\t// variant conversion implementation\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override\n\t{\n\t\tif (var.canConvert<ValueTypeStore>())\n\t\t\treturn setValue(var.value<ValueTypeStore>(), reason);\n\n\t\treturn QtnProperty::fromVariantImpl(var, reason);\n\t}\n\n\tvirtual bool toVariantImpl(QVariant &var) const override\n\t{\n\t\tvar.setValue<ValueTypeStore>(value());\n\t\treturn var.isValid();\n\t}\n\nprivate:\n\tQtnSinglePropertyBase(const QtnSinglePropertyBase &) Q_DECL_EQ_DELETE;\n};\n/*\ntemplate <typename QtnSinglePropertyBaseType>\nclass QtnSinglePropertyBaseAsImpl : public QtnSinglePropertyBaseType\n{\npublic:\n\tusing BaseValueType = typename QtnSinglePropertyBaseType::ValueType;\n\tusing BaseValueTypeStore = typename QtnSinglePropertyBaseType::ValueTypeStore;\n\nprotected:\n\tvirtual BaseValueType valueBaseImpl() const = 0;\n\tvirtual void setValueBaseImpl(BaseValueType newValue, QtnPropertyChangeReason reason) = 0;\n\nprivate:\n\tBaseValueType valueImpl() const final\n\t{\n\t\treturn valueBaseImpl();\n\t}\n\tvoid setValueImpl(BaseValueType newValue, QtnPropertyChangeReason reason) final\n\t{\n\t\tsetValueBaseImpl(std::move(newValue), reason);\n\t}\n};\n*/\ntemplate <typename QtnSinglePropertyBaseType, typename ActualValueType, typename EqPred = std::equal_to<ActualValueType>>\nclass QtnSinglePropertyBaseAs : public QtnSinglePropertyBaseType\n{\npublic:\n\tusing ThisPropertyType = QtnSinglePropertyBaseAs<QtnSinglePropertyBaseType, ActualValueType, EqPred>;\n\tusing BasePropertyType = QtnSinglePropertyBaseType;\n\n\tusing BaseValueType = typename QtnSinglePropertyBaseType::ValueType;\n\tusing BaseValueTypeStore = typename QtnSinglePropertyBaseType::ValueTypeStore;\n\tusing BaseValueTag = typename QtnSinglePropertyBaseType::ValueTag;\n\n\tusing ValueType = ActualValueType;\n\tusing ValueTypeStore = typename std::decay<ValueType>::type;\n\tusing ValueTag = PropertyValueTag<ThisPropertyType>;\n\n\tinline ValueType value() const\n\t{\n\t\treturn valueImpl(ValueTag());\n\t}\n\n\tbool setValue(ValueType newValue,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReason())\n\t{\n\t\tBaseValueTypeStore baseValue = BaseValueTypeStore();\n\t\tif (!fromActualValue(std::move(newValue), baseValue))\n\t\t\treturn false;\n\n\t\treturn BasePropertyType::setValue(baseValue, reason);\n\t}\n\n\tinline operator ValueType() const\n\t{\n\t\treturn value();\n\t}\n\n\tinline ThisPropertyType &operator=(ValueType newValue)\n\t{\n\t\tsetValue(newValue);\n\t\treturn *this;\n\t}\n\n\tinline ThisPropertyType &operator=(const ThisPropertyType &newValue)\n\t{\n\t\tsetValue(newValue.value());\n\t\treturn *this;\n\t}\n\nprotected:\n\texplicit QtnSinglePropertyBaseAs(QObject *parent)\n\t\t: BasePropertyType(parent)\n\t{\n\t}\n\n\tvirtual bool fromActualValue(ValueType actualValue, BaseValueTypeStore& baseValue) const = 0;\n\tvirtual bool toActualValue(ValueTypeStore& actualValue, BaseValueType baseValue) const = 0;\n\n\tvirtual ValueType valueImpl(ValueTag) const = 0;\n\tvirtual void setValueImpl(ValueType newValue, QtnPropertyChangeReason reason) = 0;\n\n\tvirtual bool isValueAcceptedImpl(ValueType)\n\t{\n\t\treturn true;\n\t}\n\n\tvirtual bool defaultValueImpl(ValueTypeStore &to) const\n\t{\n\t\tQ_UNUSED(to);\n\t\treturn false;\n\t}\n\n\tvirtual bool isValueEqualImpl(ValueType valueToCompare)\n\t{\n\t\treturn EqPred()(valueToCompare, value());\n\t}\n\n\tBaseValueType valueImpl(BaseValueTag) const override\n\t{\n\t\tBaseValueTypeStore baseValue = BaseValueTypeStore();\n\t\tfromActualValue(value(), baseValue);\n\t\treturn baseValue;\n\t}\n\n\tvirtual bool isValueAcceptedImpl(BaseValueType valueToAccept) override\n\t{\n\t\tValueTypeStore value = ValueTypeStore();\n\t\ttoActualValue(value, std::move(valueToAccept));\n\t\treturn isValueAcceptedImpl(std::move(value));\n\t}\n\n\tvirtual bool isValueEqualImpl(BaseValueType valueToCompare) override\n\t{\n\t\tValueTypeStore value = ValueTypeStore();\n\t\ttoActualValue(value, std::move(valueToCompare));\n\t\treturn isValueEqualImpl(std::move(value));\n\t}\n\n\tvirtual bool defaultValueImpl(BaseValueTypeStore &to) const override\n\t{\n\t\tValueTypeStore value = ValueTypeStore();\n\t\tif (defaultValueImpl(value))\n\t\t\treturn fromActualValue(value, to);\n\t\treturn false;\n\t}\n\nprivate:\n\tvoid setValueImpl(\n\t\tBaseValueType newValue, QtnPropertyChangeReason reason) override\n\t{\n\t\tValueTypeStore value = ValueTypeStore();\n\t\ttoActualValue(value, std::move(newValue));\n\t\tsetValueImpl(std::move(value), reason);\n\t}\n};\n\ntemplate <typename QtnSinglePropertyType>\nclass QtnSinglePropertyValue : public QtnSinglePropertyType\n{\npublic:\n\tusing ValueType = typename QtnSinglePropertyType::ValueType;\n\tusing ValueTypeStore = typename QtnSinglePropertyType::ValueTypeStore;\n\tusing ValueTag = typename QtnSinglePropertyType::ValueTag;\n\nprotected:\n\texplicit QtnSinglePropertyValue(QObject *parent)\n\t\t: QtnSinglePropertyType(parent)\n\t\t, m_value(ValueTypeStore())\n\t{\n\t}\n\n\tValueType valueImpl(ValueTag) const override\n\t{\n\t\treturn m_value;\n\t}\n\n\tvoid setValueImpl(\n\t\tValueType newValue, QtnPropertyChangeReason /*reason*/) override\n\t{\n\t\tm_value = newValue;\n\t}\n\nprivate:\n\tValueTypeStore m_value;\n\n\tQ_DISABLE_COPY(QtnSinglePropertyValue)\n};\n\ntemplate <typename QtnSinglePropertyType>\nclass QtnSinglePropertyCallback : public QtnSinglePropertyType\n{\npublic:\n\tusing ValueType = typename QtnSinglePropertyType::ValueType;\n\tusing ValueTypeStore = typename QtnSinglePropertyType::ValueTypeStore;\n\tusing ValueTag = typename QtnSinglePropertyType::ValueTag;\n\n\tusing CallbackValueGet = std::function<ValueTypeStore()>;\n\tusing CallbackValueSet = std::function<void(ValueType, QtnPropertyChangeReason)>;\n\tusing CallbackValueAccepted = std::function<bool(ValueType)>;\n\tusing CallbackValueEqual = std::function<bool(ValueType)>;\n\n\tinline const CallbackValueGet &callbackValueDefault() const\n\t{\n\t\treturn m_callbackValueDefault;\n\t}\n\n\tinline const CallbackValueGet &callbackValueGet() const\n\t{\n\t\treturn m_callbackValueGet;\n\t}\n\n\tinline const CallbackValueSet &callbackValueSet() const\n\t{\n\t\treturn m_callbackValueSet;\n\t}\n\n\tinline const CallbackValueAccepted &callbackValueAccepted() const\n\t{\n\t\treturn m_callbackValueAccepted;\n\t}\n\n\tinline const CallbackValueEqual &callbackValueEqual() const\n\t{\n\t\treturn m_callbackValueEqual;\n\t}\n\n\tinline void setCallbackValueDefault(const CallbackValueGet &callback)\n\t{\n\t\tm_callbackValueDefault = callback;\n\t\tthis->switchState(QtnPropertyStateResettable, callback != nullptr);\n\t}\n\n\tinline void setCallbackValueGet(const CallbackValueGet &callback)\n\t{\n\t\tm_callbackValueGet = callback;\n\t}\n\n\tinline void setCallbackValueSet(const CallbackValueSet &callback)\n\t{\n\t\tm_callbackValueSet = callback;\n\t\tthis->switchState(QtnPropertyStateImmutable, callback == nullptr);\n\t}\n\n\tinline void setCallbackValueAccepted(const CallbackValueAccepted &callback)\n\t{\n\t\tm_callbackValueAccepted = callback;\n\t}\n\n\tinline void setCallbackValueEqual(const CallbackValueEqual &callback)\n\t{\n\t\tm_callbackValueEqual = callback;\n\t}\n\nprotected:\n\texplicit QtnSinglePropertyCallback(QObject *parent)\n\t\t: QtnSinglePropertyType(parent)\n\t{\n\t}\n\n\tvirtual ValueType valueImpl(ValueTag) const override\n\t{\n\t\tQ_ASSERT(m_callbackValueGet);\n\t\treturn m_callbackValueGet();\n\t}\n\n\tvirtual void setValueImpl(\n\t\tValueType newValue, QtnPropertyChangeReason reason) override\n\t{\n\t\tQ_ASSERT(m_callbackValueSet);\n\t\tm_callbackValueSet(newValue, reason);\n\t}\n\n\tvirtual bool isValueAcceptedImpl(ValueType valueToAccept) override\n\t{\n\t\tif (m_callbackValueAccepted)\n\t\t\treturn m_callbackValueAccepted(valueToAccept);\n\n\t\treturn QtnSinglePropertyType::isValueAcceptedImpl(valueToAccept);\n\t}\n\n\tvirtual bool isValueEqualImpl(ValueType valueToCompare) override\n\t{\n\t\tif (m_callbackValueEqual)\n\t\t\treturn m_callbackValueEqual(valueToCompare);\n\n\t\treturn QtnSinglePropertyType::isValueEqualImpl(valueToCompare);\n\t}\n\n\tvirtual bool defaultValueImpl(ValueTypeStore &to) const override\n\t{\n\t\tif (m_callbackValueDefault)\n\t\t{\n\t\t\tto = m_callbackValueDefault();\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\nprivate:\n\tQ_DISABLE_COPY(QtnSinglePropertyCallback)\n\n\tCallbackValueGet m_callbackValueDefault;\n\tCallbackValueGet m_callbackValueGet;\n\tCallbackValueSet m_callbackValueSet;\n\tCallbackValueAccepted m_callbackValueAccepted;\n\tCallbackValueEqual m_callbackValueEqual;\n};\n\ntemplate <typename QtnSinglePropertyType>\nclass QtnNumericPropertyBase : public QtnSinglePropertyType\n{\n\ttemplate <class T, class Enable = void>\n\tstruct interval_t\n\t{\n\t};\n\n\ttemplate <class T>\n\tstruct interval_t<T,\n\t\ttypename std::enable_if<std::is_floating_point<T>::value>::type>\n\t{\n\t\tusing type = double;\n\t\tusing maxsigned = double;\n\t};\n\n\ttemplate <class T>\n\tstruct interval_t<T,\n\t\ttypename std::enable_if<std::is_integral<T>::value>::type>\n\t{\n\t\tusing type = typename std::make_unsigned<T>::type;\n\t\tusing maxsigned = qint64;\n\t};\n\npublic:\n\tusing ValueType = typename QtnSinglePropertyType::ValueType;\n\tusing IntervalType = typename interval_t<ValueType>::type;\n\tusing SignedMaxType = typename interval_t<ValueType>::maxsigned;\n\tusing MaxIntervalType = typename interval_t<SignedMaxType>::type;\n\n\tinline ValueType value() const\n\t{\n\t\treturn correctValue(QtnSinglePropertyType::value());\n\t}\n\n\tinline ValueType minValue() const\n\t{\n\t\treturn m_minValue;\n\t}\n\n\tinline void setMinValue(ValueType minValue)\n\t{\n\t\tif (m_minValue == minValue)\n\t\t\treturn;\n\n\t\temit this->propertyWillChange(\n\t\t\tQtnPropertyChangeReasonNewValue, nullptr, 0);\n\t\tm_minValue = minValue;\n\t\tm_maxValue = std::max(m_minValue, m_maxValue);\n\t\temit this->propertyDidChange(QtnPropertyChangeReasonNewValue);\n\t}\n\n\tinline ValueType maxValue() const\n\t{\n\t\treturn m_maxValue;\n\t}\n\n\tinline void setMaxValue(ValueType maxValue)\n\t{\n\t\tif (maxValue == m_maxValue)\n\t\t\treturn;\n\n\t\temit this->propertyWillChange(\n\t\t\tQtnPropertyChangeReasonNewValue, nullptr, 0);\n\t\tm_maxValue = maxValue;\n\t\tm_minValue = std::min(m_minValue, m_maxValue);\n\t\temit this->propertyDidChange(QtnPropertyChangeReasonNewValue);\n\t}\n\n\tinline ValueType correctValue(ValueType value) const\n\t{\n\t\tif (value < m_minValue)\n\t\t\tvalue = m_minValue;\n\n\t\tif (value > m_maxValue)\n\t\t\tvalue = m_maxValue;\n\n\t\treturn value;\n\t}\n\n\tinline ValueType stepValue() const\n\t{\n\t\treturn m_stepValue;\n\t}\n\n\tinline void setStepValue(ValueType stepValue)\n\t{\n\t\tif (stepValue == m_stepValue)\n\t\t\treturn;\n\n\t\temit this->propertyWillChange(\n\t\t\tQtnPropertyChangeReasonStateLocal, nullptr, 0);\n\t\tm_stepValue = stepValue;\n\t\temit this->propertyDidChange(QtnPropertyChangeReasonStateLocal);\n\t}\n\n\tinline void incrementValue(\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonNewValue,\n\t\tint steps = 1)\n\t{\n\t\tauto oldValue = this->value();\n\t\tValueType newValue;\n\t\tauto step = SignedMaxType(m_stepValue) * steps;\n\t\tif (step < SignedMaxType(0) &&\n\t\t\tMaxIntervalType(-step) >= IntervalType(oldValue - m_minValue))\n\t\t{\n\t\t\tnewValue = m_minValue;\n\t\t} else if (step > SignedMaxType(0) &&\n\t\t\tMaxIntervalType(step) >= IntervalType(m_maxValue - oldValue))\n\t\t{\n\t\t\tnewValue = m_maxValue;\n\t\t} else\n\t\t{\n\t\t\tnewValue = oldValue + step;\n\t\t}\n\t\tthis->setValue(newValue, reason);\n\t}\n\nprotected:\n\texplicit QtnNumericPropertyBase(QObject *parent)\n\t\t: QtnSinglePropertyType(parent)\n\t\t, m_minValue(std::numeric_limits<ValueType>::lowest())\n\t\t, m_maxValue(std::numeric_limits<ValueType>::max())\n\t\t, m_stepValue(ValueType(1))\n\t{\n\t}\n\n\tvirtual bool isValueAcceptedImpl(ValueType valueToAccept) override\n\t{\n\t\tif (valueToAccept < m_minValue)\n\t\t\treturn false;\n\n\t\tif (valueToAccept > m_maxValue)\n\t\t\treturn false;\n\n\t\treturn true;\n\t}\n\nprivate:\n\tValueType m_minValue;\n\tValueType m_maxValue;\n\tValueType m_stepValue;\n\n\tQ_DISABLE_COPY(QtnNumericPropertyBase)\n};\n\ntemplate <typename T>\ninline void qtnMakePercentProperty(T *dProp,\n\ttypename T::ValueType (*AfterGet)(typename T::ValueType),\n\tconst QByteArray &delegateName = QByteArray())\n{\n\tusing ValueType = typename T::ValueType;\n\tauto prevGet = dProp->callbackValueGet();\n\tif (prevGet)\n\t{\n\t\tdProp->setCallbackValueGet([prevGet, AfterGet]() -> ValueType {\n\t\t\treturn AfterGet(prevGet() * 100.0);\n\t\t});\n\t}\n\n\tauto prevEqual = dProp->callbackValueEqual();\n\tif (prevEqual)\n\t{\n\t\tdProp->setCallbackValueEqual([prevEqual](ValueType value) -> bool {\n\t\t\treturn prevEqual(value / 100.0);\n\t\t});\n\t}\n\n\tauto prevSet = dProp->callbackValueSet();\n\tif (prevSet)\n\t{\n\t\tdProp->setCallbackValueSet(\n\t\t\t[prevSet](ValueType value, QtnPropertyChangeReason reason) {\n\t\t\t\tprevSet(value / 100.0, reason);\n\t\t\t});\n\t}\n\n\tauto prevDefault = dProp->callbackValueDefault();\n\tif (prevDefault)\n\t{\n\t\tdProp->setCallbackValueDefault([prevDefault, AfterGet]() -> ValueType {\n\t\t\treturn AfterGet(prevDefault() * 100.0);\n\t\t});\n\t}\n\n\tQtnPropertyDelegateInfo delegate;\n\tqtnInitPercentSpinBoxDelegate(delegate);\n\tif (!delegateName.isEmpty())\n\t\tdelegate.name = delegateName;\n\tdProp->setDelegateInfo(delegate);\n}\n\ntemplate <typename QtnSinglePropertyType>\nclass QtnNumericPropertyValue : public QtnSinglePropertyType\n{\npublic:\n\tusing ValueType = typename QtnSinglePropertyType::ValueType;\n\tusing ValueTag = typename QtnSinglePropertyType::ValueTag;\n\n\tinline ValueType defaultValue() const\n\t{\n\t\treturn m_defaultValue;\n\t}\n\n\tinline void setDefaultValue(ValueType defaultValue)\n\t{\n\t\tm_defaultValue = defaultValue;\n\t}\n\nprotected:\n\texplicit QtnNumericPropertyValue(QObject *parent)\n\t\t: QtnSinglePropertyType(parent)\n\t\t, m_value(ValueType(0))\n\t\t, m_defaultValue(ValueType(0))\n\t{\n\t\tthis->addState(QtnPropertyStateResettable);\n\t}\n\n\tvirtual bool defaultValueImpl(ValueType &to) const override\n\t{\n\t\tto = this->correctValue(m_defaultValue);\n\t\treturn true;\n\t}\n\n\tvirtual ValueType valueImpl(ValueTag) const override\n\t{\n\t\treturn m_value;\n\t}\n\n\tvirtual void setValueImpl(\n\t\tValueType newValue, QtnPropertyChangeReason /*reason*/) override\n\t{\n\t\tm_value = newValue;\n\t}\n\nprivate:\n\tValueType m_value;\n\tValueType m_defaultValue;\n\n\tQ_DISABLE_COPY(QtnNumericPropertyValue)\n};\n\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<bool>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<qint32>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<quint32>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<qint64>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<quint64>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<float>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<double>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<QString>;\ntemplate class QTN_IMPORT_EXPORT QtnSinglePropertyBase<QVariant>;\n\n#endif // PROPERTY_TEMPLATES_H\n"
  },
  {
    "path": "QtnProperty/Config.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include <qglobal.h>\n\n#if defined(QTN_DYNAMIC_LIBRARY)\n#define QTN_IMPORT_EXPORT Q_DECL_EXPORT\n\n#elif defined(QTN_DYNAMIC_IMPORT)\n#define QTN_IMPORT_EXPORT Q_DECL_IMPORT\n#else\n\n#define QTN_IMPORT_EXPORT\n#ifndef QTN_STATIC_LIBRARY\n#define QTN_STATIC_LIBRARY\n#endif\n#endif\n\n#define PERCENT_SUFFIX 1\n#define DEGREE_SUFFIX 2\n"
  },
  {
    "path": "QtnProperty/Core/PropertyBool.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyBool.h\"\n\n#include <QCoreApplication>\n\nstatic bool getBoolValue(QString boolText, bool &success)\n{\n\tsuccess = true;\n\n\tif (boolText.compare(QtnPropertyBool::getBoolText(false, true),\n\t\t\tQt::CaseInsensitive) == 0)\n\t\treturn false;\n\n\tif (boolText.compare(\n\t\t\tQtnPropertyBool::getBoolText(true, true), Qt::CaseInsensitive) == 0)\n\t\treturn true;\n\n\tif (boolText.toULongLong(&success) != 0)\n\t\treturn true;\n\n\tsuccess = false;\n\treturn false;\n}\n\nQtnPropertyBoolBase::QtnPropertyBoolBase(QObject *parent)\n\t: QtnSinglePropertyBase<bool>(parent)\n{\n}\n\nbool QtnPropertyBoolBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool success = false;\n\tbool value = getBoolValue(str.trimmed(), success);\n\n\tif (!success)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyBoolBase::toStrImpl(QString &str) const\n{\n\tbool boolValue = value();\n\tstr = QtnPropertyBool::getBoolText(boolValue, true);\n\treturn true;\n}\n\nQtnPropertyBool::QtnPropertyBool(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyBoolBase>(parent)\n{\n}\n\nQString QtnPropertyBool::getBoolText(bool value, bool internal)\n{\n\tstatic const char pFalse[] = QT_TRANSLATE_NOOP(\"QtnPropertyBool\", \"False\");\n\tstatic const char pTrue[] = QT_TRANSLATE_NOOP(\"QtnPropertyBool\", \"True\");\n\n\tif (internal)\n\t\treturn QString(value ? pTrue : pFalse);\n\n\treturn QCoreApplication::translate(\n\t\t\"QtnPropertyBool\", value ? pTrue : pFalse);\n}\n\nQtnPropertyBoolCallback::QtnPropertyBoolCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyBoolBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyBool.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYBOOL_H\n#define PROPERTYBOOL_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyBoolBase : public QtnSinglePropertyBase<bool>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyBoolBase(const QtnPropertyBoolBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyBoolBase(QObject *parent = nullptr);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyBoolBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyBoolBase, bool)\n\nclass QTN_IMPORT_EXPORT QtnPropertyBoolCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyBoolBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyBoolCallback(\n\t\tconst QtnPropertyBoolCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyBoolCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyBoolCallback, QtnPropertyBoolBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyBool\n\t: public QtnSinglePropertyValue<QtnPropertyBoolBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyBool(const QtnPropertyBool &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyBool(QObject *parent = nullptr);\n\n\tstatic QString getBoolText(bool value, bool internal);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyBool, QtnPropertyBoolBase)\n};\n\n#endif // PROPERTYBOOL_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyDouble.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDouble.h\"\n\nQtnPropertyDoubleBase::QtnPropertyDoubleBase(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<double>>(parent)\n{\n}\n\nbool QtnPropertyDoubleBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toDouble(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyDoubleBase::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value(), 'g', std::numeric_limits<double>::digits10);\n\treturn true;\n}\n\nQtnPropertyDoubleCallback::QtnPropertyDoubleCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyDoubleBase>(parent)\n{\n}\n\nQtnPropertyDouble::QtnPropertyDouble(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyDoubleBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyDouble.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYDOUBLE_H\n#define PROPERTYDOUBLE_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDoubleBase\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<double>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyDoubleBase(const QtnPropertyDoubleBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyDoubleBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyDoubleBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyDoubleBase, double)\n\nclass QTN_IMPORT_EXPORT QtnPropertyDoubleCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyDoubleBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyDoubleCallback(\n\t\tconst QtnPropertyDoubleCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyDoubleCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyDoubleCallback, QtnPropertyDoubleBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDouble\n\t: public QtnNumericPropertyValue<QtnPropertyDoubleBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyDouble(const QtnPropertyDouble &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyDouble(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyDouble, QtnPropertyDoubleBase)\n};\n\n#endif // PROPERTYDOUBLE_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyEnum.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyEnum.h\"\n\nQtnPropertyEnumBase::QtnPropertyEnumBase(QObject *parent)\n\t: QtnSinglePropertyBase<QtnEnumValueType>(parent)\n\t, m_enumInfo(nullptr)\n{\n}\n\nbool QtnPropertyEnumBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tif (!m_enumInfo)\n\t\treturn false;\n\n\tconst QtnEnumValueInfo *enumValue = m_enumInfo->fromStr(str);\n\n\tif (!enumValue)\n\t\treturn false;\n\n\treturn setValue(enumValue->value(), reason);\n}\n\nbool QtnPropertyEnumBase::toStrImpl(QString &str) const\n{\n\tif (!m_enumInfo)\n\t\treturn false;\n\n\tQtnEnumValueType v = value();\n\tconst QtnEnumValueInfo *enumValue = m_enumInfo->findByValue(v);\n\treturn m_enumInfo->toStr(str, enumValue);\n}\n\nbool QtnPropertyEnumBase::isValueAcceptedImpl(ValueType valueToAccept)\n{\n\tif (!m_enumInfo)\n\t\treturn false;\n\n\tif (!m_enumInfo->findByValue(valueToAccept))\n\t\treturn false;\n\n\treturn true;\n}\n\nQtnPropertyEnumCallback::QtnPropertyEnumCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyEnumBase>(parent)\n{\n}\n\nQtnPropertyEnum::QtnPropertyEnum(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyEnumBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyEnum.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYENUM_H\n#define PROPERTYENUM_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/Enum.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnumBase\n\t: public QtnSinglePropertyBase<QtnEnumValueType>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyEnumBase(const QtnPropertyEnumBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyEnumBase(QObject *parent);\n\n\tinline const QtnEnumInfo *enumInfo() const;\n\n\tinline void setEnumInfo(const QtnEnumInfo *enumInfo);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tbool isValueAcceptedImpl(ValueType valueToAccept) override;\n\nprivate:\n\tconst QtnEnumInfo *m_enumInfo;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyEnumBase)\n};\n\nconst QtnEnumInfo *QtnPropertyEnumBase::enumInfo() const\n{\n\treturn m_enumInfo;\n}\n\nvoid QtnPropertyEnumBase::setEnumInfo(const QtnEnumInfo *enumInfo)\n{\n\tm_enumInfo = enumInfo;\n}\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyEnumBase, QtnEnumValueType)\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnumCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyEnumBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyEnumCallback(\n\t\tconst QtnPropertyEnumCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyEnumCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyEnumCallback, QtnPropertyEnumBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnum\n\t: public QtnSinglePropertyValue<QtnPropertyEnumBase>\n{\n\tQ_OBJECT QtnPropertyEnum(const QtnPropertyEnum &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyEnum(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyEnum, QtnPropertyEnumBase)\n};\n\n#endif // PROPERTYENUM_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyEnumFlags.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyEnumFlags.h\"\n\nQtnPropertyEnumFlagsBase::QtnPropertyEnumFlagsBase(QObject *parent)\n\t: QtnSinglePropertyBase<QtnEnumFlagsValueType>(parent)\n\t, m_enumInfo(0)\n{\n}\n\nbool QtnPropertyEnumFlagsBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tif (!m_enumInfo)\n\t\treturn false;\n\n\tQtnEnumFlagsValueType val = 0;\n\tQString enumStr = str.trimmed();\n\n\tif (!enumStr.isEmpty() && enumStr != \"0\")\n\t{\n\t\tstatic QRegExp parserEnumFlags(\n\t\t\tQStringLiteral(\"^\\\\s*([^|\\\\s]+)\\\\s*\\\\|(.+)$\"), Qt::CaseInsensitive);\n\n\t\twhile (parserEnumFlags.exactMatch(enumStr))\n\t\t{\n\t\t\tQStringList params = parserEnumFlags.capturedTexts();\n\n\t\t\tif (params.size() != 3)\n\t\t\t\treturn false;\n\n\t\t\tconst QtnEnumValueInfo *enumValue = m_enumInfo->fromStr(params[1]);\n\n\t\t\tif (!enumValue)\n\t\t\t\treturn false;\n\n\t\t\tval = val | enumValue->value();\n\n\t\t\tenumStr = params[2];\n\t\t}\n\n\t\tconst QtnEnumValueInfo *enumValue = m_enumInfo->fromStr(enumStr);\n\n\t\tif (!enumValue)\n\t\t\treturn false;\n\n\t\tval = val | enumValue->value();\n\t}\n\n\treturn setValue(val, reason);\n}\n\nbool QtnPropertyEnumFlagsBase::toStrImpl(QString &str) const\n{\n\tif (!m_enumInfo)\n\t\treturn false;\n\n\tQtnEnumFlagsValueType v = value();\n\n\tif (v == 0)\n\t{\n\t\tstr = \"0\";\n\t\treturn true;\n\t}\n\n\tQString strValues;\n\tm_enumInfo->forEachEnumValue(\n\t\t[&strValues, v, this](const QtnEnumValueInfo &value) -> bool //\n\t\t{\n\t\t\tif (v & value.value())\n\t\t\t{\n\t\t\t\tif (!strValues.isEmpty())\n\t\t\t\t\tstrValues += \"|\";\n\n\t\t\t\tQString enumStr;\n\t\t\t\tm_enumInfo->toStr(enumStr, &value);\n\t\t\t\tstrValues += enumStr;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\tQ_ASSERT(!strValues.isEmpty());\n\n\tstr = strValues;\n\treturn true;\n}\n\nQtnPropertyEnumFlags::QtnPropertyEnumFlags(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyEnumFlagsBase>(parent)\n{\n}\n\nQString QtnPropertyEnumFlags::getFlagLabelDescription(\n\tconst QString &flagName, const QString &ownerName)\n{\n\treturn tr(\"%1 flag for %2\").arg(flagName, ownerName);\n}\n\nQtnPropertyEnumFlagsCallback::QtnPropertyEnumFlagsCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyEnumFlagsBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyEnumFlags.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYENUMFLAGS_H\n#define PROPERTYENUMFLAGS_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/Enum.h\"\n\ntypedef qint32 QtnEnumFlagsValueType;\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnumFlagsBase\n\t: public QtnSinglePropertyBase<QtnEnumFlagsValueType>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyEnumFlagsBase(\n\t\tconst QtnPropertyEnumFlagsBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyEnumFlagsBase(QObject *parent);\n\n\tinline const QtnEnumInfo *enumInfo() const;\n\n\tinline void setEnumInfo(const QtnEnumInfo *enumInfo);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\nprivate:\n\tconst QtnEnumInfo *m_enumInfo;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyEnumFlagsBase)\n};\n\nconst QtnEnumInfo *QtnPropertyEnumFlagsBase::enumInfo() const\n{\n\treturn m_enumInfo;\n}\n\nvoid QtnPropertyEnumFlagsBase::setEnumInfo(const QtnEnumInfo *enumInfo)\n{\n\tm_enumInfo = enumInfo;\n}\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyEnumFlagsBase, QtnEnumFlagsValueType)\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnumFlagsCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyEnumFlagsBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyEnumFlagsCallback(\n\t\tconst QtnPropertyEnumFlagsCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyEnumFlagsCallback(\n\t\tQObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyEnumFlagsCallback, QtnPropertyEnumFlagsBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyEnumFlags\n\t: public QtnSinglePropertyValue<QtnPropertyEnumFlagsBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyEnumFlags(const QtnPropertyEnumFlags &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyEnumFlags(QObject *parent = nullptr);\n\n\tstatic QString getFlagLabelDescription(\n\t\tconst QString &flagName, const QString &ownerName);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyEnumFlags, QtnPropertyEnumFlagsBase)\n};\n\n#endif // PROPERTYENUMFLAGS_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyFloat.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyFloat.h\"\n\nQtnPropertyFloatBase::QtnPropertyFloatBase(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<float>>(parent)\n{\n}\n\nbool QtnPropertyFloatBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toFloat(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyFloatBase::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value(), 'g', std::numeric_limits<float>::digits10);\n\treturn true;\n}\n\nQtnPropertyFloatCallback::QtnPropertyFloatCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyFloatBase>(parent)\n{\n}\n\nQtnPropertyFloat::QtnPropertyFloat(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyFloatBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyFloat.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYFLOAT_H\n#define PROPERTYFLOAT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyFloatBase\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<float>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyFloatBase(const QtnPropertyFloatBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyFloatBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyFloatBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyFloatBase, float)\n\nclass QTN_IMPORT_EXPORT QtnPropertyFloatCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyFloatBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyFloatCallback(\n\t\tconst QtnPropertyFloatCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyFloatCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyFloatCallback, QtnPropertyFloatBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyFloat\n\t: public QtnNumericPropertyValue<QtnPropertyFloatBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyFloat(const QtnPropertyFloat &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyFloat(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyFloat, QtnPropertyFloatBase)\n};\n\n#endif // PROPERTYFLOAT_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyInt.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyInt.h\"\n\n#include <QLocale>\n\nQtnPropertyIntBase::QtnPropertyIntBase(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<qint32>>(parent)\n{\n}\n\nbool QtnPropertyIntBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyIntBase::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value());\n\treturn true;\n}\n\nQtnPropertyIntCallback::QtnPropertyIntCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyIntBase>(parent)\n{\n}\n\nQtnPropertyInt::QtnPropertyInt(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyIntBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyInt.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYINT_H\n#define PROPERTYINT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyIntBase\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<qint32>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyIntBase(const QtnPropertyIntBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyIntBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyIntBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyIntBase, qint32)\n\nclass QTN_IMPORT_EXPORT QtnPropertyIntCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyIntBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyIntCallback(\n\t\tconst QtnPropertyIntCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyIntCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyIntCallback, QtnPropertyIntBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyInt\n\t: public QtnNumericPropertyValue<QtnPropertyIntBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyInt(const QtnPropertyInt &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyInt(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyInt, QtnPropertyIntBase)\n};\n\n#endif // PROPERTYINT_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQPoint.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQPoint.h\"\n\nQtnPropertyQPointBase::QtnPropertyQPointBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nQtnProperty *QtnPropertyQPointBase::createXProperty()\n{\n\treturn createFieldProperty(&QPoint::x, &QPoint::setX,\n\t\tQtnPropertyQPoint::xKey(), QtnPropertyQPoint::xDisplayName(),\n\t\tQtnPropertyQPoint::xDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQPointBase::createYProperty()\n{\n\treturn createFieldProperty(&QPoint::y, &QPoint::setY,\n\t\tQtnPropertyQPoint::yKey(), QtnPropertyQPoint::yDisplayName(),\n\t\tQtnPropertyQPoint::yDescriptionFmt());\n}\n\nbool QtnPropertyQPointBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserPoint(\n\t\t\"^\\\\s*QPoint\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\", Qt::CaseInsensitive);\n\n\tif (!parserPoint.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserPoint.capturedTexts();\n\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tstatic QRegExp parserParams(\n\t\t\"^\\\\s*(-?\\\\d+)\\\\s*,\\\\s*(-?\\\\d+)\\\\s*$\", Qt::CaseInsensitive);\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\n\tif (params.size() != 3)\n\t\treturn false;\n\n\tbool ok = false;\n\tint x = params[1].toInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tint y = params[2].toInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QPoint(x, y), reason);\n}\n\nbool QtnPropertyQPointBase::toStrImpl(QString &str) const\n{\n\tQPoint v = value();\n\tstr = QStringLiteral(\"QPoint(%1, %2)\").arg(v.x()).arg(v.y());\n\treturn true;\n}\n\nQtnPropertyQPoint::QtnPropertyQPoint(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQPointBase>(parent)\n{\n}\n\nQString QtnPropertyQPoint::getToStringFormat()\n{\n\treturn tr(\"[%1, %2]\");\n}\n\nQString QtnPropertyQPoint::xKey()\n{\n\treturn QStringLiteral(\"x\");\n}\n\nQString QtnPropertyQPoint::xDisplayName()\n{\n\treturn tr(\"X\");\n}\n\nQString QtnPropertyQPoint::xDescriptionFmt()\n{\n\treturn tr(\"X of the %1\");\n}\n\nQString QtnPropertyQPoint::yKey()\n{\n\treturn QStringLiteral(\"y\");\n}\n\nQString QtnPropertyQPoint::yDisplayName()\n{\n\treturn tr(\"Y\");\n}\n\nQString QtnPropertyQPoint::yDescriptionFmt()\n{\n\treturn tr(\"Y of the %1\");\n}\n\nQtnPropertyQPointCallback::QtnPropertyQPointCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQPointBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQPoint.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQPOINT_H\n#define PROPERTYQPOINT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyInt.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QPoint>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPointBase\n\t: public QtnStructPropertyBase<QPoint, QtnPropertyIntCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPointBase(const QtnPropertyQPointBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPointBase(QObject *parent);\n\n\tQtnProperty *createXProperty();\n\tQtnProperty *createYProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQPointBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQPointBase, QPoint)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPointCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQPointBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPointCallback(\n\t\tconst QtnPropertyQPointCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQPointCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPointCallback, QtnPropertyQPointBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPoint\n\t: public QtnSinglePropertyValue<QtnPropertyQPointBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPoint(const QtnPropertyQPoint &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQPoint(QObject *parent = nullptr);\n\n\tstatic QString getToStringFormat();\n\n\tstatic QString xKey();\n\tstatic QString xDisplayName();\n\tstatic QString xDescriptionFmt();\n\tstatic QString yKey();\n\tstatic QString yDisplayName();\n\tstatic QString yDescriptionFmt();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQPoint, QtnPropertyQPointBase)\n};\n\n#endif // PROPERTYQPOINT_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQPointF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQPointF.h\"\n\n#include \"PropertyQPoint.h\"\n\nQtnPropertyQPointFBase::QtnPropertyQPointFBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nQtnProperty *QtnPropertyQPointFBase::createXProperty()\n{\n\treturn createFieldProperty(&QPointF::x, &QPointF::setX,\n\t\tQtnPropertyQPoint::xKey(), getXLabel(), getXDescriptionFormat());\n}\n\nQtnProperty *QtnPropertyQPointFBase::createYProperty()\n{\n\treturn createFieldProperty(&QPointF::y, &QPointF::setY,\n\t\tQtnPropertyQPoint::yKey(), getYLabel(), getYDescriptionFormat());\n}\n\nQString QtnPropertyQPointFBase::getXLabel() const\n{\n\treturn QtnPropertyQPoint::xDisplayName();\n}\n\nQString QtnPropertyQPointFBase::getXDescriptionFormat() const\n{\n\treturn QtnPropertyQPoint::xDescriptionFmt();\n}\n\nQString QtnPropertyQPointFBase::getYLabel() const\n{\n\treturn QtnPropertyQPoint::yDisplayName();\n}\n\nQString QtnPropertyQPointFBase::getYDescriptionFormat() const\n{\n\treturn QtnPropertyQPoint::yDescriptionFmt();\n}\n\nbool QtnPropertyQPointFBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserPoint(\n\t\tQLatin1String(\"^\\\\s*QPointF\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\"),\n\t\tQt::CaseInsensitive);\n\n\tif (!parserPoint.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserPoint.capturedTexts();\n\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tstatic QRegExp parserParams(\n\t\t\"^\\\\s*(\\\\-?\\\\d+(\\\\.\\\\d{0,})?)\\\\s*,\\\\s*(\\\\-?\\\\d+(\\\\.\\\\d{0,})?)\\\\s*$\",\n\t\tQt::CaseInsensitive);\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\n\tif (params.size() != 5)\n\t\treturn false;\n\n\tbool ok = false;\n\tdouble x = params[1].toDouble(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tdouble y = params[3].toDouble(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QPointF(x, y), reason);\n}\n\nbool QtnPropertyQPointFBase::toStrImpl(QString &str) const\n{\n\tQPointF v = value();\n\tstr = QStringLiteral(\"QPointF(%1, %2)\").arg(v.x()).arg(v.y());\n\treturn true;\n}\n\nQtnPropertyQPointF::QtnPropertyQPointF(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQPointFBase>(parent)\n{\n}\n\nQtnPropertyQPointFCallback::QtnPropertyQPointFCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQPointFBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQPointF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQPOINTF_H\n#define PROPERTYQPOINTF_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyDouble.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QPointF>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPointFBase\n\t: public QtnStructPropertyBase<QPointF, QtnPropertyDoubleCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPointFBase(\n\t\tconst QtnPropertyQPointFBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPointFBase(QObject *parent);\n\n\tQtnProperty *createXProperty();\n\tQtnProperty *createYProperty();\n\n\tvirtual QString getXLabel() const;\n\tvirtual QString getXDescriptionFormat() const;\n\tvirtual QString getYLabel() const;\n\tvirtual QString getYDescriptionFormat() const;\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQPointFBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQPointFBase, QPointF)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPointFCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQPointFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPointFCallback(\n\t\tconst QtnPropertyQPointFCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQPointFCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPointFCallback, QtnPropertyQPointFBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPointF\n\t: public QtnSinglePropertyValue<QtnPropertyQPointFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQPointF(const QtnPropertyQPointF &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQPointF(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPointF, QtnPropertyQPointFBase)\n};\n\n#endif // PROPERTYQPOINTF_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQRect.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQRect.h\"\n\n#include \"PropertyQSize.h\"\n\nQtnProperty *QtnPropertyQRectBase::createLeftProperty(bool move)\n{\n\treturn createFieldProperty(&QRect::left,\n\t\tmove ? &QRect::moveLeft : &QRect::setLeft, QtnPropertyQRect::leftKey(),\n\t\tQtnPropertyQRect::leftString(), QtnPropertyQRect::leftDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectBase::createTopProperty(bool move)\n{\n\treturn createFieldProperty(&QRect::top,\n\t\tmove ? &QRect::moveTop : &QRect::setTop, QtnPropertyQRect::topKey(),\n\t\tQtnPropertyQRect::topString(), QtnPropertyQRect::topDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectBase::createRightProperty(bool move)\n{\n\treturn createFieldProperty(&QRect::right,\n\t\tmove ? &QRect::moveRight : &QRect::setRight,\n\t\tQtnPropertyQRect::rightKey(), QtnPropertyQRect::rightString(),\n\t\tQtnPropertyQRect::rightDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectBase::createBottomProperty(bool move)\n{\n\treturn createFieldProperty(&QRect::bottom,\n\t\tmove ? &QRect::moveBottom : &QRect::setBottom,\n\t\tQtnPropertyQRect::bottomKey(), QtnPropertyQRect::bottomString(),\n\t\tQtnPropertyQRect::bottomDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectBase::createWidthProperty()\n{\n\treturn createFieldProperty(&QRect::width, &QRect::setWidth,\n\t\tQtnPropertyQSize::widthKey(), QtnPropertyQSize::widthDisplayName(),\n\t\tQtnPropertyQSize::widthDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectBase::createHeightProperty()\n{\n\treturn createFieldProperty(&QRect::height, &QRect::setHeight,\n\t\tQtnPropertyQSize::heightKey(), QtnPropertyQSize::heightDisplayName(),\n\t\tQtnPropertyQSize::heightDescriptionFmt());\n}\n\nQByteArray QtnPropertyQRect::delegateName(bool coordinateMode)\n{\n\tif (coordinateMode)\n\t{\n\t\treturn QByteArrayLiteral(\"LTRB\");\n\t} else\n\t{\n\t\treturn QByteArrayLiteral(\"LTWH\");\n\t}\n}\n\nQtnPropertyQRectBase::QtnPropertyQRectBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nbool QtnPropertyQRectBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserRect(\n\t\t\"^\\\\s*QRect\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\", Qt::CaseInsensitive);\n\tstatic QRegExp parserParams(\n\t\t\"^\\\\s*(-?\\\\d+)\\\\s*,\\\\s*(-?\\\\d+)\\\\s*,\\\\s*(\\\\d+)\\\\s*,\\\\s*(\\\\d+)\\\\s*$\",\n\t\tQt::CaseInsensitive);\n\n\tif (!parserRect.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserRect.capturedTexts();\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\tif (params.size() != 5)\n\t\treturn false;\n\n\tbool ok = false;\n\tint left = params[1].toInt(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tint top = params[2].toInt(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tint width = params[3].toInt(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tint height = params[4].toInt(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QRect(left, top, width, height), reason);\n}\n\nbool QtnPropertyQRectBase::toStrImpl(QString &str) const\n{\n\tauto v = value();\n\n\tstr = QStringLiteral(\"QRect(%1, %2, %3, %4)\")\n\t\t\t  .arg(v.left())\n\t\t\t  .arg(v.top())\n\t\t\t  .arg(v.width())\n\t\t\t  .arg(v.height());\n\n\treturn true;\n}\n\nQtnPropertyQRect::QtnPropertyQRect(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQRectBase>(parent)\n{\n}\n\nQString QtnPropertyQRect::getToStringFormat(bool coordinates)\n{\n\treturn coordinates ? tr(\"[(%1, %2), (%3, %4)]\") : tr(\"[(%1, %2) %3 x %4]\");\n}\n\nQString QtnPropertyQRect::leftKey()\n{\n\treturn QStringLiteral(\"left\");\n}\n\nQString QtnPropertyQRect::leftString()\n{\n\treturn tr(\"Left\");\n}\n\nQString QtnPropertyQRect::leftDescriptionFmt()\n{\n\treturn tr(\"Left position of the %1\");\n}\n\nQString QtnPropertyQRect::topKey()\n{\n\treturn QStringLiteral(\"top\");\n}\n\nQString QtnPropertyQRect::topString()\n{\n\treturn tr(\"Top\");\n}\n\nQString QtnPropertyQRect::topDescriptionFmt()\n{\n\treturn tr(\"Top position of the %1\");\n}\n\nQString QtnPropertyQRect::rightKey()\n{\n\treturn QStringLiteral(\"right\");\n}\n\nQString QtnPropertyQRect::rightString()\n{\n\treturn tr(\"Right\");\n}\n\nQString QtnPropertyQRect::rightDescriptionFmt()\n{\n\treturn tr(\"Right position of the %1\");\n}\n\nQString QtnPropertyQRect::bottomKey()\n{\n\treturn QStringLiteral(\"bottom\");\n}\n\nQString QtnPropertyQRect::bottomString()\n{\n\treturn tr(\"Bottom\");\n}\n\nQString QtnPropertyQRect::bottomDescriptionFmt()\n{\n\treturn tr(\"Bottom position of the %1\");\n}\n\nQtnPropertyQRectCallback::QtnPropertyQRectCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQRectBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQRect.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQRECT_H\n#define PROPERTYQRECT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyInt.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QRect>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRectBase\n\t: public QtnStructPropertyBase<QRect, QtnPropertyIntCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRectBase(const QtnPropertyQRectBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQRectBase(QObject *parent);\n\n\tQtnProperty *createLeftProperty(bool move);\n\tQtnProperty *createTopProperty(bool move);\n\tQtnProperty *createRightProperty(bool move);\n\tQtnProperty *createBottomProperty(bool move);\n\tQtnProperty *createWidthProperty();\n\tQtnProperty *createHeightProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQRectBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQRectBase, QRect)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRectCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQRectBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRectCallback(\n\t\tconst QtnPropertyQRectCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQRectCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQRectCallback, QtnPropertyQRectBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRect\n\t: public QtnSinglePropertyValue<QtnPropertyQRectBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRect(const QtnPropertyQRect &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQRect(QObject *parent = nullptr);\n\n\tstatic QByteArray delegateName(bool coordinateMode);\n\n\tstatic QString getToStringFormat(bool m_coordinates);\n\tstatic QString leftKey();\n\tstatic QString leftString();\n\tstatic QString leftDescriptionFmt();\n\tstatic QString topKey();\n\tstatic QString topString();\n\tstatic QString topDescriptionFmt();\n\tstatic QString rightKey();\n\tstatic QString rightString();\n\tstatic QString rightDescriptionFmt();\n\tstatic QString bottomKey();\n\tstatic QString bottomString();\n\tstatic QString bottomDescriptionFmt();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQRect, QtnPropertyQRectBase)\n};\n\n#endif // PROPERTYQRECT_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQRectF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQRectF.h\"\n\n#include \"PropertyQRect.h\"\n#include \"PropertyQSize.h\"\n\nQtnProperty *QtnPropertyQRectFBase::createLeftProperty(bool move)\n{\n\treturn createFieldProperty(&QRectF::left,\n\t\tmove ? &QRectF::moveLeft : &QRectF::setLeft,\n\t\tQtnPropertyQRect::leftKey(), QtnPropertyQRect::leftString(),\n\t\tQtnPropertyQRect::leftDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectFBase::createTopProperty(bool move)\n{\n\treturn createFieldProperty(&QRectF::top,\n\t\tmove ? &QRectF::moveTop : &QRectF::setTop, QtnPropertyQRect::topKey(),\n\t\tQtnPropertyQRect::topString(), QtnPropertyQRect::topDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectFBase::createRightProperty(bool move)\n{\n\treturn createFieldProperty(&QRectF::right,\n\t\tmove ? &QRectF::moveRight : &QRectF::setRight,\n\t\tQtnPropertyQRect::rightKey(), QtnPropertyQRect::rightString(),\n\t\tQtnPropertyQRect::rightDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectFBase::createBottomProperty(bool move)\n{\n\treturn createFieldProperty(&QRectF::bottom,\n\t\tmove ? &QRectF::moveBottom : &QRectF::setBottom,\n\t\tQtnPropertyQRect::bottomKey(), QtnPropertyQRect::bottomString(),\n\t\tQtnPropertyQRect::bottomDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectFBase::createWidthProperty()\n{\n\treturn createFieldProperty(&QRectF::width, &QRectF::setWidth,\n\t\tQtnPropertyQSize::widthKey(), QtnPropertyQSize::widthDisplayName(),\n\t\tQtnPropertyQSize::widthDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQRectFBase::createHeightProperty()\n{\n\treturn createFieldProperty(&QRectF::height, &QRectF::setHeight,\n\t\tQtnPropertyQSize::heightKey(), QtnPropertyQSize::heightDisplayName(),\n\t\tQtnPropertyQSize::heightDescriptionFmt());\n}\n\nQtnPropertyQRectFBase::QtnPropertyQRectFBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nbool QtnPropertyQRectFBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserRect(\n\t\t\"^\\\\s*QRectF\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\", Qt::CaseInsensitive);\n\tstatic QRegExp parserParams(\"^\\\\s*(\\\\-?\\\\d+(\\\\.\\\\d{0,})?)\\\\s*,\\\\s*(\\\\-?\\\\d+\"\n\t\t\t\t\t\t\t\t\"(\\\\.\\\\d{0,})?)\\\\s*,\\\\s*(\\\\d+(\\\\.\\\\d{0,})?)\\\\s*\"\n\t\t\t\t\t\t\t\t\",\\\\s*(\\\\d+(\\\\.\\\\d{0,})?)\\\\s*$\",\n\t\tQt::CaseInsensitive);\n\n\tif (!parserRect.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserRect.capturedTexts();\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\tif (params.size() != 9)\n\t\treturn false;\n\n\tbool ok = false;\n\tdouble left = params[1].toDouble(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tdouble top = params[3].toDouble(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tdouble width = params[5].toDouble(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tdouble height = params[7].toDouble(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QRectF(left, top, width, height), reason);\n}\n\nbool QtnPropertyQRectFBase::toStrImpl(QString &str) const\n{\n\tauto v = value();\n\n\tstr = QStringLiteral(\"QRectF(%1, %2, %3, %4)\")\n\t\t\t  .arg(v.left())\n\t\t\t  .arg(v.top())\n\t\t\t  .arg(v.width())\n\t\t\t  .arg(v.height());\n\n\treturn true;\n}\n\nQtnPropertyQRectF::QtnPropertyQRectF(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQRectFBase>(parent)\n{\n}\n\nQtnPropertyQRectFCallback::QtnPropertyQRectFCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQRectFBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQRectF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQRECTF_H\n#define PROPERTYQRECTF_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyDouble.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QRectF>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRectFBase\n\t: public QtnStructPropertyBase<QRectF, QtnPropertyDoubleCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRectFBase(const QtnPropertyQRectFBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQRectFBase(QObject *parent);\n\n\tQtnProperty *createLeftProperty(bool move);\n\tQtnProperty *createTopProperty(bool move);\n\tQtnProperty *createRightProperty(bool move);\n\tQtnProperty *createBottomProperty(bool move);\n\tQtnProperty *createWidthProperty();\n\tQtnProperty *createHeightProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQRectFBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQRectFBase, QRectF)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRectFCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQRectFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRectFCallback(\n\t\tconst QtnPropertyQRectFCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQRectFCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQRectFCallback, QtnPropertyQRectFBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQRectF\n\t: public QtnSinglePropertyValue<QtnPropertyQRectFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQRectF(const QtnPropertyQRectF &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQRectF(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQRectF, QtnPropertyQRectFBase)\n};\n\n#endif // PROPERTYQRECT_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQSize.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQSize.h\"\n#include \"PropertyInt.h\"\n\nQtnPropertyQSizeBase::QtnPropertyQSizeBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nQtnProperty *QtnPropertyQSizeBase::createWidthProperty()\n{\n\treturn createFieldProperty(&QSize::width, &QSize::setWidth,\n\t\tQtnPropertyQSize::widthKey(), QtnPropertyQSize::widthDisplayName(),\n\t\tQtnPropertyQSize::widthDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQSizeBase::createHeightProperty()\n{\n\treturn createFieldProperty(&QSize::height, &QSize::setHeight,\n\t\tQtnPropertyQSize::heightKey(), QtnPropertyQSize::heightDisplayName(),\n\t\tQtnPropertyQSize::heightDescriptionFmt());\n}\n\nbool QtnPropertyQSizeBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserSize(\n\t\t\"^\\\\s*QSize\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\", Qt::CaseInsensitive);\n\n\tif (!parserSize.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserSize.capturedTexts();\n\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tstatic QRegExp parserParams(\n\t\t\"^\\\\s*(-?\\\\d+)\\\\s*,\\\\s*(-?\\\\d+)\\\\s*$\", Qt::CaseInsensitive);\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\n\tif (params.size() != 3)\n\t\treturn false;\n\n\tbool ok = false;\n\tint width = params[1].toInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tint height = params[2].toInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QSize(width, height), reason);\n}\n\nbool QtnPropertyQSizeBase::toStrImpl(QString &str) const\n{\n\tQSize v = value();\n\tstr = QString(\"QSize(%1, %2)\").arg(v.width()).arg(v.height());\n\treturn true;\n}\n\nQtnPropertyQSize::QtnPropertyQSize(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQSizeBase>(parent)\n{\n}\n\nQString QtnPropertyQSize::getToStringFormat()\n{\n\treturn tr(\"[%1 x %2]\");\n}\n\nQString QtnPropertyQSize::widthKey()\n{\n\treturn QStringLiteral(\"width\");\n}\n\nQString QtnPropertyQSize::widthDisplayName()\n{\n\treturn tr(\"Width\");\n}\n\nQString QtnPropertyQSize::widthDescriptionFmt()\n{\n\treturn tr(\"Width of the %1\");\n}\n\nQString QtnPropertyQSize::heightKey()\n{\n\treturn QStringLiteral(\"height\");\n}\n\nQString QtnPropertyQSize::heightDisplayName()\n{\n\treturn tr(\"Height\");\n}\n\nQString QtnPropertyQSize::heightDescriptionFmt()\n{\n\treturn tr(\"Height of the %1\");\n}\n\nQtnPropertyQSizeCallback::QtnPropertyQSizeCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQSizeBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQSize.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQSIZE_H\n#define PROPERTYQSIZE_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyInt.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QSize>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSizeBase\n\t: public QtnStructPropertyBase<QSize, QtnPropertyIntCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSizeBase(const QtnPropertyQSizeBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQSizeBase(QObject *parent);\n\n\tQtnProperty *createWidthProperty();\n\tQtnProperty *createHeightProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQSizeBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQSizeBase, QSize)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSizeCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQSizeBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSizeCallback(\n\t\tconst QtnPropertyQSizeCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQSizeCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQSizeCallback, QtnPropertyQSizeBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSize\n\t: public QtnSinglePropertyValue<QtnPropertyQSizeBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSize(const QtnPropertyQSize &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQSize(QObject *parent = nullptr);\n\n\tstatic QString getToStringFormat();\n\tstatic QString widthKey();\n\tstatic QString widthDisplayName();\n\tstatic QString widthDescriptionFmt();\n\tstatic QString heightKey();\n\tstatic QString heightDisplayName();\n\tstatic QString heightDescriptionFmt();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQSize, QtnPropertyQSizeBase)\n};\n\n#endif // PROPERTYQSIZE_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQSizeF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQSizeF.h\"\n\n#include \"PropertyQSize.h\"\n\nQtnPropertyQSizeFBase::QtnPropertyQSizeFBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nQtnProperty *QtnPropertyQSizeFBase::createWidthProperty()\n{\n\treturn createFieldProperty(&QSizeF::width, &QSizeF::setWidth,\n\t\tQtnPropertyQSize::widthKey(), QtnPropertyQSize::widthDisplayName(),\n\t\tQtnPropertyQSize::widthDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQSizeFBase::createHeightProperty()\n{\n\treturn createFieldProperty(&QSizeF::height, &QSizeF::setHeight,\n\t\tQtnPropertyQSize::heightKey(), QtnPropertyQSize::heightDisplayName(),\n\t\tQtnPropertyQSize::heightDescriptionFmt());\n}\n\nbool QtnPropertyQSizeFBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserSize(\n\t\t\"^\\\\s*QSizeF\\\\s*\\\\(([^\\\\)]+)\\\\)\\\\s*$\", Qt::CaseInsensitive);\n\n\tif (!parserSize.exactMatch(str))\n\t\treturn false;\n\n\tQStringList params = parserSize.capturedTexts();\n\n\tif (params.size() != 2)\n\t\treturn false;\n\n\tstatic QRegExp parserParams(\n\t\t\"^\\\\s*(\\\\-?\\\\d+(\\\\.\\\\d{0,})?)\\\\s*,\\\\s*(\\\\-?\\\\d+(\\\\.\\\\d{0,})?)\\\\s*$\",\n\t\tQt::CaseInsensitive);\n\n\tif (!parserParams.exactMatch(params[1]))\n\t\treturn false;\n\n\tparams = parserParams.capturedTexts();\n\n\tif (params.size() != 5)\n\t\treturn false;\n\n\tbool ok = false;\n\tdouble width = params[1].toDouble(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tdouble height = params[3].toDouble(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QSizeF(width, height), reason);\n}\n\nbool QtnPropertyQSizeFBase::toStrImpl(QString &str) const\n{\n\tQSizeF v = value();\n\tstr = QString(\"QSizeF(%1, %2)\").arg(v.width()).arg(v.height());\n\treturn true;\n}\n\nQtnPropertyQSizeF::QtnPropertyQSizeF(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQSizeFBase>(parent)\n{\n}\n\nQtnPropertyQSizeFCallback::QtnPropertyQSizeFCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQSizeFBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQSizeF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYQSIZEF_H\n#define PROPERTYQSIZEF_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"PropertyDouble.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include <QSizeF>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSizeFBase\n\t: public QtnStructPropertyBase<QSizeF, QtnPropertyDoubleCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSizeFBase(const QtnPropertyQSizeFBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQSizeFBase(QObject *parent);\n\n\tQtnProperty *createWidthProperty();\n\tQtnProperty *createHeightProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQSizeFBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQSizeFBase, QSizeF)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSizeFCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQSizeFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSizeFCallback(\n\t\tconst QtnPropertyQSizeFCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQSizeFCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQSizeFCallback, QtnPropertyQSizeFBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQSizeF\n\t: public QtnSinglePropertyValue<QtnPropertyQSizeFBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQSizeF(const QtnPropertyQSizeF &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQSizeF(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQSizeF, QtnPropertyQSizeFBase)\n};\n\n#endif // PROPERTYQSIZEF_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQString.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQString.h\"\n\nQtnPropertyQStringBase::QtnPropertyQStringBase(QObject *parent)\n\t: QtnSinglePropertyBase<QString>(parent)\n{\n}\n\nQtnPropertyQStringBase &QtnPropertyQStringBase::operator=(const char *newValue)\n{\n\tsetValue(QString(newValue));\n\treturn *this;\n}\n\nbool QtnPropertyQStringBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\treturn setValue(str, reason);\n}\n\nbool QtnPropertyQStringBase::toStrImpl(QString &str) const\n{\n\tstr = value();\n\treturn true;\n}\n\nQtnPropertyQString::QtnPropertyQString(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQStringBase>(parent)\n{\n}\n\nQtnPropertyQString &QtnPropertyQString::operator=(const char *newValue)\n{\n\tsetValue(QString(newValue));\n\treturn *this;\n}\n\nbool QtnPropertyQString::isMultilineText(const QString &text)\n{\n\treturn text.contains('\\n') || text.contains('\\r');\n}\n\nQString QtnPropertyQString::getEmptyPlaceholderStr()\n{\n\treturn tr(\"(Empty)\");\n}\n\nQString QtnPropertyQString::getPlaceholderStr(\n\tconst QString &text, bool checkMultiline)\n{\n\tif (checkMultiline && isMultilineText(text))\n\t\treturn tr(\"(Multiline Text)\");\n\n\tif (text.isEmpty())\n\t\treturn getEmptyPlaceholderStr();\n\n\treturn QString();\n}\n\nQString QtnPropertyQString::getReadOnlyPropertyTitleFormat()\n{\n\treturn tr(\"%1 (Read only)\");\n}\n\nQtnPropertyQStringCallback::QtnPropertyQStringCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQStringBase>(parent)\n{\n}\n\nQtnPropertyQStringCallback &QtnPropertyQStringCallback::operator=(\n\tconst char *newValue)\n{\n\tsetValue(QString(newValue));\n\treturn *this;\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyQString.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYSTRING_H\n#define PROPERTYSTRING_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyQStringBase\n\t: public QtnSinglePropertyBase<QString>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQStringBase(\n\t\tconst QtnPropertyQStringBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQStringBase(QObject *parent);\n\n\tQtnPropertyQStringBase &operator=(const char *newValue);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQStringBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyQStringBase, QString)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQStringCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQStringBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQStringCallback(\n\t\tconst QtnPropertyQStringCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQStringCallback(QObject *parent = nullptr);\n\n\tQtnPropertyQStringCallback &operator=(const char *newValue);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQStringCallback, QtnPropertyQStringBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQString\n\t: public QtnSinglePropertyValue<QtnPropertyQStringBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQString(const QtnPropertyQString &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQString(QObject *parent = nullptr);\n\n\tQtnPropertyQString &operator=(const char *newValue);\n\n\tstatic bool isMultilineText(const QString &text);\n\tstatic QString getEmptyPlaceholderStr();\n\tstatic QString getPlaceholderStr(const QString &text, bool checkMultiline);\n\tstatic QString getReadOnlyPropertyTitleFormat();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQString, QtnPropertyQStringBase)\n};\n\n#endif // PROPERTYSTRING_H\n"
  },
  {
    "path": "QtnProperty/Core/PropertyUInt.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyUInt.h\"\n\n#include <QLocale>\n\nQtnPropertyUIntBase::QtnPropertyUIntBase(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<quint32>>(parent)\n{\n}\n\nbool QtnPropertyUIntBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toUInt(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyUIntBase::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value());\n\treturn true;\n}\n\nQtnPropertyUIntCallback::QtnPropertyUIntCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyUIntBase>(parent)\n{\n}\n\nQtnPropertyUInt::QtnPropertyUInt(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyUIntBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/Core/PropertyUInt.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYUINT_H\n#define PROPERTYUINT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyUIntBase\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<quint32>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUIntBase(const QtnPropertyUIntBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyUIntBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyUIntBase)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyUIntBase, quint32)\n\nclass QTN_IMPORT_EXPORT QtnPropertyUIntCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyUIntBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUIntCallback(\n\t\tconst QtnPropertyUIntCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyUIntCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyUIntCallback, QtnPropertyUIntBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyUInt\n\t: public QtnNumericPropertyValue<QtnPropertyUIntBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUInt(const QtnPropertyUInt &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyUInt(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyUInt, QtnPropertyUIntBase)\n};\n\n#endif // PROPERTYUINT_H\n"
  },
  {
    "path": "QtnProperty/CustomPropertyEditorDialog.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"CustomPropertyEditorDialog.h\"\n#include \"ui_CustomPropertyEditorDialog.h\"\n\n#include \"Utils/InplaceEditing.h\"\n#include \"PropertyView.h\"\n\n#include \"VarProperty.h\"\n\n#include <QMenu>\n#include <QShortcut>\n\nCustomPropertyEditorDialog::CustomPropertyEditorDialog(QWidget *parent)\n\t: QDialog(parent)\n\t, ui(new Ui::CustomPropertyEditorDialog)\n{\n\tui->setupUi(this);\n\n\tupdateTitle();\n\n\tsetWindowFlags((windowFlags() & ~(Qt::WindowContextHelpButtonHint)) |\n\t\tQt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint);\n\n\tQObject::connect(ui->propertyWidget->propertyView(),\n\t\t&QtnPropertyView::activePropertyChanged, this,\n\t\t&CustomPropertyEditorDialog::onActivePropertyChanged);\n\n#ifdef Q_OS_MAC\n\tQtnPropertyWidgetEx::addShortcutForAction(QKeySequence(Qt::Key_Backspace),\n\t\tui->actionPropertyDelete, this, Qt::WindowShortcut);\n#endif\n\tQtnPropertyWidgetEx::addShortcutForAction(QKeySequence(Qt::Key_Delete),\n\t\tui->actionPropertyDelete, this, Qt::WindowShortcut);\n\n#ifdef Q_OS_WIN\n\tQtnPropertyWidgetEx::addShortcutForAction(\n\t\tQKeySequence(Qt::CTRL | Qt::Key_Insert), ui->actionPropertyCopy, this,\n\t\tQt::WindowShortcut);\n\tQtnPropertyWidgetEx::addShortcutForAction(\n\t\tQKeySequence(Qt::SHIFT | Qt::Key_Insert), ui->actionPropertyPaste, this,\n\t\tQt::WindowShortcut);\n#endif\n\n\tQtnPropertyWidgetEx::addShortcutForAction(ui->actionPropertyCut->shortcut(),\n\t\tui->actionPropertyCut, this, Qt::WindowShortcut);\n\tQtnPropertyWidgetEx::addShortcutForAction(\n\t\tui->actionPropertyCopy->shortcut(), ui->actionPropertyCopy, this,\n\t\tQt::WindowShortcut);\n\tQtnPropertyWidgetEx::addShortcutForAction(\n\t\tui->actionPropertyPaste->shortcut(), ui->actionPropertyPaste, this,\n\t\tQt::WindowShortcut);\n\n\tQtnPropertyWidgetEx::addShortcutForAction(\n\t\tui->actionPropertyOptions->shortcut(), ui->actionPropertyOptions, this,\n\t\tQt::WindowShortcut);\n\tQtnPropertyWidgetEx::addShortcutForAction(ui->actionPropertyAdd->shortcut(),\n\t\tui->actionPropertyAdd, this, Qt::WindowShortcut);\n\n\tui->propertyWidget->connectDeleteAction(ui->actionPropertyDelete, true);\n\tui->propertyWidget->connectCutAction(ui->actionPropertyCut, true);\n\tui->propertyWidget->connectCopyAction(ui->actionPropertyCopy, true);\n\tui->propertyWidget->connectPasteAction(ui->actionPropertyPaste, true);\n}\n\nCustomPropertyEditorDialog::~CustomPropertyEditorDialog()\n{\n\tdelete ui;\n}\n\nbool CustomPropertyEditorDialog::execute(const QString &title, QVariant &data)\n{\n\tui->propertyWidget->setData(&data, title);\n\n\tupdateActions();\n\n\tshow();\n\traise();\n\texec();\n\n\tif (result() == Accepted)\n\t{\n\t\tui->propertyWidget->updateData();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nvoid CustomPropertyEditorDialog::setReadOnly(bool value)\n{\n\tui->propertyWidget->setReadOnly(value);\n\tupdateTitle();\n\n\tif (value)\n\t{\n\t\tui->buttonBox->setStandardButtons(QDialogButtonBox::Close);\n\t} else\n\t{\n\t\tui->buttonBox->setStandardButtons(\n\t\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel);\n\t}\n}\n\nvoid CustomPropertyEditorDialog::accept()\n{\n\tqtnStopInplaceEdit(false);\n\n\tQDialog::accept();\n}\n\nvoid CustomPropertyEditorDialog::reject()\n{\n\tqtnStopInplaceEdit(false);\n\n\tQDialog::reject();\n}\n\nvoid CustomPropertyEditorDialog::onActivePropertyChanged(\n\tQtnPropertyBase *activeProperty)\n{\n\tupdateActions(activeProperty);\n}\n\nvoid CustomPropertyEditorDialog::on_buttonBox_clicked(QAbstractButton *button)\n{\n\tswitch (ui->buttonBox->buttonRole(button))\n\t{\n\t\tcase QDialogButtonBox::AcceptRole:\n\t\t\taccept();\n\t\t\tbreak;\n\n\t\tcase QDialogButtonBox::RejectRole:\n\t\t\treject();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nvoid CustomPropertyEditorDialog::on_propertyWidget_customContextMenuRequested(\n\tconst QPoint &pos)\n{\n\tauto property = ui->propertyWidget->propertyView()->activeProperty();\n\n\tif (nullptr != property)\n\t{\n\t\tqtnStopInplaceEdit(false);\n\n\t\tQMenu menu(this);\n\n\t\tmenu.addAction(ui->actionPropertyOptions);\n\t\tmenu.addSeparator();\n\n\t\tmenu.addAction(ui->actionPropertyAdd);\n\t\tmenu.addAction(ui->actionPropertyDuplicate);\n\t\tmenu.addSeparator();\n\t\tmenu.addAction(ui->actionPropertyCut);\n\t\tmenu.addAction(ui->actionPropertyCopy);\n\t\tmenu.addAction(ui->actionPropertyPaste);\n\t\tmenu.addSeparator();\n\t\tmenu.addAction(ui->actionPropertyDelete);\n\n\t\tupdateActions(property);\n\t\tmenu.exec(ui->propertyWidget->mapToGlobal(pos));\n\t}\n}\n\nvoid CustomPropertyEditorDialog::on_actionPropertyAdd_triggered()\n{\n\tui->propertyWidget->addProperty();\n}\n\nvoid CustomPropertyEditorDialog::on_actionPropertyDuplicate_triggered()\n{\n\tui->propertyWidget->duplicateProperty();\n}\n\nvoid CustomPropertyEditorDialog::on_actionPropertyOptions_triggered()\n{\n\tui->propertyWidget->propertyOptions();\n}\n\nvoid CustomPropertyEditorDialog::updateActions(QtnPropertyBase *property)\n{\n\tauto widget = ui->propertyWidget;\n\tbool readOnly = widget->isReadOnly();\n\n\tif (nullptr == property)\n\t\tproperty = ui->propertyWidget->propertyView()->activeProperty();\n\n\tauto add_text = tr(\"New...\");\n\n\tauto var_property = QtnCustomPropertyWidget::getVarProperty(property);\n\n\tif (nullptr != var_property)\n\t{\n\t\tswitch (var_property->GetType())\n\t\t{\n\t\t\tcase VarProperty::Map:\n\t\t\t\tadd_text = tr(\"New Property...\");\n\t\t\t\tbreak;\n\n\t\t\tcase VarProperty::List:\n\t\t\t\tadd_text = tr(\"New Element...\");\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbool not_top_parent = (var_property != var_property->TopParent());\n\t\tui->actionPropertyAdd->setEnabled(\n\t\t\t!readOnly && property->id() == VarProperty::PID_EXTRA);\n\t\tui->actionPropertyDuplicate->setEnabled(!readOnly && not_top_parent);\n\t\tui->actionPropertyOptions->setEnabled(true);\n\t\tui->actionPropertyDelete->setEnabled(\n\t\t\t!readOnly && not_top_parent && widget->canDeleteProperty(property));\n\t} else\n\t{\n\t\tui->actionPropertyAdd->setEnabled(false);\n\t\tui->actionPropertyDuplicate->setEnabled(false);\n\t\tui->actionPropertyOptions->setEnabled(false);\n\t\tui->actionPropertyDelete->setEnabled(false);\n\t}\n\n\tui->actionPropertyAdd->setText(add_text);\n\n\tui->actionPropertyCut->setEnabled(widget->canCutToClipboard());\n\tui->actionPropertyCopy->setEnabled(widget->canCopyToClipboard());\n\tui->actionPropertyPaste->setEnabled(widget->canPasteFromClipboard());\n}\n\nvoid CustomPropertyEditorDialog::updateTitle()\n{\n\tsetWindowTitle(ui->propertyWidget->isReadOnly()\n\t\t\t? tr(\"Read-only Properties\")\n\t\t\t: tr(\"Edit Custom Properties\"));\n}\n"
  },
  {
    "path": "QtnProperty/CustomPropertyEditorDialog.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"CustomPropertyOptionsDialog.h\"\n#include \"PropertyWidgetEx.h\"\n\n#include <QDialog>\n#include <QVariant>\n\n#include <functional>\n\nnamespace Ui\n{\nclass CustomPropertyEditorDialog;\n}\n\nclass QAbstractButton;\nclass QtnProperty;\nclass QtnPropertyBase;\nclass QtnPropertySet;\nclass VarProperty;\n\nclass QTN_IMPORT_EXPORT CustomPropertyEditorDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit CustomPropertyEditorDialog(QWidget *parent = nullptr);\n\tvirtual ~CustomPropertyEditorDialog() override;\n\n\tbool execute(const QString &title, QVariant &data);\n\n\tvoid setReadOnly(bool value);\n\n\tvirtual void accept() override;\n\tvirtual void reject() override;\n\nsignals:\n\tvoid apply(const QVariant &data);\n\nprivate slots:\n\tvoid onActivePropertyChanged(QtnPropertyBase *activeProperty);\n\n\tvoid on_buttonBox_clicked(QAbstractButton *button);\n\n\tvoid on_propertyWidget_customContextMenuRequested(const QPoint &pos);\n\n\tvoid on_actionPropertyAdd_triggered();\n\n\tvoid on_actionPropertyDuplicate_triggered();\n\n\tvoid on_actionPropertyOptions_triggered();\n\nprivate:\n\tvoid updateActions(QtnPropertyBase *property = nullptr);\n\tvoid updateTitle();\n\n\tUi::CustomPropertyEditorDialog *ui;\n};\n"
  },
  {
    "path": "QtnProperty/CustomPropertyEditorDialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>CustomPropertyEditorDialog</class>\n <widget class=\"QDialog\" name=\"CustomPropertyEditorDialog\">\n  <property name=\"geometry\">\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>389</width>\n    <height>468</height>\n   </rect>\n  </property>\n  <property name=\"windowTitle\">\n   <string notr=\"true\"/>\n  </property>\n  <property name=\"sizeGripEnabled\">\n   <bool>true</bool>\n  </property>\n  <property name=\"modal\">\n   <bool>true</bool>\n  </property>\n  <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\n   <property name=\"spacing\">\n    <number>0</number>\n   </property>\n   <property name=\"leftMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"topMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"rightMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"bottomMargin\">\n    <number>6</number>\n   </property>\n   <item>\n    <widget class=\"QtnCustomPropertyWidget\" name=\"propertyWidget\" native=\"true\">\n     <property name=\"focusPolicy\">\n      <enum>Qt::StrongFocus</enum>\n     </property>\n     <property name=\"contextMenuPolicy\">\n      <enum>Qt::CustomContextMenu</enum>\n     </property>\n     <property name=\"acceptDrops\">\n      <bool>true</bool>\n     </property>\n    </widget>\n   </item>\n   <item>\n    <widget class=\"QDialogButtonBox\" name=\"buttonBox\">\n     <property name=\"focusPolicy\">\n      <enum>Qt::StrongFocus</enum>\n     </property>\n     <property name=\"standardButtons\">\n      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>\n     </property>\n    </widget>\n   </item>\n  </layout>\n  <action name=\"actionPropertyAdd\">\n   <property name=\"text\">\n    <string notr=\"true\"/>\n   </property>\n   <property name=\"toolTip\">\n    <string notr=\"true\"/>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">Ctrl+=</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n  <action name=\"actionPropertyDelete\">\n   <property name=\"text\">\n    <string>Delete</string>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">Del</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n  <action name=\"actionPropertyDuplicate\">\n   <property name=\"text\">\n    <string>Duplicate...</string>\n   </property>\n   <property name=\"toolTip\">\n    <string notr=\"true\">Duplicate</string>\n   </property>\n  </action>\n  <action name=\"actionPropertyOptions\">\n   <property name=\"text\">\n    <string>Options...</string>\n   </property>\n   <property name=\"toolTip\">\n    <string notr=\"true\">Options</string>\n   </property>\n   <property name=\"statusTip\">\n    <string/>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">F2</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n  <action name=\"actionPropertyCut\">\n   <property name=\"text\">\n    <string>Cut</string>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">Ctrl+X</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n  <action name=\"actionPropertyCopy\">\n   <property name=\"text\">\n    <string>Copy</string>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">Ctrl+C</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n  <action name=\"actionPropertyPaste\">\n   <property name=\"text\">\n    <string>Paste</string>\n   </property>\n   <property name=\"shortcut\">\n    <string notr=\"true\">Ctrl+V</string>\n   </property>\n   <property name=\"shortcutContext\">\n    <enum>Qt::WindowShortcut</enum>\n   </property>\n  </action>\n </widget>\n <customwidgets>\n  <customwidget>\n   <class>QtnCustomPropertyWidget</class>\n   <extends>QWidget</extends>\n   <header>QtnProperty/CustomPropertyWidget.h</header>\n   <container>1</container>\n  </customwidget>\n </customwidgets>\n <resources/>\n <connections/>\n</ui>\n"
  },
  {
    "path": "QtnProperty/CustomPropertyOptionsDialog.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"CustomPropertyOptionsDialog.h\"\n#include \"ui_CustomPropertyOptionsDialog.h\"\n\n#include <QLabel>\n#include <QLineEdit>\n#include <QSpinBox>\n#include <QDialogButtonBox>\n#include <QAbstractButton>\n#include <QMessageBox>\n\nBasePropertyDialog::BasePropertyDialog(QWidget *parent)\n\t: QDialog(parent)\n\t, result_index(-1)\n{\n\tsetWindowFlags(\n\t\t(windowFlags() &\n\t\t\t~(Qt::WindowContextHelpButtonHint | Qt::WindowMinMaxButtonsHint)) |\n\t\tQt::MSWindowsFixedSizeDialogHint | Qt::CustomizeWindowHint);\n}\n\nvoid BasePropertyDialog::initWithCount(\n\tint actual_index, int existing_count, bool readonly)\n{\n\tif (actual_index < 0)\n\t\tactual_index = existing_count;\n\n\tresult_index = -1;\n\tresult_name = \"\";\n\n\tGetLabel()->setText(index_label);\n\tGetNameEdit()->setVisible(false);\n\tauto index_edit = GetIndexEdit();\n\tindex_edit->setVisible(true);\n\tindex_edit->setMinimum(0);\n\tindex_edit->setMaximum(existing_count);\n\tindex_edit->setValue(actual_index);\n\tindex_edit->setReadOnly(readonly);\n}\n\nvoid BasePropertyDialog::initWithName(const QString &actual_name,\n\tconst IsNameAvailableCB &is_name_available, bool readonly)\n{\n\tresult_index = -1;\n\tresult_name = \"\";\n\n\tthis->is_name_available = is_name_available;\n\n\tGetLabel()->setText(name_label);\n\tGetIndexEdit()->setVisible(false);\n\tauto name_edit = GetNameEdit();\n\tname_edit->setVisible(true);\n\tname_edit->setText(actual_name);\n\tname_edit->setReadOnly(readonly);\n}\n\nbool BasePropertyDialog::execute()\n{\n\tshow();\n\traise();\n\n\texec();\n\n\treturn result() == DialogCode::Accepted;\n}\n\nbool BasePropertyDialog::ValidateInput()\n{\n\tauto name_edit = GetNameEdit();\n\n\tif (name_edit->isVisible())\n\t{\n\t\tauto name = name_edit->text();\n\n\t\tif (nullptr == is_name_available || is_name_available(name))\n\t\t{\n\t\t\tresult_name = name;\n\t\t} else\n\t\t{\n\t\t\tQMessageBox::critical(this, QApplication::applicationName(),\n\t\t\t\ttr(\"Property with name '%1' is already exist.\").arg(name));\n\t\t\treturn false;\n\t\t}\n\t} else\n\t{\n\t\tresult_index = GetIndexEdit()->value();\n\t}\n\n\treturn true;\n}\n\nvoid BasePropertyDialog::on_buttonBox_clicked(QAbstractButton *button)\n{\n\tswitch (GetButtonBox()->buttonRole(button))\n\t{\n\t\tcase QDialogButtonBox::AcceptRole:\n\t\t{\n\t\t\tif (ValidateInput())\n\t\t\t\taccept();\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QDialogButtonBox::RejectRole:\n\t\t{\n\t\t\treject();\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nCustomPropertyOptionsDialog::CustomPropertyOptionsDialog(QWidget *parent)\n\t: BasePropertyDialog(parent)\n\t, ui(new Ui::CustomPropertyOptionsDialog)\n{\n\tui->setupUi(this);\n\n\tindex_label = tr(\"Index:\");\n\tname_label = tr(\"Name:\");\n}\n\nCustomPropertyOptionsDialog::~CustomPropertyOptionsDialog()\n{\n\tdelete ui;\n}\n\nvoid CustomPropertyOptionsDialog::executeReadOnly()\n{\n\tsetReadOnly(true);\n\tBasePropertyDialog::execute();\n}\n\nbool CustomPropertyOptionsDialog::execute(QtnCustomPropertyData &result)\n{\n\tsetReadOnly(false);\n\n\tif (BasePropertyDialog::execute())\n\t{\n\t\tresult.index = result_index;\n\t\tresult.name = result_name;\n\t\tresult.value = value_type;\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nvoid CustomPropertyOptionsDialog::setType(QVariant::Type type)\n{\n\tswitch (type)\n\t{\n\t\tcase QVariant::List:\n\t\t\tui->rbList->setChecked(true);\n\t\t\tbreak;\n\n\t\tcase QVariant::Map:\n\t\t\tui->rbDictionary->setChecked(true);\n\t\t\tbreak;\n\n\t\tcase QVariant::Bool:\n\t\t\tui->rbBoolean->setChecked(true);\n\t\t\tbreak;\n\n\t\tcase QVariant::Int:\n\t\tcase QVariant::UInt:\n\t\tcase QVariant::LongLong:\n\t\tcase QVariant::ULongLong:\n\t\tcase QVariant::Double:\n\t\t\tui->rbNumeric->setChecked(true);\n\t\t\tbreak;\n\n\t\tcase QVariant::String:\n\t\tcase QVariant::Char:\n\t\tcase QVariant::Color:\n\t\t\tui->rbString->setChecked(true);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tui->rbNull->setChecked(true);\n\t\t\tbreak;\n\t}\n}\n\nvoid CustomPropertyOptionsDialog::setTypeBoxEnabled(bool value)\n{\n\tui->typeBox->setEnabled(value);\n}\n\nvoid CustomPropertyOptionsDialog::setReadOnly(bool readOnly)\n{\n\tsetTypeBoxEnabled(!readOnly);\n\tGetLabel()->setEnabled(!readOnly);\n\tGetNameEdit()->setEnabled(!readOnly);\n\tGetIndexEdit()->setEnabled(!readOnly);\n\n\tGetButtonBox()->setStandardButtons(readOnly\n\t\t\t? QDialogButtonBox::Close\n\t\t\t: QDialogButtonBox::Ok | QDialogButtonBox::Cancel);\n}\n\nbool CustomPropertyOptionsDialog::ValidateInput()\n{\n\tif (BasePropertyDialog::ValidateInput())\n\t{\n\t\tif (ui->rbNull->isChecked())\n\t\t\tvalue_type.clear();\n\t\telse if (ui->rbBoolean->isChecked())\n\t\t\tvalue_type = false;\n\t\telse if (ui->rbNumeric->isChecked())\n\t\t\tvalue_type = 0.0;\n\t\telse if (ui->rbString->isChecked())\n\t\t\tvalue_type = \"\";\n\t\telse if (ui->rbDictionary->isChecked())\n\t\t\tvalue_type = QVariantMap();\n\t\telse if (ui->rbList->isChecked())\n\t\t\tvalue_type = QVariantList();\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nQLabel *CustomPropertyOptionsDialog::GetLabel()\n{\n\treturn ui->label;\n}\n\nQLineEdit *CustomPropertyOptionsDialog::GetNameEdit()\n{\n\treturn ui->editName;\n}\n\nQSpinBox *CustomPropertyOptionsDialog::GetIndexEdit()\n{\n\treturn ui->editIndex;\n}\n\nQDialogButtonBox *CustomPropertyOptionsDialog::GetButtonBox()\n{\n\treturn ui->buttonBox;\n}\n\nQString QtnCustomPropertyData::displayName() const\n{\n\tif (index >= 0)\n\t\treturn nameForIndex(index);\n\n\treturn name;\n}\n\nQString QtnCustomPropertyData::nameForIndex(int index)\n{\n\treturn QStringLiteral(\"[%1]\").arg(index);\n}\n"
  },
  {
    "path": "QtnProperty/CustomPropertyOptionsDialog.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n\n#include <QDialog>\n#include <QVariant>\n\n#include <functional>\n\nclass QLabel;\nclass QLineEdit;\nclass QSpinBox;\nclass QDialogButtonBox;\nclass QAbstractButton;\n\ntypedef std::function<bool(const QString &)> IsNameAvailableCB;\n\nclass QTN_IMPORT_EXPORT BasePropertyDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit BasePropertyDialog(QWidget *parent = nullptr);\n\n\tvoid initWithCount(\n\t\tint actual_index, int existing_count, bool readonly = false);\n\tvoid initWithName(const QString &actual_name,\n\t\tconst IsNameAvailableCB &is_name_available, bool readonly = false);\n\nprivate slots:\n\tvoid on_buttonBox_clicked(QAbstractButton *button);\n\nprotected:\n\tbool execute();\n\n\tvirtual bool ValidateInput();\n\tvirtual QLabel *GetLabel() = 0;\n\tvirtual QLineEdit *GetNameEdit() = 0;\n\tvirtual QSpinBox *GetIndexEdit() = 0;\n\tvirtual QDialogButtonBox *GetButtonBox() = 0;\n\n\tIsNameAvailableCB is_name_available;\n\tint result_index;\n\tQString result_name;\n\n\tQString index_label;\n\tQString name_label;\n};\n\nnamespace Ui\n{\nclass CustomPropertyOptionsDialog;\n}\n\nstruct QTN_IMPORT_EXPORT QtnCustomPropertyData\n{\n\tint index;\n\tQString name;\n\tQVariant value;\n\n\tQString displayName() const;\n\tstatic QString nameForIndex(int index);\n};\n\nclass QTN_IMPORT_EXPORT CustomPropertyOptionsDialog : public BasePropertyDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit CustomPropertyOptionsDialog(QWidget *parent = nullptr);\n\tvirtual ~CustomPropertyOptionsDialog() override;\n\n\tvoid executeReadOnly();\n\tbool execute(QtnCustomPropertyData &result);\n\n\tvoid setType(QVariant::Type type);\n\tvoid setTypeBoxEnabled(bool value);\n\n\tvoid setReadOnly(bool readOnly);\n\nprotected:\n\tvirtual bool ValidateInput() override;\n\tvirtual QLabel *GetLabel() override;\n\tvirtual QLineEdit *GetNameEdit() override;\n\tvirtual QSpinBox *GetIndexEdit() override;\n\tvirtual QDialogButtonBox *GetButtonBox() override;\n\n\tQVariant value_type;\n\tUi::CustomPropertyOptionsDialog *ui;\n};\n"
  },
  {
    "path": "QtnProperty/CustomPropertyOptionsDialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>CustomPropertyOptionsDialog</class>\n <widget class=\"QDialog\" name=\"CustomPropertyOptionsDialog\">\n  <property name=\"windowModality\">\n   <enum>Qt::NonModal</enum>\n  </property>\n  <property name=\"geometry\">\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>221</width>\n    <height>291</height>\n   </rect>\n  </property>\n  <property name=\"sizePolicy\">\n   <sizepolicy hsizetype=\"Fixed\" vsizetype=\"Fixed\">\n    <horstretch>0</horstretch>\n    <verstretch>0</verstretch>\n   </sizepolicy>\n  </property>\n  <property name=\"windowTitle\">\n   <string notr=\"true\"/>\n  </property>\n  <property name=\"modal\">\n   <bool>true</bool>\n  </property>\n  <layout class=\"QVBoxLayout\" name=\"verticalLayout_2\">\n   <property name=\"spacing\">\n    <number>9</number>\n   </property>\n   <property name=\"leftMargin\">\n    <number>9</number>\n   </property>\n   <property name=\"topMargin\">\n    <number>9</number>\n   </property>\n   <property name=\"rightMargin\">\n    <number>9</number>\n   </property>\n   <property name=\"bottomMargin\">\n    <number>9</number>\n   </property>\n   <item>\n    <widget class=\"QLabel\" name=\"label\">\n     <property name=\"maximumSize\">\n      <size>\n       <width>16777215</width>\n       <height>17</height>\n      </size>\n     </property>\n     <property name=\"text\">\n      <string>Name:</string>\n     </property>\n     <property name=\"margin\">\n      <number>2</number>\n     </property>\n    </widget>\n   </item>\n   <item>\n    <widget class=\"QWidget\" name=\"widget\" native=\"true\">\n     <property name=\"minimumSize\">\n      <size>\n       <width>0</width>\n       <height>21</height>\n      </size>\n     </property>\n     <property name=\"maximumSize\">\n      <size>\n       <width>16777215</width>\n       <height>21</height>\n      </size>\n     </property>\n     <layout class=\"QHBoxLayout\" name=\"horizontalLayout\">\n      <property name=\"leftMargin\">\n       <number>0</number>\n      </property>\n      <property name=\"topMargin\">\n       <number>0</number>\n      </property>\n      <property name=\"rightMargin\">\n       <number>0</number>\n      </property>\n      <property name=\"bottomMargin\">\n       <number>0</number>\n      </property>\n      <item>\n       <widget class=\"QSpinBox\" name=\"editIndex\"/>\n      </item>\n      <item>\n       <widget class=\"QLineEdit\" name=\"editName\"/>\n      </item>\n     </layout>\n    </widget>\n   </item>\n   <item>\n    <widget class=\"QGroupBox\" name=\"typeBox\">\n     <property name=\"minimumSize\">\n      <size>\n       <width>0</width>\n       <height>141</height>\n      </size>\n     </property>\n     <property name=\"title\">\n      <string>Type</string>\n     </property>\n     <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbNumeric\">\n        <property name=\"text\">\n         <string>Numeric</string>\n        </property>\n        <property name=\"checked\">\n         <bool>false</bool>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbString\">\n        <property name=\"text\">\n         <string>String</string>\n        </property>\n        <property name=\"checked\">\n         <bool>false</bool>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbBoolean\">\n        <property name=\"text\">\n         <string>Boolean</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbDictionary\">\n        <property name=\"text\">\n         <string>Dictionary</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbList\">\n        <property name=\"text\">\n         <string>List</string>\n        </property>\n       </widget>\n      </item>\n      <item>\n       <widget class=\"QRadioButton\" name=\"rbNull\">\n        <property name=\"text\">\n         <string>Null</string>\n        </property>\n        <property name=\"checked\">\n         <bool>true</bool>\n        </property>\n       </widget>\n      </item>\n     </layout>\n    </widget>\n   </item>\n   <item>\n    <widget class=\"QDialogButtonBox\" name=\"buttonBox\">\n     <property name=\"standardButtons\">\n      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>\n     </property>\n     <property name=\"centerButtons\">\n      <bool>true</bool>\n     </property>\n    </widget>\n   </item>\n  </layout>\n </widget>\n <resources/>\n <connections/>\n</ui>\n"
  },
  {
    "path": "QtnProperty/CustomPropertyWidget.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"CustomPropertyWidget.h\"\n\n#include \"VarProperty.h\"\n\n#include \"PropertySet.h\"\n#include \"PropertyView.h\"\n#include \"Utils/InplaceEditing.h\"\n#include \"CustomPropertyOptionsDialog.h\"\n\n#include <QMouseEvent>\n#include <QDragEnterEvent>\n#include <QDrag>\n#include <QMimeData>\n#include <QMenu>\n#include <QJsonDocument>\n#include <QJsonObject>\n#include <QJsonArray>\n#include <QMessageBox>\n#include <QApplication>\n#include <QPushButton>\n\nstatic const QString kCustomPropertyData =\n\tQStringLiteral(\"QtnCustomPropertyData\");\n\nQtnCustomPropertyWidget::QtnCustomPropertyWidget(QWidget *parent)\n\t: QtnPropertyWidgetEx(parent)\n\t, dataPtr(nullptr)\n\t, lastAddType(QVariant::Invalid)\n\t, readOnly(false)\n\t, autoUpdate(false)\n\t, backupAutoUpdate(false)\n\t, rootSet(nullptr)\n{\n}\n\nvoid QtnCustomPropertyWidget::setReadOnly(bool value)\n{\n\tif (!readOnly)\n\t{\n\t\treadOnly = value;\n\n\t\tif (nullptr != rootSet)\n\t\t{\n\t\t\trootSet->switchState(QtnPropertyStateImmutable, value, true);\n\t\t}\n\t}\n}\n\nvoid QtnCustomPropertyWidget::setData(\n\tQVariant *dataPtr, const QString &title, bool force)\n{\n\tif (force || this->dataPtr != dataPtr)\n\t{\n\t\tthis->dataPtr = dataPtr;\n\t\tsetPropertySet(nullptr);\n\t\tdelete rootSet;\n\n\t\tif (nullptr != dataPtr)\n\t\t{\n\t\t\trootSet = new QtnPropertySet(this);\n\n\t\t\tif (readOnly)\n\t\t\t\trootSet->setState(QtnPropertyStateImmutable, true);\n\n\t\t\tnewProperty(rootSet, *dataPtr, title, -1, nullptr);\n\n\t\t\tsetPropertySet(rootSet);\n\t\t} else\n\t\t\trootSet = nullptr;\n\t}\n}\n\nbool QtnCustomPropertyWidget::canDeleteProperty(QtnPropertyBase *property)\n{\n\tif (readOnly || !property || !property->isWritable())\n\t{\n\t\treturn false;\n\t}\n\tauto var_property = getVarProperty(property);\n\n\tif (nullptr != var_property)\n\t\treturn (var_property != var_property->TopParent());\n\n\treturn false;\n}\n\nbool QtnCustomPropertyWidget::canCutToClipboard()\n{\n\treturn !readOnly && canDeleteProperty(propertyView()->activeProperty());\n}\n\nbool QtnCustomPropertyWidget::canPasteFromClipboard()\n{\n\tif (readOnly)\n\t{\n\t\treturn false;\n\t}\n\tauto p = getActiveProperty();\n\tif (!p)\n\t{\n\t\treturn false;\n\t}\n\n\tif (!p->isWritable())\n\t{\n\t\treturn false;\n\t}\n\n\treturn QtnPropertyWidgetEx::canPasteFromClipboard();\n}\n\nvoid QtnCustomPropertyWidget::addProperty()\n{\n\tif (readOnly)\n\t\treturn;\n\n\tQtnPropertyBase *property;\n\tVarProperty *var_property;\n\n\tif (getActiveVarProperty(property, var_property))\n\t{\n\t\tCustomPropertyOptionsDialog dialog(this);\n\t\tQtnCustomPropertyData result_data;\n\n\t\tswitch (var_property->GetType())\n\t\t{\n\t\t\tcase VarProperty::List:\n\t\t\t{\n\t\t\t\tdialog.setWindowTitle(tr(\"New Element\"));\n\t\t\t\tdialog.initWithCount(-1, var_property->GetChildrenCount());\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase VarProperty::Map:\n\t\t\t{\n\t\t\t\tdialog.setWindowTitle(tr(\"New Property\"));\n\t\t\t\tdialog.initWithName(QString(),\n\t\t\t\t\tstd::bind(&VarProperty::IsChildNameAvailable, var_property,\n\t\t\t\t\t\tstd::placeholders::_1, nullptr));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\tdialog.setType(lastAddType);\n\n\t\tif (dialog.execute(result_data))\n\t\t{\n\t\t\tlastAddType = result_data.value.type();\n\t\t\taddProperty(property, result_data);\n\t\t}\n\t}\n}\n\nvoid QtnCustomPropertyWidget::duplicateProperty()\n{\n\tif (readOnly)\n\t\treturn;\n\n\tQtnPropertyBase *property;\n\tVarProperty *var_property;\n\n\tif (getActiveVarProperty(property, var_property))\n\t{\n\t\tCustomPropertyOptionsDialog dialog(this);\n\t\tQtnCustomPropertyData result_data;\n\n\t\tauto var_parent = var_property->VarParent();\n\n\t\tswitch (var_parent->GetType())\n\t\t{\n\t\t\tcase VarProperty::List:\n\t\t\t{\n\t\t\t\tdialog.setWindowTitle(tr(\"Duplicate Element\"));\n\t\t\t\tdialog.initWithCount(\n\t\t\t\t\tvar_property->GetIndex(), var_parent->GetChildrenCount());\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase VarProperty::Map:\n\t\t\t{\n\t\t\t\tdialog.setWindowTitle(tr(\"Duplicate Property\"));\n\t\t\t\tdialog.initWithName(var_property->GetName(),\n\t\t\t\t\tstd::bind(&VarProperty::IsChildNameAvailable, var_parent,\n\t\t\t\t\t\tstd::placeholders::_1, nullptr));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tQ_ASSERT(false);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tdialog.setType(var_property->GetVariantType());\n\t\tdialog.setTypeBoxEnabled(false);\n\n\t\tif (dialog.execute(result_data))\n\t\t\tduplicateProperty(property, result_data);\n\t}\n}\n\nvoid QtnCustomPropertyWidget::propertyOptions()\n{\n\tQtnPropertyBase *property;\n\tVarProperty *var_property;\n\n\tif (getActiveVarProperty(property, var_property))\n\t{\n\t\tCustomPropertyOptionsDialog dialog(this);\n\t\tQtnCustomPropertyData result_data;\n\n\t\tauto var_parent = var_property->VarParent();\n\n\t\tdialog.setWindowTitle(tr(\"Property Options\"));\n\n\t\tif (nullptr == var_parent)\n\t\t{\n\t\t\tdialog.initWithName(var_property->GetName(), nullptr, true);\n\t\t} else\n\t\t{\n\t\t\tswitch (var_parent->GetType())\n\t\t\t{\n\t\t\t\tcase VarProperty::List:\n\t\t\t\t{\n\t\t\t\t\tdialog.setWindowTitle(tr(\"Element Options\"));\n\t\t\t\t\tdialog.initWithCount(var_property->GetIndex(),\n\t\t\t\t\t\tvar_parent->GetChildrenCount() - 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase VarProperty::Map:\n\t\t\t\t{\n\t\t\t\t\tdialog.initWithName(var_property->GetName(),\n\t\t\t\t\t\tstd::bind(&VarProperty::IsChildNameAvailable,\n\t\t\t\t\t\t\tvar_parent, std::placeholders::_1, var_property));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tQ_ASSERT(false);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tdialog.setType(var_property->GetVariantType());\n\n\t\tif (readOnly)\n\t\t{\n\t\t\tdialog.executeReadOnly();\n\t\t} else if (dialog.execute(result_data))\n\t\t{\n\t\t\tauto old_data = var_property->CreateVariant();\n\n\t\t\tswitch (result_data.value.type())\n\t\t\t{\n\t\t\t\tcase QVariant::Bool:\n\t\t\t\t\tresult_data.value = old_data.toBool();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase QVariant::Char:\n\t\t\t\tcase QVariant::String:\n\t\t\t\t\tresult_data.value = old_data.toString();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase QVariant::Int:\n\t\t\t\tcase QVariant::UInt:\n\t\t\t\tcase QVariant::LongLong:\n\t\t\t\tcase QVariant::ULongLong:\n\t\t\t\tcase QVariant::Double:\n\t\t\t\t\tresult_data.value = old_data.toDouble();\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tif (var_property->GetType() ==\n\t\t\t\t\t\tVarProperty::GetTypeFromValue(result_data.value))\n\t\t\t\t\t\tresult_data.value.swap(old_data);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (var_property->GetType())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase VarProperty::List:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (result_data.value.type() == QVariant::Map)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\told_data.clear();\n\t\t\t\t\t\t\t\t\tQVariantMap result;\n\n\t\t\t\t\t\t\t\t\tfor (auto property :\n\t\t\t\t\t\t\t\t\t\tvar_property->GetChildren())\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tresult.insert(property->GetName(),\n\t\t\t\t\t\t\t\t\t\t\tproperty->CreateVariant());\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tresult_data.value = result;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tcase VarProperty::Map:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (result_data.value.type() == QVariant::List)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\told_data.clear();\n\t\t\t\t\t\t\t\t\tQVariantList result;\n\n\t\t\t\t\t\t\t\t\tfor (auto property :\n\t\t\t\t\t\t\t\t\t\tvar_property->GetChildren())\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tresult.push_back(\n\t\t\t\t\t\t\t\t\t\t\tproperty->CreateVariant());\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tresult_data.value = result;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tupdatePropertyOptions(property, result_data);\n\t\t}\n\t}\n}\n\nvoid QtnCustomPropertyWidget::setAutoUpdate(bool yes)\n{\n\tif (autoUpdate != yes)\n\t{\n\t\tautoUpdate = yes;\n\n\t\tif (yes)\n\t\t\tupdateData();\n\t}\n}\n\nvoid QtnCustomPropertyWidget::onPropertyValueAccept(\n\tvoid *valueToAccept, bool *accept)\n{\n\tif (nullptr != accept)\n\t{\n\t\tbool ok = VarProperty::PropertyValueAccept(\n\t\t\tqobject_cast<QtnProperty *>(sender()), valueToAccept);\n\t\tQ_ASSERT(ok);\n\n\t\t*accept = ok;\n\n\t\tif (autoUpdate)\n\t\t\tupdateData();\n\t}\n}\n\nvoid QtnCustomPropertyWidget::editData(const QVariant &oldValue)\n{\n\temit dataEdited(oldValue);\n}\n\nbool QtnCustomPropertyWidget::dataHasSupportedFormats(const QMimeData *data)\n{\n\tif (nullptr != data)\n\t{\n\t\treturn QtnPropertyWidgetEx::dataHasSupportedFormats(data) ||\n\t\t\tdata->hasFormat(kCustomPropertyData);\n\t}\n\n\treturn false;\n}\n\nvoid QtnCustomPropertyWidget::deleteProperty(QtnPropertyBase *property)\n{\n\tif (!canDeleteProperty(property))\n\t\treturn;\n\n\tauto var_property = getVarProperty(property);\n\n\tif (nullptr != var_property)\n\t{\n\t\tif (var_property != var_property->TopParent())\n\t\t{\n\t\t\tvar_property->RemoveFromParent();\n\n\t\t\tauto set = qobject_cast<QtnPropertySet *>(property->parent());\n\t\t\tauto &set_properties = set->childProperties();\n\t\t\tauto active_property_index =\n\t\t\t\tset_properties.indexOf(propertyView()->activeProperty());\n\t\t\tupdateSet(set,\n\t\t\t\tactive_property_index >= 0 ? active_property_index\n\t\t\t\t\t\t\t\t\t\t   : set_properties.indexOf(property));\n\t\t}\n\t}\n}\n\nQMimeData *QtnCustomPropertyWidget::getPropertyDataForAction(\n\tQtnPropertyBase *property, Qt::DropAction action)\n{\n\tauto varProperty = getVarProperty(property);\n\n\tif (nullptr != varProperty)\n\t{\n\t\tswitch (action)\n\t\t{\n\t\t\tcase Qt::MoveAction:\n\t\t\tcase Qt::CopyAction:\n\t\t\tcase Qt::IgnoreAction:\n\t\t\t{\n\t\t\t\tauto mime = new QMimeData;\n\n\t\t\t\tauto variant = varProperty->CreateVariant();\n\n\t\t\t\tQJsonObject jobj;\n\t\t\t\tjobj.insert(\n\t\t\t\t\tvarProperty->GetName(), QJsonValue::fromVariant(variant));\n\n\t\t\t\tQJsonDocument doc;\n\t\t\t\tdoc.setObject(jobj);\n\n\t\t\t\tQByteArray json(doc.toJson());\n\t\t\t\tint start = json.indexOf('{') + 1;\n\t\t\t\tint end = json.lastIndexOf('}');\n\n\t\t\t\tmime->setText(\n\t\t\t\t\tQString::fromUtf8(&json.constData()[start], end - start)\n\t\t\t\t\t\t.trimmed());\n\n\t\t\t\tmime->setData(kCustomPropertyData, doc.toBinaryData());\n\n\t\t\t\treturn mime;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n\nbool QtnCustomPropertyWidget::insertReplaceOrCancel(\n\tQtnPropertyBase *destination, QtnCustomPropertyData &customData)\n{\n\tauto varProperty = getVarProperty(destination);\n\tQ_ASSERT(nullptr != varProperty);\n\n\tenum\n\t{\n\t\tCANCEL,\n\t\tINSERT,\n\t\tREPLACE\n\t};\n\n\tint choice = REPLACE;\n\n\tauto insertDestination = qobject_cast<QtnPropertySet *>(destination);\n\n\tif (nullptr == insertDestination)\n\t{\n\t\tif (varProperty != varProperty->TopParent())\n\t\t\tinsertDestination =\n\t\t\t\tqobject_cast<QtnPropertySet *>(destination->parent());\n\t}\n\n\tif (nullptr != insertDestination)\n\t{\n\t\tQMessageBox mb(QMessageBox::Question,\n\t\t\tQApplication::applicationDisplayName(),\n\t\t\ttr(\"Do you want to insert new property \"\n\t\t\t   \"from clipboard or to replace the selected one?\"),\n\t\t\tQMessageBox::Cancel, this);\n\n\t\tauto insertButton =\n\t\t\tmb.addButton(tr(\"Insert\", \"Paste\"), QMessageBox::AcceptRole);\n\t\tauto replaceButton =\n\t\t\tmb.addButton(tr(\"Replace\", \"Paste\"), QMessageBox::AcceptRole);\n\t\tmb.setDefaultButton(replaceButton);\n\n\t\tmb.show();\n\t\tmb.raise();\n\t\tmb.exec();\n\n\t\tif (mb.clickedButton() == insertButton)\n\t\t\tchoice = INSERT;\n\t\telse if (mb.clickedButton() == replaceButton)\n\t\t\tchoice = REPLACE;\n\t\telse\n\t\t\tchoice = CANCEL;\n\t}\n\n\tswitch (choice)\n\t{\n\t\tcase INSERT:\n\t\t{\n\t\t\tif (insertDestination == destination)\n\t\t\t{\n\t\t\t\tswitch (varProperty->GetType())\n\t\t\t\t{\n\t\t\t\t\tcase VarProperty::List:\n\t\t\t\t\t\tcustomData.index = varProperty->GetChildrenCount();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase VarProperty::Map:\n\t\t\t\t\t\tcustomData.index = -1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taddProperty(insertDestination, customData);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase REPLACE:\n\t\t{\n\t\t\tcustomData.name = varProperty->GetName();\n\t\t\tupdatePropertyOptions(destination, customData);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool QtnCustomPropertyWidget::applyPropertyData(const QMimeData *data,\n\tQtnPropertyBase *destination, QtnApplyPosition position)\n{\n\tif (readOnly || !destination)\n\t\treturn false;\n\n\tauto varProperty = getVarProperty(destination);\n\n\tif (nullptr != varProperty)\n\t{\n\t\tQtnCustomPropertyData customData;\n\n\t\tif (data->hasFormat(kCustomPropertyData))\n\t\t{\n\t\t\tauto doc =\n\t\t\t\tQJsonDocument::fromBinaryData(data->data(kCustomPropertyData));\n\n\t\t\tif (doc.isObject())\n\t\t\t{\n\t\t\t\tauto obj = doc.object();\n\n\t\t\t\tbool ok = false;\n\n\t\t\t\tint insertIndex = varProperty->GetIndex();\n\n\t\t\t\tif (QtnApplyPosition::Over == position &&\n\t\t\t\t\tvarProperty->GetType() == VarProperty::Value)\n\t\t\t\t{\n\t\t\t\t\tposition = QtnApplyPosition::After;\n\t\t\t\t}\n\n\t\t\t\tfor (auto it = obj.begin(); it != obj.end(); ++it)\n\t\t\t\t{\n\t\t\t\t\tcustomData.value = it.value().toVariant();\n\n\t\t\t\t\tswitch (position)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase QtnApplyPosition::Before:\n\t\t\t\t\t\tcase QtnApplyPosition::After:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (varProperty != varProperty->TopParent())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tauto parent_prop =\n\t\t\t\t\t\t\t\t\tqobject_cast<QtnPropertyBase *>(\n\t\t\t\t\t\t\t\t\t\tdestination->parent());\n\n\t\t\t\t\t\t\t\tif (!parent_prop->isWritable())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tswitch (getVarProperty(parent_prop)->GetType())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase VarProperty::Map:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcustomData.index = -1;\n\t\t\t\t\t\t\t\t\t\tcustomData.name = it.key();\n\t\t\t\t\t\t\t\t\t\taddProperty(parent_prop, customData);\n\t\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcase VarProperty::List:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcustomData.name.clear();\n\n\t\t\t\t\t\t\t\t\t\tcustomData.index = insertIndex;\n\n\t\t\t\t\t\t\t\t\t\tif (QtnApplyPosition::After == position)\n\t\t\t\t\t\t\t\t\t\t\tcustomData.index++;\n\n\t\t\t\t\t\t\t\t\t\taddProperty(parent_prop, customData);\n\t\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase QtnApplyPosition::Over:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!destination->isWritable())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tswitch (varProperty->GetType())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase VarProperty::Map:\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcustomData.index = -1;\n\t\t\t\t\t\t\t\t\tcustomData.name = it.key();\n\t\t\t\t\t\t\t\t\taddProperty(destination, customData);\n\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase VarProperty::List:\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcustomData.name.clear();\n\t\t\t\t\t\t\t\t\tcustomData.index =\n\t\t\t\t\t\t\t\t\t\tvarProperty->GetChildrenCount();\n\t\t\t\t\t\t\t\t\taddProperty(destination, customData);\n\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase QtnApplyPosition::None:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!destination->isWritable())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcustomData.index = varProperty->GetIndex();\n\t\t\t\t\t\t\tcustomData.name = it.key();\n\t\t\t\t\t\t\tok = insertReplaceOrCancel(destination, customData);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tinsertIndex++;\n\t\t\t\t}\n\n\t\t\t\tif (ok)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if (destination->isWritable())\n\t\t{\n\t\t\tcustomData.index = varProperty->GetIndex();\n\t\t\tcustomData.name = \"\";\n\n\t\t\tif (data->hasColor())\n\t\t\t{\n\t\t\t\tcustomData.value = data->colorData();\n\n\t\t\t\treturn insertReplaceOrCancel(destination, customData);\n\t\t\t}\n\n\t\t\tif (data->hasUrls())\n\t\t\t{\n\t\t\t\tQVariantList list;\n\n\t\t\t\tfor (auto &url : data->urls())\n\t\t\t\t{\n\t\t\t\t\tif (url.isLocalFile())\n\t\t\t\t\t\tlist.push_back(url.toLocalFile());\n\t\t\t\t\telse\n\t\t\t\t\t\tlist.push_back(url.toString());\n\t\t\t\t}\n\n\t\t\t\tif (list.size() > 1)\n\t\t\t\t{\n\t\t\t\t\tcustomData.value = list;\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tcustomData.value = list.at(0);\n\t\t\t\t}\n\n\t\t\t\treturn insertReplaceOrCancel(destination, customData);\n\t\t\t}\n\n\t\t\tif (data->hasText())\n\t\t\t{\n\t\t\t\tauto srcText = data->text().toUtf8();\n\t\t\t\tauto text = srcText;\n\t\t\t\ttext.prepend('{');\n\t\t\t\ttext.append('}');\n\t\t\t\tQJsonParseError parseResult;\n\t\t\t\tauto doc = QJsonDocument::fromJson(text, &parseResult);\n\n\t\t\t\tif (QJsonParseError::NoError == parseResult.error)\n\t\t\t\t{\n\t\t\t\t\tauto object = doc.object();\n\n\t\t\t\t\tif (object.size() == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto it = object.begin();\n\t\t\t\t\t\tcustomData.name = it.key();\n\t\t\t\t\t\tcustomData.value = it.value().toVariant();\n\n\t\t\t\t\t\treturn insertReplaceOrCancel(destination, customData);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (object.size() > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tcustomData.value = object.toVariantMap();\n\n\t\t\t\t\t\treturn insertReplaceOrCancel(destination, customData);\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\ttext = srcText;\n\t\t\t\t\ttext.prepend('[');\n\t\t\t\t\ttext.append(']');\n\n\t\t\t\t\tdoc = QJsonDocument::fromJson(text, &parseResult);\n\n\t\t\t\t\tif (QJsonParseError::NoError == parseResult.error)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto array = doc.array();\n\n\t\t\t\t\t\tif (array.size() == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomData.value = array.at(0).toVariant();\n\n\t\t\t\t\t\t\treturn insertReplaceOrCancel(\n\t\t\t\t\t\t\t\tdestination, customData);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (array.size() > 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomData.value = array.toVariantList();\n\n\t\t\t\t\t\t\treturn insertReplaceOrCancel(\n\t\t\t\t\t\t\t\tdestination, customData);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdoc = QJsonDocument::fromJson(srcText, &parseResult);\n\n\t\t\t\tif (QJsonParseError::NoError == parseResult.error)\n\t\t\t\t{\n\t\t\t\t\tcustomData.value = doc.toVariant();\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tcustomData.value = data->text();\n\t\t\t\t}\n\n\t\t\t\treturn insertReplaceOrCancel(destination, customData);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid QtnCustomPropertyWidget::dropEvent(QDropEvent *event)\n{\n\tif (readOnly)\n\t{\n\t\tevent->ignore();\n\t\treturn;\n\t}\n\n\tbackupAutoUpdate = autoUpdate;\n\tautoUpdate = false;\n\tQtnPropertyWidgetEx::dropEvent(event);\n}\n\nvoid QtnCustomPropertyWidget::dropEnd()\n{\n\tif (readOnly)\n\t\treturn;\n\n\tQtnPropertyWidgetEx::dropEnd();\n\tautoUpdate = backupAutoUpdate;\n\n\tif (autoUpdate)\n\t\tupdateData();\n}\n\nvoid QtnCustomPropertyWidget::updateData()\n{\n\tif (!readOnly && nullptr != dataPtr && nullptr != rootSet)\n\t{\n\t\tauto varProperty = getVarProperty(rootSet->childProperties().at(0));\n\t\tauto oldValue = *dataPtr;\n\t\t*dataPtr = varProperty->CreateVariant();\n\t\teditData(oldValue);\n\t}\n}\n\nvoid QtnCustomPropertyWidget::updateSet(\n\tQtnPropertyBase *setProperty, int childIndex)\n{\n\tQ_ASSERT(nullptr != setProperty);\n\n\tauto varProperty = getVarProperty(setProperty);\n\tQ_ASSERT(nullptr != varProperty);\n\n\tauto data = varProperty->CreateVariant();\n\n\tauto var_parent = varProperty->VarParent();\n\n\tvarProperty->RemoveFromParent();\n\n\tauto new_set = newProperty(nullptr, data, varProperty->GetName(),\n\t\tvarProperty->GetIndex(), var_parent)\n\t\t\t\t\t   ->asPropertySet();\n\n\tQ_ASSERT(nullptr != new_set);\n\n\tauto property_parent =\n\t\tqobject_cast<QtnPropertySet *>(setProperty->parent());\n\tQ_ASSERT(nullptr != property_parent);\n\n\tint property_index =\n\t\tproperty_parent->childProperties().indexOf(setProperty);\n\tproperty_parent->removeChildProperty(setProperty);\n\n\tdelete setProperty;\n\n\tproperty_parent->addChildProperty(new_set, true, property_index);\n\tauto view = propertyView();\n\tauto &child_properties = new_set->childProperties();\n\n\tif (child_properties.isEmpty())\n\t\tview->setActiveProperty(new_set);\n\telse\n\t{\n\t\tint count = child_properties.count();\n\n\t\tif (childIndex >= count)\n\t\t\tchildIndex = count - 1;\n\n\t\tview->setActiveProperty(child_properties.at(childIndex));\n\t}\n\n\tif (autoUpdate)\n\t\tupdateData();\n}\n\nbool QtnCustomPropertyWidget::getActiveVarProperty(\n\tQtnPropertyBase *&property, VarProperty *&varProperty)\n{\n\tproperty = propertyView()->activeProperty();\n\n\tvarProperty = getVarProperty(property);\n\n\treturn varProperty != nullptr;\n}\n\nVarProperty *QtnCustomPropertyWidget::getVarProperty(QtnPropertyBase *source)\n{\n\tVarProperty *varProperty = nullptr;\n\n\tif (nullptr != source)\n\t{\n\t\tvarProperty = source->findChild<VarProperty *>(\n\t\t\tQString(), Qt::FindDirectChildrenOnly);\n\t}\n\n\treturn varProperty;\n}\n\nQtnPropertyBase *QtnCustomPropertyWidget::newProperty(QtnPropertySet *parent,\n\tconst QVariant &value, const QString &key, int index,\n\tVarProperty *mapParent)\n{\n\treturn VarProperty::NewExtraProperty(\n\t\tparent, value, key, index, mapParent, [this](QtnProperty *property) {\n\t\t\tQObject::connect(property, &QtnProperty::propertyValueAccept, this,\n\t\t\t\t&QtnCustomPropertyWidget::onPropertyValueAccept);\n\t\t});\n}\n\nvoid QtnCustomPropertyWidget::addProperty(\n\tQtnPropertyBase *source, const QtnCustomPropertyData &data)\n{\n\tQ_ASSERT(nullptr != source);\n\tauto varProperty = getVarProperty(source);\n\tQ_ASSERT(nullptr != varProperty);\n\tauto set = source->asPropertySet();\n\tQ_ASSERT(nullptr != set);\n\n\tif (data.index >= 0)\n\t\tQ_ASSERT(data.index <= varProperty->GetChildrenCount());\n\n\tauto new_property =\n\t\tnewProperty(nullptr, data.value, data.name, data.index, varProperty);\n\n\tstd::vector<QtnPropertyBase *> children;\n\n\tfor (auto child : set->childProperties())\n\t{\n\t\tchildren.push_back(child);\n\t}\n\n\tif (data.index >= 0)\n\t\tchildren.insert(children.begin() + data.index, new_property);\n\telse\n\t\tchildren.push_back(new_property);\n\n\tauto isList = (VarProperty::List == varProperty->GetType());\n\n\tif (isList)\n\t{\n\t\tint count = static_cast<int>(children.size());\n\n\t\tfor (int i = 0; i < count; i++)\n\t\t{\n\t\t\tauto property = children.at(i);\n\t\t\tauto var_property = getVarProperty(property);\n\t\t\tvar_property->SetIndex(i);\n\t\t\tproperty->setName(var_property->GetName());\n\t\t}\n\t} else\n\t{\n\t\tstd::sort(children.begin(), children.end(),\n\t\t\t[](QtnPropertyBase *a, QtnPropertyBase *b) -> bool {\n\t\t\t\treturn QString::localeAwareCompare(a->name(), b->name()) < 0;\n\t\t\t});\n\t}\n\n\tauto it = std::find(children.begin(), children.end(), new_property);\n\n\tset->addChildProperty(new_property, true, int(it - children.begin()));\n\n\tpropertyView()->setActiveProperty(new_property, true);\n\n\tif (autoUpdate)\n\t\tupdateData();\n}\n\nvoid QtnCustomPropertyWidget::duplicateProperty(\n\tQtnPropertyBase *source, const QtnCustomPropertyData &data)\n{\n\tauto varProperty = getVarProperty(source);\n\tQ_ASSERT(nullptr != varProperty);\n\n\tauto set = qobject_cast<QtnPropertySet *>(source->parent());\n\tQ_ASSERT(nullptr != set);\n\n\taddProperty(set, { data.index, data.name, varProperty->CreateVariant() });\n}\n\nvoid QtnCustomPropertyWidget::updatePropertyOptions(\n\tQtnPropertyBase *source, const QtnCustomPropertyData &data)\n{\n\tauto varProperty = getVarProperty(source);\n\tQ_ASSERT(nullptr != varProperty);\n\n\tauto set = qobject_cast<QtnPropertySet *>(source->parent());\n\tQ_ASSERT(nullptr != set);\n\n\tbool refresh_siblings = false;\n\n\tint old_index = varProperty->GetIndex();\n\n\tbool top_property = (varProperty == varProperty->TopParent());\n\n\tif (!top_property)\n\t{\n\t\trefresh_siblings = varProperty->SetIndex(data.index);\n\t\trefresh_siblings = varProperty->SetName(data.name) || refresh_siblings;\n\t}\n\n\tauto var_parent = varProperty->VarParent();\n\n\tif (!refresh_siblings)\n\t{\n\t\tint index = set->childProperties().indexOf(source);\n\n\t\tQString prop_name(top_property ? varProperty->GetName() : data.name);\n\n\t\tvarProperty->RemoveFromParent();\n\t\tset->removeChildProperty(source);\n\n\t\tdelete source;\n\n\t\tauto new_property =\n\t\t\tnewProperty(nullptr, data.value, prop_name, data.index, var_parent);\n\n\t\tset->addChildProperty(new_property, true, index);\n\n\t\tpropertyView()->setActiveProperty(new_property, true);\n\n\t\tif (autoUpdate)\n\t\t\tupdateData();\n\t} else\n\t{\n\t\tvarProperty->SetValue(data.value);\n\n\t\tint index = data.index;\n\n\t\tauto children = var_parent->GetChildren();\n\n\t\tif (index < 0)\n\t\t{\n\t\t\tstd::sort(children.begin(), children.end(),\n\t\t\t\t[](VarProperty *a, VarProperty *b) -> bool {\n\t\t\t\t\treturn QString::localeAwareCompare(\n\t\t\t\t\t\t\t   a->GetName(), b->GetName()) < 0;\n\t\t\t\t});\n\n\t\t\tauto it = std::find(children.begin(), children.end(), varProperty);\n\n\t\t\tindex = int(it - children.begin());\n\t\t} else if (old_index != index)\n\t\t{\n\t\t\tchildren.at(index)->SetIndex(old_index);\n\t\t}\n\n\t\tupdateSet(set, index);\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/CustomPropertyWidget.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"PropertyWidgetEx.h\"\n\n#include <QVariant>\n\nclass VarProperty;\n\nstruct QtnCustomPropertyData;\n\nclass QTN_IMPORT_EXPORT QtnCustomPropertyWidget : public QtnPropertyWidgetEx\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QtnCustomPropertyWidget(QWidget *parent = nullptr);\n\n\tinline bool isReadOnly() const;\n\tvoid setReadOnly(bool value);\n\tinline QVariant *getData() const;\n\tvoid setData(QVariant *dataPtr, const QString &title = QString(),\n\t\tbool force = false);\n\n\tvirtual bool canDeleteProperty(QtnPropertyBase *property) override;\n\tvirtual bool canCutToClipboard() override;\n\tvirtual bool canPasteFromClipboard() override;\n\n\tvoid addProperty();\n\tvoid duplicateProperty();\n\tvoid propertyOptions();\n\n\tinline bool isAutoUpdate() const;\n\tvoid setAutoUpdate(bool yes);\n\tvoid updateData();\n\n\tstatic VarProperty *getVarProperty(QtnPropertyBase *source);\n\nsignals:\n\tvoid dataEdited(const QVariant &oldValue);\n\nprivate:\n\tvoid onPropertyValueAccept(void *valueToAccept, bool *accept);\n\nprotected:\n\tvirtual void editData(const QVariant &oldValue);\n\tvirtual bool dataHasSupportedFormats(const QMimeData *data) override;\n\tvirtual void deleteProperty(QtnPropertyBase *property) override;\n\tvirtual QMimeData *getPropertyDataForAction(\n\t\tQtnPropertyBase *property, Qt::DropAction dropAction) override;\n\tvirtual bool applyPropertyData(const QMimeData *data,\n\t\tQtnPropertyBase *destination, QtnApplyPosition position) override;\n\tvirtual void dropEvent(QDropEvent *event) override;\n\tvirtual void dropEnd() override;\n\nprivate:\n\tvoid updateSet(QtnPropertyBase *setProperty, int childIndex);\n\n\tbool getActiveVarProperty(\n\t\tQtnPropertyBase *&property, VarProperty *&varProperty);\n\tQtnPropertyBase *newProperty(QtnPropertySet *parent, const QVariant &value,\n\t\tconst QString &key, int index, VarProperty *mapParent);\n\n\tvoid addProperty(\n\t\tQtnPropertyBase *source, const QtnCustomPropertyData &data);\n\tvoid duplicateProperty(\n\t\tQtnPropertyBase *source, const QtnCustomPropertyData &data);\n\tvoid updatePropertyOptions(\n\t\tQtnPropertyBase *source, const QtnCustomPropertyData &data);\n\tbool insertReplaceOrCancel(\n\t\tQtnPropertyBase *destination, QtnCustomPropertyData &customData);\n\n\tQVariant *dataPtr;\n\tQVariant::Type lastAddType;\n\tbool readOnly : 1;\n\tbool autoUpdate : 1;\n\tbool backupAutoUpdate : 1;\n\nprotected:\n\tQtnPropertySet *rootSet;\n};\n\nbool QtnCustomPropertyWidget::isReadOnly() const\n{\n\treturn readOnly;\n}\n\nQVariant *QtnCustomPropertyWidget::getData() const\n{\n\treturn dataPtr;\n}\n\nbool QtnCustomPropertyWidget::isAutoUpdate() const\n{\n\treturn autoUpdate;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateBool.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateBool.h\"\n\n#include \"QtnProperty/Core/PropertyBool.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/PropertyView.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n\n#include <QStyleOption>\n#include <QCheckBox>\n#include <QComboBox>\n#include <QLineEdit>\n#include <QMouseEvent>\n\nQByteArray qtnLabelFalseAttr()\n{\n\treturn QByteArrayLiteral(\"labelFalse\");\n}\n\nQByteArray qtnLabelTrueAttr()\n{\n\treturn QByteArrayLiteral(\"labelTrue\");\n}\n\nclass QtnPropertyBoolComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyBoolBase, QComboBox>\n{\npublic:\n\tQtnPropertyBoolComboBoxHandler(\n\t\tQtnPropertyDelegate *delegate, QComboBox &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onCurrentIndexChanged(int index);\n};\n\nQtnPropertyDelegateBoolCheck::QtnPropertyDelegateBoolCheck(\n\tQtnPropertyBoolBase &owner)\n\t: QtnPropertyDelegateTyped(owner)\n{\n}\n\nvoid QtnPropertyDelegateBoolCheck::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyBoolBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateBoolCheck, QtnPropertyBoolBase>,\n\t\tqtnCheckBoxDelegate());\n}\n\nbool QtnPropertyDelegateBoolCheck::createSubItemValueImpl(\n\tQtnDrawContext &context, QtnSubItem &subItemValue)\n{\n\tsubItemValue.trackState();\n\tsubItemValue.rect.adjust(context.widget->valueLeftMargin(), 0, 0, 0);\n\tsubItemValue.rect.setWidth(\n\t\tcontext.style()->pixelMetric(QStyle::PM_IndicatorWidth));\n\n\tsubItemValue.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\tQStyleOptionButton opt;\n\t\topt.rect = item.rect;\n\t\topt.state = state(context.isActive, item);\n\n\t\tif (stateProperty()->isMultiValue())\n\t\t{\n\t\t\topt.state |= QStyle::State_NoChange;\n\t\t} else\n\t\t{\n\t\t\tbool value = owner().value();\n\t\t\topt.state |= (value ? QStyle::State_On : QStyle::State_Off);\n\t\t}\n\n\t\tcontext.painter->drawControl(QStyle::CE_CheckBox, opt);\n\t};\n\n\tsubItemValue.eventHandler = [this](QtnEventContext &context,\n\t\t\t\t\t\t\t\t\tconst QtnSubItem &,\n\t\t\t\t\t\t\t\t\tQtnPropertyToEdit *toEdit) {\n\t\tbool toggleValue = false;\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QEvent::MouseButtonRelease:\n\t\t\t\ttoggleValue = true;\n\t\t\t\tbreak;\n\n\t\t\tcase QEvent::KeyPress:\n\t\t\t{\n\t\t\t\tint key = context.eventAs<QKeyEvent>()->key();\n\t\t\t\ttoggleValue = (key == Qt::Key_Space) || (key == Qt::Key_Return);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\n\t\tif (toggleValue)\n\t\t{\n\t\t\ttoEdit->setup(property(), [this]() -> QWidget * {\n\t\t\t\tQtnPropertyDelegateBoolCheck *thiz = this;\n\t\t\t\tauto &p = thiz->owner();\n\t\t\t\tp.setValue(!p.value(), editReason());\n\t\t\t\treturn nullptr;\n\t\t\t});\n\t\t}\n\n\t\treturn true;\n\t};\n\n\treturn true;\n}\n\nQtnPropertyDelegateBoolCombobox::QtnPropertyDelegateBoolCombobox(\n\tQtnPropertyBoolBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyBoolBase>(owner)\n{\n\tm_labels[0] = QtnPropertyBool::getBoolText(false, false);\n\tm_labels[1] = QtnPropertyBool::getBoolText(true, false);\n}\n\nvoid QtnPropertyDelegateBoolCombobox::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyBoolBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateBoolCombobox,\n\t\t\tQtnPropertyBoolBase>,\n\t\tqtnComboBoxDelegate());\n}\n\nvoid QtnPropertyDelegateBoolCombobox::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnLabelFalseAttr(), m_labels[0]);\n\tinfo.loadAttribute(qtnLabelTrueAttr(), m_labels[1]);\n}\n\nQWidget *QtnPropertyDelegateBoolCombobox::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQComboBox *comboBox = new QtnPropertyComboBox(this, parent);\n\tcomboBox->addItem(m_labels[0], false);\n\tcomboBox->addItem(m_labels[1], true);\n\n\tcomboBox->setGeometry(rect);\n\n\t// connect widget and property\n\tnew QtnPropertyBoolComboBoxHandler(this, *comboBox);\n\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcomboBox->showPopup();\n\n\treturn comboBox;\n}\n\nbool QtnPropertyDelegateBoolCombobox::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tstrValue = m_labels[owner().value() ? 1 : 0];\n\treturn true;\n}\n\nQtnPropertyBoolComboBoxHandler::QtnPropertyBoolComboBoxHandler(\n\tQtnPropertyDelegate *delegate, QComboBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),\n\t\tthis, &QtnPropertyBoolComboBoxHandler::onCurrentIndexChanged);\n}\n\nvoid QtnPropertyBoolComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\teditor().setEnabled(stateProperty()->isEditableByUser());\n\n\tif (stateProperty()->isMultiValue())\n\t\teditor().setCurrentIndex(-1);\n\telse\n\t{\n\t\teditor().setCurrentIndex(property().value() ? 1 : 0);\n\t}\n\n\tupdating--;\n}\n\nvoid QtnPropertyBoolComboBoxHandler::onCurrentIndexChanged(int index)\n{\n\tif (index >= 0)\n\t{\n\t\tauto data = editor().itemData(index);\n\n\t\tif (data.canConvert<bool>())\n\t\t{\n\t\t\tonValueChanged(data.toBool());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateBool.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_BOOL_H\n#define PROPERTY_DELEGATE_BOOL_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyBool.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateBoolCheck\n\t: public QtnPropertyDelegateTyped<QtnPropertyBoolBase,\n\t\t  QtnPropertyDelegateWithValue>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateBoolCheck)\n\npublic:\n\tQtnPropertyDelegateBoolCheck(QtnPropertyBoolBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tbool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) override;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateBoolCombobox\n\t: public QtnPropertyDelegateTyped<QtnPropertyBoolBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateBoolCombobox)\n\npublic:\n\tQtnPropertyDelegateBoolCombobox(QtnPropertyBoolBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\nprivate:\n\tQString m_labels[2];\n};\n\n#endif // PROPERTY_DELEGATE_BOOL_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateDouble.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateDouble.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QCoreApplication>\n#include <QLocale>\n\nclass QtnPropertyDoubleSpinBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyDoubleBase, QDoubleSpinBox>\n{\npublic:\n\tQtnPropertyDoubleSpinBoxHandler(\n\t\tQtnPropertyDelegateDouble *delegate, QDoubleSpinBox &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvirtual void updateValue() override;\n\nprivate:\n\tQtnPropertyDelegateDouble *m_delegate;\n};\n\nQtnPropertyDelegateDouble::QtnPropertyDelegateDouble(\n\tQtnPropertyDoubleBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyDoubleBase>(owner)\n\t, m_multiplier(1.0)\n\t, m_precision(std::numeric_limits<double>::digits10 - 1)\n{\n}\n\nvoid QtnPropertyDelegateDouble::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyDoubleBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateDouble, QtnPropertyDoubleBase>,\n\t\tqtnSpinBoxDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyDoubleBase::staticMetaObject,\n\t\t&qtnCreateDelegate<\n\t\t\tQtnPropertyDelegateSlideBoxTyped<QtnPropertyDoubleBase>,\n\t\t\tQtnPropertyDoubleBase>,\n\t\tqtnSliderBoxDelegate());\n}\n\ndouble QtnPropertyDelegateDouble::stepValue() const\n{\n\treturn m_step.isValid() ? m_step.toDouble() : owner().stepValue();\n}\n\nQWidget *QtnPropertyDelegateDouble::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto spinBox = new QtnDoubleSpinBox(parent);\n\tspinBox->setDecimals(m_precision);\n\tspinBox->setSuffix(m_suffix);\n\tspinBox->setGeometry(rect);\n\n\tnew QtnPropertyDoubleSpinBoxHandler(this, *spinBox);\n\n\tspinBox->selectAll();\n\n\tif (stateProperty()->isEditableByUser())\n\t\tqtnInitNumEdit(spinBox, inplaceInfo, NUM_FLOAT);\n\n\treturn spinBox;\n}\n\nbool QtnPropertyDelegateDouble::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<QtnPropertyDoubleBase>::\n\t\t\tacceptKeyPressedForInplaceEditImpl(keyEvent))\n\t{\n\t\treturn true;\n\t}\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_FLOAT);\n}\n\nbool QtnPropertyDelegateDouble::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QtnDoubleSpinBox::valueToText(\n\t\tcurrentValue(), QLocale(), m_precision, true);\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nvoid QtnPropertyDelegateDouble::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tinfo.loadAttribute(qtnMultiplierAttr(), m_multiplier);\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tm_step = info.attributes.value(qtnStepAttr());\n\tif (m_step.isValid())\n\t{\n\t\tbool ok;\n\t\tdouble step = m_step.toDouble(&ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tm_step = QVariant();\n\t\t} else\n\t\t{\n\t\t\tm_step = step;\n\t\t}\n\t}\n\tm_precision = qBound(0, m_precision, std::numeric_limits<double>::digits10);\n\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\n\tif (!qIsFinite(m_multiplier) || qFuzzyCompare(m_multiplier, 0.0))\n\t{\n\t\tm_multiplier = 1.0;\n\t}\n\tfixMinMaxVariant<double>(m_min, m_max);\n}\n\ndouble QtnPropertyDelegateDouble::minValue() const\n{\n\treturn (m_min.isValid() ? m_min.toDouble() : owner().minValue()) *\n\t\tm_multiplier;\n}\n\ndouble QtnPropertyDelegateDouble::maxValue() const\n{\n\treturn (m_max.isValid() ? m_max.toDouble() : owner().maxValue()) *\n\t\tm_multiplier;\n}\n\ndouble QtnPropertyDelegateDouble::multiplier() const\n{\n\treturn m_multiplier;\n}\n\ndouble QtnPropertyDelegateDouble::currentValue() const\n{\n\treturn qBound(minValue(), owner().value() * m_multiplier, maxValue());\n}\n\nQtnPropertyDoubleSpinBoxHandler::QtnPropertyDoubleSpinBoxHandler(\n\tQtnPropertyDelegateDouble *delegate, QDoubleSpinBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t, m_delegate(delegate)\n{\n\tupdateEditor();\n\n\teditor.setKeyboardTracking(false);\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QDoubleSpinBox::*)(double)>(\n\t\t\t&QDoubleSpinBox::valueChanged),\n\t\tthis, &QtnPropertyDoubleSpinBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyDoubleSpinBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\teditor().setSingleStep(m_delegate->stepValue());\n\teditor().setRange(m_delegate->minValue(), m_delegate->maxValue());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().setValue(editor().minimum());\n\t\teditor().setSpecialValueText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setValue(m_delegate->currentValue());\n\t\teditor().setSpecialValueText(QString());\n\t}\n\n\teditor().selectAll();\n\n\tupdating--;\n}\n\nvoid QtnPropertyDoubleSpinBoxHandler::updateValue()\n{\n\tif (this->propertyBase())\n\t{\n\t\tthis->property().setValue(newValue / m_delegate->multiplier(),\n\t\t\tthis->delegate()->editReason());\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateDouble.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#pragma once\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyDouble.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateDouble\n\t: public QtnPropertyDelegateTyped<QtnPropertyDoubleBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateDouble)\n\n\tQString m_suffix;\n\tdouble m_multiplier;\n\tint m_precision;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQVariant m_step;\n\npublic:\n\tQtnPropertyDelegateDouble(QtnPropertyDoubleBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tdouble stepValue() const;\n\tdouble minValue() const;\n\tdouble maxValue() const;\n\tdouble multiplier() const;\n\tdouble currentValue() const;\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n};\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateEnum.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateEnum.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n\n#include <QComboBox>\n#include <QLineEdit>\n\nclass QtnPropertyEnumComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyEnumBase, QComboBox>\n{\npublic:\n\tQtnPropertyEnumComboBoxHandler(\n\t\tQtnPropertyDelegate *delegate, QComboBox &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onCurrentIndexChanged(int index);\n};\n\nvoid QtnPropertyDelegateEnum::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyEnumBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateEnum, QtnPropertyEnumBase>,\n\t\tqtnComboBoxDelegate());\n}\n\nQtnPropertyDelegateEnum::QtnPropertyDelegateEnum(QtnPropertyEnumBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyEnumBase>(owner)\n{\n}\n\nQWidget *QtnPropertyDelegateEnum::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tconst QtnEnumInfo *info = owner().enumInfo();\n\n\tif (!info)\n\t\treturn 0;\n\n\tQComboBox *combo = new QtnPropertyComboBox(this, parent);\n\tinfo->forEachEnumValue([combo](const QtnEnumValueInfo &value) -> bool {\n\t\tcombo->addItem(value.displayName(), QVariant(value.value()));\n\t\treturn true;\n\t});\n\n\tcombo->setGeometry(rect);\n\n\tnew QtnPropertyEnumComboBoxHandler(this, *combo);\n\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcombo->showPopup();\n\n\treturn combo;\n}\n\nbool QtnPropertyDelegateEnum::propertyValueToStrImpl(QString &strValue) const\n{\n\tconst QtnEnumInfo *info = owner().enumInfo();\n\tconst QtnEnumValueInfo *valueInfo =\n\t\tinfo ? info->findByValue(owner().value()) : 0;\n\n\tif (!valueInfo)\n\t\treturn false;\n\n\tstrValue = valueInfo->displayName();\n\treturn true;\n}\n\nQtnPropertyEnumComboBoxHandler::QtnPropertyEnumComboBoxHandler(\n\tQtnPropertyDelegate *delegate, QComboBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),\n\t\tthis, &QtnPropertyEnumComboBoxHandler::onCurrentIndexChanged);\n}\n\nvoid QtnPropertyEnumComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\teditor().setEnabled(stateProperty()->isEditableByUser());\n\n\tif (stateProperty()->isMultiValue())\n\t\teditor().setCurrentIndex(-1);\n\telse\n\t{\n\t\tint index = editor().findData(property().value());\n\t\teditor().setCurrentIndex(index);\n\t}\n\n\tupdating--;\n}\n\nvoid QtnPropertyEnumComboBoxHandler::onCurrentIndexChanged(int index)\n{\n\tif (index >= 0)\n\t{\n\t\tQVariant data = editor().itemData(index);\n\n\t\tif (data.canConvert<int>())\n\t\t\tonValueChanged(data.toInt());\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateEnum.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_ENUM_H\n#define PROPERTY_DELEGATE_ENUM_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyEnum.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateEnum\n\t: public QtnPropertyDelegateTyped<QtnPropertyEnumBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateEnum)\n\npublic:\n\tQtnPropertyDelegateEnum(QtnPropertyEnumBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_ENUM_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateEnumFlags.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateEnumFlags.h\"\n#include \"QtnProperty/Core/PropertyBool.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/MultiProperty.h\"\n\n#include <QLineEdit>\n\nstatic QString enumFlagsProperty2Str(const QtnPropertyEnumFlagsBase &property)\n{\n\tQString text;\n\n\tauto enumInfo = property.enumInfo();\n\n\tif (nullptr == enumInfo)\n\t\treturn text;\n\n\tauto value = property.value();\n\n\tif (value == 0)\n\t\treturn text;\n\n\tfor (const QtnEnumValueInfo &e : enumInfo->getVector())\n\t{\n\t\tif (value & e.value())\n\t\t{\n\t\t\tif (!text.isEmpty())\n\t\t\t\ttext += \"|\";\n\n\t\t\ttext += e.displayName();\n\t\t}\n\t}\n\n\treturn text;\n}\n\nclass QtnPropertyEnumFlagsLineEditHandler\n\t: public QtnPropertyEditorHandler<QtnPropertyEnumFlagsBase, QLineEdit>\n{\npublic:\n\tQtnPropertyEnumFlagsLineEditHandler(\n\t\tQtnPropertyDelegate *delegate, QLineEdit &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n};\n\nQtnPropertyDelegateEnumFlags::QtnPropertyDelegateEnumFlags(\n\tQtnPropertyEnumFlagsBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyEnumFlagsBase>(owner)\n{\n\tconst QtnEnumInfo *enumInfo = owner.enumInfo();\n\n\tif (enumInfo)\n\t{\n\t\tfor (const QtnEnumValueInfo &e : enumInfo->getVector())\n\t\t{\n\t\t\tif (e.state() == QtnEnumValueStateNone)\n\t\t\t{\n\t\t\t\tQtnEnumValueType enumValue = e.value();\n\n\t\t\t\tauto flagProperty = new QtnPropertyBoolCallback;\n\t\t\t\tflagProperty->setDisplayName(e.displayName());\n\t\t\t\tflagProperty->setName(e.name());\n\t\t\t\tflagProperty->setDescription(\n\t\t\t\t\tQtnPropertyEnumFlags::getFlagLabelDescription(\n\t\t\t\t\t\te.displayName(), owner.displayName()));\n\n\t\t\t\tflagProperty->setCallbackValueGet(\n\t\t\t\t\t[&owner, enumValue]() -> bool {\n\t\t\t\t\t\treturn owner.value() & enumValue;\n\t\t\t\t\t});\n\t\t\t\tflagProperty->setCallbackValueSet(\n\t\t\t\t\t[&owner, enumValue](bool value, QtnPropertyChangeReason reason) {\n\t\t\t\t\t\tif (value)\n\t\t\t\t\t\t\towner.setValue(owner.value() | enumValue, reason);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\towner.setValue(owner.value() & ~enumValue, reason);\n\t\t\t\t\t});\n\n\t\t\t\taddSubProperty(flagProperty);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid QtnPropertyDelegateEnumFlags::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyEnumFlagsBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateEnumFlags,\n\t\t\tQtnPropertyEnumFlagsBase>,\n\t\tQByteArrayLiteral(\"FlagsList\"));\n}\n\nQWidget *QtnPropertyDelegateEnumFlags::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQLineEdit *lineEdit = new QLineEdit(parent);\n\tlineEdit->setGeometry(rect);\n\n\tnew QtnPropertyEnumFlagsLineEditHandler(this, *lineEdit);\n\n\tif (inplaceInfo)\n\t{\n\t\tlineEdit->selectAll();\n\t}\n\n\treturn lineEdit;\n}\n\nbool QtnPropertyDelegateEnumFlags::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tstrValue = enumFlagsProperty2Str(owner());\n\treturn true;\n}\n\nQtnPropertyEnumFlagsLineEditHandler::QtnPropertyEnumFlagsLineEditHandler(\n\tQtnPropertyDelegate *delegate, QLineEdit &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n{\n\teditor.setReadOnly(true);\n\n\tupdateEditor();\n}\n\nvoid QtnPropertyEnumFlagsLineEditHandler::updateEditor()\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().clear();\n\t\teditor().setPlaceholderText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setText(enumFlagsProperty2Str(property()));\n\t\teditor().setPlaceholderText(QString());\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateEnumFlags.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_ENUM_FLAGS_H\n#define PROPERTY_DELEGATE_ENUM_FLAGS_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyEnumFlags.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateEnumFlags\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyEnumFlagsBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateEnumFlags)\n\npublic:\n\tQtnPropertyDelegateEnumFlags(QtnPropertyEnumFlagsBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_ENUM_FLAGS_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateFloat.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateFloat.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QCoreApplication>\n#include <QLocale>\n\nQByteArray qtnMultiplierAttr()\n{\n\treturn QByteArrayLiteral(\"multiplier\");\n}\n\nQByteArray qtnPrecisionAttr()\n{\n\treturn QByteArrayLiteral(\"precision\");\n}\n\nclass QtnPropertyFloatSpinBoxHandler\n\t: public QtnPropertyEditorHandler<QtnPropertyFloatBase, QDoubleSpinBox>\n{\npublic:\n\tusing Inherited =\n\t\tQtnPropertyEditorHandler<QtnPropertyFloatBase, QDoubleSpinBox>;\n\n\tQtnPropertyFloatSpinBoxHandler(\n\t\tQtnPropertyDelegateFloat *delegate, QDoubleSpinBox &editor);\n\n\tvoid onValueChanged(double value);\n\n\tvirtual void updateEditor() override;\n\tvoid updateValue();\n\nprivate:\n\tQtnPropertyDelegateFloat *m_delegate;\n\tdouble newValue;\n\tunsigned updating;\n};\n\nQtnPropertyDelegateFloat::QtnPropertyDelegateFloat(QtnPropertyFloatBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyFloatBase>(owner)\n\t, m_multiplier(1.0)\n\t, m_precision(std::numeric_limits<float>::digits10 - 1)\n{\n}\n\nvoid QtnPropertyDelegateFloat::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyFloatBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateFloat, QtnPropertyFloatBase>,\n\t\tqtnSpinBoxDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyFloatBase::staticMetaObject,\n\t\t&qtnCreateDelegate<\n\t\t\tQtnPropertyDelegateSlideBoxTyped<QtnPropertyFloatBase>,\n\t\t\tQtnPropertyFloatBase>,\n\t\tqtnSliderBoxDelegate());\n}\n\ndouble QtnPropertyDelegateFloat::stepValue() const\n{\n\tif (m_step.isValid())\n\t{\n\t\treturn m_step.toDouble();\n\t}\n\n\tfloat sv = owner().stepValue();\n\treturn qint64(sv * 100000.0) / 100000.0;\n}\n\nQWidget *QtnPropertyDelegateFloat::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto spinBox = new QtnDoubleSpinBox(parent);\n\tspinBox->setDecimals(m_precision);\n\tspinBox->setSuffix(m_suffix);\n\tspinBox->setGeometry(rect);\n\n\tnew QtnPropertyFloatSpinBoxHandler(this, *spinBox);\n\n\tspinBox->selectAll();\n\n\tif (stateProperty()->isEditableByUser())\n\t\tqtnInitNumEdit(spinBox, inplaceInfo, NUM_FLOAT);\n\n\treturn spinBox;\n}\n\nbool QtnPropertyDelegateFloat::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<\n\t\t\tQtnPropertyFloatBase>::acceptKeyPressedForInplaceEditImpl(keyEvent))\n\t{\n\t\treturn true;\n\t}\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_FLOAT);\n}\n\nbool QtnPropertyDelegateFloat::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QtnDoubleSpinBox::valueToText(\n\t\tcurrentValue(), QLocale(), m_precision, true);\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nvoid QtnPropertyDelegateFloat::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tinfo.loadAttribute(qtnMultiplierAttr(), m_multiplier);\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\n\tm_step = info.attributes.value(qtnStepAttr());\n\tif (m_step.isValid())\n\t{\n\t\tbool ok;\n\t\tfloat step = m_step.toDouble(&ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tm_step = QVariant();\n\t\t} else\n\t\t{\n\t\t\tm_step = step;\n\t\t}\n\t}\n\n\tm_precision = qBound(0, m_precision, std::numeric_limits<float>::digits10);\n\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\n\tif (!qIsFinite(m_multiplier) || qFuzzyCompare(m_multiplier, 0.0))\n\t{\n\t\tm_multiplier = 1.0;\n\t}\n\tfixMinMaxVariant<float>(m_min, m_max);\n}\n\ndouble QtnPropertyDelegateFloat::minValue() const\n{\n\treturn (m_min.isValid() ? m_min.toFloat() : owner().minValue()) *\n\t\tm_multiplier;\n}\n\ndouble QtnPropertyDelegateFloat::maxValue() const\n{\n\treturn (m_max.isValid() ? m_max.toFloat() : owner().maxValue()) *\n\t\tm_multiplier;\n}\n\ndouble QtnPropertyDelegateFloat::multiplier() const\n{\n\treturn m_multiplier;\n}\n\ndouble QtnPropertyDelegateFloat::currentValue() const\n{\n\treturn qBound(minValue(), owner().value() * m_multiplier, maxValue());\n}\n\nQtnPropertyFloatSpinBoxHandler::QtnPropertyFloatSpinBoxHandler(\n\tQtnPropertyDelegateFloat *delegate, QDoubleSpinBox &editor)\n\t: Inherited(delegate, editor)\n\t, m_delegate(delegate)\n\t, updating(0)\n{\n\tnewValue = this->property().value();\n\tupdateEditor();\n\n\teditor.setKeyboardTracking(false);\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QDoubleSpinBox::*)(double)>(\n\t\t\t&QDoubleSpinBox::valueChanged),\n\t\tthis, &QtnPropertyFloatSpinBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyFloatSpinBoxHandler::onValueChanged(double value)\n{\n\tif (updating > 0)\n\t\treturn;\n\tnewValue = value;\n\tupdateValue();\n}\n\nvoid QtnPropertyFloatSpinBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\teditor().setSingleStep(m_delegate->stepValue());\n\teditor().setRange(m_delegate->minValue(), m_delegate->maxValue());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().setValue(editor().minimum());\n\t\teditor().setSpecialValueText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setValue(m_delegate->currentValue());\n\t\teditor().setSpecialValueText(QString());\n\t}\n\n\teditor().selectAll();\n\n\tupdating--;\n}\n\nvoid QtnPropertyFloatSpinBoxHandler::updateValue()\n{\n\tif (this->propertyBase())\n\t{\n\t\tthis->property().setValue(newValue / m_delegate->multiplier(),\n\t\t\tthis->delegate()->editReason());\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateFloat.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#pragma once\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyFloat.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateFloat\n\t: public QtnPropertyDelegateTyped<QtnPropertyFloatBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateFloat)\n\n\tQString m_suffix;\n\tdouble m_multiplier;\n\tint m_precision;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQVariant m_step;\n\npublic:\n\tQtnPropertyDelegateFloat(QtnPropertyFloatBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tdouble stepValue() const;\n\tdouble minValue() const;\n\tdouble maxValue() const;\n\tdouble multiplier() const;\n\tdouble currentValue() const;\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n};\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateInt.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateInt.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QCoreApplication>\n#include <QSpinBox>\n#include <QLocale>\n\nQByteArray qtnSpinBoxDelegate()\n{\n\treturn QByteArrayLiteral(\"SpinBox\");\n}\n\nQByteArray qtnSliderBoxDelegate()\n{\n\treturn QByteArrayLiteral(\"SliderBox\");\n}\n\nQByteArray qtnSuffixAttr()\n{\n\treturn QByteArrayLiteral(\"suffix\");\n}\n\nQByteArray qtnMinAttr()\n{\n\treturn QByteArrayLiteral(\"min\");\n}\n\nQByteArray qtnMaxAttr()\n{\n\treturn QByteArrayLiteral(\"max\");\n}\n\nQByteArray qtnStepAttr()\n{\n\treturn QByteArrayLiteral(\"step\");\n}\n\nvoid qtnInitPercentSpinBoxDelegate(QtnPropertyDelegateInfo &delegate)\n{\n\tdelegate.name = qtnSpinBoxDelegate();\n\tdelegate.attributes[qtnSuffixAttr()] = QLocale().percent();\n}\n\nvoid qtnInitDegreeSpinBoxDelegate(QtnPropertyDelegateInfo &delegate)\n{\n\tdelegate.name = qtnSpinBoxDelegate();\n\tdelegate.attributes[qtnSuffixAttr()] = QString::fromUtf8(\"º\");\n}\n\nclass QtnPropertyIntSpinBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyIntBase, QSpinBox>\n{\npublic:\n\tQtnPropertyIntSpinBoxHandler(\n\t\tQtnPropertyDelegateInt *delegate, QSpinBox &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\nprivate:\n\tQtnPropertyDelegateInt *m_delegate;\n};\n\nQtnPropertyDelegateInt::QtnPropertyDelegateInt(QtnPropertyIntBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyIntBase>(owner)\n{\n}\n\nvoid QtnPropertyDelegateInt::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyIntBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateInt, QtnPropertyIntBase>,\n\t\tqtnSpinBoxDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyIntBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateSlideBoxTyped<QtnPropertyIntBase>,\n\t\t\tQtnPropertyIntBase>,\n\t\tqtnSliderBoxDelegate());\n}\n\nint QtnPropertyDelegateInt::stepValue() const\n{\n\treturn m_step.isValid() ? m_step.toInt() : owner().stepValue();\n}\n\nint QtnPropertyDelegateInt::minValue() const\n{\n\treturn m_min.isValid() ? m_min.toInt() : owner().minValue();\n}\n\nint QtnPropertyDelegateInt::maxValue() const\n{\n\treturn m_max.isValid() ? m_max.toInt() : owner().maxValue();\n}\n\nint QtnPropertyDelegateInt::currentValue() const\n{\n\treturn qBound(minValue(), owner().value(), maxValue());\n}\n\nQWidget *QtnPropertyDelegateInt::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto spinBox = new QSpinBox(parent);\n\tspinBox->setSuffix(m_suffix);\n\tspinBox->setGeometry(rect);\n\n\tnew QtnPropertyIntSpinBoxHandler(this, *spinBox);\n\n\tspinBox->selectAll();\n\n\tif (stateProperty()->isEditableByUser())\n\t\tqtnInitNumEdit(spinBox, inplaceInfo, NUM_SIGNED_INT);\n\n\treturn spinBox;\n}\n\nbool QtnPropertyDelegateInt::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<\n\t\t\tQtnPropertyIntBase>::acceptKeyPressedForInplaceEditImpl(keyEvent))\n\t{\n\t\treturn true;\n\t}\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_SIGNED_INT);\n}\n\nvoid QtnPropertyDelegateInt::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\tm_step = info.attributes.value(qtnStepAttr());\n\tif (m_step.isValid())\n\t{\n\t\tbool ok;\n\t\tint step = m_step.toInt(&ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tm_step = QVariant();\n\t\t} else\n\t\t{\n\t\t\tm_step = step;\n\t\t}\n\t}\n\tfixMinMaxVariant<int>(m_min, m_max);\n}\n\nbool QtnPropertyDelegateInt::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QLocale().toString(currentValue());\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nQtnPropertyIntSpinBoxHandler::QtnPropertyIntSpinBoxHandler(\n\tQtnPropertyDelegateInt *delegate, QSpinBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t, m_delegate(delegate)\n{\n\tupdateEditor();\n\n\teditor.setKeyboardTracking(false);\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,\n\t\t&QtnPropertyIntSpinBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyIntSpinBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\teditor().setSingleStep(m_delegate->stepValue());\n\teditor().setRange(m_delegate->minValue(), m_delegate->maxValue());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().setValue(editor().minimum());\n\t\teditor().setSpecialValueText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setValue(m_delegate->currentValue());\n\t\teditor().setSpecialValueText(QString());\n\t}\n\n\teditor().selectAll();\n\n\tupdating--;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateInt.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_INT_H\n#define PROPERTY_DELEGATE_INT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyInt.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateInt\n\t: public QtnPropertyDelegateTyped<QtnPropertyIntBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateInt)\n\n\tQString m_suffix;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQVariant m_step;\n\npublic:\n\tQtnPropertyDelegateInt(QtnPropertyIntBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tint stepValue() const;\n\tint minValue() const;\n\tint maxValue() const;\n\tint currentValue() const;\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_INT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQPoint.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQPoint.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QLocale>\n#include <QLineEdit>\n\nQByteArray qtnXDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"xDisplayName\");\n}\n\nQByteArray qtnXDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"xDescription\");\n}\n\nQByteArray qtnYDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"yDisplayName\");\n}\n\nQByteArray qtnYDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"yDescription\");\n}\n\nQtnPropertyDelegateQPoint::QtnPropertyDelegateQPoint(\n\tQtnPropertyQPointBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQPointBase>(owner)\n{\n\tauto xProperty = owner.createXProperty();\n\taddSubProperty(xProperty);\n\n\tauto yProperty = owner.createYProperty();\n\taddSubProperty(yProperty);\n}\n\nvoid QtnPropertyDelegateQPoint::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQPointBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQPoint, QtnPropertyQPointBase>,\n\t\t\"XY\");\n}\n\nvoid qtnApplyQPointDelegateAttributes(\n\tQtnPropertyDelegate *to, const QtnPropertyDelegateInfo &info)\n{\n\tenum\n\t{\n\t\tX,\n\t\tY,\n\t\tTOTAL\n\t};\n\tQ_ASSERT(to->subPropertyCount() == TOTAL);\n\tstatic const QtnSubPropertyInfo KEYS[TOTAL] = {\n\t\t{ X, QtnPropertyQPoint::xKey(), qtnXDisplayNameAttr(),\n\t\t\tqtnXDescriptionAttr() },\n\t\t{ Y, QtnPropertyQPoint::yKey(), qtnYDisplayNameAttr(),\n\t\t\tqtnYDescriptionAttr() },\n\t};\n\n\tto->applySubPropertyInfos(info, KEYS, TOTAL);\n}\n\nvoid QtnPropertyDelegateQPoint::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\n\tqtnApplyQPointDelegateAttributes(this, info);\n}\n\nQWidget *QtnPropertyDelegateQPoint::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQPoint::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQPoint::getToStringFormat().arg(\n\t\tlocale.toString(value.x()) + m_suffix,\n\t\tlocale.toString(value.y()) + m_suffix);\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQPoint.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QPOINT_H\n#define PROPERTY_DELEGATE_QPOINT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQPoint.h\"\n\nclass QtnPropertyQPointBase;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQPoint\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQPointBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQPoint)\n\n\tQString m_suffix;\n\npublic:\n\tQtnPropertyDelegateQPoint(QtnPropertyQPointBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QPOINT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQPointF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQPointF.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Core/PropertyQPoint.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n\n#include <QLineEdit>\n#include <QLocale>\n\nQtnPropertyDelegateQPointF::QtnPropertyDelegateQPointF(\n\tQtnPropertyQPointFBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQPointFBase>(owner)\n\t, m_multiplier(1.0)\n\t, m_precision(std::numeric_limits<qreal>::digits10 - 1)\n{\n\taddSubProperty(owner.createXProperty());\n\taddSubProperty(owner.createYProperty());\n}\n\nvoid QtnPropertyDelegateQPointF::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQPointFBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQPointF, QtnPropertyQPointFBase>,\n\t\t\"QPointF\");\n}\n\nextern void qtnApplyQPointDelegateAttributes(\n\tQtnPropertyDelegate *to, const QtnPropertyDelegateInfo &info);\n\nvoid QtnPropertyDelegateQPointF::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tinfo.loadAttribute(qtnMultiplierAttr(), m_multiplier);\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tm_precision = qBound(0, m_precision, std::numeric_limits<qreal>::digits10);\n\tif (!qIsFinite(m_multiplier) || qFuzzyCompare(m_multiplier, 0.0))\n\t{\n\t\tm_multiplier = 1;\n\t}\n\n\tqtnApplyQPointDelegateAttributes(this, info);\n}\n\nQWidget *QtnPropertyDelegateQPointF::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQPointF::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQPoint::getToStringFormat().arg(\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.x() * m_multiplier, locale, m_precision, true) +\n\t\t\tm_suffix,\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.y() * m_multiplier, locale, m_precision, true) +\n\t\t\tm_suffix);\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQPointF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QPOINTF_H\n#define PROPERTY_DELEGATE_QPOINTF_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQPointF.h\"\n\nclass QtnPropertyQPointFBase;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQPointF\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQPointFBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQPointF)\n\n\tQString m_suffix;\n\tdouble m_multiplier;\n\tint m_precision;\n\npublic:\n\tQtnPropertyDelegateQPointF(QtnPropertyQPointFBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QPOINTF_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQRect.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQRect.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Core/PropertyQSize.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QLineEdit>\n\nQByteArray qtnLTWHDelegateName()\n{\n\treturn QByteArrayLiteral(\"LTWH\");\n}\n\nQByteArray qtnLTRBDelegateName()\n{\n\treturn QByteArrayLiteral(\"LTRB\");\n}\n\nQByteArray qtnLeftDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"leftDisplayName\");\n}\n\nQByteArray qtnLeftDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"leftDescription\");\n}\n\nQByteArray qtnTopDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"topDisplayName\");\n}\n\nQByteArray qtnTopDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"topDescription\");\n}\n\nQByteArray qtnRightDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"rightDisplayName\");\n}\n\nQByteArray qtnRightDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"rightDescription\");\n}\n\nQByteArray qtnBottomDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"bottomDisplayName\");\n}\n\nQByteArray qtnBottomDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"bottomDescription\");\n}\n\nQByteArray qtnWidthDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"widthDisplayName\");\n}\n\nQByteArray qtnWidthDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"widthDescription\");\n}\n\nQByteArray qtnHeightDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"heightDisplayName\");\n}\n\nQByteArray qtnHeightDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"heightDescription\");\n}\n\nQtnPropertyDelegateQRect::QtnPropertyDelegateQRect(\n\tQtnPropertyQRectBase &owner, bool useCoordinates)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQRectBase>(owner)\n\t, m_coordinates(useCoordinates)\n{\n\taddSubProperty(owner.createLeftProperty(!m_coordinates));\n\taddSubProperty(owner.createTopProperty(!m_coordinates));\n\n\tif (m_coordinates)\n\t{\n\t\taddSubProperty(owner.createRightProperty(false));\n\t\taddSubProperty(owner.createBottomProperty(false));\n\t} else\n\t{\n\t\taddSubProperty(owner.createWidthProperty());\n\t\taddSubProperty(owner.createHeightProperty());\n\t}\n}\n\nstatic QtnPropertyDelegate *qtnCreateDelegateLTRB(QtnPropertyBase &owner)\n{\n\tauto theOwner = qobject_cast<QtnPropertyQRectBase *>(&owner);\n\tif (!theOwner)\n\t\treturn nullptr;\n\n\treturn new QtnPropertyDelegateQRect(*theOwner, true);\n}\n\nvoid QtnPropertyDelegateQRect::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQRectBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQRect, QtnPropertyQRectBase>,\n\t\tqtnLTWHDelegateName());\n\n\tfactory.registerDelegate(&QtnPropertyQRectBase::staticMetaObject,\n\t\t&qtnCreateDelegateLTRB, qtnLTRBDelegateName());\n}\n\nvoid qtnApplyQRectDelegateAttributes(QtnPropertyDelegate *to,\n\tconst QtnPropertyDelegateInfo &info, bool coordinates)\n{\n\tenum\n\t{\n\t\tLEFT = 0,\n\t\tTOP = 1,\n\t\tWIDTH = 2,\n\t\tHEIGHT = 3,\n\t\tRIGHT = 2,\n\t\tBOTTOM = 3,\n\t\tTOTAL\n\t};\n\tQ_ASSERT(to->subPropertyCount() == TOTAL);\n\tif (coordinates)\n\t{\n\t\tstatic const QtnSubPropertyInfo LTRB[TOTAL] = {\n\t\t\t{ LEFT, QtnPropertyQRect::leftKey(), qtnLeftDisplayNameAttr(),\n\t\t\t\tqtnLeftDescriptionAttr() },\n\t\t\t{ TOP, QtnPropertyQRect::topKey(), qtnTopDisplayNameAttr(),\n\t\t\t\tqtnTopDescriptionAttr() },\n\t\t\t{ RIGHT, QtnPropertyQRect::rightKey(), qtnRightDisplayNameAttr(),\n\t\t\t\tqtnRightDescriptionAttr() },\n\t\t\t{ BOTTOM, QtnPropertyQRect::bottomKey(), qtnBottomDisplayNameAttr(),\n\t\t\t\tqtnBottomDescriptionAttr() },\n\t\t};\n\t\tto->applySubPropertyInfos(info, LTRB, TOTAL);\n\t} else\n\t{\n\t\tstatic const QtnSubPropertyInfo LTWH[TOTAL] = {\n\t\t\t{ LEFT, QtnPropertyQRect::leftKey(), qtnLeftDisplayNameAttr(),\n\t\t\t\tqtnLeftDescriptionAttr() },\n\t\t\t{ TOP, QtnPropertyQRect::topKey(), qtnTopDisplayNameAttr(),\n\t\t\t\tqtnTopDescriptionAttr() },\n\t\t\t{ WIDTH, QtnPropertyQSize::widthKey(), qtnWidthDisplayNameAttr(),\n\t\t\t\tqtnWidthDescriptionAttr() },\n\t\t\t{ HEIGHT, QtnPropertyQSize::heightKey(), qtnHeightDisplayNameAttr(),\n\t\t\t\tqtnHeightDescriptionAttr() },\n\n\t\t};\n\t\tto->applySubPropertyInfos(info, LTWH, TOTAL);\n\t}\n}\n\nvoid QtnPropertyDelegateQRect::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tqtnApplyQRectDelegateAttributes(this, info, m_coordinates);\n}\n\nQWidget *QtnPropertyDelegateQRect::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQRect::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue =\n\t\tQtnPropertyQRect::getToStringFormat(m_coordinates)\n\t\t\t.arg(locale.toString(value.left()), locale.toString(value.top()),\n\t\t\t\tlocale.toString(m_coordinates ? value.right() : value.width()),\n\t\t\t\tlocale.toString(\n\t\t\t\t\tm_coordinates ? value.bottom() : value.height()));\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQRect.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QRECT_H\n#define PROPERTY_DELEGATE_QRECT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQRect.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQRect\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQRectBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQRect)\n\n\tbool m_coordinates;\n\npublic:\n\tQtnPropertyDelegateQRect(\n\t\tQtnPropertyQRectBase &owner, bool useCoordinates = false);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QRECT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQRectF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQRectF.h\"\n#include \"QtnProperty/Core/PropertyQRect.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n\n#include <QLineEdit>\n\nQtnPropertyDelegateQRectF::QtnPropertyDelegateQRectF(\n\tQtnPropertyQRectFBase &owner, bool useCoordinates)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQRectFBase>(owner)\n\t, m_coordinates(useCoordinates)\n\t, m_precision(std::numeric_limits<qreal>::digits10 - 1)\n{\n\taddSubProperty(owner.createLeftProperty(!m_coordinates));\n\taddSubProperty(owner.createTopProperty(!m_coordinates));\n\n\tif (m_coordinates)\n\t{\n\t\taddSubProperty(owner.createRightProperty(false));\n\t\taddSubProperty(owner.createBottomProperty(false));\n\t} else\n\t{\n\t\taddSubProperty(owner.createWidthProperty());\n\t\taddSubProperty(owner.createHeightProperty());\n\t}\n}\n\nstatic QtnPropertyDelegate *qtnCreateDelegateLTRB(QtnPropertyBase &owner)\n{\n\tauto theOwner = qobject_cast<QtnPropertyQRectFBase *>(&owner);\n\tif (!theOwner)\n\t\treturn nullptr;\n\n\treturn new QtnPropertyDelegateQRectF(*theOwner, true);\n}\n\nvoid QtnPropertyDelegateQRectF::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQRectFBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQRectF, QtnPropertyQRectFBase>,\n\t\tqtnLTWHDelegateName());\n\n\tfactory.registerDelegate(&QtnPropertyQRectFBase::staticMetaObject,\n\t\t&qtnCreateDelegateLTRB, qtnLTRBDelegateName());\n}\n\nextern void qtnApplyQRectDelegateAttributes(QtnPropertyDelegate *to,\n\tconst QtnPropertyDelegateInfo &info, bool coordinates);\n\nvoid QtnPropertyDelegateQRectF::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tm_precision = qBound(0, m_precision, std::numeric_limits<qreal>::digits10);\n\tqtnApplyQRectDelegateAttributes(this, info, m_coordinates);\n}\n\nQWidget *QtnPropertyDelegateQRectF::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQRectF::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQRect::getToStringFormat(m_coordinates)\n\t\t\t\t   .arg(QtnDoubleSpinBox::valueToText(\n\t\t\t\t\t\t\tvalue.left(), locale, m_precision, true),\n\t\t\t\t\t   QtnDoubleSpinBox::valueToText(\n\t\t\t\t\t\t   value.top(), locale, m_precision, true),\n\t\t\t\t\t   QtnDoubleSpinBox::valueToText(\n\t\t\t\t\t\t   m_coordinates ? value.right() : value.width(),\n\t\t\t\t\t\t   locale, m_precision, true),\n\t\t\t\t\t   QtnDoubleSpinBox::valueToText(\n\t\t\t\t\t\t   m_coordinates ? value.bottom() : value.height(),\n\t\t\t\t\t\t   locale, m_precision, true));\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQRectF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QRECTF_H\n#define PROPERTY_DELEGATE_QRECTF_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQRectF.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQRectF\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQRectFBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQRectF)\n\n\tbool m_coordinates;\n\tint m_precision;\n\npublic:\n\tQtnPropertyDelegateQRectF(\n\t\tQtnPropertyQRectFBase &owner, bool useCoordinates = false);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\nprivate:\n\tenum\n\t{\n\t\tLEFT = 0,\n\t\tTOP = 1,\n\t\tWIDTH = 2,\n\t\tHEIGHT = 3,\n\t\tRIGHT = 2,\n\t\tBOTTOM = 3\n\t};\n};\n\n#endif // PROPERTY_DELEGATE_QRECTF_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQSize.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#include \"PropertyDelegateQSize.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QLineEdit>\n#include <QLocale>\n\nQtnPropertyDelegateQSize::QtnPropertyDelegateQSize(QtnPropertyQSizeBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQSizeBase>(owner)\n{\n\taddSubProperty(owner.createWidthProperty());\n\taddSubProperty(owner.createHeightProperty());\n}\n\nvoid QtnPropertyDelegateQSize::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQSizeBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQSize, QtnPropertyQSizeBase>,\n\t\t\"WH\");\n}\n\nvoid qtnApplyQSizeDelegateAttributes(\n\tQtnPropertyDelegate *to, const QtnPropertyDelegateInfo &info)\n{\n\tenum\n\t{\n\t\tWIDTH,\n\t\tHEIGHT,\n\t\tTOTAL\n\t};\n\tQ_ASSERT(to->subPropertyCount() == TOTAL);\n\tstatic const QtnSubPropertyInfo KEYS[TOTAL] = {\n\t\t{ WIDTH, QtnPropertyQSize::widthKey(), qtnWidthDisplayNameAttr(),\n\t\t\tqtnWidthDescriptionAttr() },\n\t\t{ HEIGHT, QtnPropertyQSize::heightKey(), qtnHeightDisplayNameAttr(),\n\t\t\tqtnHeightDescriptionAttr() },\n\t};\n\n\tto->applySubPropertyInfos(info, KEYS, TOTAL);\n}\n\nvoid QtnPropertyDelegateQSize::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tqtnApplyQSizeDelegateAttributes(this, info);\n}\n\nQWidget *QtnPropertyDelegateQSize::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQSize::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQSize::getToStringFormat().arg(\n\t\tlocale.toString(value.width()), locale.toString(value.height()));\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQSize.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QSIZE_H\n#define PROPERTY_DELEGATE_QSIZE_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQSize.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQSize\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQSizeBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQSize)\n\npublic:\n\tQtnPropertyDelegateQSize(QtnPropertyQSizeBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QSIZE_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQSizeF.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#include \"PropertyDelegateQSizeF.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Core/PropertyQSize.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n\n#include <QLineEdit>\n#include <QLocale>\n\nQtnPropertyDelegateQSizeF::QtnPropertyDelegateQSizeF(\n\tQtnPropertyQSizeFBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQSizeFBase>(owner)\n\t, m_precision(std::numeric_limits<qreal>::digits10 - 1)\n{\n\taddSubProperty(owner.createWidthProperty());\n\taddSubProperty(owner.createHeightProperty());\n}\n\nvoid QtnPropertyDelegateQSizeF::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQSizeFBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQSizeF, QtnPropertyQSizeFBase>,\n\t\t\"WH\");\n}\n\nextern void qtnApplyQSizeDelegateAttributes(\n\tQtnPropertyDelegate *to, const QtnPropertyDelegateInfo &info);\n\nvoid QtnPropertyDelegateQSizeF::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tm_precision = qBound(0, m_precision, std::numeric_limits<qreal>::digits10);\n\tqtnApplyQSizeDelegateAttributes(this, info);\n}\n\nQWidget *QtnPropertyDelegateQSizeF::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQSizeF::propertyValueToStrImpl(QString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQSize::getToStringFormat().arg(\n\t\tQtnDoubleSpinBox::valueToText(value.width(), locale, m_precision, true),\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.height(), locale, m_precision, true));\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQSizeF.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QSIZEF_H\n#define PROPERTY_DELEGATE_QSIZEF_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQSizeF.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQSizeF\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQSizeFBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQSizeF)\n\n\tint m_precision;\n\npublic:\n\tQtnPropertyDelegateQSizeF(QtnPropertyQSizeFBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QSIZEF_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQString.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2019 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQString.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/Utils/MultilineTextDialog.h\"\n#include \"QtnProperty/Utils/InplaceEditing.h\"\n#include \"QtnProperty/Utils/QtnCompleterLineEdit.h\"\n#include \"QtnProperty/PropertyView.h\"\n\n#include <QLineEdit>\n#include <QKeyEvent>\n#include <QFileInfo>\n#include <QFileDialog>\n#include <QComboBox>\n#include <QCompleter>\n#include <QTimer>\n#include <QDebug>\n#include <QStringListModel>\n#include <QAbstractItemView>\n#include <QListView>\n\nstatic QString toSingleLine(const QString &str)\n{\n\tint n = str.indexOf('\\n');\n\tint r = str.indexOf('\\r');\n\tint len = n < 0 ? r : (r < 0 ? n : qMin(n, r));\n\treturn QString(str.data(), len);\n}\n\nQByteArray qtnMultiLineEditAttr()\n{\n\treturn QByteArrayLiteral(\"multiline_edit\");\n}\n\nQByteArray qtnMaxLengthAttr()\n{\n\treturn QByteArrayLiteral(\"max_length\");\n}\n\nQByteArray qtnPlaceholderAttr()\n{\n\treturn QByteArrayLiteral(\"placeholder\");\n}\n\nQByteArray qtnItemsAttr()\n{\n\treturn QByteArrayLiteral(\"items\");\n}\n\nQByteArray qtnEditableAttr()\n{\n\treturn QByteArrayLiteral(\"editable\");\n}\n\nQByteArray qtnInvalidColorAttr()\n{\n\treturn QByteArrayLiteral(\"invalidColor\");\n}\n\nQByteArray qtnShowRelativePathAttr()\n{\n\treturn QByteArrayLiteral(\"showRelativePath\");\n}\n\nQByteArray qtnFileNameFilterAttr()\n{\n\treturn QByteArrayLiteral(\"nameFilter\");\n}\n\nQByteArray qtnFileNameFiltersAttr()\n{\n\treturn QByteArrayLiteral(\"nameFilters\");\n}\n\nQByteArray qtnDefaultSuffixAttr()\n{\n\treturn QByteArrayLiteral(\"defaultSuffix\");\n}\n\nQByteArray qtnDefaultDirAttr()\n{\n\treturn QByteArrayLiteral(\"defaultDirectory\");\n}\n\nQByteArray qtnOptionsAttr()\n{\n\treturn QByteArrayLiteral(\"options\");\n}\n\nQByteArray qtnFileModeAttr()\n{\n\treturn QByteArrayLiteral(\"fileMode\");\n}\n\nQByteArray qtnViewModeAttr()\n{\n\treturn QByteArrayLiteral(\"viewMode\");\n}\n\nQByteArray qtnAcceptModeAttr()\n{\n\treturn QByteArrayLiteral(\"acceptMode\");\n}\n\nQByteArray qtnGetCandidatesFnAttr()\n{\n\treturn QByteArrayLiteral(\"GetCandidatesFn\");\n}\n\nQByteArray qtnCreateCandidateFnAttr()\n{\n\treturn QByteArrayLiteral(\"CreateCandidateFn\");\n}\n\nQByteArray qtnCreateCandidateIconAttr()\n{\n\treturn QByteArrayLiteral(\"CreateCandidateIcon\");\n}\n\nQByteArray qtnCreateCandidateToolTipAttr()\n{\n\treturn QByteArrayLiteral(\"CreateCandidateToolTip\");\n}\n\nQByteArray qtnLineEditDelegate()\n{\n\treturn QByteArrayLiteral(\"LineEdit\");\n}\n\nQByteArray qtnSelectFileDelegate()\n{\n\treturn QByteArrayLiteral(\"File\");\n}\n\nQByteArray qtnCallbackDelegate()\n{\n\treturn QByteArrayLiteral(\"Callback\");\n}\n\nclass QtnPropertyQStringLineEditHandler\n\t: public QtnPropertyEditorHandler<QtnPropertyQStringBase, QLineEdit>\n{\npublic:\n\tQtnPropertyQStringLineEditHandler(QtnPropertyDelegate *delegate,\n\t\tQLineEdit &editor, const QString &placeholder);\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvoid updateValue();\n\nprivate:\n\tQString placeholder;\n};\n\nclass QtnPropertyQStringMultilineEditBttnHandler\n\t: public QtnPropertyEditorBttnHandler<QtnPropertyQStringBase,\n\t\t  QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQStringMultilineEditBttnHandler(QtnPropertyDelegate *delegate,\n\t\tQtnLineEditBttn &editor, const QString &placeholder);\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvirtual void revertInput() override;\n\tvirtual void onToolButtonClick() override;\n\nprivate:\n\tvoid onEditingFinished();\n\tvoid onToolButtonClicked(bool);\n\n\tMultilineTextDialog *dialog;\n\tDialogContainerPtr dialogContainer;\n\tbool multiline;\n\tQString placeholder;\n};\n\nQtnPropertyDelegateQString::QtnPropertyDelegateQString(\n\tQtnPropertyQStringBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyQStringBase>(owner)\n\t, m_maxLength(0x1000000)\n\t, m_multiline(true)\n{\n}\n\nvoid QtnPropertyDelegateQString::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQStringBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQString, QtnPropertyQStringBase>,\n\t\tqtnLineEditDelegate());\n}\n\nvoid QtnPropertyDelegateQString::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnMultiLineEditAttr(), m_multiline);\n\tinfo.loadAttribute(qtnMaxLengthAttr(), m_maxLength);\n\tinfo.loadAttribute(qtnPlaceholderAttr(), m_placeholder);\n}\n\nbool QtnPropertyDelegateQString::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<QtnPropertyQStringBase>::\n\t\t\tacceptKeyPressedForInplaceEditImpl(keyEvent))\n\t\treturn true;\n\n\t// accept any printable key\n\treturn qtnAcceptForLineEdit(keyEvent);\n}\n\nQWidget *QtnPropertyDelegateQString::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tif (m_multiline)\n\t{\n\t\tQtnLineEditBttn *editor = new QtnLineEditBttn(parent);\n\t\teditor->setGeometry(rect);\n\n\t\teditor->lineEdit->setMaxLength(m_maxLength);\n\t\teditor->lineEdit->setPlaceholderText(m_placeholder);\n\n\t\tnew QtnPropertyQStringMultilineEditBttnHandler(\n\t\t\tthis, *editor, m_placeholder);\n\n\t\tqtnInitLineEdit(editor->lineEdit, inplaceInfo);\n\t\treturn editor;\n\t}\n\n\tQLineEdit *lineEdit = new QLineEdit(parent);\n\tlineEdit->setMaxLength(m_maxLength);\n\tlineEdit->setPlaceholderText(m_placeholder);\n\tlineEdit->setGeometry(rect);\n\n\tnew QtnPropertyQStringLineEditHandler(this, *lineEdit, m_placeholder);\n\n\tqtnInitLineEdit(lineEdit, inplaceInfo);\n\n\treturn lineEdit;\n}\n\nbool QtnPropertyDelegateQString::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = owner().value();\n\n\tauto placeholder = strValue.isEmpty() && !m_placeholder.isEmpty()\n\t\t? m_placeholder\n\t\t: QtnPropertyQString::getPlaceholderStr(strValue, m_multiline);\n\n\tif (!placeholder.isEmpty())\n\t\tstrValue.swap(placeholder);\n\n\treturn true;\n}\n\nbool QtnPropertyDelegateQString::isPlaceholderColor() const\n{\n\tauto text = owner().value();\n\tif (text.isEmpty() && !m_placeholder.isEmpty())\n\t{\n\t\treturn true;\n\t}\n\n\treturn !QtnPropertyQString::getPlaceholderStr(text, m_multiline).isEmpty();\n}\n\nclass QtnPropertyQStringFileLineEditBttnHandler\n\t: public QtnPropertyEditorBttnHandler<QtnPropertyQStringBase,\n\t\t  QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQStringFileLineEditBttnHandler(\n\t\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor);\n\n\tvoid applyAttributes(const QtnPropertyDelegateInfo &info);\n\n\tvirtual void onToolButtonClick() override;\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onToolButtonClicked(bool);\n\tvoid onEditingFinished();\n\n\tQFileDialog *dialog;\n\tDialogContainerPtr dialogContainer;\n\tQString defaultDirectory;\n};\n\nQtnPropertyDelegateQStringInvalidBase::QtnPropertyDelegateQStringInvalidBase(\n\tQtnPropertyQStringBase &owner)\n\t: QtnPropertyDelegateQString(owner)\n\t, m_invalidColor(Qt::red)\n{\n\tm_multiline = false;\n}\n\nvoid QtnPropertyDelegateQStringInvalidBase::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnInvalidColorAttr(), m_invalidColor);\n}\n\nvoid QtnPropertyDelegateQStringInvalidBase::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tQPen oldPen = painter.pen();\n\n\tif ((m_invalidColor.alpha() != 0) && isNormalPainterState(painter) &&\n\t\t!isPlaceholderColor() && !isPropertyValid() &&\n\t\tstateProperty()->isEditableByUser())\n\t{\n\t\tpainter.setPen(m_invalidColor.rgb());\n\t}\n\n\tQtnPropertyDelegateQString::drawValueImpl(painter, rect);\n\tpainter.setPen(oldPen);\n}\n\nQtnPropertyDelegateQStringFile::QtnPropertyDelegateQStringFile(\n\tQtnPropertyQStringBase &owner)\n\t: QtnPropertyDelegateQStringInvalidBase(owner)\n{\n}\n\nvoid QtnPropertyDelegateQStringFile::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyQStringBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQStringFile,\n\t\t\tQtnPropertyQStringBase>,\n\t\tqtnSelectFileDelegate());\n}\n\nvoid QtnPropertyDelegateQStringFile::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tQtnPropertyDelegateQStringInvalidBase::applyAttributesImpl(info);\n\tm_editorAttributes = info;\n}\n\nbool QtnPropertyDelegateQStringFile::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tif (!owner().value().isEmpty())\n\t{\n\t\tstrValue = QDir::toNativeSeparators(\n\t\t\tshouldShowRelativePath() ? relativeFilePath() : absoluteFilePath());\n\t\treturn true;\n\t}\n\n\treturn QtnPropertyDelegateQStringInvalidBase::propertyValueToStrImpl(\n\t\tstrValue);\n}\n\nbool QtnPropertyDelegateQStringFile::toolTipImpl(QString &strValue) const\n{\n\tstrValue = QDir::toNativeSeparators(absoluteFilePath());\n\treturn true;\n}\n\nQWidget *QtnPropertyDelegateQStringFile::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQtnLineEditBttn *editor = new QtnLineEditBttn(parent);\n\teditor->setGeometry(rect);\n\n\tauto handler = new QtnPropertyQStringFileLineEditBttnHandler(this, *editor);\n\thandler->applyAttributes(m_editorAttributes);\n\n\tqtnInitLineEdit(editor->lineEdit, inplaceInfo);\n\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQStringFile::isPropertyValid() const\n{\n\tauto filePath = absoluteFilePath();\n\n\tif (filePath.isEmpty())\n\t\treturn true;\n\n\tauto fileMode = QFileDialog::FileMode(m_editorAttributes.getAttribute(\n\t\tqtnFileModeAttr(), QFileDialog::AnyFile));\n\n\tswitch (fileMode)\n\t{\n\t\tcase QFileDialog::AnyFile:\n\t\t\treturn true;\n\n\t\tcase QFileDialog::ExistingFile:\n\t\tcase QFileDialog::ExistingFiles:\n\t\t\treturn QFileInfo(filePath).isFile();\n\n\t\tcase QFileDialog::Directory:\n\t\tcase QFileDialog::DirectoryOnly:\n\t\t\treturn QFileInfo(filePath).isDir();\n\t}\n\n\treturn false;\n}\n\nQString QtnPropertyDelegateQStringFile::defaultDirectory() const\n{\n\treturn m_editorAttributes.getAttribute(qtnDefaultDirAttr(), QString());\n}\n\nQString QtnPropertyDelegateQStringFile::absoluteFilePath() const\n{\n\tQString result = owner().value();\n\n\tif (!result.isEmpty() && QDir::isRelativePath(result))\n\t{\n\t\tauto defaultDir = defaultDirectory();\n\t\tif (!defaultDir.isEmpty())\n\t\t\tresult = QDir(defaultDir).filePath(result);\n\t}\n\n\treturn result;\n}\n\nQString QtnPropertyDelegateQStringFile::relativeFilePath() const\n{\n\tQString result = owner().value();\n\n\tif (!result.isEmpty() && QDir::isAbsolutePath(result))\n\t{\n\t\tauto defaultDir = defaultDirectory();\n\n\t\tif (!defaultDir.isEmpty())\n\t\t\treturn QDir(defaultDir).relativeFilePath(result);\n\t}\n\n\treturn result;\n}\n\nbool QtnPropertyDelegateQStringFile::shouldShowRelativePath() const\n{\n\tif (defaultDirectory().isEmpty())\n\t\treturn false;\n\n\treturn m_editorAttributes.getAttribute(qtnShowRelativePathAttr(), false);\n}\n\nclass QtnPropertyQStringListComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyQStringBase, QComboBox>\n{\npublic:\n\tQtnPropertyQStringListComboBoxHandler(QtnPropertyDelegate *delegate,\n\t\tQComboBox &editor, const QtnPropertyDelegateInfo &info);\n\nprivate:\n\tvirtual void updateEditor() override;\n\tvirtual void updateValue() override;\n};\n\nQtnPropertyDelegateQStringList::QtnPropertyDelegateQStringList(\n\tQtnPropertyQStringBase &owner)\n\t: QtnPropertyDelegateQString(owner)\n{\n}\n\nvoid QtnPropertyDelegateQStringList::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyQStringBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQStringList,\n\t\t\tQtnPropertyQStringBase>,\n\t\tqtnComboBoxDelegate());\n}\n\nvoid QtnPropertyDelegateQStringList::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tm_editorAttributes = info;\n}\n\nQWidget *QtnPropertyDelegateQStringList::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQComboBox *editor = new QtnPropertyComboBox(this, parent);\n\teditor->setGeometry(rect);\n\n\tauto handler = new QtnPropertyQStringListComboBoxHandler(\n\t\tthis, *editor, m_editorAttributes);\n\tQ_UNUSED(handler);\n\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t{\n\t\teditor->showPopup();\n\t}\n\n\treturn editor;\n}\n\nQtnPropertyQStringListComboBoxHandler::QtnPropertyQStringListComboBoxHandler(\n\tQtnPropertyDelegate *delegate, QComboBox &editor,\n\tconst QtnPropertyDelegateInfo &info)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\tbool editable = false;\n\tinfo.loadAttribute(qtnEditableAttr(), editable);\n\tQStringList items;\n\tinfo.loadAttribute(qtnItemsAttr(), items);\n\n\teditor.clear();\n\teditor.addItems(items);\n\teditor.setEditable(editable);\n\teditor.setAutoCompletion(false);\n\n\tif (editable)\n\t\teditor.installEventFilter(this);\n\tupdateEditor();\n\n\tQObject::connect(&editor, &QComboBox::currentTextChanged, this,\n\t\t&QtnPropertyQStringListComboBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyQStringListComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setEnabled(stateProperty()->isEditableByUser());\n\n\tauto lineEdit = editor().lineEdit();\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().clearEditText();\n\t\tif (lineEdit)\n\t\t{\n\t\t\tlineEdit->setPlaceholderText(\n\t\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t\t}\n\t} else\n\t{\n\t\teditor().setCurrentText(property());\n\t\tif (editor().currentText() != property().value())\n\t\t\teditor().setCurrentIndex(-1);\n\t\tif (lineEdit)\n\t\t{\n\t\t\tlineEdit->setPlaceholderText(QString());\n\t\t}\n\t}\n\n\tif (lineEdit)\n\t\tlineEdit->selectAll();\n\n\tupdating--;\n}\n\nvoid QtnPropertyQStringListComboBoxHandler::updateValue()\n{\n\tif (!editor().isEditable() || canApply())\n\t{\n\t\tproperty().setValue(toSingleLine(newValue), delegate()->editReason());\n\t}\n\n\tapplyReset();\n}\n\nQtnPropertyQStringFileLineEditBttnHandler::\n\tQtnPropertyQStringFileLineEditBttnHandler(\n\t\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n\t, dialog(new QFileDialog(&editor))\n{\n\tdialogContainer = connectDialog(dialog);\n\n\tupdateEditor();\n\n\teditor.lineEdit->installEventFilter(this);\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQStringFileLineEditBttnHandler::onToolButtonClicked);\n\tQObject::connect(editor.lineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQStringFileLineEditBttnHandler::onEditingFinished);\n}\n\nvoid QtnPropertyQStringFileLineEditBttnHandler::applyAttributes(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tint option = 0;\n\n\tif (info.loadAttribute(qtnAcceptModeAttr(), option))\n\t\tdialog->setAcceptMode(QFileDialog::AcceptMode(option));\n\n\tQString str;\n\n\tif (info.loadAttribute(qtnDefaultSuffixAttr(), str))\n\t\tdialog->setDefaultSuffix(str);\n\n\tif (info.loadAttribute(qtnDefaultDirAttr(), str))\n\t\tdefaultDirectory = str;\n\n\tif (info.loadAttribute(qtnFileModeAttr(), option))\n\t\tdialog->setFileMode(QFileDialog::FileMode(option));\n\n\tif (info.loadAttribute(qtnOptionsAttr(), option))\n\t\tdialog->setOptions(QFileDialog::Options(QFlag(option)));\n\n\tif (info.loadAttribute(qtnViewModeAttr(), option))\n\t\tdialog->setViewMode(QFileDialog::ViewMode(option));\n\n\tif (info.loadAttribute(qtnFileNameFilterAttr(), str))\n\t\tdialog->setNameFilter(str);\n\n\tQStringList list;\n\n\tif (info.loadAttribute(qtnFileNameFiltersAttr(), list))\n\t\tdialog->setNameFilters(list);\n}\n\nvoid QtnPropertyQStringFileLineEditBttnHandler::onToolButtonClick()\n{\n\tonToolButtonClicked(false);\n}\n\nvoid QtnPropertyQStringFileLineEditBttnHandler::updateEditor()\n{\n\tbool editable = stateProperty()->isEditableByUser();\n\teditor().lineEdit->setReadOnly(!editable);\n\teditor().toolButton->setEnabled(editable);\n\n\tauto path = QDir::toNativeSeparators(property().value());\n\teditor().setTextForProperty(stateProperty(), path);\n\n\tif (!stateProperty()->isMultiValue())\n\t{\n\t\tauto edit = editor().lineEdit;\n\t\tedit->setPlaceholderText(\n\t\t\tQtnPropertyQString::getPlaceholderStr(edit->text(), false));\n\n\t\tedit->selectAll();\n\t}\n}\n\nvoid QtnPropertyQStringFileLineEditBttnHandler::onToolButtonClicked(bool)\n{\n\tauto property = &this->property();\n\tvolatile bool destroyed = false;\n\tauto connection = QObject::connect(property, &QObject::destroyed,\n\t\t[&destroyed]() mutable { destroyed = true; });\n\treverted = true;\n\tauto dialogContainer = this->dialogContainer;\n\tQString filePath = property->value();\n\tQString dirPath = this->defaultDirectory;\n\tQFileInfo fileInfo(filePath);\n\n\tif (!filePath.isEmpty())\n\t{\n\t\tfilePath = QDir(dirPath).filePath(filePath);\n\t\tfileInfo.setFile(filePath);\n\t\tdirPath = fileInfo.path();\n\t}\n\n\tdialog->setDirectory(dirPath);\n\tdialog->selectFile(filePath);\n\n\tif (dialog->exec() == QDialog::Accepted && !destroyed)\n\t{\n\t\tQStringList files = dialog->selectedFiles();\n\n\t\tif (files.size() == 1)\n\t\t\tproperty->setValue(QDir::toNativeSeparators(files.first()),\n\t\t\t\tdelegate()->editReason());\n\t}\n\n\tif (!destroyed)\n\t\tQObject::disconnect(connection);\n\n\tQ_UNUSED(dialogContainer);\n}\n\nvoid QtnPropertyQStringFileLineEditBttnHandler::onEditingFinished()\n{\n\tif (canApply())\n\t{\n\t\tproperty().setValue(\n\t\t\teditor().lineEdit->text(), delegate()->editReason());\n\t}\n\n\tapplyReset();\n}\n\nQtnPropertyQStringMultilineEditBttnHandler::\n\tQtnPropertyQStringMultilineEditBttnHandler(QtnPropertyDelegate *delegate,\n\t\tQtnLineEditBttn &editor, const QString &placeholder)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n\t, dialog(new MultilineTextDialog(&editor))\n\t, multiline(false)\n\t, placeholder(placeholder)\n{\n\tdialogContainer = connectDialog(dialog);\n\tupdateEditor();\n\n\teditor.lineEdit->installEventFilter(this);\n\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQStringMultilineEditBttnHandler::onToolButtonClicked);\n\n\tQObject::connect(editor.lineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQStringMultilineEditBttnHandler::onEditingFinished);\n}\n\nvoid QtnPropertyQStringMultilineEditBttnHandler::updateEditor()\n{\n\tauto edit = editor().lineEdit;\n\tedit->setReadOnly(!stateProperty()->isEditableByUser());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tedit->clear();\n\t\tedit->setPlaceholderText(QtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\tauto text = property().value();\n\n\t\tif (QtnPropertyQString::isMultilineText(text))\n\t\t{\n\t\t\tmultiline = true;\n\t\t\tedit->setText(QString());\n\t\t} else\n\t\t{\n\t\t\tmultiline = false;\n\t\t\tedit->setText(text);\n\t\t}\n\n\t\tif (text.isEmpty() && !placeholder.isEmpty())\n\t\t{\n\t\t\tedit->setPlaceholderText(placeholder);\n\t\t} else\n\t\t{\n\t\t\tedit->setPlaceholderText(\n\t\t\t\tQtnPropertyQString::getPlaceholderStr(text, true));\n\t\t}\n\t\tedit->selectAll();\n\t}\n}\n\nvoid QtnPropertyQStringMultilineEditBttnHandler::revertInput()\n{\n\treverted = true;\n}\n\nvoid QtnPropertyQStringMultilineEditBttnHandler::onToolButtonClick()\n{\n\tonToolButtonClicked(false);\n}\n\nvoid QtnPropertyQStringMultilineEditBttnHandler::onEditingFinished()\n{\n\tif (canApply())\n\t{\n\t\tauto text = editor().lineEdit->text();\n\n\t\tif (!multiline || !text.isEmpty())\n\t\t{\n\t\t\tproperty().setValue(text, delegate()->editReason());\n\t\t\tupdateEditor();\n\t\t}\n\t}\n\n\tapplyReset();\n}\n\nvoid QtnPropertyQStringMultilineEditBttnHandler::onToolButtonClicked(bool)\n{\n\tauto text = editor().lineEdit->text();\n\n\tauto property = &this->property();\n\n\tif (text.isEmpty() && multiline)\n\t{\n\t\ttext = property->value();\n\t}\n\n\treverted = true;\n\tbool readonly = !stateProperty()->isEditableByUser();\n\tauto dialogContainer = this->dialogContainer;\n\tdialog->setReadOnly(readonly);\n\n\tif (readonly)\n\t{\n\t\tdialog->setWindowTitle(\n\t\t\tQtnPropertyQString::getReadOnlyPropertyTitleFormat().arg(\n\t\t\t\tproperty->displayName()));\n\t} else\n\t{\n\t\tdialog->setWindowTitle(property->displayName());\n\t}\n\n\tdialog->setText(text);\n\tdialog->show();\n\tdialog->raise();\n\tvolatile bool destroyed = false;\n\tauto connection = QObject::connect(this, &QObject::destroyed,\n\t\t[&destroyed]() mutable { destroyed = true; });\n\n\tif (dialog->exec() == QDialog::Accepted && !destroyed)\n\t\tproperty->setValue(dialog->getText(), delegate()->editReason());\n\n\tif (!destroyed)\n\t{\n\t\tQObject::disconnect(connection);\n\t\tupdateEditor();\n\t}\n\n\tQ_UNUSED(dialogContainer);\n}\n\nQtnPropertyQStringLineEditHandler::QtnPropertyQStringLineEditHandler(\n\tQtnPropertyDelegate *delegate, QLineEdit &editor,\n\tconst QString &placeholder)\n\t: QtnPropertyEditorHandler(delegate, editor)\n\t, placeholder(placeholder)\n{\n\tupdateEditor();\n\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQStringLineEditHandler::updateValue);\n}\n\nvoid QtnPropertyQStringLineEditHandler::updateEditor()\n{\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().clear();\n\t\teditor().setPlaceholderText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\tauto text = property().value();\n\t\teditor().setText(text);\n\t\teditor().setPlaceholderText(text.isEmpty() && !placeholder.isEmpty()\n\t\t\t\t? placeholder\n\t\t\t\t: QtnPropertyQString::getPlaceholderStr(text, false));\n\t\teditor().selectAll();\n\t}\n}\n\nvoid QtnPropertyQStringLineEditHandler::updateValue()\n{\n\tif (canApply())\n\t{\n\t\tproperty().setValue(\n\t\t\ttoSingleLine(editor().text()), delegate()->editReason());\n\t}\n\n\tapplyReset();\n}\n\nclass QtnPropertyQStringCandidatesComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyQStringBase, QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQStringCandidatesComboBoxHandler(\n\t\tQtnPropertyDelegateQStringCallback *delegate,\n\t\tQtnCompleterLineEdit *lineEdit, QtnLineEditBttn &editor,\n\t\tconst QString &placeholder);\n\n\tvoid shouldFinishEdit();\n\nprivate:\n\tvoid updateCandidates();\n\tvoid updatePlaceholder(const QString &text);\n\n\tvirtual bool canApply() const override;\n\tvirtual void updateEditor() override;\n\tvirtual void revertInput() override;\n\tvirtual bool eventFilter(QObject *watched, QEvent *event) override;\n\n\tvoid onItemActivated();\n\n\tbool createNewCandidate(QString candidate);\n\n\tvoid onEditingFinished();\n\tvoid onToolButtonClicked();\n\n\tvoid connectLineEdit();\n\tvoid disconnectLineEdit();\n\nprivate:\n\tQtnGetCandidatesFn m_getCandidatesFn;\n\tQtnCreateCandidateFn m_createCandidateFn;\n\tQtnCompleterLineEdit *mLineEdit;\n\n\tQStringList m_candidates;\n\tQString m_placeholder;\n};\n\nQtnPropertyDelegateQStringCallback::QtnPropertyDelegateQStringCallback(\n\tQtnPropertyQStringBase &owner)\n\t: QtnPropertyDelegateQString(owner)\n{\n}\n\nvoid QtnPropertyDelegateQStringCallback::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyQStringBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQStringCallback,\n\t\t\tQtnPropertyQStringBase>,\n\t\tqtnCallbackDelegate());\n}\n\nvoid QtnPropertyDelegateQStringCallback::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tm_editorAttributes = info;\n}\n\nQWidget *QtnPropertyDelegateQStringCallback::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto lineEdit = new QtnCompleterLineEdit;\n\tauto editor = new QtnLineEditBttn(parent, QStringLiteral(\"*\"), lineEdit);\n\teditor->setGeometry(rect);\n\teditor->lineEdit->setPlaceholderText(m_placeholder);\n\n\tnew QtnPropertyQStringCandidatesComboBoxHandler(\n\t\tthis, lineEdit, *editor, m_placeholder);\n\n\tqtnInitLineEdit(lineEdit, inplaceInfo);\n\n\treturn editor;\n}\n\nQtnPropertyQStringCandidatesComboBoxHandler::\n\tQtnPropertyQStringCandidatesComboBoxHandler(\n\t\tQtnPropertyDelegateQStringCallback *delegate,\n\t\tQtnCompleterLineEdit *lineEdit, QtnLineEditBttn &editor,\n\t\tconst QString &placeholder)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t, mLineEdit(lineEdit)\n\t, m_placeholder(placeholder)\n{\n\tauto model = new QStringListModel(&editor);\n\tauto completer = lineEdit->completer();\n\tQ_ASSERT(completer);\n\tlineEdit->setCompleterModel(model);\n\n\tauto &attributes = delegate->m_editorAttributes;\n\teditor.toolButton->setIcon(\n\t\tattributes.getAttribute<QIcon>(qtnCreateCandidateIconAttr()));\n\n\tauto text = attributes.getAttribute<QString>(qtnCreateCandidateIconAttr());\n\n\tif (!text.isEmpty())\n\t{\n\t\teditor.toolButton->setText(text);\n\t}\n\n\teditor.toolButton->setToolTip(\n\t\tattributes.getAttribute<QString>(qtnCreateCandidateToolTipAttr()));\n\n\tattributes.loadAttribute(qtnCreateCandidateFnAttr(), m_createCandidateFn);\n\tattributes.loadAttribute(qtnGetCandidatesFnAttr(), m_getCandidatesFn);\n\n\tupdateCandidates();\n\tQtnPropertyQStringCandidatesComboBoxHandler::updateEditor();\n\n\tmLineEdit->installEventFilter(this);\n\tcompleter->popup()->installEventFilter(this);\n\tcompleter->popup()->viewport()->installEventFilter(this);\n\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::onToolButtonClicked);\n\n\tconnectLineEdit();\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::updateCandidates()\n{\n\tupdating++;\n\n\tif (m_getCandidatesFn)\n\t\tm_candidates = m_getCandidatesFn();\n\n\tauto completer = editor().lineEdit->completer();\n\tQ_ASSERT(completer);\n\tQ_ASSERT(qobject_cast<QStringListModel *>(completer->model()));\n\tauto model = static_cast<QStringListModel *>(completer->model());\n\tmodel->setStringList(m_candidates);\n\n\tupdating--;\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::updatePlaceholder(\n\tconst QString &text)\n{\n\tQString placeholderStr;\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tplaceholderStr = QtnMultiProperty::getMultiValuePlaceholder();\n\t} else if (text.isEmpty())\n\t{\n\t\tif (m_placeholder.isEmpty())\n\t\t{\n\t\t\tplaceholderStr = QtnPropertyQString::getEmptyPlaceholderStr();\n\t\t} else\n\t\t{\n\t\t\tplaceholderStr = m_placeholder;\n\t\t}\n\t} else\n\t{\n\t\tplaceholderStr = QtnPropertyQString::getPlaceholderStr(text, false);\n\t}\n\teditor().lineEdit->setPlaceholderText(placeholderStr);\n}\n\nbool QtnPropertyQStringCandidatesComboBoxHandler::canApply() const\n{\n\treturn !reverted && returned && stateProperty() &&\n\t\tstateProperty()->isEditableByUser();\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\tbool enabled = stateProperty()->isEditableByUser();\n\n\tmLineEdit->setReadOnly(!enabled);\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tmLineEdit->clear();\n\t} else\n\t{\n\t\tmLineEdit->setText(property());\n\t}\n\n\tupdatePlaceholder(mLineEdit->text());\n\n\tQMetaObject::invokeMethod(mLineEdit, \"complete\", Qt::QueuedConnection);\n\tmLineEdit->selectAll();\n\n\tupdating--;\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::shouldFinishEdit()\n{\n\tQMetaObject::invokeMethod(\n\t\tmLineEdit, \"editingFinished\", Qt::QueuedConnection);\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::revertInput()\n{\n\tif (updating)\n\t\treturn;\n\treverted = true;\n\tshouldFinishEdit();\n}\n\nbool QtnPropertyQStringCandidatesComboBoxHandler::eventFilter(\n\tQObject *watched, QEvent *event)\n{\n\tswitch (event->type())\n\t{\n\t\tcase QEvent::MouseButtonPress:\n\t\tcase QEvent::MouseButtonRelease:\n\t\tcase QEvent::MouseMove:\n\t\tcase QEvent::MouseButtonDblClick:\n\t\t{\n\t\t\tauto me = static_cast<QMouseEvent *>(event);\n\t\t\tauto toolButton = editor().toolButton;\n\t\t\tauto localPos = toolButton->mapFromGlobal(me->globalPos());\n\t\t\tif (toolButton->rect().contains(localPos))\n\t\t\t{\n\t\t\t\tQObject *toolButtonObject = toolButton;\n\t\t\t\tQMouseEvent buttonEvent(event->type(), localPos,\n\t\t\t\t\tme->windowPos(), me->globalPos(), me->button(),\n\t\t\t\t\tme->buttons(), me->modifiers(), me->source());\n\t\t\t\ttoolButtonObject->event(&buttonEvent);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn QObject::eventFilter(watched, event);\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::onItemActivated()\n{\n\tif (updating)\n\t\treturn;\n\n\treturned = true;\n\tshouldFinishEdit();\n}\n\nbool QtnPropertyQStringCandidatesComboBoxHandler::createNewCandidate(\n\tQString candidate)\n{\n\tif (!m_createCandidateFn || updating)\n\t\treturn false;\n\n\tqtnRetainInplaceEditor();\n\tupdating++;\n\n\tcandidate = m_createCandidateFn(&editor(), candidate);\n\n\tupdating--;\n\tif (!candidate.isEmpty())\n\t{\n\t\tonValueChanged(candidate);\n\t\tupdateCandidates();\n\t}\n\n\tqtnReleaseInplaceEditor();\n\treturn !candidate.isEmpty();\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::onEditingFinished()\n{\n\tif (updating)\n\t\treturn;\n\n\tdisconnectLineEdit();\n\tif (canApply())\n\t{\n\t\tauto text = toSingleLine(mLineEdit->text());\n\n\t\tif (!m_createCandidateFn || text.isEmpty() ||\n\t\t\tm_candidates.contains(text, Qt::CaseInsensitive))\n\t\t{\n\t\t\tproperty().setValue(text, delegate()->editReason());\n\t\t} else\n\t\t{\n\t\t\tif (!createNewCandidate(text))\n\t\t\t{\n\t\t\t\tapplyReset();\n\t\t\t\tconnectLineEdit();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tapplyReset();\n\tqtnStopInplaceEdit();\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::onToolButtonClicked()\n{\n\tcreateNewCandidate(mLineEdit->text());\n\tapplyReset();\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::connectLineEdit()\n{\n\tQObject::connect(mLineEdit, &QLineEdit::textChanged, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::updatePlaceholder);\n\tQObject::connect(mLineEdit, &QtnCompleterLineEdit::returnPressed, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::onItemActivated);\n\tQObject::connect(mLineEdit, &QtnCompleterLineEdit::escaped, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::revertInput);\n\tQObject::connect(mLineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::onEditingFinished,\n\t\tQt::QueuedConnection);\n\tQObject::connect(mLineEdit->completer(),\n\t\tstatic_cast<void (QCompleter::*)(const QModelIndex &)>(\n\t\t\t&QCompleter::activated),\n\t\tthis, &QtnPropertyQStringCandidatesComboBoxHandler::onItemActivated);\n}\n\nvoid QtnPropertyQStringCandidatesComboBoxHandler::disconnectLineEdit()\n{\n\tQObject::disconnect(mLineEdit, &QtnCompleterLineEdit::returnPressed, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::onItemActivated);\n\tQObject::disconnect(mLineEdit, &QtnCompleterLineEdit::escaped, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::revertInput);\n\tQObject::disconnect(mLineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQStringCandidatesComboBoxHandler::onEditingFinished);\n\tQObject::disconnect(mLineEdit->completer(),\n\t\tstatic_cast<void (QCompleter::*)(const QModelIndex &)>(\n\t\t\t&QCompleter::activated),\n\t\tthis, &QtnPropertyQStringCandidatesComboBoxHandler::onItemActivated);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateQString.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2019 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QSTRING_H\n#define PROPERTY_DELEGATE_QSTRING_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQString.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQString\n\t: public QtnPropertyDelegateTyped<QtnPropertyQStringBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQString)\n\n\ttypedef QtnPropertyDelegateTyped<QtnPropertyQStringBase> Inherited;\n\npublic:\n\tQtnPropertyDelegateQString(QtnPropertyQStringBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\n\tvirtual bool isPlaceholderColor() const override;\n\nprotected:\n\tint m_maxLength;\n\tbool m_multiline;\n\tQString m_placeholder;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQStringInvalidBase\n\t: public QtnPropertyDelegateQString\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQStringInvalidBase)\n\nprotected:\n\tQtnPropertyDelegateQStringInvalidBase(QtnPropertyQStringBase &owner);\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\tvirtual void drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\n\tvirtual bool isPropertyValid() const = 0;\n\nprivate:\n\tQColor m_invalidColor;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQStringFile\n\t: public QtnPropertyDelegateQStringInvalidBase\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQStringFile)\n\npublic:\n\tQtnPropertyDelegateQStringFile(QtnPropertyQStringBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\tvirtual bool toolTipImpl(QString &strValue) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool isPropertyValid() const override;\n\tQString defaultDirectory() const;\n\tQString absoluteFilePath() const;\n\tQString relativeFilePath() const;\n\tbool shouldShowRelativePath() const;\n\nprivate:\n\tQtnPropertyDelegateInfo m_editorAttributes;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQStringList\n\t: public QtnPropertyDelegateQString\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQStringList)\n\npublic:\n\tQtnPropertyDelegateQStringList(QtnPropertyQStringBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\nprivate:\n\tQtnPropertyDelegateInfo m_editorAttributes;\n};\n\nusing QtnGetCandidatesFn = std::function<QStringList()>;\nusing QtnCreateCandidateFn = std::function<QString(QWidget *, QString)>;\nQ_DECLARE_METATYPE(QtnGetCandidatesFn);\nQ_DECLARE_METATYPE(QtnCreateCandidateFn);\n\nclass QtnPropertyQStringCandidatesComboBoxHandler;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQStringCallback\n\t: public QtnPropertyDelegateQString\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQStringCallback)\n\npublic:\n\tQtnPropertyDelegateQStringCallback(QtnPropertyQStringBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\nprivate:\n\tQtnPropertyDelegateInfo m_editorAttributes;\n\tfriend class QtnPropertyQStringCandidatesComboBoxHandler;\n};\n\n#endif // PROPERTY_DELEGATE_QSTRING_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateUInt.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateUInt.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Utils/QtnInt64SpinBox.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QCoreApplication>\n#include <QLocale>\n\nclass QtnPropertyUIntSpinBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyUIntBase, QtnInt64SpinBox>\n{\npublic:\n\tQtnPropertyUIntSpinBoxHandler(\n\t\tQtnPropertyDelegateUInt *delegate, QtnInt64SpinBox &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvoid onValueChanged(qint64 value);\n\nprivate:\n\tQtnPropertyDelegateUInt *m_delegate;\n};\n\nQtnPropertyDelegateUInt::QtnPropertyDelegateUInt(QtnPropertyUIntBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyUIntBase>(owner)\n{\n}\n\nvoid QtnPropertyDelegateUInt::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyUIntBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateUInt, QtnPropertyUIntBase>,\n\t\tqtnSpinBoxDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyUIntBase::staticMetaObject,\n\t\t&qtnCreateDelegate<\n\t\t\tQtnPropertyDelegateSlideBoxTyped<QtnPropertyUIntBase>,\n\t\t\tQtnPropertyUIntBase>,\n\t\tqtnSliderBoxDelegate());\n}\n\nuint QtnPropertyDelegateUInt::stepValue() const\n{\n\treturn m_step.isValid() ? m_step.toUInt() : owner().stepValue();\n}\n\nuint QtnPropertyDelegateUInt::minValue() const\n{\n\treturn m_min.isValid() ? m_min.toUInt() : owner().minValue();\n}\n\nuint QtnPropertyDelegateUInt::maxValue() const\n{\n\treturn m_max.isValid() ? m_max.toUInt() : owner().maxValue();\n}\n\nuint QtnPropertyDelegateUInt::currentValue() const\n{\n\treturn qBound(minValue(), owner().value(), maxValue());\n}\n\nQWidget *QtnPropertyDelegateUInt::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto spinBox = new QtnInt64SpinBox(parent);\n\tspinBox->setSuffix(m_suffix);\n\tspinBox->setGeometry(rect);\n\n\tnew QtnPropertyUIntSpinBoxHandler(this, *spinBox);\n\n\tspinBox->selectAll();\n\n\tif (stateProperty()->isEditableByUser())\n\t\tqtnInitNumEdit(spinBox, inplaceInfo, NUM_UNSIGNED_INT);\n\n\treturn spinBox;\n}\n\nbool QtnPropertyDelegateUInt::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<\n\t\t\tQtnPropertyUIntBase>::acceptKeyPressedForInplaceEditImpl(keyEvent))\n\t\treturn true;\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_UNSIGNED_INT);\n}\n\nvoid QtnPropertyDelegateUInt::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\tm_step = info.attributes.value(qtnStepAttr());\n\tif (m_step.isValid())\n\t{\n\t\tbool ok;\n\t\tuint step = m_step.toUInt(&ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tm_step = QVariant();\n\t\t} else\n\t\t{\n\t\t\tm_step = step;\n\t\t}\n\t}\n\tfixMinMaxVariant<uint>(m_min, m_max);\n}\n\nbool QtnPropertyDelegateUInt::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QLocale().toString(currentValue());\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nQtnPropertyUIntSpinBoxHandler::QtnPropertyUIntSpinBoxHandler(\n\tQtnPropertyDelegateUInt *delegate, QtnInt64SpinBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t, m_delegate(delegate)\n{\n\tupdateEditor();\n\n\teditor.setKeyboardTracking(false);\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QtnInt64SpinBox::*)(qint64)>(\n\t\t\t&QtnInt64SpinBox::valueChanged),\n\t\tthis, &QtnPropertyUIntSpinBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyUIntSpinBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\teditor().setSingleStep(m_delegate->stepValue());\n\teditor().setRange(m_delegate->minValue(), m_delegate->maxValue());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().setValue(editor().minimum());\n\t\teditor().setSpecialValueText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setValue(m_delegate->currentValue());\n\t\teditor().setSpecialValueText(QString());\n\t}\n\n\teditor().selectAll();\n\n\tupdating--;\n}\n\nvoid QtnPropertyUIntSpinBoxHandler::onValueChanged(qint64 value)\n{\n\tQtnPropertyEditorHandlerVT::onValueChanged(ValueTypeStore(value));\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Core/PropertyDelegateUInt.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_UINT_H\n#define PROPERTY_DELEGATE_UINT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyUInt.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateUInt\n\t: public QtnPropertyDelegateTyped<QtnPropertyUIntBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateUInt)\n\n\tQString m_suffix;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQVariant m_step;\n\npublic:\n\tQtnPropertyDelegateUInt(QtnPropertyUIntBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tuint stepValue() const;\n\tuint minValue() const;\n\tuint maxValue() const;\n\tuint currentValue() const;\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_UINT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateButton.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateButton.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/PropertyView.h\"\n#include \"QtnProperty/GUI/PropertyButton.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QStyleOptionButton>\n#include <QKeyEvent>\n\nQByteArray qtnLinkDelegateName()\n{\n\treturn QByteArrayLiteral(\"Link\");\n}\n\nQByteArray qtnTitleAttr()\n{\n\treturn QByteArrayLiteral(\"title\");\n}\n\nvoid QtnPropertyDelegateButton::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyButton::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateButton, QtnPropertyButton>,\n\t\t\"Button\");\n}\n\nvoid QtnPropertyDelegateButtonLink::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyButton::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateButtonLink, QtnPropertyButton>,\n\t\tqtnLinkDelegateName());\n}\n\nQtnPropertyDelegateButton::QtnPropertyDelegateButton(QtnPropertyButton &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyButton, QtnPropertyDelegate>(owner)\n{\n\tm_title = owner.displayName();\n}\n\nvoid QtnPropertyDelegateButton::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnTitleAttr(), m_title);\n}\n\nvoid QtnPropertyDelegateButton::createSubItemsImpl(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem buttonItem(context.rect);\n\tbuttonItem.trackState();\n\tbuttonItem.setPropertyDescriptionAsTooltip(owner());\n\n\tbuttonItem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t const QtnSubItem &item) {\n\n\t\tauto style = context.style();\n\n\t\tQStyleOptionButton option;\n\t\tcontext.initStyleOption(option);\n\n\t\toption.state = state(context.isActive, item);\n\t\tif (0 == (option.state & QStyle::State_Sunken))\n\t\t{\n\t\t\toption.state |= QStyle::State_Raised;\n\t\t}\n#ifdef Q_OS_MAC\n\t\toption.state &= ~QStyle::State_MouseOver;\n\t\toption.features = QStyleOptionButton::Flat;\n#endif\n\n\t\t// dont initialize styleObject from widget for QWindowsVistaStyle\n\t\t// this disables buggous animations\n\t\tif (style->inherits(\"QWindowsVistaStyle\"))\n\t\t\toption.styleObject = nullptr;\n\n\t\toption.rect = item.rect;\n\t\toption.text = m_title;\n\n\t\towner().invokePreDrawButton(&option);\n\n\t\t// draw button\n\t\tstyle->drawControl(\n\t\t\tQStyle::CE_PushButton, &option, context.painter, context.widget);\n\t};\n\n\tbuttonItem.eventHandler = [this](QtnEventContext &context,\n\t\t\t\t\t\t\t\t  const QtnSubItem &,\n\t\t\t\t\t\t\t\t  QtnPropertyToEdit *) -> bool {\n\t\tbool doClick = false;\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QtnSubItemEvent::ReleaseMouse:\n\t\t\t\tdoClick = true;\n\t\t\t\tbreak;\n\n\t\t\tcase QEvent::KeyPress:\n\t\t\t\tint key = context.eventAs<QKeyEvent>()->key();\n\t\t\t\tdoClick = (key == Qt::Key_Space) || (key == Qt::Key_Return);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (doClick)\n\t\t{\n\t\t\towner().invokeClick();\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tsubItems.append(buttonItem);\n}\n\nQtnPropertyDelegateButtonLink::QtnPropertyDelegateButtonLink(\n\tQtnPropertyButton &owner)\n\t: QtnPropertyDelegateButton(owner)\n{\n}\n\nvoid QtnPropertyDelegateButtonLink::createSubItemsImpl(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem linkItem(context.rect.marginsRemoved(context.margins));\n\tlinkItem.rect.setWidth(context.painter->fontMetrics().width(m_title));\n\tlinkItem.setPropertyDescriptionAsTooltip(owner());\n\tlinkItem.trackState();\n\n\tlinkItem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\n\t\tcontext.painter->save();\n\n\t\tQColor linkColor = context.palette().color(context.colorGroup(),\n\t\t\tcontext.isActive ? QPalette::HighlightedText : QPalette::Link);\n\t\tswitch (item.state())\n\t\t{\n\t\t\tcase QtnSubItemStateUnderCursor:\n\t\t\t{\n\t\t\t\tauto font = context.painter->font();\n\t\t\t\tfont.setUnderline(true);\n\t\t\t\tcontext.painter->setFont(font);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QtnSubItemStatePushed:\n\t\t\t{\n\t\t\t\tauto font = context.painter->font();\n\t\t\t\tfont.setUnderline(true);\n\t\t\t\tcontext.painter->setFont(font);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (context.isActive)\n\t\t{\n\t\t\tcontext.painter->fillRect(\n\t\t\t\tcontext.rect, context.palette().color(QPalette::Highlight));\n\t\t}\n\n\t\tcontext.painter->setPen(linkColor);\n\n\t\tcontext.painter->drawText(\n\t\t\titem.rect, Qt::AlignLeading | Qt::AlignVCenter, m_title);\n\n\t\tcontext.painter->restore();\n\t};\n\n\tlinkItem.eventHandler = [this](QtnEventContext &context, const QtnSubItem &,\n\t\t\t\t\t\t\t\tQtnPropertyToEdit *) -> bool {\n\t\tbool doClick = false;\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QEvent::KeyPress:\n\t\t\t{\n\t\t\t\tint key = context.eventAs<QKeyEvent>()->key();\n\t\t\t\tdoClick = (key == Qt::Key_Space) || (key == Qt::Key_Return);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QtnSubItemEvent::Activated:\n\t\t\t{\n\t\t\t\tm_widgetCursor = context.widget->cursor();\n\t\t\t\tcontext.widget->setCursor(Qt::PointingHandCursor);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QtnSubItemEvent::Deactivated:\n\t\t\t{\n\t\t\t\tcontext.widget->setCursor(m_widgetCursor);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QtnSubItemEvent::ReleaseMouse:\n\t\t\t{\n\t\t\t\tdoClick = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (doClick)\n\t\t{\n\t\t\towner().invokeClick();\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tsubItems.append(linkItem);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateButton.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_BUTTON_H\n#define PROPERTY_DELEGATE_BUTTON_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyButton.h\"\n\nclass QtnPropertyButton;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateButton\n\t: public QtnPropertyDelegateTyped<QtnPropertyButton, QtnPropertyDelegate>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateButton)\n\npublic:\n\tQtnPropertyDelegateButton(QtnPropertyButton &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvoid applyAttributesImpl(const QtnPropertyDelegateInfo &info) override;\n\tvoid createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) override;\n\n\tQString m_title;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateButtonLink\n\t: public QtnPropertyDelegateButton\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateButtonLink)\n\npublic:\n\tQtnPropertyDelegateButtonLink(QtnPropertyButton &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvoid createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) override;\n\nprivate:\n\tQCursor m_widgetCursor;\n};\n\n#endif // PROPERTY_DELEGATE_BUTTON_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQBrush.cpp",
    "content": "\n/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQBrush.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QComboBox>\n#include <QStyledItemDelegate>\n#include <QPaintEvent>\n\nQByteArray qtnShowAllAttr()\n{\n\treturn QByteArrayLiteral(\"showAll\");\n}\n\nvoid QtnPropertyDelegateQBrushStyle::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(\n\t\t&QtnPropertyQBrushStyleBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQBrushStyle,\n\t\t\tQtnPropertyQBrushStyleBase>,\n\t\tqtnComboBoxDelegate());\n}\n\nstatic void drawBrushStyle(\n\tQStyle *style, QPainter &painter, QRect rect, Qt::BrushStyle brushStyle)\n{\n\tswitch (brushStyle)\n\t{\n\t\tcase Qt::NoBrush:\n\t\tcase Qt::LinearGradientPattern:\n\t\tcase Qt::RadialGradientPattern:\n\t\tcase Qt::ConicalGradientPattern:\n\t\tcase Qt::TexturePattern:\n\t\t{\n\t\t\tQString str;\n\t\t\tQtnPropertyQBrushStyle::translateBrushStyle(brushStyle, str);\n\t\t\tqtnDrawValueText(str, painter, rect, style);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t{\n\t\t\trect.adjust(2, 2, -2, -2);\n\t\t\tauto brush = painter.brush();\n\t\t\tbrush.setStyle(brushStyle);\n\t\t\tauto oldBrush = painter.brush();\n\t\t\tpainter.setBrush(brush);\n\t\t\tpainter.drawRect(rect);\n\t\t\tpainter.setBrush(oldBrush);\n\t\t}\n\t}\n}\n\nclass QtnPropertyBrushStyleItemDelegate : public QStyledItemDelegate\n{\n\tQComboBox *m_owner;\n\npublic:\n\tQtnPropertyBrushStyleItemDelegate(QComboBox *owner);\n\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n};\n\nclass QtnPropertyBrushStyleComboBox : public QtnPropertyComboBox\n{\npublic:\n\texplicit QtnPropertyBrushStyleComboBox(\n\t\tQtnPropertyDelegate *delegate, QWidget *parent = Q_NULLPTR);\n\nprotected:\n\tvirtual void customPaint(QPainter &painter, const QRect &rect) override;\n};\n\nclass QtnPropertyBrushStyleComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyQBrushStyleBase, QComboBox>\n{\npublic:\n\tQtnPropertyBrushStyleComboBoxHandler(\n\t\tQtnPropertyDelegate *delegate, QComboBox &editor);\n\nprivate:\n\tvoid updateEditor() override;\n\n\tvoid onCurrentIndexChanged(int index);\n};\n\nQtnPropertyDelegateQBrushStyle::QtnPropertyDelegateQBrushStyle(\n\tQtnPropertyQBrushStyleBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyQBrushStyleBase>(owner)\n\t, m_showAll(false)\n{\n}\n\nvoid QtnPropertyDelegateQBrushStyle::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnShowAllAttr(), m_showAll);\n}\n\nvoid QtnPropertyDelegateQBrushStyle::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tQtnPropertyDelegateTyped::drawValueImpl(painter, rect);\n\t} else\n\t{\n\t\tauto value = owner().value();\n\t\tdrawBrushStyle(painter.style(), painter, rect, value);\n\t}\n}\n\nQWidget *QtnPropertyDelegateQBrushStyle::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tif (stateProperty()->isEditableByUser())\n\t{\n\t\tQComboBox *combo = new QtnPropertyBrushStyleComboBox(this, parent);\n\t\tcombo->setLineEdit(nullptr);\n\t\tcombo->setItemDelegate(new QtnPropertyBrushStyleItemDelegate(combo));\n\t\tif (m_showAll)\n\t\t{\n\t\t\tfor (auto bs = Qt::NoBrush; bs <= Qt::ConicalGradientPattern;\n\t\t\t\t bs = Qt::BrushStyle(bs + 1))\n\t\t\t{\n\t\t\t\tcombo->addItem(QString(), QVariant::fromValue(bs));\n\t\t\t}\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::TexturePattern));\n\t\t} else\n\t\t{\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::NoBrush));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::SolidPattern));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::HorPattern));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::VerPattern));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::CrossPattern));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::BDiagPattern));\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::FDiagPattern));\n\t\t\tcombo->addItem(\n\t\t\t\tQString(), QVariant::fromValue(Qt::DiagCrossPattern));\n\t\t}\n\n\t\tcombo->setGeometry(rect);\n\n\t\tnew QtnPropertyBrushStyleComboBoxHandler(this, *combo);\n\n\t\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\t\tcombo->showPopup();\n\n\t\treturn combo;\n\t}\n\n\treturn nullptr;\n}\n\nbool QtnPropertyDelegateQBrushStyle::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\treturn QtnPropertyQBrushStyle::translateBrushStyle(\n\t\towner().value(), strValue);\n}\n\nQtnPropertyBrushStyleComboBoxHandler::QtnPropertyBrushStyleComboBoxHandler(\n\tQtnPropertyDelegate *delegate, QComboBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),\n\t\tthis, &QtnPropertyBrushStyleComboBoxHandler::onCurrentIndexChanged);\n}\n\nvoid QtnPropertyBrushStyleComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\tif (stateProperty()->isMultiValue())\n\t\teditor().setCurrentIndex(-1);\n\telse\n\t{\n\t\tint index = editor().findData(QVariant::fromValue(property().value()));\n\t\teditor().setCurrentIndex(index);\n\t}\n\n\tupdating--;\n}\n\nvoid QtnPropertyBrushStyleComboBoxHandler::onCurrentIndexChanged(int index)\n{\n\tif (index >= 0)\n\t{\n\t\tQVariant data = editor().itemData(index);\n\n\t\tif (data.canConvert<Qt::BrushStyle>())\n\t\t\tonValueChanged(data.value<Qt::BrushStyle>());\n\t}\n}\n\nQtnPropertyBrushStyleComboBox::QtnPropertyBrushStyleComboBox(\n\tQtnPropertyDelegate *delegate, QWidget *parent)\n\t: QtnPropertyComboBox(delegate, parent)\n{\n}\n\nvoid QtnPropertyBrushStyleComboBox::customPaint(\n\tQPainter &painter, const QRect &rect)\n{\n\tauto brushStyle = currentData().value<Qt::BrushStyle>();\n\tdrawBrushStyle(style(), painter, rect, brushStyle);\n}\n\nQtnPropertyBrushStyleItemDelegate::QtnPropertyBrushStyleItemDelegate(\n\tQComboBox *owner)\n\t: m_owner(owner)\n{\n}\n\nvoid QtnPropertyBrushStyleItemDelegate::paint(QPainter *painter,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\tQStyledItemDelegate::paint(painter, option, index);\n\tauto brushStyle = index.data(Qt::UserRole).value<Qt::BrushStyle>();\n\tdrawBrushStyle(m_owner->style(), *painter, option.rect, brushStyle);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQBrush.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QBRUSH_H\n#define PROPERTY_DELEGATE_QBRUSH_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyQBrush.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQBrushStyle\n\t: public QtnPropertyDelegateTyped<QtnPropertyQBrushStyleBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQBrushStyle)\n\npublic:\n\tQtnPropertyDelegateQBrushStyle(QtnPropertyQBrushStyleBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual void drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\nprivate:\n\tbool m_showAll;\n};\n\n#endif // PROPERTY_DELEGATE_QBRUSH_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQColor.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQColor.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Utils/InplaceEditing.h\"\n\n#include <QColorDialog>\n\nQByteArray qtnShapeAttr()\n{\n\treturn QByteArrayLiteral(\"shape\");\n}\n\nQByteArray qtnRgbSubItemsAttr()\n{\n\treturn QByteArrayLiteral(\"rgbSubItems\");\n}\n\nQByteArray qtnSolidDelegateName()\n{\n\treturn QByteArrayLiteral(\"Solid\");\n}\n\nQByteArray qtnSelectColorDelegateName()\n{\n\treturn QByteArrayLiteral(\"SelectColor\");\n}\n\nclass QtnPropertyQColorLineEditBttnHandler\n\t: public QtnPropertyEditorBttnHandler<QtnPropertyQColorBase,\n\t\t  QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQColorLineEditBttnHandler(\n\t\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor);\n\nprotected:\n\tvirtual void onToolButtonClick() override;\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onToolButtonClicked(bool);\n\tvoid onEditingFinished();\n};\n\nQtnPropertyDelegateQColor::QtnPropertyDelegateQColor(\n\tQtnPropertyQColorBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQColorBase>(owner)\n\t, m_shape(QtnColorDelegateShapeSquare)\n{\n}\n\nvoid QtnPropertyDelegateQColor::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQColorBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQColor, QtnPropertyQColorBase>,\n\t\tqtnSelectColorDelegateName());\n}\n\nvoid QtnPropertyDelegateQColor::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnShapeAttr(), m_shape);\n\n\tif (info.getAttribute(qtnRgbSubItemsAttr(), false))\n\t{\n\t\taddSubProperty(owner().createRedProperty());\n\t\taddSubProperty(owner().createGreenProperty());\n\t\taddSubProperty(owner().createBlueProperty());\n\t}\n}\n\nvoid QtnPropertyDelegateQColor::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tQtnPropertyDelegateTypedEx::drawValueImpl(painter, rect);\n\t\treturn;\n\t}\n\n\tQColor value = owner().value();\n\n\tQRect textRect = rect;\n\n\tif (m_shape != QtnColorDelegateShapeNone)\n\t{\n\t\tQRect colorRect = rect;\n\t\tcolorRect.setWidth(colorRect.height());\n\t\tcolorRect.adjust(2, 2, -2, -2);\n\n\t\tif (m_shape == QtnColorDelegateShapeSquare)\n\t\t{\n\t\t\tpainter.fillRect(colorRect,\n\t\t\t\tpainter.style()->standardPalette().color(\n\t\t\t\t\tstateProperty()->isEditableByUser() ? QPalette::Active\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: QPalette::Disabled,\n\t\t\t\t\tQPalette::Text));\n\t\t\tcolorRect.adjust(1, 1, -1, -1);\n\t\t\tpainter.fillRect(colorRect, value);\n\t\t} else if (m_shape == QtnColorDelegateShapeCircle)\n\t\t{\n\t\t\tauto oldBrush = painter.brush();\n\t\t\tbool oldAntiAliasing =\n\t\t\t\tpainter.testRenderHint(QPainter::Antialiasing);\n\t\t\tpainter.setRenderHint(QPainter::Antialiasing);\n\n\t\t\tpainter.setBrush(value);\n\t\t\tpainter.drawEllipse(colorRect);\n\n\t\t\tpainter.setRenderHint(QPainter::Antialiasing, oldAntiAliasing);\n\t\t\tpainter.setBrush(oldBrush);\n\t\t}\n\n\t\ttextRect.setLeft(colorRect.right() + 3);\n\t}\n\n\tif (textRect.isValid())\n\t{\n\t\tQtnPropertyDelegateTyped<QtnPropertyQColorBase>::drawValueImpl(\n\t\t\tpainter, textRect);\n\t}\n}\n\nQWidget *QtnPropertyDelegateQColor::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQtnLineEditBttn *editor = new QtnLineEditBttn(parent);\n\teditor->setGeometry(rect);\n\n\tnew QtnPropertyQColorLineEditBttnHandler(this, *editor);\n\n\tif (inplaceInfo)\n\t{\n\t\teditor->lineEdit->selectAll();\n\t}\n\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQColor::propertyValueToStrImpl(QString &strValue) const\n{\n\treturn owner().toStr(strValue);\n}\n\nQtnPropertyDelegateQColorSolid::QtnPropertyDelegateQColorSolid(\n\tQtnPropertyQColorBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyQColorBase>(owner)\n{\n}\n\nvoid QtnPropertyDelegateQColorSolid::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyQColorBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQColorSolid,\n\t\t\tQtnPropertyQColorBase>,\n\t\tqtnSolidDelegateName());\n}\n\nbool QtnPropertyDelegateQColorSolid::createSubItemValueImpl(\n\tQtnDrawContext &context, QtnSubItem &subItemValue)\n{\n\tif (!QtnPropertyDelegateTyped<\n\t\t\tQtnPropertyQColorBase>::createSubItemValueImpl(context,\n\t\t\tsubItemValue))\n\t\treturn false;\n\n\t// correct left value rect\n\tsubItemValue.rect.setLeft(context.splitPos);\n\treturn true;\n}\n\nvoid QtnPropertyDelegateQColorSolid::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tQtnPropertyDelegateTyped::drawValueImpl(painter, rect);\n\t\treturn;\n\t}\n\n\tauto boxRect = rect;\n\tboxRect.adjust(2, 2, -2, -2);\n\tpainter.fillRect(boxRect, owner());\n}\n\nQWidget *QtnPropertyDelegateQColorSolid::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQ_UNUSED(rect);\n\tQ_UNUSED(inplaceInfo);\n\n\tQColorDialog dlg(owner(), parent);\n\tif (dlg.exec() == QDialog::Accepted)\n\t{\n\t\towner().setValue(dlg.currentColor(), editReason());\n\t}\n\n\treturn nullptr;\n}\n\nQtnPropertyQColorLineEditBttnHandler::QtnPropertyQColorLineEditBttnHandler(\n\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n{\n\tif (!stateProperty()->isEditableByUser())\n\t{\n\t\teditor.lineEdit->setReadOnly(true);\n\t\teditor.toolButton->setEnabled(false);\n\t}\n\n\tQtnPropertyQColorLineEditBttnHandler::updateEditor();\n\teditor.lineEdit->installEventFilter(this);\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQColorLineEditBttnHandler::onToolButtonClicked);\n\tQObject::connect(editor.lineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQColorLineEditBttnHandler::onEditingFinished);\n}\n\nvoid QtnPropertyQColorLineEditBttnHandler::onToolButtonClick()\n{\n\tonToolButtonClicked(false);\n}\n\nvoid QtnPropertyQColorLineEditBttnHandler::updateEditor()\n{\n\tQString str;\n\tproperty().toStr(str);\n\teditor().setTextForProperty(stateProperty(), str);\n\teditor().lineEdit->selectAll();\n}\n\nvoid QtnPropertyQColorLineEditBttnHandler::onToolButtonClicked(bool)\n{\n\tauto property = &this->property();\n\tvolatile bool destroyed = false;\n\tauto connection = QObject::connect(property, &QObject::destroyed,\n\t\t[&destroyed]() mutable { destroyed = true; });\n\treverted = true;\n\tauto dialog = new QColorDialog(property->value(), editorBase());\n\tauto dialogContainer = connectDialog(dialog);\n\n\tif (dialog->exec() == QDialog::Accepted && !destroyed)\n\t{\n\t\tproperty->setValue(dialog->currentColor(), delegate()->editReason());\n\t}\n\n\tif (!destroyed)\n\t\tQObject::disconnect(connection);\n\n\tQ_UNUSED(dialogContainer);\n}\n\nvoid QtnPropertyQColorLineEditBttnHandler::onEditingFinished()\n{\n\tif (canApply())\n\t{\n\t\tproperty().fromStr(editor().lineEdit->text(), delegate()->editReason());\n\t}\n\n\tapplyReset();\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQColor.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QCOLOR_H\n#define PROPERTY_DELEGATE_QCOLOR_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyQColor.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQColor\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQColorBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQColor)\n\npublic:\n\tQtnPropertyDelegateQColor(QtnPropertyQColorBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual void drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\nprivate:\n\tquint32 m_shape;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQColorSolid\n\t: public QtnPropertyDelegateTyped<QtnPropertyQColorBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQColorSolid)\n\npublic:\n\tQtnPropertyDelegateQColorSolid(QtnPropertyQColorBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual bool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) override;\n\n\tvirtual void drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n};\n\n#endif // PROPERTY_DELEGATE_QCOLOR_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQFont.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQFont.h\"\n#include \"QtnProperty/Core/PropertyQString.h\"\n#include \"QtnProperty/Core/PropertyInt.h\"\n#include \"QtnProperty/Core/PropertyBool.h\"\n#include \"QtnProperty/Core/PropertyEnum.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/PropertySet.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QFontDialog>\n#include <QFontDatabase>\n\nQByteArray qtnSelectFontDelegate()\n{\n\treturn QByteArrayLiteral(\"SelectFont\");\n}\n\nclass QtnPropertyQFontLineEditBttnHandler\n\t: public QtnPropertyEditorBttnHandler<QtnPropertyQFontBase, QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQFontLineEditBttnHandler(\n\t\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor);\n\nprotected:\n\tvirtual void onToolButtonClick() override;\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onToolButtonClicked(bool);\n};\n\nstatic const QtnEnumInfo *styleStrategyEnum()\n{\n\tstatic QScopedPointer<QtnEnumInfo> enumInfo;\n\n\tif (nullptr == enumInfo)\n\t{\n\t\tQVector<QtnEnumValueInfo> items;\n\t\titems.append(QtnEnumValueInfo(QFont::PreferDefault, \"PreferDefault\",\n\t\t\tQtnPropertyQFont::getPreferDefaultStr()));\n\t\titems.append(QtnEnumValueInfo(QFont::NoAntialias, \"NoAntialias\",\n\t\t\tQtnPropertyQFont::getNoAntialiasStr()));\n\t\titems.append(QtnEnumValueInfo(QFont::PreferAntialias, \"PreferAntialias\",\n\t\t\tQtnPropertyQFont::getPreferAntialiasStr()));\n\t\tenumInfo.reset(new QtnEnumInfo(\"FontStyleStrategy\", items));\n\t}\n\n\treturn enumInfo.data();\n}\n\nenum\n{\n\tSizeUnitPixel,\n\tSizeUnitPoint\n};\n\nstatic const QtnEnumInfo *sizeUnitEnum()\n{\n\tstatic QScopedPointer<QtnEnumInfo> enumInfo;\n\n\tif (nullptr == enumInfo)\n\t{\n\t\tQVector<QtnEnumValueInfo> items;\n\t\titems.append(QtnEnumValueInfo(\n\t\t\tSizeUnitPixel, \"Pixel\", QtnPropertyQFont::getPixelStr()));\n\t\titems.append(QtnEnumValueInfo(\n\t\t\tSizeUnitPoint, \"Point\", QtnPropertyQFont::getPointStr()));\n\t\tenumInfo.reset(new QtnEnumInfo(\"FontSizeUnit\", items));\n\t}\n\n\treturn enumInfo.data();\n}\n\nstatic void applyFontStyle(QFont &font)\n{\n#ifdef Q_OS_MAC\n\tauto style = font.styleName();\n\n\tif (!style.isEmpty())\n\t{\n\t\tauto family = font.family();\n\t\tQFontDatabase db;\n\n\t\tfor (const auto &s : db.styles(family))\n\t\t{\n\t\t\tif (s == style)\n\t\t\t{\n\t\t\t\tfont.setBold(db.bold(family, style));\n\t\t\t\tfont.setItalic(db.italic(family, style));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n#else\n\tQ_UNUSED(font);\n#endif\n}\n\nQtnPropertyDelegateQFont::QtnPropertyDelegateQFont(QtnPropertyQFontBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQFontBase>(owner)\n{\n\tauto propertyStyle = new QtnPropertyQStringCallback;\n\tauto propertyFamily = new QtnPropertyQStringCallback;\n\taddSubProperty(propertyFamily);\n\n\tpropertyFamily->setName(QStringLiteral(\"family\"));\n\tpropertyFamily->setDisplayName(QtnPropertyQFont::getFamilyLabel());\n\tpropertyFamily->setDescription(\n\t\tQtnPropertyQFont::getFamilyDescription(owner.name()));\n\tpropertyFamily->setCallbackValueGet(\n\t\t[&owner]() -> QString { return owner.value().family(); });\n\tpropertyFamily->setCallbackValueSet([&owner, propertyStyle](QString value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setFamily(value);\n\t\tapplyFontStyle(font);\n\t\towner.setValue(font, reason);\n\n#ifdef Q_OS_MAC\n\t\tQtnPropertyDelegateInfo delegate;\n\t\tdelegate.name = qtnComboBoxDelegate();\n\t\tQFontDatabase fDB;\n\t\tdelegate.attributes[qtnItemsAttr()] =\n\t\t\tQStringList(QString()) + fDB.styles(value);\n\t\tdelegate.attributes[qtnEditableAttr()] = true;\n\t\tpropertyStyle->setDelegateInfo(delegate);\n\n\t\towner.postUpdateEvent(QtnPropertyChangeReasonChildren);\n#else\n\t\tQ_UNUSED(propertyStyle);\n#endif\n\t});\n\n\tQtnPropertyDelegateInfo delegate;\n\tdelegate.name = qtnComboBoxDelegate();\n\tQFontDatabase fDB;\n\tdelegate.attributes[qtnItemsAttr()] = fDB.families();\n\tpropertyFamily->setDelegateInfo(delegate);\n\n\tpropertyStyle->setName(QStringLiteral(\"style\"));\n\tpropertyStyle->setDisplayName(QtnPropertyQFont::getStyleLabel());\n\tpropertyStyle->setDescription(\n\t\tQtnPropertyQFont::getStyleDescription(owner.name()));\n\tpropertyStyle->setCallbackValueGet(\n\t\t[&owner]() -> QString { return owner.value().styleName(); });\n\tpropertyStyle->setCallbackValueSet([&owner](QString value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setStyleName(value);\n\t\tapplyFontStyle(font);\n\t\towner.setValue(font, reason);\n\t});\n\n#ifdef Q_OS_MAC\n\tdelegate.name = qtnComboBoxDelegate();\n\tdelegate.attributes[qtnItemsAttr()] =\n\t\tQStringList(QString()) + fDB.styles(owner.value().family());\n\tdelegate.attributes[qtnEditableAttr()] = true;\n#else\n\tdelegate.name = qtnLineEditDelegate();\n\tdelegate.attributes[qtnMultiLineEditAttr()] = false;\n#endif\n\tpropertyStyle->setDelegateInfo(delegate);\n\n\taddSubProperty(propertyStyle);\n\n\tauto propertySize = new QtnPropertyIntCallback;\n\taddSubProperty(propertySize);\n\tpropertySize->setName(QStringLiteral(\"size\"));\n\tpropertySize->setDisplayName(QtnPropertyQFont::getSizeLabel());\n\tpropertySize->setDescription(\n\t\tQtnPropertyQFont::getSizeDescription(owner.name()));\n\tpropertySize->setCallbackValueGet([&owner]() -> qint32 {\n\t\tint ps = owner.value().pointSize();\n\n\t\tif (ps < 0)\n\t\t\tps = owner.value().pixelSize();\n\n\t\tif (ps <= 0)\n\t\t\tps = 1;\n\n\t\tif (ps > 256)\n\t\t\tps = 256;\n\n\t\treturn ps;\n\t});\n\tpropertySize->setCallbackValueSet([&owner](qint32 value, QtnPropertyChangeReason reason) {\n\t\tif (value <= 0)\n\t\t\tvalue = 1;\n\t\telse if (value > 256)\n\t\t\tvalue = 256;\n\n\t\tQFont font = owner.value();\n\n\t\tif (font.pointSize() > 0)\n\t\t{\n\t\t\tfont.setPointSize(value);\n\t\t} else\n\t\t{\n\t\t\tfont.setPixelSize(value);\n\t\t}\n\n\t\towner.setValue(font, reason);\n\t});\n\n\tpropertySize->setMinValue(1);\n\tpropertySize->setMaxValue(256);\n\n\tQtnPropertyEnumCallback *propertySizeUnit = new QtnPropertyEnumCallback;\n\taddSubProperty(propertySizeUnit);\n\tpropertySizeUnit->setName(QStringLiteral(\"sizeUnit\"));\n\tpropertySizeUnit->setDisplayName(QtnPropertyQFont::getSizeUnitLabel());\n\tpropertySizeUnit->setDescription(\n\t\tQtnPropertyQFont::getSizeUnitDescription(owner.name()));\n\tpropertySizeUnit->setEnumInfo(sizeUnitEnum());\n\tpropertySizeUnit->setCallbackValueGet([&owner]() -> QtnEnumValueType {\n\t\tif (owner.value().pointSize() < 0)\n\t\t\treturn SizeUnitPixel;\n\n\t\treturn SizeUnitPoint;\n\t});\n\n\tpropertySizeUnit->setCallbackValueSet([&owner](QtnEnumValueType value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\n\t\tint size = std::max(font.pointSize(), font.pixelSize());\n\n\t\tif (size <= 0)\n\t\t\tsize = 1;\n\n\t\tif (size > 256)\n\t\t\tsize = 256;\n\n\t\tswitch (value)\n\t\t{\n\t\t\tcase SizeUnitPixel:\n\t\t\t\tfont.setPixelSize(size);\n\t\t\t\tbreak;\n\n\t\t\tcase SizeUnitPoint:\n\t\t\t\tfont.setPointSize(size);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\towner.setValue(font, reason);\n\t});\n\n\tQtnPropertyBoolCallback *propertyBold = new QtnPropertyBoolCallback;\n\taddSubProperty(propertyBold);\n\tpropertyBold->setName(QStringLiteral(\"bold\"));\n\tpropertyBold->setDisplayName(QtnPropertyQFont::getBoldLabel());\n\tpropertyBold->setDescription(\n\t\tQtnPropertyQFont::getBoldDescription(owner.name()));\n\tpropertyBold->setCallbackValueGet(\n\t\t[&owner]() -> bool { return owner.value().bold(); });\n\tpropertyBold->setCallbackValueSet([&owner](bool value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\n\t\tif (font.bold() != value)\n\t\t{\n#ifdef Q_OS_MAC\n\t\t\tauto style = font.styleName();\n\n\t\t\tif (!style.isEmpty())\n\t\t\t{\n\t\t\t\tauto family = font.family();\n\t\t\t\tQFontDatabase db;\n\n\t\t\t\tfor (auto &s : db.styles(family))\n\t\t\t\t{\n\t\t\t\t\tif (s == style)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value != db.bold(family, style))\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n#endif\n\t\t\tfont.setBold(value);\n\t\t\towner.setValue(font, reason);\n\t\t}\n\t});\n\n\tQtnPropertyBoolCallback *propertyItalic = new QtnPropertyBoolCallback;\n\taddSubProperty(propertyItalic);\n\tpropertyItalic->setName(QStringLiteral(\"italic\"));\n\tpropertyItalic->setDisplayName(QtnPropertyQFont::getItalicLabel());\n\tpropertyItalic->setDescription(\n\t\tQtnPropertyQFont::getItalicDescription(owner.name()));\n\tpropertyItalic->setCallbackValueGet(\n\t\t[&owner]() -> bool { return owner.value().italic(); });\n\tpropertyItalic->setCallbackValueSet([&owner](bool value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\n\t\tif (font.italic() != value)\n\t\t{\n#ifdef Q_OS_MAC\n\t\t\tauto style = font.styleName();\n\n\t\t\tif (!style.isEmpty())\n\t\t\t{\n\t\t\t\tauto family = font.family();\n\t\t\t\tQFontDatabase db;\n\n\t\t\t\tfor (auto &s : db.styles(family))\n\t\t\t\t{\n\t\t\t\t\tif (s == style)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value != db.italic(family, style))\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n#endif\n\t\t\tfont.setItalic(value);\n\t\t\towner.setValue(font, reason);\n\t\t}\n\t});\n\n\tQtnPropertyBoolCallback *propertyUnderline = new QtnPropertyBoolCallback;\n\taddSubProperty(propertyUnderline);\n\tpropertyUnderline->setName(QStringLiteral(\"underline\"));\n\tpropertyUnderline->setDisplayName(QtnPropertyQFont::getUnderlineLabel());\n\tpropertyUnderline->setDescription(\n\t\tQtnPropertyQFont::getUnderlineDescription(owner.name()));\n\tpropertyUnderline->setCallbackValueGet(\n\t\t[&owner]() -> bool { return owner.value().underline(); });\n\tpropertyUnderline->setCallbackValueSet([&owner](bool value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setUnderline(value);\n\t\towner.setValue(font, reason);\n\t});\n\n\tQtnPropertyBoolCallback *propertyStrikeout = new QtnPropertyBoolCallback;\n\taddSubProperty(propertyStrikeout);\n\tpropertyStrikeout->setName(QStringLiteral(\"strikeout\"));\n\tpropertyStrikeout->setDisplayName(QtnPropertyQFont::getStrikeoutLabel());\n\tpropertyStrikeout->setDescription(\n\t\tQtnPropertyQFont::getStrikeoutDescription(owner.name()));\n\tpropertyStrikeout->setCallbackValueGet(\n\t\t[&owner]() -> bool { return owner.value().strikeOut(); });\n\tpropertyStrikeout->setCallbackValueSet([&owner](bool value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setStrikeOut(value);\n\t\towner.setValue(font, reason);\n\t});\n\n\tQtnPropertyBoolCallback *propertyKerning = new QtnPropertyBoolCallback;\n\taddSubProperty(propertyKerning);\n\tpropertyKerning->setName(QStringLiteral(\"kerning\"));\n\tpropertyKerning->setDisplayName(QtnPropertyQFont::getKerningLabel());\n\tpropertyKerning->setDescription(\n\t\tQtnPropertyQFont::getKerningDescription(owner.name()));\n\tpropertyKerning->setCallbackValueGet(\n\t\t[&owner]() -> bool { return owner.value().kerning(); });\n\tpropertyKerning->setCallbackValueSet([&owner](bool value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setKerning(value);\n\t\towner.setValue(font, reason);\n\t});\n\n\tauto propertyAntialiasing = new QtnPropertyEnumCallback(nullptr);\n\taddSubProperty(propertyAntialiasing);\n\tpropertyAntialiasing->setName(QStringLiteral(\"antialiasing\"));\n\tpropertyAntialiasing->setDisplayName(\n\t\tQtnPropertyQFont::getAntialiasingLabel());\n\tpropertyAntialiasing->setDescription(\n\t\tQtnPropertyQFont::getAntialiasingDescription(owner.name()));\n\tpropertyAntialiasing->setEnumInfo(styleStrategyEnum());\n\tpropertyAntialiasing->setCallbackValueGet([&owner]() -> QtnEnumValueType {\n\t\treturn owner.value().styleStrategy();\n\t});\n\tpropertyAntialiasing->setCallbackValueSet([&owner](QtnEnumValueType value, QtnPropertyChangeReason reason) {\n\t\tQFont font = owner.value();\n\t\tfont.setStyleStrategy(static_cast<QFont::StyleStrategy>(value));\n\t\towner.setValue(font, reason);\n\t});\n}\n\nvoid QtnPropertyDelegateQFont::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQFontBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQFont, QtnPropertyQFontBase>,\n\t\tqtnSelectFontDelegate());\n}\n\nQString QtnPropertyDelegateQFont::fontToStrWithFormat(\n\tconst QFont &font, const QString &format)\n{\n\treturn QString(format).arg(fontToStr(font));\n}\n\nQString QtnPropertyDelegateQFont::fontToStr(const QFont &font)\n{\n\tint size = font.pointSize();\n\tbool pixels = (size < 0);\n\n\tif (pixels)\n\t\tsize = font.pixelSize();\n\n\treturn QString(\"%1, %2 %3\")\n\t\t.arg(font.family(), QString::number(size),\n\t\t\tQString(pixels ? \"px\" : \"pt\"));\n}\n\nvoid QtnPropertyDelegateQFont::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tQtnPropertyDelegateTypedEx::drawValueImpl(painter, rect);\n\t\treturn;\n\t}\n\n\tQFont value = owner().value();\n\n\tQRect textRect = rect;\n\n\tif (textRect.isValid())\n\t{\n\t\tQRect br;\n\n\t\tQFont oldFont = painter.font();\n\t\tQFont newFont(value);\n\t\tnewFont.setPointSize(oldFont.pointSize());\n\t\tpainter.setFont(newFont);\n\t\tpainter.drawText(\n\t\t\ttextRect, Qt::AlignLeading | Qt::AlignVCenter, \"A\", &br);\n\t\tpainter.setFont(oldFont);\n\n\t\ttextRect.setLeft(br.right() + 3);\n\t}\n\n\tif (textRect.isValid())\n\t{\n\t\tQtnPropertyDelegateTypedEx<QtnPropertyQFontBase>::drawValueImpl(\n\t\t\tpainter, textRect);\n\t}\n}\n\nQWidget *QtnPropertyDelegateQFont::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQtnLineEditBttn *editor = new QtnLineEditBttn(parent);\n\teditor->setGeometry(rect);\n\n\tnew QtnPropertyQFontLineEditBttnHandler(this, *editor);\n\n\tif (inplaceInfo)\n\t{\n\t\teditor->lineEdit->selectAll();\n\t}\n\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQFont::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = fontToStrWithFormat(owner().value());\n\treturn true;\n}\n\nQtnPropertyQFontLineEditBttnHandler::QtnPropertyQFontLineEditBttnHandler(\n\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n{\n\teditor.lineEdit->setReadOnly(true);\n\n\tif (!stateProperty()->isEditableByUser())\n\t{\n\t\teditor.toolButton->setEnabled(false);\n\t}\n\n\tupdateEditor();\n\teditor.lineEdit->installEventFilter(this);\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQFontLineEditBttnHandler::onToolButtonClicked);\n}\n\nvoid QtnPropertyQFontLineEditBttnHandler::onToolButtonClick()\n{\n\tonToolButtonClicked(false);\n}\n\nvoid QtnPropertyQFontLineEditBttnHandler::updateEditor()\n{\n\teditor().setTextForProperty(stateProperty(),\n\t\tQtnPropertyDelegateQFont::fontToStrWithFormat(property()));\n\teditor().lineEdit->selectAll();\n}\n\nvoid QtnPropertyQFontLineEditBttnHandler::onToolButtonClicked(bool)\n{\n\tauto property = &this->property();\n\tvolatile bool destroyed = false;\n\tauto connection = QObject::connect(property, &QObject::destroyed,\n\t\t[&destroyed]() mutable { destroyed = true; });\n\tauto dialog = new QFontDialog(property->value(), editorBase());\n\tauto dialogContainer = connectDialog(dialog);\n\n\tif (dialog->exec() == QDialog::Accepted && !destroyed)\n\t{\n\t\tauto font = property->value();\n\t\tauto styleStrategy = font.styleStrategy();\n\t\tint pixelSize = font.pixelSize();\n\t\tfont = dialog->currentFont();\n\n\t\tif (pixelSize > 0)\n\t\t\tfont.setPixelSize(font.pointSize());\n\n\t\tfont.setStyleStrategy(styleStrategy);\n\n\t\tproperty->setValue(\n\t\t\tfont, delegate()->editReason() | QtnPropertyChangeReasonChildren);\n\t}\n\n\tif (!destroyed)\n\t\tQObject::disconnect(connection);\n\n\tQ_UNUSED(dialogContainer);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQFont.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QFONT_H\n#define PROPERTY_DELEGATE_QFONT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyQFont.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQFont\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQFontBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQFont)\n\npublic:\n\tQtnPropertyDelegateQFont(QtnPropertyQFontBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tstatic QString fontToStrWithFormat(\n\t\tconst QFont &font, const QString &format = QString(\"[%1]\"));\n\tstatic QString fontToStr(const QFont &font);\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\nprotected:\n\tvirtual void drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n};\n\n#endif // PROPERTY_DELEGATE_QFONT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQPen.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQPen.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Core/PropertyDouble.h\"\n#include \"QtnProperty/Core/PropertyQSize.h\"\n#include \"QtnProperty/Core/PropertyEnum.h\"\n#include \"QtnProperty/GUI/PropertyQColor.h\"\n#include \"QtnProperty/MultiProperty.h\"\n\n#include <QComboBox>\n#include <QStyledItemDelegate>\n#include <QPaintEvent>\n\nQByteArray qtnShowNoPenAttr()\n{\n\treturn QByteArrayLiteral(\"showNoPen\");\n}\n\nQByteArray qtnEditColorAttr()\n{\n\treturn QByteArrayLiteral(\"editColor\");\n}\n\nQByteArray qtnEditStyleAttr()\n{\n\treturn QByteArrayLiteral(\"editStyle\");\n}\n\nQByteArray qtnEditCapStyleAttr()\n{\n\treturn QByteArrayLiteral(\"editCapStyle\");\n}\n\nQByteArray qtnEditJoinStyleAttr()\n{\n\treturn QByteArrayLiteral(\"editJoinStyle\");\n}\n\nQByteArray qtnEditWidthAttr()\n{\n\treturn QByteArrayLiteral(\"editWidth\");\n}\n\nvoid QtnPropertyDelegateQPenStyle::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQPenStyleBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQPenStyle,\n\t\t\tQtnPropertyQPenStyleBase>,\n\t\tqtnComboBoxDelegate());\n}\n\nstatic void drawPenStyle(QPainter &painter, QRect rect, Qt::PenStyle penStyle)\n{\n\trect.adjust(2, 2, -2, -2);\n\tQPen pen = painter.pen();\n\tpen.setStyle(penStyle);\n\tpainter.save();\n\tpainter.setPen(pen);\n\tauto midY = rect.center().y();\n\tpainter.drawLine(rect.left(), midY, rect.right(), midY);\n\tpainter.restore();\n}\n\nclass QtnPropertyPenStyleItemDelegate : public QStyledItemDelegate\n{\npublic:\n\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n};\n\nclass QtnPropertyPenStyleComboBox : public QtnPropertyComboBox\n{\npublic:\n\texplicit QtnPropertyPenStyleComboBox(\n\t\tQtnPropertyDelegate *delegate, QWidget *parent = Q_NULLPTR);\n\nprotected:\n\tvirtual void customPaint(QPainter &painter, const QRect &rect) override;\n};\n\nclass QtnPropertyPenStyleComboBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyQPenStyleBase, QComboBox>\n{\npublic:\n\tQtnPropertyPenStyleComboBoxHandler(\n\t\tQtnPropertyDelegate *delegate, QComboBox &editor);\n\nprivate:\n\tvoid updateEditor() override;\n\n\tvoid onCurrentIndexChanged(int index);\n};\n\nQtnPropertyDelegateQPenStyle::QtnPropertyDelegateQPenStyle(\n\tQtnPropertyQPenStyleBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyQPenStyleBase>(owner)\n\t, m_showNoPen(false)\n{\n}\n\nvoid QtnPropertyDelegateQPenStyle::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnShowNoPenAttr(), m_showNoPen);\n}\n\nvoid QtnPropertyDelegateQPenStyle::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tQtnPropertyDelegateTyped::drawValueImpl(painter, rect);\n\t\treturn;\n\t}\n\n\tQt::PenStyle value = owner().value();\n\tdrawPenStyle(painter, rect, value);\n}\n\nQWidget *QtnPropertyDelegateQPenStyle::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tif (stateProperty()->isEditableByUser())\n\t{\n\t\tQComboBox *combo = new QtnPropertyPenStyleComboBox(this, parent);\n\t\tcombo->setLineEdit(nullptr);\n\t\tcombo->setItemDelegate(new QtnPropertyPenStyleItemDelegate());\n\t\tauto startStyle = m_showNoPen ? Qt::NoPen : Qt::SolidLine;\n\t\tfor (auto ps = (int) startStyle; ps < Qt::CustomDashLine; ++ps)\n\t\t\tcombo->addItem(QString(), QVariant::fromValue(Qt::PenStyle(ps)));\n\n\t\tcombo->setGeometry(rect);\n\n\t\tnew QtnPropertyPenStyleComboBoxHandler(this, *combo);\n\n\t\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\t\tcombo->showPopup();\n\n\t\treturn combo;\n\t}\n\n\treturn nullptr;\n}\n\nbool QtnPropertyDelegateQPenStyle::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tauto info =\n\t\tQtnPropertyQPenBase::penStyleEnum().findByValue(int(owner().value()));\n\tif (!info)\n\t\treturn false;\n\n\tstrValue = info->displayName();\n\treturn true;\n}\n\nvoid QtnPropertyDelegateQPen::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQPenBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQPen, QtnPropertyQPenBase>,\n\t\tqtnLineEditDelegate());\n}\n\nclass QtnPropertyQPenLineEditHandler\n\t: public QtnPropertyEditorHandler<QtnPropertyQPenBase, QLineEdit>\n{\npublic:\n\tQtnPropertyQPenLineEditHandler(\n\t\tQtnPropertyDelegate *delegate, QLineEdit &editor);\n\nprivate:\n\tvoid updateEditor() override;\n};\n\nQtnPropertyDelegateQPen::QtnPropertyDelegateQPen(QtnPropertyQPenBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQPenBase>(owner)\n{\n}\n\nvoid QtnPropertyDelegateQPen::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tauto owner = &this->owner();\n\n\t{\n\t\tbool editColor = true;\n\t\tinfo.loadAttribute(qtnEditColorAttr(), editColor);\n\n\t\tif (editColor)\n\t\t{\n\t\t\taddSubProperty(\n\t\t\t\tqtnCreateFieldProperty<QtnPropertyQColorCallback>(owner,\n\t\t\t\t\t&QPen::color, &QPen::setColor, QtnPropertyQPen::colorKey(),\n\t\t\t\t\tQtnPropertyQPen::colorDisplayName(),\n\t\t\t\t\tQtnPropertyQPen::colorDescriptionFmt()));\n\t\t}\n\t}\n\n\t{\n\t\tbool editStyle = true;\n\t\tinfo.loadAttribute(qtnEditStyleAttr(), editStyle);\n\n\t\tif (editStyle)\n\t\t{\n\t\t\taddSubProperty(\n\t\t\t\tqtnCreateFieldProperty<QtnPropertyQPenStyleCallback>(owner,\n\t\t\t\t\t&QPen::style, &QPen::setStyle, QtnPropertyQPen::styleKey(),\n\t\t\t\t\tQtnPropertyQPen::styleDisplayName(),\n\t\t\t\t\tQtnPropertyQPen::styleDescriptionFmt()));\n\t\t}\n\t}\n\n\t{\n\t\tbool editWidth = true;\n\t\tinfo.loadAttribute(qtnEditWidthAttr(), editWidth);\n\n\t\tif (editWidth)\n\t\t{\n\t\t\tauto widthProperty =\n\t\t\t\tqtnCreateFieldProperty<QtnPropertyDoubleCallback>(owner,\n\t\t\t\t\t&QPen::widthF, &QPen::setWidthF,\n\t\t\t\t\tQtnPropertyQSize::widthKey(),\n\t\t\t\t\tQtnPropertyQSize::widthDisplayName(),\n\t\t\t\t\tQtnPropertyQSize::widthDescriptionFmt());\n\t\t\taddSubProperty(widthProperty);\n\n\t\t\twidthProperty->setMinValue(0.0);\n\t\t}\n\t}\n\n\t{\n\t\tbool editCapStyle = true;\n\t\tinfo.loadAttribute(qtnEditCapStyleAttr(), editCapStyle);\n\n\t\tif (editCapStyle)\n\t\t{\n\t\t\tstatic_assert(\n\t\t\t\tsizeof(Qt::PenCapStyle) == sizeof(int), \"enum size mismatch\");\n\t\t\tauto capStyleProperty =\n\t\t\t\tqtnCreateFieldProperty<QtnPropertyEnumCallback>(owner,\n\t\t\t\t\treinterpret_cast<int (QPen::*)() const>(&QPen::capStyle),\n\t\t\t\t\treinterpret_cast<void (QPen::*)(int)>(&QPen::setCapStyle),\n\t\t\t\t\tQtnPropertyQPen::capStyleKey(),\n\t\t\t\t\tQtnPropertyQPen::capStyleDisplayName(),\n\t\t\t\t\tQtnPropertyQPen::capStyleDescriptionFmt());\n\t\t\tcapStyleProperty->setEnumInfo(&QtnPropertyQPen::penCapStyleEnum());\n\t\t\taddSubProperty(capStyleProperty);\n\t\t}\n\t}\n\n\t{\n\t\tbool editJoinStyle = true;\n\t\tinfo.loadAttribute(qtnEditJoinStyleAttr(), editJoinStyle);\n\n\t\tif (editJoinStyle)\n\t\t{\n\t\t\tstatic_assert(\n\t\t\t\tsizeof(Qt::PenJoinStyle) == sizeof(int), \"enum size mismatch\");\n\t\t\tauto joinStyleProperty =\n\t\t\t\tqtnCreateFieldProperty<QtnPropertyEnumCallback>(owner,\n\t\t\t\t\treinterpret_cast<int (QPen::*)() const>(&QPen::joinStyle),\n\t\t\t\t\treinterpret_cast<void (QPen::*)(int)>(&QPen::setJoinStyle),\n\t\t\t\t\tQtnPropertyQPen::joinStyleKey(),\n\t\t\t\t\tQtnPropertyQPen::joinStyleDisplayName(),\n\t\t\t\t\tQtnPropertyQPen::joinStyleDescriptionFmt());\n\t\t\tjoinStyleProperty->setEnumInfo(\n\t\t\t\t&QtnPropertyQPen::penJoinStyleEnum());\n\t\t\taddSubProperty(joinStyleProperty);\n\t\t}\n\t}\n}\n\nQWidget *QtnPropertyDelegateQPen::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *)\n{\n\tauto editor = new QLineEdit(parent);\n\teditor->setGeometry(rect);\n\n\tnew QtnPropertyQPenLineEditHandler(this, *editor);\n\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQPen::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QtnPropertyQPen::rootDisplayValue();\n\treturn true;\n}\n\nvoid QtnPropertyPenStyleItemDelegate::paint(QPainter *painter,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\tQStyledItemDelegate::paint(painter, option, index);\n\tauto penStyle = index.data(Qt::UserRole).value<Qt::PenStyle>();\n\tdrawPenStyle(*painter, option.rect, penStyle);\n}\n\nQtnPropertyPenStyleComboBox::QtnPropertyPenStyleComboBox(\n\tQtnPropertyDelegate *delegate, QWidget *parent)\n\t: QtnPropertyComboBox(delegate, parent)\n{\n}\n\nvoid QtnPropertyPenStyleComboBox::customPaint(\n\tQPainter &painter, const QRect &rect)\n{\n\tauto penStyle = currentData().value<Qt::PenStyle>();\n\tdrawPenStyle(painter, rect, penStyle);\n}\n\nQtnPropertyPenStyleComboBoxHandler::QtnPropertyPenStyleComboBoxHandler(\n\tQtnPropertyDelegate *delegate, QComboBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),\n\t\tthis, &QtnPropertyPenStyleComboBoxHandler::onCurrentIndexChanged);\n}\n\nvoid QtnPropertyPenStyleComboBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\tif (stateProperty()->isMultiValue())\n\t\teditor().setCurrentIndex(-1);\n\telse\n\t{\n\t\tint index = editor().findData(QVariant::fromValue(property().value()));\n\t\teditor().setCurrentIndex(index);\n\t}\n\n\tupdating--;\n}\n\nvoid QtnPropertyPenStyleComboBoxHandler::onCurrentIndexChanged(int index)\n{\n\tif (index >= 0)\n\t{\n\t\tQVariant data = editor().itemData(index);\n\n\t\tif (data.canConvert<Qt::PenStyle>())\n\t\t\tonValueChanged(data.value<Qt::PenStyle>());\n\t}\n}\n\nQtnPropertyQPenLineEditHandler::QtnPropertyQPenLineEditHandler(\n\tQtnPropertyDelegate *delegate, QLineEdit &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n{\n\teditor.setReadOnly(true);\n\teditor.setPlaceholderText(stateProperty()->isMultiValue()\n\t\t\t? QtnMultiProperty::getMultiValuePlaceholder()\n\t\t\t: QtnPropertyQPen::rootDisplayValue());\n}\n\nvoid QtnPropertyQPenLineEditHandler::updateEditor()\n{\n\t// do nothing\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQPen.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_QPEN_H\n#define PROPERTY_DELEGATE_QPEN_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyQPen.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQPenStyle\n\t: public QtnPropertyDelegateTyped<QtnPropertyQPenStyleBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQPenStyle)\n\npublic:\n\tQtnPropertyDelegateQPenStyle(QtnPropertyQPenStyleBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvoid applyAttributesImpl(const QtnPropertyDelegateInfo &info) override;\n\n\tvoid drawValueImpl(\n\t\tQStylePainter &painter, const QRect &rect) const override;\n\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tbool propertyValueToStrImpl(QString &strValue) const override;\n\nprivate:\n\tbool m_showNoPen;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQPen\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQPenBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQPen)\n\npublic:\n\tQtnPropertyDelegateQPen(QtnPropertyQPenBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvoid applyAttributesImpl(const QtnPropertyDelegateInfo &info) override;\n\n\tQWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tbool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_QPEN_H\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQVector3D.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateQVector3D.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Core/PropertyQPoint.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Utils/DoubleSpinBox.h\"\n\n#include <QLineEdit>\n#include <QLocale>\n\nQByteArray qtnZDisplayNameAttr()\n{\n\treturn QByteArrayLiteral(\"zDisplayName\");\n}\n\nQByteArray qtnZDescriptionAttr()\n{\n\treturn QByteArrayLiteral(\"zDescription\");\n}\n\nQtnPropertyDelegateQVector3D::QtnPropertyDelegateQVector3D(\n\tQtnPropertyQVector3DBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQVector3DBase>(owner)\n\t, m_multiplier(1.0)\n\t, m_precision(std::numeric_limits<float>::digits10 - 1)\n{\n\taddSubProperty(owner.createXProperty());\n\taddSubProperty(owner.createYProperty());\n\taddSubProperty(owner.createZProperty());\n}\n\nvoid QtnPropertyDelegateQVector3D::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQVector3DBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQVector3D,\n\t\t\tQtnPropertyQVector3DBase>,\n\t\tQByteArrayLiteral(\"QVector3D\"));\n}\n\nextern void qtnApplyQPointDelegateAttributes(\n\tQtnPropertyDelegate *to, const QtnPropertyDelegateInfo &info);\n\nvoid QtnPropertyDelegateQVector3D::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tinfo.loadAttribute(qtnMultiplierAttr(), m_multiplier);\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tm_precision = qBound(0, m_precision, std::numeric_limits<float>::digits10);\n\tif (!qIsFinite(m_multiplier) || qFuzzyCompare(m_multiplier, 0.0))\n\t{\n\t\tm_multiplier = 1.0;\n\t}\n\n\tenum\n\t{\n\t\tX,\n\t\tY,\n\t\tZ,\n\t\tTOTAL\n\t};\n\tQ_ASSERT(subPropertyCount() == TOTAL);\n\tstatic const QtnSubPropertyInfo KEYS[TOTAL] = {\n\t\t{ X, QtnPropertyQPoint::xKey(), qtnXDisplayNameAttr(),\n\t\t\tqtnXDescriptionAttr() },\n\t\t{ Y, QtnPropertyQPoint::yKey(), qtnYDisplayNameAttr(),\n\t\t\tqtnYDescriptionAttr() },\n\t\t{ Z, QtnPropertyQVector3D::zKey(), qtnZDisplayNameAttr(),\n\t\t\tqtnZDescriptionAttr() },\n\t};\n\n\tapplySubPropertyInfos(info, KEYS, TOTAL);\n}\n\nQWidget *QtnPropertyDelegateQVector3D::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nbool QtnPropertyDelegateQVector3D::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tauto value = owner().value();\n\n\tQLocale locale;\n\tstrValue = QtnPropertyQVector3D::getToStringFormat().arg(\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.x() * m_multiplier, locale, m_precision, true) +\n\t\t\tm_suffix,\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.y() * m_multiplier, locale, m_precision, true) +\n\t\t\tm_suffix,\n\t\tQtnDoubleSpinBox::valueToText(\n\t\t\tvalue.z() * m_multiplier, locale, m_precision, true) +\n\t\t\tm_suffix);\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/GUI/PropertyDelegateQVector3D.h",
    "content": "/*******************************************************************************\nCopyright (c) 2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#pragma once\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/GUI/PropertyQVector3D.h\"\n\nclass QtnPropertyQVector3DBase;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQVector3D\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQVector3DBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQVector3D)\n\n\tQString m_suffix;\n\tdouble m_multiplier;\n\tint m_precision;\n\npublic:\n\tQtnPropertyDelegateQVector3D(QtnPropertyQVector3DBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegate.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegate.h\"\n#include \"Utils/QtnConnections.h\"\n#include \"Utils/PropertyEditorHandler.h\"\n#include \"PropertyView.h\"\n\n#include <QPainterPath>\n\nQtnPropertyDelegate::QtnPropertyDelegate(QtnPropertyBase &ownerProperty)\n\t: m_ownerProperty(&ownerProperty)\n\t, m_stateProperty(nullptr)\n{\n}\n\nQtnPropertyDelegate::~QtnPropertyDelegate()\n{\n\tif (m_editorHandler)\n\t\tm_editorHandler->cleanup();\n}\n\nvoid QtnPropertyDelegate::init()\n{\n\t// do nothing\n}\n\nQtnPropertyChangeReason QtnPropertyDelegate::editReason() const\n{\n\tQtnPropertyChangeReason result = QtnPropertyChangeReasonEdit;\n\tif (stateProperty()->isMultiValue())\n\t\tresult |= QtnPropertyChangeReasonMultiEdit;\n\treturn result;\n}\n\nvoid QtnPropertyDelegate::applySubPropertyInfo(\n\tconst QtnPropertyDelegateInfo &info, const QtnSubPropertyInfo &subInfo)\n{\n\tQtnPropertyDelegateInfo subDelegateInfo;\n\tauto &subAttributes = subDelegateInfo.attributes;\n\tsubAttributes = info.attributes;\n\tauto vSubDelegate = subAttributes.value(subInfo.key.toUtf8());\n\tswitch (vSubDelegate.type())\n\t{\n\t\tcase QVariant::Map:\n\t\tcase QVariant::Hash:\n\t\t{\n\t\t\tauto vmap = vSubDelegate.toMap();\n\t\t\tstatic const auto sNameKey = QStringLiteral(\"name\");\n\t\t\tfor (auto it = vmap.cbegin(); it != vmap.cend(); ++it)\n\t\t\t{\n\t\t\t\tif (it.key() == sNameKey)\n\t\t\t\t{\n\t\t\t\t\tauto vname = vmap.value(sNameKey);\n\t\t\t\t\tsubDelegateInfo.name = vname.type() == QVariant::ByteArray\n\t\t\t\t\t\t? vname.toByteArray()\n\t\t\t\t\t\t: vname.toString().toUtf8();\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tsubAttributes[it.key().toUtf8()] = it.value();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tauto p = subProperty(subInfo.id);\n\tp->setName(subInfo.key);\n\tinfo.storeAttributeValue(subInfo.displayNameAttr, p,\n\t\t&QtnPropertyBase::displayName, &QtnPropertyBase::setDisplayName);\n\tinfo.storeAttributeValue(subInfo.descriptionAttr, p,\n\t\t&QtnPropertyBase::description, &QtnPropertyBase::setDescription);\n\tp->setDelegateInfo(subDelegateInfo);\n}\n\nvoid QtnPropertyDelegate::applySubPropertyInfos(\n\tconst QtnPropertyDelegateInfo &info, const QtnSubPropertyInfo *subInfos,\n\tint count)\n{\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tapplySubPropertyInfo(info, subInfos[i]);\n\t}\n}\n\nbool QtnPropertyDelegate::isSplittable() const\n{\n\treturn false;\n}\n\nint QtnPropertyDelegate::subPropertyCountImpl() const\n{\n\treturn 0;\n}\n\nQtnPropertyBase *QtnPropertyDelegate::subPropertyImpl(int index)\n{\n\tQ_UNUSED(index);\n\treturn nullptr;\n}\n\nvoid QtnPropertyDelegate::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tQ_UNUSED(info);\n}\n\nQStyle::State QtnPropertyDelegate::state(\n\tbool isActive, const QtnSubItem &subItem) const\n{\n\tauto subState = subItem.state();\n\tQStyle::State state = QStyle::State_Active;\n\tif (stateProperty()->isEditableByUser())\n\t\tstate |= QStyle::State_Enabled;\n\tif (isActive)\n\t{\n\t\tstate |= QStyle::State_Selected;\n\t\tstate |= QStyle::State_HasFocus;\n\t}\n\n\tif (subState == QtnSubItemStateUnderCursor)\n\t\tstate |= QStyle::State_MouseOver;\n\telse if (subState == QtnSubItemStatePushed)\n\t\tstate |= QStyle::State_Sunken;\n\n\treturn state;\n}\n\nvoid QtnPropertyDelegate::addSubItemLock(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tif (!stateProperty()->isUnlockable())\n\t{\n\t\treturn;\n\t}\n\n\tQtnSubItem item(context.rect.marginsRemoved(context.margins));\n\titem.rect.setWidth(item.rect.height());\n\tcontext.margins.setLeft(context.margins.left() + item.rect.height() +\n\t\tcontext.widget->valueLeftMargin());\n\n\titem.setTextAsTooltip(stateProperty()->isLocked()\n\t\t\t? QtnPropertyView::tr(\"Unlock\")\n\t\t\t: QtnPropertyView::tr(\"Lock\"));\n\n\titem.trackState();\n\n\tif (item.rect.isValid())\n\t{\n\t\titem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\t\tdrawButton(context, item, QIcon(),\n\t\t\t\tstateProperty()->isLocked()\n\t\t\t\t\t? QString::fromUtf8(\"\\xF0\\x9F\\x93\\x95\")\n\t\t\t\t\t: QString::fromUtf8(\"\\xF0\\x9F\\x93\\x96\"));\n\t\t};\n\n\t\titem.eventHandler = [this](QtnEventContext &context, const QtnSubItem &,\n\t\t\t\t\t\t\t\tQtnPropertyToEdit *) -> bool {\n\t\t\tif ((context.eventType() == QEvent::MouseButtonPress) ||\n\t\t\t\t(context.eventType() == QEvent::MouseButtonDblClick))\n\t\t\t{\n\t\t\t\tQtnConnections connections;\n\t\t\t\tcontext.widget->connectPropertyToEdit(\n\t\t\t\t\tstateProperty(), connections);\n\t\t\t\tstateProperty()->toggleLock(editReason());\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\tsubItems.append(item);\n\t}\n}\n\nQColor QtnPropertyDelegate::disabledTextColor(const QStylePainter &painter)\n{\n\tauto palette = painter.style()->standardPalette();\n#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)\n\treturn palette.color(QPalette::Active, QPalette::PlaceholderText);\n#else\n\treturn palette.color(QPalette::Disabled, QPalette::Text);\n#endif\n}\n\nvoid QtnPropertyDelegate::addSubItemBranchNode(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tif (!context.hasChildren)\n\t\treturn;\n\n\tQtnSubItem brItem(context.rect.marginsRemoved(context.margins));\n\tbrItem.rect.setWidth(brItem.rect.height());\n\tcontext.margins.setLeft(context.margins.left() + brItem.rect.height());\n\tbrItem.trackState();\n\n\tif (!brItem.rect.isValid())\n\t\treturn;\n\n\tbrItem.drawHandler = [this](\n\t\t\t\t\t\t\t QtnDrawContext &context, const QtnSubItem &item) {\n\t\tauto &painter = *context.painter;\n\t\tQRectF branchRect = item.rect;\n\t\tqreal side = branchRect.height() / qreal(3.5);\n\t\tQColor fillClr = context.palette().color(QPalette::Text);\n\t\tQColor outlineClr = (item.state() != QtnSubItemStateNone)\n\t\t\t? Qt::blue\n\t\t\t: context.palette().color(QPalette::Text);\n\n\t\tpainter.save();\n\t\tpainter.setPen(outlineClr);\n\n\t\tQPainterPath branchPath;\n\t\tif (stateProperty()->isCollapsed())\n\t\t{\n\t\t\tbranchPath.moveTo(\n\t\t\t\tbranchRect.left() + side, branchRect.top() + side);\n\t\t\tbranchPath.lineTo(branchRect.right() - side - 1,\n\t\t\t\tbranchRect.top() + branchRect.height() / qreal(2.0));\n\t\t\tbranchPath.lineTo(\n\t\t\t\tbranchRect.left() + side, branchRect.bottom() - side);\n\t\t\tbranchPath.closeSubpath();\n\t\t} else\n\t\t{\n\t\t\tbranchPath.moveTo(\n\t\t\t\tbranchRect.left() + side, branchRect.top() + side);\n\t\t\tbranchPath.lineTo(\n\t\t\t\tbranchRect.right() - side, branchRect.top() + side);\n\t\t\tbranchPath.lineTo(\n\t\t\t\tbranchRect.left() + branchRect.width() / qreal(2.0),\n\t\t\t\tbranchRect.bottom() - side - 1);\n\t\t\tbranchPath.closeSubpath();\n\t\t}\n\n\t\tif (painter.testRenderHint(QPainter::Antialiasing))\n\t\t{\n\t\t\tpainter.fillPath(branchPath, fillClr);\n\t\t\tpainter.drawPath(branchPath);\n\t\t} else\n\t\t{\n\t\t\tpainter.setRenderHint(QPainter::Antialiasing, true);\n\t\t\tpainter.fillPath(branchPath, fillClr);\n\t\t\tpainter.drawPath(branchPath);\n\t\t\tpainter.setRenderHint(QPainter::Antialiasing, false);\n\t\t}\n\n\t\tpainter.restore();\n\t};\n\n\tbrItem.eventHandler = [this](QtnEventContext &context, const QtnSubItem &,\n\t\t\t\t\t\t\t  QtnPropertyToEdit *) -> bool {\n\t\tif ((context.eventType() == QEvent::MouseButtonPress) ||\n\t\t\t(context.eventType() == QEvent::MouseButtonDblClick))\n\t\t{\n\t\t\tstateProperty()->toggleState(QtnPropertyStateCollapsed);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tbrItem.tooltipHandler = [this](QtnEventContext &,\n\t\t\t\t\t\t\t\tconst QtnSubItem &) -> QString {\n\t\treturn (stateProperty()->isCollapsed())\n\t\t\t? QtnPropertyView::tr(\"Click to expand\")\n\t\t\t: QtnPropertyView::tr(\"Click to collapse\");\n\t};\n\n\tsubItems.append(brItem);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegate.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_H\n#define QTN_PROPERTY_DELEGATE_H\n\n#include \"QtnProperty/Config.h\"\n#include \"QtnProperty/Property.h\"\n#include \"PropertyDelegateAux.h\"\n\n#include <QStylePainter>\n\nclass QtnPropertyDelegateFactory;\nstruct QtnSubPropertyInfo;\n\nclass QtnPropertyEditorHandlerBase;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegate\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegate)\n\n\tfriend class QtnPropertyEditorHandlerBase;\n\tQtnPropertyDelegateFactory *m_factory = nullptr;\n\tQtnPropertyEditorHandlerBase *m_editorHandler = nullptr;\n\npublic:\n\tvirtual ~QtnPropertyDelegate();\n\tvirtual void init();\n\n\tstatic QIcon resetIcon();\n\n\tQtnPropertyChangeReason editReason() const;\n\n\tinline QtnPropertyBase *stateProperty() const;\n\tinline void setStateProperty(QtnPropertyBase *p);\n\n\tinline QtnPropertyBase *property();\n\tinline const QtnPropertyBase *propertyImmutable() const;\n\n\tinline QtnPropertyDelegateFactory *factory() const;\n\tinline void setFactory(QtnPropertyDelegateFactory *factory);\n\n\t// for complex properties like PropertyQFont\n\tinline int subPropertyCount() const;\n\tinline QtnPropertyBase *subProperty(int index);\n\n\t// tune up with attributes\n\tinline void applyAttributes(const QtnPropertyDelegateInfo &info);\n\t// create GUI sub elements to present property on PropertyView\n\tinline void createSubItems(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems);\n\n\tvoid addSubItemBranchNode(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems);\n\n\tvoid applySubPropertyInfo(\n\t\tconst QtnPropertyDelegateInfo &info, const QtnSubPropertyInfo &subInfo);\n\tvoid applySubPropertyInfos(const QtnPropertyDelegateInfo &info,\n\t\tconst QtnSubPropertyInfo *subInfo, int count);\n\n\tvirtual bool isSplittable() const;\n\nprotected:\n\tQtnPropertyDelegate(QtnPropertyBase &ownerProperty);\n\n\tvoid drawButton(const QtnDrawContext &context, const QtnSubItem &item,\n\t\tconst QIcon &icon, const QString &text);\n\n\tvirtual int subPropertyCountImpl() const;\n\tvirtual QtnPropertyBase *subPropertyImpl(int index);\n\n\tvirtual void applyAttributesImpl(const QtnPropertyDelegateInfo &info);\n\n\tvirtual void createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) = 0;\n\n\t// helper functions\n\tQStyle::State state(bool isActive, const QtnSubItem &subItem) const;\n\n\tvoid addSubItemLock(QtnDrawContext &context, QList<QtnSubItem> &subItems);\n\n\tstatic QColor disabledTextColor(const QStylePainter &painter);\n\nprotected:\n\tQtnPropertyBase *m_ownerProperty;\n\tQtnPropertyBase *m_stateProperty;\n};\n\nQtnPropertyBase *QtnPropertyDelegate::stateProperty() const\n{\n\treturn m_stateProperty ? m_stateProperty : m_ownerProperty;\n}\n\nvoid QtnPropertyDelegate::setStateProperty(QtnPropertyBase *p)\n{\n\tm_stateProperty = p;\n}\n\nQtnPropertyBase *QtnPropertyDelegate::property()\n{\n\treturn m_ownerProperty;\n}\n\nconst QtnPropertyBase *QtnPropertyDelegate::propertyImmutable() const\n{\n\treturn m_ownerProperty;\n}\n\nQtnPropertyDelegateFactory *QtnPropertyDelegate::factory() const\n{\n\treturn m_factory;\n}\n\nvoid QtnPropertyDelegate::setFactory(QtnPropertyDelegateFactory *factory)\n{\n\tm_factory = factory;\n}\n\nint QtnPropertyDelegate::subPropertyCount() const\n{\n\treturn subPropertyCountImpl();\n}\n\nQtnPropertyBase *QtnPropertyDelegate::subProperty(int index)\n{\n\treturn subPropertyImpl(index);\n}\n\nvoid QtnPropertyDelegate::applyAttributes(const QtnPropertyDelegateInfo &info)\n{\n\tapplyAttributesImpl(info);\n}\n\nvoid QtnPropertyDelegate::createSubItems(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tcreateSubItemsImpl(context, subItems);\n}\n\n#endif // QTN_PROPERTY_DELEGATE_H\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegateAux.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateAux.h\"\n#include \"QtnProperty/PropertyView.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/Utils/InplaceEditing.h\"\n#include \"QtnProperty/Utils/QtnConnections.h\"\n\n#include <QMouseEvent>\n#include <QToolTip>\n\nQtnSubItem::QtnSubItem(const QRect &rect)\n\t: rect(rect)\n\t, m_trackState(false)\n\t, m_activeCount(0)\n\t, m_state(QtnSubItemStateNone)\n{\n}\n\nvoid QtnSubItem::setTextAsTooltip(const QString &text)\n{\n\ttooltipHandler = [text](QtnEventContext &, const QtnSubItem &) -> QString {\n\t\treturn text;\n\t};\n}\n\nvoid QtnSubItem::setPropertyNameAsTooltip(const QtnPropertyBase &property)\n{\n\ttooltipHandler = [&property](\n\t\t\t\t\t\t QtnEventContext &, const QtnSubItem &) -> QString {\n\t\treturn property.displayName();\n\t};\n}\n\nvoid QtnSubItem::setPropertyDescriptionAsTooltip(\n\tconst QtnPropertyBase &property)\n{\n\ttooltipHandler = [&property](\n\t\t\t\t\t\t QtnEventContext &, const QtnSubItem &) -> QString {\n\t\tauto descr = property.description();\n\t\tif (descr.isEmpty())\n\t\t\treturn property.displayName();\n\n\t\treturn descr;\n\t};\n}\n\nbool QtnSubItem::activate(QtnPropertyView *widget, QPoint mousePos)\n{\n\tif (!m_trackState)\n\t\treturn false;\n\n\tQ_ASSERT(m_activeCount <= 1);\n\tif (m_activeCount > 1)\n\t\treturn false;\n\n\t++m_activeCount;\n\n\tif (m_state != QtnSubItemStateUnderCursor)\n\t{\n\t\tm_state = QtnSubItemStateUnderCursor;\n\t\twidget->viewport()->update();\n\t\tselfEvent(QtnSubItemEvent::Activated, widget, mousePos);\n\t}\n\n\treturn true;\n}\n\nbool QtnSubItem::deactivate(QtnPropertyView *widget, QPoint mousePos)\n{\n\tif (!m_trackState)\n\t\treturn false;\n\n\tQ_ASSERT(m_activeCount > 0);\n\tif (m_activeCount == 0)\n\t\treturn false;\n\n\t--m_activeCount;\n\n\tif ((m_activeCount == 0) && (m_state != QtnSubItemStateNone))\n\t{\n\t\tm_state = QtnSubItemStateNone;\n\t\twidget->viewport()->update();\n\t\tselfEvent(QtnSubItemEvent::Deactivated, widget, mousePos);\n\t}\n\n\treturn true;\n}\n\nbool QtnSubItem::grabMouse(QtnPropertyView *widget, QPoint mousePos)\n{\n\tQ_ASSERT(m_activeCount > 0);\n\tQ_ASSERT(m_state == QtnSubItemStateUnderCursor);\n\n\tm_state = QtnSubItemStatePushed;\n\twidget->viewport()->update();\n\tselfEvent(QtnSubItemEvent::PressMouse, widget, mousePos);\n\n\treturn true;\n}\n\nbool QtnSubItem::releaseMouse(QtnPropertyView *widget, QPoint mousePos)\n{\n\tQ_ASSERT(m_activeCount > 0);\n\tQ_ASSERT(m_state == QtnSubItemStatePushed);\n\n\tm_state = QtnSubItemStateUnderCursor;\n\twidget->viewport()->update();\n\tselfEvent(QtnSubItemEvent::ReleaseMouse, widget, mousePos);\n\n\treturn true;\n}\n\nvoid QtnSubItem::draw(QtnDrawContext &context) const\n{\n\tif (drawHandler)\n\t\tdrawHandler(context, *this);\n}\n\nbool QtnSubItem::event(QtnEventContext &context)\n{\n\tif (m_trackState)\n\t{\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QEvent::MouseButtonPress:\n\t\t\tcase QEvent::MouseButtonDblClick:\n\t\t\t{\n\t\t\t\tauto event = context.eventAs<QMouseEvent>();\n\t\t\t\tif (event->button() == Qt::LeftButton)\n\t\t\t\t\tcontext.grabMouse(this, event->pos());\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QEvent::MouseButtonRelease:\n\t\t\t{\n\t\t\t\tauto event = context.eventAs<QMouseEvent>();\n\t\t\t\tif ((event->button() == Qt::LeftButton) &&\n\t\t\t\t\t(m_state == QtnSubItemStatePushed))\n\t\t\t\t\tcontext.releaseMouse(this, event->pos());\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (context.eventType() == QEvent::ToolTip)\n\t{\n\t\tif (!tooltipHandler)\n\t\t\treturn false;\n\n\t\tQString tooltipText = tooltipHandler(context, *this);\n\t\tif (!tooltipText.isEmpty())\n\t\t{\n\t\t\tauto event = context.eventAs<QHelpEvent>();\n\t\t\tQToolTip::showText(\n\t\t\t\tevent->globalPos(), tooltipText, context.widget, rect);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (eventHandler)\n\t{\n\t\tQtnPropertyToEdit propertyToEdit;\n\t\tbool result = eventHandler(context, *this, &propertyToEdit);\n\t\tif (propertyToEdit.isValid())\n\t\t{\n\t\t\tauto editProperty = propertyToEdit.property();\n\t\t\tbool editable = editProperty->isEditableByUser();\n\t\t\tstd::shared_ptr<QtnConnections> connections;\n\t\t\tif (editable)\n\t\t\t{\n\t\t\t\tconnections = std::make_shared<QtnConnections>();\n\t\t\t\tstd::weak_ptr<QtnConnections> weakConnections = connections;\n\t\t\t\tconnections->push_back(\n\t\t\t\t\tQObject::connect(editProperty, &QObject::destroyed,\n\t\t\t\t\t\t[weakConnections]() //\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!weakConnections.expired())\n\t\t\t\t\t\t\t\tweakConnections.lock()->clear();\n\t\t\t\t\t\t}));\n\t\t\t\tcontext.widget->connectPropertyToEdit(\n\t\t\t\t\teditProperty, *connections.get());\n\t\t\t}\n\t\t\tauto editor = propertyToEdit.createEditor();\n\t\t\tif (editor)\n\t\t\t{\n\t\t\t\tif (editable)\n\t\t\t\t{\n\t\t\t\t\tQObject::connect(editor, &QObject::destroyed,\n\t\t\t\t\t\t[connections]() { connections->disconnect(); });\n\t\t\t\t}\n\n\t\t\t\tqtnStartInplaceEdit(editor);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn false;\n}\n\nbool QtnSubItem::selfEvent(\n\tQtnSubItemEvent::Type type, QtnPropertyView *widget, QPoint mousePos)\n{\n\tQtnSubItemEvent event_(type, mousePos);\n\tQtnEventContext context{ &event_, widget };\n\treturn event(context);\n}\n\nQStyle *QtnDrawContext::style() const\n{\n\treturn widget->style();\n}\n\nvoid QtnDrawContext::initStyleOption(QStyleOption &option) const\n{\n\toption.initFrom(widget);\n\t// State_MouseOver should be set explicitly\n\toption.state &= ~QStyle::State_MouseOver;\n}\n\nconst QPalette &QtnDrawContext::palette() const\n{\n\treturn widget->palette();\n}\n\nQPalette::ColorGroup QtnDrawContext::colorGroup() const\n{\n\treturn palette().currentColorGroup();\n}\n\nQColor QtnDrawContext::alternateColor() const\n{\n\tauto color = palette().color(QPalette::Button);\n\tif (color == palette().color(QPalette::Window))\n\t{\n\t\tcolor = color.darker(120);\n\t}\n\treturn color;\n}\n\nQColor QtnDrawContext::textColorFor(bool normalText) const\n{\n\tQPalette::ColorRole role;\n\tQPalette::ColorGroup group =\n\t\tnormalText ? palette().currentColorGroup() : QPalette::Disabled;\n\tif (isActive)\n\t{\n\t\trole = QPalette::HighlightedText;\n\t} else if (normalText)\n\t{\n\t\trole = QPalette::Text;\n\t} else\n\t{\n#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)\n\t\tgroup = QPalette::Active;\n\t\trole = QPalette::PlaceholderText;\n#else\n\t\tgroup = QPalette::Disabled;\n\t\trole = QPalette::Text;\n#endif\n\t}\n\n\treturn palette().color(group, role);\n}\n\nvoid QtnEventContext::updateWidget()\n{\n\twidget->viewport()->update();\n}\n\nbool QtnEventContext::grabMouse(QtnSubItem *subItem, QPoint mousePos)\n{\n\treturn widget->grabMouseForSubItem(subItem, mousePos);\n}\n\nbool QtnEventContext::releaseMouse(QtnSubItem *subItem, QPoint mousePos)\n{\n\treturn widget->releaseMouseForSubItem(subItem, mousePos);\n}\n\nQtnSubItemEvent::QtnSubItemEvent(Type type, QPoint mousePos)\n\t: QEvent((QEvent::Type) type)\n\t, m_mousePos(mousePos)\n{\n}\n\nQString qtnElidedText(const QPainter &painter, const QString &text,\n\tconst QRect &rect, bool *elided)\n{\n\tQString newText =\n\t\tpainter.fontMetrics().elidedText(text, Qt::ElideRight, rect.width());\n\n\tif (elided)\n\t\t*elided = (newText != text);\n\n\treturn newText;\n}\n\nvoid qtnDrawValueText(\n\tconst QString &text, QPainter &painter, const QRect &rect, QStyle *style)\n{\n\tif (text.isEmpty())\n\t\treturn;\n\n\tauto textRect = rect;\n\tif (style)\n\t{\n\t\ttextRect.adjust(style->pixelMetric(QStyle::PM_ButtonMargin), 0, 0, 0);\n\t}\n\n\tpainter.drawText(textRect, Qt::AlignLeading | Qt::AlignVCenter,\n\t\tqtnElidedText(painter, text, textRect, nullptr));\n}\n\nQtnPropertyToEdit::QtnPropertyToEdit()\n\t: m_property(nullptr)\n{\n}\n\nQtnPropertyToEdit::QtnPropertyToEdit(const QtnPropertyToEdit &other)\n{\n\tm_property = other.m_property;\n\tm_editorMaker = other.m_editorMaker;\n}\n\nvoid QtnPropertyToEdit::setup(\n\tQtnPropertyBase *property, const EditorMaker &editorMaker)\n{\n\tQ_ASSERT(property);\n\tQ_ASSERT(editorMaker);\n\tm_property = property;\n\tm_editorMaker = editorMaker;\n}\n\nQWidget *QtnPropertyToEdit::createEditor() const\n{\n\tif (!m_editorMaker)\n\t\treturn nullptr;\n\n\treturn m_editorMaker();\n}\n\nbool QtnPropertyToEdit::isValid() const\n{\n\treturn m_property && m_editorMaker;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegateAux.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_AUX_H\n#define QTN_PROPERTY_DELEGATE_AUX_H\n\n#include \"QtnProperty/FunctionalHelpers.h\"\n\n#include <QStyleOption>\n#include <QStylePainter>\n#include <QEvent>\n#include <QVariant>\n\nclass QtnPropertyBase;\nclass QtnPropertyView;\nstruct QtnDrawContext;\nstruct QtnEventContext;\n\nclass QTN_IMPORT_EXPORT QtnSubItemEvent : public QEvent\n{\npublic:\n\tenum Type\n\t{\n\t\tActivated = 3 * QEvent::User + 15,\n\t\tDeactivated = 3 * QEvent::User + 16,\n\t\tPressMouse = 3 * QEvent::User + 17,\n\t\tReleaseMouse = 3 * QEvent::User + 18\n\t};\n\n\tQtnSubItemEvent(Type type, QPoint mousePos);\n\n\tinline QPoint pos() const;\n\tinline int x() const;\n\tinline int y() const;\n\nprivate:\n\tQPoint m_mousePos;\n};\n\nQPoint QtnSubItemEvent::pos() const\n{\n\treturn m_mousePos;\n}\n\nint QtnSubItemEvent::x() const\n{\n\treturn m_mousePos.x();\n}\n\nint QtnSubItemEvent::y() const\n{\n\treturn m_mousePos.y();\n}\n\nenum QtnSubItemState\n{\n\tQtnSubItemStateNone,\n\tQtnSubItemStateUnderCursor,\n\tQtnSubItemStatePushed\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyToEdit\n{\npublic:\n\tusing EditorMaker = std::function<QWidget *()>;\n\n\tQtnPropertyToEdit();\n\tQtnPropertyToEdit(const QtnPropertyToEdit &other);\n\n\tvoid setup(QtnPropertyBase *property, const EditorMaker &editorMaker);\n\n\tQtnPropertyBase *property() const;\n\tQWidget *createEditor() const;\n\n\tbool isValid() const;\n\nprivate:\n\tQtnPropertyBase *m_property;\n\tEditorMaker m_editorMaker;\n};\n\ninline QtnPropertyBase *QtnPropertyToEdit::property() const\n{\n\treturn m_property;\n}\n\nstruct QTN_IMPORT_EXPORT QtnSubItem\n{\n\tusing DrawHandler =\n\t\tstd::function<void(QtnDrawContext &, const QtnSubItem &)>;\n\tusing EventHandler = std::function<bool(\n\t\tQtnEventContext &, const QtnSubItem &, QtnPropertyToEdit *)>;\n\tusing ToolTipHandler =\n\t\tstd::function<QString(QtnEventContext &, const QtnSubItem &)>;\n\n\tQtnSubItem(const QRect &rect);\n\n\tQRect rect;\n\n\tDrawHandler drawHandler;\n\tEventHandler eventHandler;\n\tToolTipHandler tooltipHandler;\n\n\tinline QtnSubItemState state() const;\n\tinline void trackState();\n\n\tvoid setTextAsTooltip(const QString &text);\n\tvoid setPropertyNameAsTooltip(const QtnPropertyBase &property);\n\tvoid setPropertyDescriptionAsTooltip(const QtnPropertyBase &property);\n\nprivate:\n\tbool activate(QtnPropertyView *widget, QPoint mousePos);\n\tbool deactivate(QtnPropertyView *widget, QPoint mousePos);\n\n\tbool grabMouse(QtnPropertyView *widget, QPoint mousePos);\n\tbool releaseMouse(QtnPropertyView *widget, QPoint mousePos);\n\n\tvoid draw(QtnDrawContext &context) const;\n\tbool event(QtnEventContext &context);\n\tbool selfEvent(\n\t\tQtnSubItemEvent::Type type, QtnPropertyView *widget, QPoint mousePos);\n\n\tbool m_trackState;\n\tquint8 m_activeCount;\n\tQtnSubItemState m_state;\n\n\tfriend class QtnPropertyView;\n};\n\nQtnSubItemState QtnSubItem::state() const\n{\n\treturn m_state;\n}\n\nvoid QtnSubItem::trackState()\n{\n\tm_trackState = true;\n}\n\nstruct QTN_IMPORT_EXPORT QtnDrawContext\n{\npublic:\n\tQStylePainter *painter;\n\tconst QtnPropertyView *widget;\n\n\tconst QRect rect;\n\tQMargins margins;\n\tconst int splitPos;\n\n\tconst bool isActive;\n\tconst bool hasChildren;\n\n\tQStyle *style() const;\n\tvoid initStyleOption(QStyleOption &option) const;\n\tconst QPalette &palette() const;\n\tQPalette::ColorGroup colorGroup() const;\n\tQColor alternateColor() const;\n\tQColor textColorFor(bool normalText) const;\n};\n\nstruct QTN_IMPORT_EXPORT QtnEventContext\n{\npublic:\n\tQEvent *event;\n\tQtnPropertyView *widget;\n\n\tinline int eventType() const;\n\ttemplate <class EventT>\n\tEventT *eventAs()\n\t{\n\t\treturn static_cast<EventT *>(event);\n\t}\n\n\tvoid updateWidget();\n\nprivate:\n\tbool grabMouse(QtnSubItem *subItem, QPoint mousePos);\n\tbool releaseMouse(QtnSubItem *subItem, QPoint mousePos);\n\n\tfriend struct QtnSubItem;\n};\n\nint QtnEventContext::eventType() const\n{\n\treturn static_cast<int>(event->type());\n}\n\nQTN_IMPORT_EXPORT QString qtnElidedText(const QPainter &painter,\n\tconst QString &text, const QRect &rect, bool *elided = 0);\nQTN_IMPORT_EXPORT void qtnDrawValueText(const QString &text, QPainter &painter,\n\tconst QRect &rect, QStyle *style = nullptr);\n\ntemplate <typename T,\n\ttypename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>\nvoid fixMinMaxVariant(QVariant &minv, QVariant &maxv)\n{\n\tbool minOk;\n\tbool maxOk;\n\tdouble min = minv.toDouble(&minOk);\n\tdouble max = maxv.toDouble(&maxOk);\n\tif (!minOk || max < min || !qIsFinite(min) ||\n\t\tmin < std::numeric_limits<T>::lowest() ||\n\t\tmin > std::numeric_limits<T>::max())\n\t{\n\t\tminv = QVariant();\n\t} else\n\t{\n\t\tminv = min;\n\t}\n\tif (!maxOk || max < min || !qIsFinite(max) ||\n\t\tmax < std::numeric_limits<T>::lowest() ||\n\t\tmax > std::numeric_limits<T>::max())\n\t{\n\t\tmaxv = QVariant();\n\t} else\n\t{\n\t\tmaxv = max;\n\t}\n}\n\ntemplate <typename T,\n\ttypename std::enable_if<std::is_integral<T>::value>::type * = nullptr>\nvoid fixMinMaxVariant(QVariant &minv, QVariant &maxv)\n{\n\tif (minv.type() == QVariant::ULongLong)\n\t{\n\t\tquint64 min = minv.toULongLong();\n\t\tif (min > quint64(std::numeric_limits<T>::max()))\n\t\t{\n\t\t\tminv = QVariant();\n\t\t} else\n\t\t{\n\t\t\tminv = T(min);\n\t\t}\n\t} else\n\t{\n\t\tbool minOk;\n\t\tqint64 min = minv.toLongLong(&minOk);\n\t\tif (!minOk || min < qint64(std::numeric_limits<T>::min()) ||\n\t\t\t(min >= 0 && quint64(min) > quint64(std::numeric_limits<T>::max())))\n\t\t{\n\t\t\tminv = QVariant();\n\t\t} else\n\t\t{\n\t\t\tminv = T(min);\n\t\t}\n\t}\n\n\tif (maxv.type() == QVariant::ULongLong)\n\t{\n\t\tquint64 max = maxv.toULongLong();\n\t\tif (max > quint64(std::numeric_limits<T>::max()))\n\t\t{\n\t\t\tmaxv = QVariant();\n\t\t} else\n\t\t{\n\t\t\tmaxv = T(max);\n\t\t}\n\t} else\n\t{\n\t\tbool maxOk;\n\t\tqint64 max = maxv.toLongLong(&maxOk);\n\t\tif (!maxOk || max < qint64(std::numeric_limits<T>::min()) ||\n\t\t\t(max >= 0 && quint64(max) > quint64(std::numeric_limits<T>::max())))\n\t\t{\n\t\t\tmaxv = QVariant();\n\t\t} else\n\t\t{\n\t\t\tmaxv = T(max);\n\t\t}\n\t}\n\n\tif (minv.isValid() && maxv.isValid() && maxv < minv)\n\t{\n\t\tminv = QVariant();\n\t\tmaxv = QVariant();\n\t}\n}\n\n#endif // QTN_PROPERTY_DELEGATE_AUX_H\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegateFactory.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateFactory.h\"\n#include \"Utils/PropertyDelegateMisc.h\"\n#include \"Utils/PropertyDelegatePropertySet.h\"\n#include \"Utils/PropertyDelegateGeoCoord.h\"\n#include \"Utils/PropertyDelegateGeoPoint.h\"\n#include \"Core/PropertyDelegateBool.h\"\n#include \"Core/PropertyDelegateInt.h\"\n#include \"Core/PropertyDelegateUInt.h\"\n#include \"Core/PropertyDelegateDouble.h\"\n#include \"Core/PropertyDelegateFloat.h\"\n#include \"Core/PropertyDelegateEnum.h\"\n#include \"Core/PropertyDelegateEnumFlags.h\"\n#include \"Core/PropertyDelegateQString.h\"\n#include \"Core/PropertyDelegateQPoint.h\"\n#include \"Core/PropertyDelegateQPointF.h\"\n#include \"Core/PropertyDelegateQSize.h\"\n#include \"Core/PropertyDelegateQSizeF.h\"\n#include \"Core/PropertyDelegateQRect.h\"\n#include \"Core/PropertyDelegateQRectF.h\"\n#include \"GUI/PropertyDelegateQColor.h\"\n#include \"GUI/PropertyDelegateQPen.h\"\n#include \"GUI/PropertyDelegateQBrush.h\"\n#include \"GUI/PropertyDelegateQFont.h\"\n#include \"GUI/PropertyDelegateQVector3D.h\"\n#include \"GUI/PropertyDelegateButton.h\"\n#include \"QtnProperty/PropertyQKeySequence.h\"\n#include \"QtnProperty/PropertyInt64.h\"\n#include \"QtnProperty/PropertyUInt64.h\"\n#include \"QtnProperty/MultiProperty.h\"\n#include \"QtnProperty/PropertyQVariant.h\"\n\n#include <QDebug>\n\nQtnPropertyDelegateFactory::QtnPropertyDelegateFactory(\n\tQtnPropertyDelegateFactory *superFactory)\n\t: m_superFactory(nullptr)\n{\n\tsetSuperFactory(superFactory);\n}\n\nvoid QtnPropertyDelegateFactory::setSuperFactory(\n\tQtnPropertyDelegateFactory *superFactory)\n{\n\tQ_ASSERT(m_superFactory != this);\n\tm_superFactory = superFactory;\n}\n\nQtnPropertyDelegate *QtnPropertyDelegateFactory::createDelegate(\n\tQtnPropertyBase &owner)\n{\n\tauto factory = this;\n\n\twhile (factory)\n\t{\n\t\tauto result = factory->createDelegateInternal(owner);\n\t\tif (result)\n\t\t{\n\t\t\tresult->setFactory(this);\n\t\t\tresult->init();\n\t\t\treturn result;\n\t\t}\n\n\t\tfactory = factory->m_superFactory;\n\t}\n\n\tauto delegateInfo = owner.delegateInfo();\n\tQByteArray delegateName;\n\n\tif (delegateInfo)\n\t\tdelegateName = delegateInfo->name;\n\n\t// create delegate stub\n\tif (delegateName.isEmpty())\n\t{\n\t\tqWarning() << \"Cannot find default delegate for property\"\n\t\t\t\t   << owner.name();\n\t\tqWarning() << \"Did you forget to register default delegate for \"\n\t\t\t\t   << owner.metaObject()->className() << \"type?\";\n\t} else\n\t{\n\t\tqWarning() << \"Cannot find delegate with name\" << delegateName\n\t\t\t\t   << \"for property\" << owner.name();\n\t\tqWarning() << \"Did you forget to register\" << delegateName\n\t\t\t\t   << \"delegate for\" << owner.metaObject()->className()\n\t\t\t\t   << \"type?\";\n\t}\n\n\treturn qtnCreateDelegateError(owner,\n\t\tQString(\"Delegate <%1> unknown\")\n\t\t\t.arg(QString::fromLatin1(delegateName)));\n}\n\nQtnPropertyDelegate *QtnPropertyDelegateFactory::createDelegateInternal(\n\tQtnPropertyBase &owner)\n{\n\tconst QMetaObject *metaObject = owner.metaObject();\n\n\tCreateFunction createFunction = nullptr;\n\twhile (metaObject && !createFunction)\n\t{\n\t\t// try to find delegate factory by class name\n\t\tauto it = m_createItems.find(metaObject);\n\n\t\tif (it != m_createItems.end())\n\t\t{\n\t\t\t// try to find delegate factory by name\n\t\t\tconst CreateItem &createItem = it.value();\n\t\t\tauto delegateInfo = owner.delegateInfo();\n\t\t\tQByteArray delegateName;\n\n\t\t\tif (delegateInfo)\n\t\t\t\tdelegateName = delegateInfo->name;\n\n\t\t\tif (delegateName.isEmpty())\n\t\t\t{\n\t\t\t\tcreateFunction = createItem.defaultCreateFunction;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tauto jt = createItem.createFunctions.find(delegateName);\n\t\t\t\tif (jt != createItem.createFunctions.end())\n\t\t\t\t\tcreateFunction = jt.value();\n\t\t\t}\n\t\t}\n\n\t\tmetaObject = metaObject->superClass();\n\t}\n\n\tif (!createFunction)\n\t\treturn nullptr;\n\n\treturn createFunction(owner);\n}\n\nbool QtnPropertyDelegateFactory::registerDelegateDefault(\n\tconst QMetaObject *propertyMetaObject, const CreateFunction &createFunction,\n\tconst QByteArray &delegateName)\n{\n\tQ_ASSERT(propertyMetaObject);\n\tQ_ASSERT(createFunction);\n\n\t// find or create creation record\n\tCreateItem &createItem = m_createItems[propertyMetaObject];\n\t// register default create function\n\tcreateItem.defaultCreateFunction = createFunction;\n\n\tif (!delegateName.isEmpty())\n\t{\n\t\treturn registerDelegate(\n\t\t\tpropertyMetaObject, createFunction, delegateName);\n\t}\n\n\treturn true;\n}\n\nbool QtnPropertyDelegateFactory::registerDelegate(\n\tconst QMetaObject *propertyMetaObject, const CreateFunction &createFunction,\n\tconst QByteArray &delegateName)\n{\n\tQ_ASSERT(propertyMetaObject);\n\tQ_ASSERT(createFunction);\n\tQ_ASSERT(!delegateName.isEmpty());\n\n\t// find or create creation record\n\tCreateItem &createItem = m_createItems[propertyMetaObject];\n\t// register create function\n\tcreateItem.createFunctions[delegateName] = createFunction;\n\n\treturn true;\n}\n\nbool QtnPropertyDelegateFactory::unregisterDelegate(\n\tconst QMetaObject *propertyMetaObject)\n{\n\tQ_ASSERT(propertyMetaObject);\n\n\tauto it = m_createItems.find(propertyMetaObject);\n\tif (it == m_createItems.end())\n\t\treturn false;\n\n\tm_createItems.erase(it);\n\treturn true;\n}\n\nbool QtnPropertyDelegateFactory::unregisterDelegate(\n\tconst QMetaObject *propertyMetaObject, const QByteArray &delegateName)\n{\n\tQ_ASSERT(propertyMetaObject);\n\tQ_ASSERT(!delegateName.isEmpty());\n\n\tauto it = m_createItems.find(propertyMetaObject);\n\tif (it == m_createItems.end())\n\t\treturn false;\n\n\tauto &createFunctions = it->createFunctions;\n\tauto it2 = createFunctions.find(delegateName);\n\tif (it2 == createFunctions.end())\n\t\treturn false;\n\n\tcreateFunctions.erase(it2);\n\treturn true;\n}\n\nvoid QtnPropertyDelegateFactory::registerDefaultDelegates(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tQtnPropertyDelegatePropertySet::Register(factory);\n\tQtnPropertyDelegateBoolCheck::Register(factory);\n\tQtnPropertyDelegateBoolCombobox::Register(factory);\n\tQtnPropertyDelegateInt::Register(factory);\n\tQtnPropertyDelegateUInt::Register(factory);\n\tQtnPropertyDelegateInt64::Register(factory);\n\tQtnPropertyDelegateUInt64::Register(factory);\n\tQtnPropertyDelegateDouble::Register(factory);\n\tQtnPropertyDelegateFloat::Register(factory);\n\tQtnPropertyDelegateEnum::Register(factory);\n\tQtnPropertyDelegateEnumFlags::Register(factory);\n\tQtnPropertyDelegateQString::Register(factory);\n\tQtnPropertyDelegateQStringFile::Register(factory);\n\tQtnPropertyDelegateQStringList::Register(factory);\n\tQtnPropertyDelegateQStringCallback::Register(factory);\n\tQtnPropertyDelegateQPoint::Register(factory);\n\tQtnPropertyDelegateQPointF::Register(factory);\n\tQtnPropertyDelegateQSize::Register(factory);\n\tQtnPropertyDelegateQSizeF::Register(factory);\n\tQtnPropertyDelegateQRect::Register(factory);\n\tQtnPropertyDelegateQRectF::Register(factory);\n\tQtnPropertyDelegateGeoCoord::Register(factory);\n\tQtnPropertyDelegateGeoPoint::Register(factory);\n\tQtnPropertyDelegateQColor::Register(factory);\n\tQtnPropertyDelegateQColorSolid::Register(factory);\n\tQtnPropertyDelegateQFont::Register(factory);\n\tQtnPropertyDelegateButton::Register(factory);\n\tQtnPropertyDelegateButtonLink::Register(factory);\n\tQtnPropertyDelegateQPenStyle::Register(factory);\n\tQtnPropertyDelegateQPen::Register(factory);\n\tQtnPropertyDelegateQBrushStyle::Register(factory);\n\tQtnPropertyDelegateQKeySequence::Register(factory);\n\tQtnPropertyDelegateQVector3D::Register(factory);\n\tQtnPropertyDelegateQVariant::Register(factory);\n\tQtnMultiPropertyDelegate::Register(factory);\n}\n\nstatic QScopedPointer<QtnPropertyDelegateFactory> _staticInstance;\n\nQtnPropertyDelegateFactory &QtnPropertyDelegateFactory::staticInstance()\n{\n\tif (!_staticInstance)\n\t{\n\t\t_staticInstance.reset(new QtnPropertyDelegateFactory);\n\t\tregisterDefaultDelegates(*_staticInstance.data());\n\t}\n\treturn *_staticInstance.data();\n}\n\nvoid QtnPropertyDelegateFactory::resetDefaultInstance(\n\tQtnPropertyDelegateFactory *factory)\n{\n\tif (_staticInstance)\n\t{\n\t\tauto currentFactory = factory;\n\t\twhile (currentFactory)\n\t\t{\n\t\t\tif (currentFactory == _staticInstance.data())\n\t\t\t{\n\t\t\t\t_staticInstance.take();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrentFactory = currentFactory->superFactory();\n\t\t}\n\t}\n\n\t_staticInstance.reset(factory);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/PropertyDelegateFactory.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_FACTORY_H\n#define QTN_PROPERTY_DELEGATE_FACTORY_H\n\n#include \"PropertyDelegate.h\"\n#include <QMap>\n\n#include <functional>\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateFactory\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateFactory)\n\npublic:\n\tusing CreateFunction =\n\t\tstd::function<QtnPropertyDelegate *(QtnPropertyBase &)>;\n\n\texplicit QtnPropertyDelegateFactory(\n\t\tQtnPropertyDelegateFactory *superFactory = nullptr);\n\n\tstatic void registerDefaultDelegates(QtnPropertyDelegateFactory &factory);\n\n\tinline QtnPropertyDelegateFactory *superFactory();\n\tvoid setSuperFactory(QtnPropertyDelegateFactory *superFactory);\n\n\tQtnPropertyDelegate *createDelegate(QtnPropertyBase &owner);\n\n\tbool registerDelegateDefault(const QMetaObject *propertyMetaObject,\n\t\tconst CreateFunction &createFunction,\n\t\tconst QByteArray &delegateName = QByteArray());\n\tbool registerDelegate(const QMetaObject *propertyMetaObject,\n\t\tconst CreateFunction &createFunction, const QByteArray &delegateName);\n\n\tbool unregisterDelegate(const QMetaObject *propertyMetaObject);\n\tbool unregisterDelegate(\n\t\tconst QMetaObject *propertyMetaObject, const QByteArray &delegateName);\n\n\tstatic QtnPropertyDelegateFactory &staticInstance();\n\tstatic void resetDefaultInstance(QtnPropertyDelegateFactory *factory);\n\nprivate:\n\tQtnPropertyDelegate *createDelegateInternal(QtnPropertyBase &owner);\n\n\tQtnPropertyDelegateFactory *m_superFactory;\n\n\tstruct CreateItem\n\t{\n\t\tCreateFunction defaultCreateFunction;\n\t\tQMap<QByteArray, CreateFunction> createFunctions;\n\t};\n\n\tQMap<const QMetaObject *, CreateItem> m_createItems;\n};\n\nQtnPropertyDelegateFactory *QtnPropertyDelegateFactory::superFactory()\n{\n\treturn m_superFactory;\n}\n\ntemplate <typename PropertyDelegateClass, typename PropertyClass>\nQtnPropertyDelegate *qtnCreateDelegate(QtnPropertyBase &owner)\n{\n\tPropertyClass *theOwner = qobject_cast<PropertyClass *>(&owner);\n\tif (!theOwner)\n\t\treturn nullptr;\n\n\treturn new PropertyDelegateClass(*theOwner);\n}\n\n#endif // QTN_PROPERTY_DELEGATE_FACTORY_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateGeoCoord.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateGeoCoord.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorHandler.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n\n#include <QLineEdit>\n\nQByteArray qtnGeoCoordDelegateName()\n{\n\treturn QByteArrayLiteral(\"GeoCoord\");\n}\n\nvoid QtnPropertyDelegateGeoCoord::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyDoubleBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateGeoCoord, QtnPropertyDoubleBase>,\n\t\tqtnGeoCoordDelegateName());\n}\n\nQString val2strGeoCoord(const double c)\n{\n\tQString s;\n\ts = c < 0 ? \"-\" : \"\";\n\tdouble r = qAbs(c);\n\tint deg = static_cast<int>(r);\n\tr -= deg;\n\tr *= 60;\n\tint min = static_cast<int>(r);\n\tr -= min;\n\tr *= 60;\n\tint sec = static_cast<int>(r);\n\tif (sec == 60)\n\t{\n\t\tsec = 0;\n\t\t++min;\n\t\tif (min == 60)\n\t\t{\n\t\t\tmin = 0;\n\t\t\t++deg;\n\t\t}\n\t}\n\n\tQString txt = QString::fromUtf8(\"%1 %2° %3\\' %4\\\"\")\n\t\t\t\t\t  .arg(s)\n\t\t\t\t\t  .arg(deg, 3, 10, QChar('0'))\n\t\t\t\t\t  .arg(min, 2, 10, QChar('0'))\n\t\t\t\t\t  .arg(sec, 2, 10, QChar('0'));\n\treturn txt;\n}\n\ndouble str2valGeoCoord(const QString &strVal)\n{\n\tstatic const QRegExp parserDeg(\n\t\tQString::fromUtf8(\".*(\\\\d+)°.*\"), Qt::CaseInsensitive);\n\tstatic const QRegExp parserMin(\".*(\\\\d+)\\'.*\", Qt::CaseInsensitive);\n\tstatic const QRegExp parserSec(\".*(\\\\d+\\\\.?\\\\d*)\\\".*\", Qt::CaseInsensitive);\n\tstatic const QRegExp parserSign(\"^(-).*\", Qt::CaseInsensitive);\n\n\tQString str = strVal;\n\tstr.remove(\" \");\n\tqreal val = 0.;\n\tif (parserDeg.exactMatch(str))\n\t{\n\t\tif (parserDeg.capturedTexts().size() == 2)\n\t\t{\n\t\t\tval += parserDeg.capturedTexts().at(1).toInt();\n\t\t}\n\t}\n\tif (parserMin.exactMatch(str))\n\t{\n\t\tif (parserMin.capturedTexts().size() == 2)\n\t\t{\n\t\t\tval += parserMin.capturedTexts().at(1).toInt() / 60.;\n\t\t}\n\t}\n\tif (parserSec.exactMatch(str))\n\t{\n\t\tif (parserSec.capturedTexts().size() == 2)\n\t\t{\n\t\t\tval += parserSec.capturedTexts().at(1).toDouble() / 60. / 60.;\n\t\t}\n\t}\n\tif (parserSign.exactMatch(str))\n\t{\n\t\tval = -val;\n\t}\n\treturn val;\n}\n\nclass QtnPropertyGeoCoordLineEditHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyDoubleBase, QLineEdit>\n{\npublic:\n\tQtnPropertyGeoCoordLineEditHandler(\n\t\tQtnPropertyDelegate *delegate, QLineEdit &editor);\n\nprivate:\n\tvirtual void updateEditor() override;\n\tvoid onValueChanged();\n};\n\nQtnPropertyDelegateGeoCoord::QtnPropertyDelegateGeoCoord(\n\tQtnPropertyDoubleBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyDoubleBase>(owner)\n{\n}\n\nQWidget *QtnPropertyDelegateGeoCoord::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tbool editable = stateProperty()->isEditableByUser();\n\tauto lineEdit =\n\t\tcreateValueEditorLineEdit(parent, rect, !editable, inplaceInfo);\n\n\tnew QtnPropertyGeoCoordLineEditHandler(this, *lineEdit);\n\n\tif (editable)\n\t\tqtnInitNumEdit(lineEdit, inplaceInfo, NUM_SIGNED_INT);\n\n\treturn lineEdit;\n}\n\nbool QtnPropertyDelegateGeoCoord::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tstrValue = val2strGeoCoord(owner().value());\n\treturn true;\n}\n\nQtnPropertyGeoCoordLineEditHandler::QtnPropertyGeoCoordLineEditHandler(\n\tQtnPropertyDelegate *delegate, QLineEdit &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n{\n\teditor.setInputMask(QString::fromUtf8(\"# 000° 00\\' 00\\\"\"));\n\n\tupdateEditor();\n\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyGeoCoordLineEditHandler::onValueChanged);\n}\n\nvoid QtnPropertyGeoCoordLineEditHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().clear();\n\t} else\n\t{\n\t\teditor().setText(val2strGeoCoord(property().value()));\n\t\teditor().selectAll();\n\t}\n\n\tupdating--;\n}\n\nvoid QtnPropertyGeoCoordLineEditHandler::onValueChanged()\n{\n\tif (canApply())\n\t{\n\t\tproperty().setValue(\n\t\t\tstr2valGeoCoord(editor().text()), delegate()->editReason());\n\t}\n\n\tapplyReset();\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateGeoCoord.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_GEOCOORD_H\n#define PROPERTY_DELEGATE_GEOCOORD_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyDouble.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateGeoCoord\n\t: public QtnPropertyDelegateTyped<QtnPropertyDoubleBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateGeoCoord)\n\npublic:\n\tQtnPropertyDelegateGeoCoord(QtnPropertyDoubleBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_GEOCOORD_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateGeoPoint.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateGeoPoint.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n\n#include <QLineEdit>\n#include <QCoreApplication>\n\nQByteArray qtnGeoPointDelegateName()\n{\n\treturn QByteArrayLiteral(\"GeoPoint\");\n}\n\nvoid QtnPropertyDelegateGeoPoint::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegate(&QtnPropertyQPointFBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateGeoPoint, QtnPropertyQPointFBase>,\n\t\tqtnGeoPointDelegateName());\n}\n\nQString QtnPropertyDelegateGeoPoint::longitudeKey()\n{\n\treturn QStringLiteral(\"longitude\");\n}\n\nQString QtnPropertyDelegateGeoPoint::longitudeDisplayName()\n{\n\treturn QCoreApplication::instance()->translate(\n\t\t\"GeoPoint\", QT_TRANSLATE_NOOP(\"GeoPoint\", \"Longitude\"));\n}\n\nQString QtnPropertyDelegateGeoPoint::longitudeDescriptionFmt()\n{\n\treturn QCoreApplication::instance()->translate(\n\t\t\"GeoPoint\", QT_TRANSLATE_NOOP(\"GeoPoint\", \"Longitude of %1\"));\n}\n\nQString QtnPropertyDelegateGeoPoint::latitudeKey()\n{\n\treturn QStringLiteral(\"latitude\");\n}\n\nQString QtnPropertyDelegateGeoPoint::latitudeDisplayName()\n{\n\treturn QCoreApplication::instance()->translate(\n\t\t\"GeoPoint\", QT_TRANSLATE_NOOP(\"GeoPoint\", \"Latitude\"));\n}\n\nQString QtnPropertyDelegateGeoPoint::latitudeDescriptionFmt()\n{\n\treturn QCoreApplication::instance()->translate(\n\t\t\"GeoPoint\", QT_TRANSLATE_NOOP(\"GeoPoint\", \"Latitude of %1\"));\n}\n\nQtnPropertyDelegateGeoPoint::QtnPropertyDelegateGeoPoint(\n\tQtnPropertyQPointFBase &owner)\n\t: QtnPropertyDelegateTypedEx<QtnPropertyQPointFBase>(owner)\n{\n\tQtnPropertyDelegateInfo geoDelegate;\n\tgeoDelegate.name = qtnGeoCoordDelegateName();\n\tauto longitudeSubProperty =\n\t\towner.createFieldProperty(&QPointF::x, &QPointF::setX, longitudeKey(),\n\t\t\tlongitudeDisplayName(), longitudeDescriptionFmt());\n\tlongitudeSubProperty->setDelegateInfo(geoDelegate);\n\n\tauto latitudeSubProperty =\n\t\towner.createFieldProperty(&QPointF::y, &QPointF::setY, latitudeKey(),\n\t\t\tlatitudeDisplayName(), latitudeDescriptionFmt());\n\tlatitudeSubProperty->setDelegateInfo(geoDelegate);\n\n\taddSubProperty(longitudeSubProperty);\n\taddSubProperty(latitudeSubProperty);\n}\n\nvoid QtnPropertyDelegateGeoPoint::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tenum\n\t{\n\t\tX,\n\t\tY,\n\t\tTOTAL\n\t};\n\tQ_ASSERT(subPropertyCount() == TOTAL);\n\n\tstatic const QtnSubPropertyInfo KEYS[TOTAL] = {\n\t\t{ X, longitudeKey(), qtnXDisplayNameAttr(), qtnXDescriptionAttr() },\n\t\t{ Y, latitudeKey(), qtnYDisplayNameAttr(), qtnYDescriptionAttr() },\n\t};\n\n\tapplySubPropertyInfos(info, KEYS, TOTAL);\n}\n\nQWidget *QtnPropertyDelegateGeoPoint::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorLineEdit(parent, rect, true, inplaceInfo);\n}\n\nextern QString val2strGeoCoord(const double);\n\nbool QtnPropertyDelegateGeoPoint::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tQPointF value = owner().value();\n\tstrValue = QString(\"%1 x %2\")\n\t\t\t\t   .arg(val2strGeoCoord(value.x()))\n\t\t\t\t   .arg(val2strGeoCoord(value.y()));\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateGeoPoint.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_DELEGATE_GEOPOINT_H\n#define PROPERTY_DELEGATE_GEOPOINT_H\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n#include \"QtnProperty/Core/PropertyQPointF.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateGeoPoint\n\t: public QtnPropertyDelegateTypedEx<QtnPropertyQPointFBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateGeoPoint)\n\npublic:\n\tQtnPropertyDelegateGeoPoint(QtnPropertyQPointFBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tstatic QString longitudeKey();\n\tstatic QString longitudeDisplayName();\n\tstatic QString longitudeDescriptionFmt();\n\n\tstatic QString latitudeKey();\n\tstatic QString latitudeDisplayName();\n\tstatic QString latitudeDescriptionFmt();\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n\n#endif // PROPERTY_DELEGATE_GEOPOINT_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateMisc.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateMisc.h\"\n#include \"QtnProperty/PropertyView.h\"\n#include \"QtnProperty/Utils/InplaceEditing.h\"\n#include \"QtnProperty/MultiProperty.h\"\n\n#include <QLineEdit>\n#include <QKeyEvent>\n\nstatic QIcon qtnResetIcon;\n\nQIcon QtnPropertyDelegate::resetIcon()\n{\n\tif (!qtnResetIcon.isNull())\n\t\treturn qtnResetIcon;\n\n\tconst char iconData16[] =\n\t\t\"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/\"\n\t\t\"9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\"\n\t\t\"bWFnZVJlYWR5ccllPAAAAsJJREFUeNp0UktIVGEUPve/\"\n\t\t\"j7l37h2aCSQRzEU46jg5D3QWBUnaWGKE\"\n\t\t\"WTmjNYobF4EERYWYD8bMVUW7XEVGtWsduIloZWoINRkR0oCLWaRCNa/76vzXuRdb+F/O/\"\n\t\t\"V/nfN85\"\n\t\t\"/3eY2tpaOGgwhAFCyKJpmNcNw/iz/\"\n\t\t\"y6bzVozMeHgj+d4kGU5JSvyZ5Zj22mAfWcPYq1tw8ESNiYI\"\n\t\t\"whtJlH673W7T4/EAWp2iKO94gX/IMIywLx440zTtdAVknJLc0rjL5SIIAhzHAc/ze8AsS/\"\n\t\t\"c383/z\"\n\t\t\"XcViMYFHGQcA6wRRFJ9KkjQiu2VAJisA2RwmCkj3oXCo7kr/\"\n\t\t\"ZY+TgfXjuA5MeUSRFeB4DsKRMCQH\"\n\t\t\"EuBv8EPfhUtAWKwUiZIDSUgOJt5jyIYDQFFrampmy2rZcmxqaoSpmcm3eDd96kT7suJRTN\"\n\t\t\"9hH9y6\"\n\t\t\"fQui0ch0WySWLpfLsLW1VQFAqVRdbaVlqKoKvX29q23RWHepVLLSDgQDMJOe2a2uPtIfaY\"\n\t\t\"kuaaoG\"\n\t\t\"9rvZGbDFQlHA+\"\n\t\t\"i0An893p1Qsga7roBENHj959AnveluaQ1l6tl8BS8a19VVAiQAbBTRNgwdz8znq\"\n\t\t\"SFkoIAafDDYez+\"\n\t\t\"qaLiHZKGY6inPCAQgFw3q9v16lwRRkc3Nz1moVBDB0A5rqAwV6jg11V3SJC6Ik\"\n\t\t\"LqD/mANA2c51n12jM33QQr5wEVVZAAYOVWoVUNIJZL6HPULlhrEbY/n/\"\n\t\t\"AOJd8ckz8U5Hb5R0FJtp\"\n\t\t\"F9c/\"\n\t\t\"BZdQQtb72Bss7Y2e8z3Q0Xk67TwiTbO5Ibi0ur6yWFVVNfTq5WvAIMDep2UcpVnRQGpXrw\"\n\t\t\"1C\"\n\t\t\"ajj1DP0/5HK5vQ72+rxAGALffmwIuJ/KfMmMLz5/\"\n\t\t\"QVY+rgDVm2bU2tYKQ8MpI9AcmEeftP9YQ3n7\"\n\t\t\"13YFwOvdW1SYvn7PxHA7gRZHk9AKaEtoc/igy7ZCOzs7Vtw/\"\n\t\t\"AQYASsoRySkHkqIAAAAASUVORK5C\"\n\t\t\"YII=\";\n\n\tconst char iconData32[] =\n\t\t\"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU\"\n\t\t\"1BAACx\"\n\t\t\"jwv8YQUAAAVlSURBVFhH1ZdrTJtVGMdP7y29F3qld4kwNgaGWwiYgYKySRZm0LmREca6aD\"\n\t\t\"IBRZcR\"\n\t\t\"xTDJzBLD0ImBbMmInxDj/GLcZJkf1EFU2KIfNGJiQBZmVkYYiUBbSluf5+W8tXcg4gd/\"\n\t\t\"y+Ht+zzn\"\n\t\t\"Pc//POc6shPYbLZ3tVqtjL5uCy59/\"\n\t\t\"ivUanUbCPgZhJRR05bZEQEqlUqoUCpsSqVyzJnlPJebmyuk\"\n\t\t\"rk3ZEQF8AZ+kpaUREMFVKpRvBoKBCbvdnk3dKdkRAaFQiHC5XCIWi4lCoSCQiXypTPqTw+\"\n\t\t\"HooFWS\"\n\t\t\"wqHPLWG1WnMhUAOPx6uBZyF8LRGLIKhSwQTncDiMmGAgSLw+\"\n\t\t\"L1ldWSXLq8s3fR7f8bm5uXu0mSi2\"\n\t\t\"JMBsNmcJBIJzIrHosEgoIgKhgIAIptdYwMe8RxIMBonf7yeeVQ/xeDx/\"\n\t\t\"raysvDQ7OztM3WE2FQBj\"\n\t\t\"eVgsEX8kgT8ggAnGBsYepwKzEQgEiM/rIyAAy/\"\n\t\t\"DMzEwjdTOknAM2p61TKpWOwLiKZXIZk2Y+n88E\"\n\t\t\"RzBAqoJgZkA7MRqN5O2es0bGGEHSLlgd1ga5VP6pTCYjQqEwHHTbgA67w05On3l9SavTHd\"\n\t\t\"Gn60ep\"\n\t\t\"hyGhABxzmMm/\"\n\t\t\"wEwWikSiqFTjENQdrCNFRYUkZ1cOYzv6QiOT5lgwC1VPVBHXi64fZSJZvUajuUtd\"\n\t\t\"YRIKKHis4Aak7ilMeWTPnY84SfsrbV6L1XyBGwxdS083fIf2fZX7YM4Fo9rCoWo5cZzU7n\"\n\t\t\"/6imfZ\"\n\t\t\"1woryENdUcQJcDqdVuj5H9I0KYfH/\"\n\t\t\"2dm796dS3re6ZnkCfjHtErtb9TMUF5RHoRHuC3oKel844zv\"\n\t\t\"0ZzsNq1Ke5maExI3sCaT6SSo53C4G2saC+50Hac7bunTDWWxwRG2HpY9eXvIexf75iB4+\"\n\t\t\"WbBkTgB\"\n\t\t\"PD73CLumsUFczzU11WuGDGM9zIUA44gB6+Fya3i+gZzt6f4qQ63Nh+\"\n\t\t\"B3qDslcQJWVlZtOOkwMLuZ\"\n\t\t\"2B2Oz+DAWaRV4oCJGnqru4sca2rsAaG1qerGEifA6/\"\n\t\t\"Xy8cmmFHuWt3fXFcaZhIv9798vKSmt06r1\"\n\t\t\"3cmylIxYATx2ybECMAvfj92+\"\n\t\t\"zRiTYDFZy3Tpumv0dVtECcCAMpk0nH62DA0NmWiVhCRa31slSgCm\"\n\t\t\"D9brOgZlM4BIJJLnmB/bwGAwaGFFrWeaM0NsMRgNc9QdJm4OWKyWPyMF4JDML8y/\"\n\t\t\"CtcuJa2yJWAn\"\n\t\t\"7YX9hAdP/\"\n\t\t\"E0UcgU58MwBNXWHiRPwZHX16Pr6ejj9HPgX8AdUKo1qgFbZFJ1OV+Nf9zfhNo5bN3Nc\"\n\t\t\"w6ZW8XjFD7RKmDgBRaVFfSWlJUxwZghgTuJGBEKOQlrPQ5WU9z24nNbK5fIRPMAwe2wmLR\"\n\t\t\"YL7Cc1\"\n\t\t\"vbRamDgBuNO5Tp74mgdnQOQwYINwrHbCuN6BIBW0ehiwGfR6/\"\n\t\t\"SWo8yX0VhO5meFSbnE13zUbzTcY\"\n\t\t\"YwRxZwHiXnJnXR25OjXw4UDUssSG/Gt+4lvzERim+3D1ugf+RWjFwOfx8/\"\n\t\t\"CmhEIx5ZHfHXq2nrS2\"\n\t\t\"t+2PPYqRhAKQhUX3y4ODl/o/Hh4JN4bg0KAQdo7geY/\"\n\t\t\"nBp6a2OvImxIGr6yqJF3dXR+YtKZ2xhhD\"\n\t\t\"UgHI/MP589e/uN7Z19uHPabWDbDxjR9QoJVIkQj6m5qbiMvV8kmGWtcI/\"\n\t\t\"oQ7ZEoBiPuhu3lmevry\"\n\t\t\"QP+gYHJiklpTk5OTTU61niL5BXt7cHum5oRsKgBZWFjIDfGCF6Z+\"\n\t\t\"nar99ptbZHx8nMxMz1DvBpmZ\"\n\t\t\"JlIMq6eiopwUlxRPQGJe02v0Y9SdlC0JYHmw9KCQhIKH4LOD8JqHV25Y78x/\"\n\t\t\"RmAofg9xyCiXE/w8\"\n\t\t\"Q2W4ufHFf4zb7ZYtLS1p6Ov/EUL+BmFpBSMtaelKAAAAAElFTkSuQmCC\";\n\n\t{\n\t\tauto bytes = QByteArray::fromBase64(iconData16);\n\t\tQPixmap pixmap;\n\t\tpixmap.loadFromData(bytes);\n\t\tqtnResetIcon.addPixmap(pixmap);\n\t}\n\n\t{\n\t\tauto bytes = QByteArray::fromBase64(iconData32);\n\t\tQPixmap pixmap;\n\t\tpixmap.loadFromData(bytes);\n\t\tqtnResetIcon.addPixmap(pixmap);\n\t}\n\n\treturn qtnResetIcon;\n}\n\nvoid QtnPropertyDelegateWithValues::createSubItemsImpl(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\taddSubItemBackground(context, subItems);\n\taddSubItemSelection(context, subItems);\n\taddSubItemBranchNode(context, subItems);\n\taddSubItemLock(context, subItems);\n\taddSubItemName(context, subItems);\n\taddSubItemReset(context, subItems);\n\taddSubItemValues(context, subItems);\n}\n\nbool QtnPropertyDelegateWithValues::isSplittable() const\n{\n\treturn true;\n}\n\nQtnPropertyDelegateWithValues::QtnPropertyDelegateWithValues(\n\tQtnPropertyBase &owner)\n\t: QtnPropertyDelegate(owner)\n{\n}\n\nvoid QtnPropertyDelegateWithValues::addSubItemBackground(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem bgItem(context.rect);\n\n\tif (!bgItem.rect.isValid())\n\t\treturn;\n\n\tbgItem.drawHandler = [](QtnDrawContext &context, const QtnSubItem &item) //\n\t{\n\t\tauto &painter = *context.painter;\n\t\tconst auto &rect = item.rect;\n\t\tauto splitPos = context.splitPos;\n\n\t\tQPen oldPen = painter.pen();\n\t\tQPen linesPen(context.palette().color(QPalette::Button));\n\t\tpainter.setPen(linesPen);\n\n\t\t// draw item borders\n\t\tpainter.drawLine(rect.bottomLeft(), rect.bottomRight());\n\t\tpainter.drawLine(splitPos, rect.top(), splitPos, rect.bottom());\n\n\t\tpainter.setPen(oldPen);\n\t};\n\n\tsubItems.append(bgItem);\n}\n\nvoid QtnPropertyDelegateWithValues::addSubItemSelection(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem selItem(context.rect);\n\n\tif (!selItem.rect.isValid())\n\t\treturn;\n\n\tselItem.drawHandler = [](QtnDrawContext &context, const QtnSubItem &item) //\n\t{\n\t\t// highlight background if active property\n\t\tif (context.isActive)\n\t\t{\n\t\t\tcontext.painter->fillRect(\n\t\t\t\titem.rect, context.palette().color(QPalette::Highlight));\n\t\t}\n\t};\n\n\tsubItems.append(selItem);\n}\n\nvoid QtnPropertyDelegateWithValues::addSubItemName(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQtnSubItem nameItem(context.rect.marginsRemoved(context.margins));\n\tnameItem.rect.setRight(context.splitPos);\n\tnameItem.setPropertyDescriptionAsTooltip(*propertyImmutable());\n\n\tif (!nameItem.rect.isValid())\n\t\treturn;\n\n\tnameItem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\tcontext.painter->save();\n\n\t\tcontext.painter->setPen(\n\t\t\tcontext.textColorFor(stateProperty()->isEditableByUser()));\n\n\t\tif (!stateProperty()->valueIsDefault())\n\t\t{\n\t\t\tauto font = context.painter->font();\n\t\t\tfont.setBold(true);\n\t\t\tcontext.painter->setFont(font);\n\t\t}\n\n\t\tcontext.painter->drawText(item.rect,\n\t\t\tint(Qt::AlignLeading | Qt::AlignVCenter) | Qt::TextSingleLine,\n\t\t\tqtnElidedText(\n\t\t\t\t*context.painter, property()->displayName(), item.rect));\n\n\t\tcontext.painter->restore();\n\t};\n\n\tsubItems.append(nameItem);\n}\n\nvoid QtnPropertyDelegateWithValues::addSubItemReset(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tif (!stateProperty()->isResettable() || stateProperty()->valueIsDefault())\n\t{\n\t\treturn;\n\t}\n\n\tQtnSubItem resetItem(context.rect.marginsRemoved(context.margins));\n\tresetItem.rect.setLeft(resetItem.rect.right() - resetItem.rect.height());\n\tif (!resetItem.rect.isValid())\n\t\treturn;\n\n\tresetItem.setTextAsTooltip(QtnPropertyView::tr(\"Reset to default value\"));\n\tresetItem.trackState();\n\n\tresetItem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\tconst QtnSubItem &item) {\n\t\tdrawButton(context, item, resetIcon(),\n\t\t\tQtnPropertyView::tr(\"R\", \"Reset button text\"));\n\t};\n\n\tresetItem.eventHandler = [this](QtnEventContext &context,\n\t\t\t\t\t\t\t\t const QtnSubItem &,\n\t\t\t\t\t\t\t\t QtnPropertyToEdit *toEdit) -> bool {\n\t\tbool doClick = false;\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QtnSubItemEvent::ReleaseMouse:\n\t\t\t\tdoClick = true;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (doClick)\n\t\t{\n\t\t\ttoEdit->setup(stateProperty(), [this]() -> QWidget * {\n\t\t\t\tstateProperty()->reset(editReason());\n\t\t\t\treturn nullptr;\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tsubItems.append(resetItem);\n}\n\nvoid QtnPropertyDelegateWithValues::addSubItemValues(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tauto rect = context.rect.marginsRemoved(context.margins);\n\trect.setLeft(context.splitPos);\n\n\tif (stateProperty()->isResettable() && !stateProperty()->valueIsDefault())\n\t{\n\t\trect.setRight(rect.right() - rect.height());\n\t}\n\n\tif (rect.isValid())\n\t\tcreateSubItemValuesImpl(context, rect, subItems);\n}\n\nQtnPropertyDelegateWithValue::QtnPropertyDelegateWithValue(\n\tQtnPropertyBase &owner)\n\t: QtnPropertyDelegateWithValues(owner)\n{\n}\n\nvoid QtnPropertyDelegateWithValue::createSubItemValuesImpl(\n\tQtnDrawContext &context, const QRect &valueRect,\n\tQList<QtnSubItem> &subItems)\n{\n\tQtnSubItem subItem(valueRect);\n\tif (createSubItemValueImpl(context, subItem))\n\t\tsubItems.append(subItem);\n}\n\nbool QtnPropertyDelegateWithValueEditor::propertyValueToStr(\n\tQString &strValue) const\n{\n\treturn propertyValueToStrImpl(strValue);\n}\n\nQtnPropertyDelegateWithValueEditor::QtnPropertyDelegateWithValueEditor(\n\tQtnPropertyBase &owner)\n\t: QtnPropertyDelegateWithValue(owner)\n{\n}\n\nbool QtnPropertyDelegateWithValueEditor::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tQ_UNUSED(strValue);\n\treturn false;\n}\n\nbool QtnPropertyDelegateWithValueEditor::toolTipImpl(QString &strValue) const\n{\n\treturn propertyValueToStrImpl(strValue);\n}\n\nbool QtnPropertyDelegateWithValueEditor::createSubItemValueImpl(\n\tQtnDrawContext &, QtnSubItem &subItemValue)\n{\n\tsubItemValue.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\t// draw property value\n\t\tauto oldBrush = context.painter->brush();\n\t\tauto oldPen = context.painter->pen();\n\t\tauto isNormalText = stateProperty()->isEditableByUser() &&\n\t\t\t!stateProperty()->isMultiValue();\n\t\tauto cg = isNormalText ? context.colorGroup() : QPalette::Disabled;\n\t\tauto color = context.textColorFor(isNormalText);\n\t\tauto bgColor = context.isActive\n\t\t\t? context.palette().color(cg, QPalette::Highlight)\n\t\t\t: context.alternateColor();\n\n\t\tcontext.painter->setBrush(bgColor);\n\t\tcontext.painter->setPen(color);\n\t\tdrawValueImpl(*context.painter, item.rect);\n\t\tcontext.painter->setBrush(oldBrush);\n\t\tcontext.painter->setPen(oldPen);\n\t};\n\n\tsubItemValue.eventHandler = [this](QtnEventContext &context,\n\t\t\t\t\t\t\t\t\tconst QtnSubItem &item,\n\t\t\t\t\t\t\t\t\tQtnPropertyToEdit *propertyToEdit) -> bool {\n\t\tbool doEdit = false;\n\t\tswitch (context.eventType())\n\t\t{\n\t\t\tcase QEvent::MouseButtonDblClick:\n\t\t\t\tdoEdit = (context.widget->propertyViewStyle() &\n\t\t\t\t\tQtnPropertyViewStyleDblClickActivation);\n\t\t\t\tbreak;\n\n\t\t\tcase QEvent::MouseButtonRelease:\n\t\t\t\tdoEdit = !(context.widget->propertyViewStyle() &\n\t\t\t\t\tQtnPropertyViewStyleDblClickActivation);\n\t\t\t\tbreak;\n\n\t\t\tcase QEvent::KeyPress:\n\t\t\t\tdoEdit = acceptKeyPressedForInplaceEditImpl(\n\t\t\t\t\tcontext.eventAs<QKeyEvent>());\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (doEdit)\n\t\t{\n\t\t\tauto ctx = &context;\n\t\t\tauto it = &item;\n\t\t\tpropertyToEdit->setup(property(), [this, ctx, it]() -> QWidget * {\n\t\t\t\tQtnInplaceInfo inplaceInfo;\n\t\t\t\tinplaceInfo.activationEvent = ctx->event;\n\t\t\t\treturn createValueEditorImpl(\n\t\t\t\t\tctx->widget->viewport(), it->rect, &inplaceInfo);\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tsubItemValue.tooltipHandler = [this](QtnEventContext &,\n\t\t\t\t\t\t\t\t\t  const QtnSubItem &) -> QString {\n\t\tif (stateProperty()->isMultiValue())\n\t\t{\n\t\t\treturn QtnMultiProperty::getMultiValuePlaceholder();\n\t\t}\n\t\tQString valueText;\n\t\tif (!toolTipImpl(valueText))\n\t\t\treturn QString();\n\t\treturn valueText;\n\t};\n\n\treturn true;\n}\n\nbool QtnPropertyDelegateWithValueEditor::isNormalPainterState(\n\tconst QStylePainter &painter) const\n{\n\tif (!stateProperty())\n\t{\n\t\treturn false;\n\t}\n\n\tif (!stateProperty()->isEditableByUser())\n\t{\n\t\treturn false;\n\t}\n\n\tauto palette = painter.style()->standardPalette();\n\treturn palette.currentColorGroup() != QPalette::Disabled &&\n\t\tpainter.brush().color() != palette.color(QPalette::Highlight);\n}\n\nbool QtnPropertyDelegateWithValueEditor::isPlaceholderColor() const\n{\n\treturn false;\n}\n\nvoid QtnPropertyDelegateWithValueEditor::drawValueImpl(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tqtnDrawValueText(QtnMultiProperty::getMultiValuePlaceholder(), painter,\n\t\t\trect, painter.style());\n\t\treturn;\n\t}\n\n\tQString strValue;\n\tif (propertyValueToStrImpl(strValue))\n\t{\n\t\tQPen oldPen;\n\t\tbool penChanged = false;\n\t\tif (isNormalPainterState(painter) && isPlaceholderColor())\n\t\t{\n\t\t\toldPen = painter.pen();\n\t\t\tpenChanged = true;\n\t\t\tpainter.setPen(disabledTextColor(painter));\n\t\t}\n\t\tqtnDrawValueText(strValue, painter, rect, painter.style());\n\t\tif (penChanged)\n\t\t{\n\t\t\tpainter.setPen(oldPen);\n\t\t}\n\t}\n}\n\nbool QtnPropertyDelegateWithValueEditor::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tint key = keyEvent->key();\n    return  (key == Qt::Key_Space) ||\n            (key == Qt::Key_Return) ||\n            (key == Qt::Key_Enter);\n}\n\nQLineEdit *QtnPropertyDelegateWithValueEditor::createValueEditorLineEdit(\n\tQWidget *parent, const QRect &rect, bool readOnly,\n\tQtnInplaceInfo *inplaceInfo) const\n{\n\tQLineEdit *lineEdit = new QLineEdit(parent);\n\tlineEdit->setGeometry(rect);\n\tlineEdit->setReadOnly(readOnly);\n\tlineEdit->setPlaceholderText(QtnMultiProperty::getMultiValuePlaceholder());\n\n\tif (!stateProperty()->isMultiValue())\n\t{\n\t\tQString strValue;\n\t\tpropertyValueToStrImpl(strValue);\n\t\tlineEdit->setText(strValue);\n\t}\n\n\tif (inplaceInfo)\n\t{\n\t\tlineEdit->selectAll();\n\t}\n\n\treturn lineEdit;\n}\n\nQtnPropertyDelegateError::QtnPropertyDelegateError(\n\tQtnPropertyBase &owner, const QString &error)\n\t: QtnPropertyDelegateWithValue(owner)\n\t, m_error(error)\n{\n}\n\nbool QtnPropertyDelegateError::createSubItemValueImpl(\n\tQtnDrawContext & /*context*/, QtnSubItem &subItemValue)\n{\n\tsubItemValue.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\tQPen oldPen = context.painter->pen();\n\t\tcontext.painter->setPen(Qt::red);\n\t\tqtnDrawValueText(m_error, *context.painter, item.rect, context.style());\n\t\tcontext.painter->setPen(oldPen);\n\t};\n\n\treturn true;\n}\n\nQtnPropertyDelegate *qtnCreateDelegateError(\n\tQtnPropertyBase &owner, QString error)\n{\n\treturn new QtnPropertyDelegateError(owner, error);\n}\n\nQtnInplaceInfo::QtnInplaceInfo()\n\t: activationEvent(0)\n{\n}\n\nvoid QtnPropertyDelegate::drawButton(const QtnDrawContext &context,\n\tconst QtnSubItem &item, const QIcon &icon, const QString &text)\n{\n\tauto style = context.style();\n\n\tQStyleOptionToolButton option;\n\tcontext.initStyleOption(option);\n\n\toption.state = state(context.isActive, item);\n\toption.state &= ~QStyle::State_HasFocus;\n\tif (0 == (option.state & QStyle::State_Sunken))\n\t{\n\t\toption.state |= QStyle::State_Raised;\n\t}\n\t// dont initialize styleObject from widget for QWindowsVistaStyle\n\t// this disables buggous animations\n\tif (style->inherits(\"QWindowsVistaStyle\"))\n\t\toption.styleObject = nullptr;\n#ifdef Q_OS_MAC\n\toption.state &= ~QStyle::State_MouseOver;\n#endif\n\toption.features = QStyleOptionToolButton::None;\n\toption.subControls = QStyle::SC_ToolButton;\n\toption.activeSubControls = QStyle::SC_ToolButton;\n\toption.toolButtonStyle = Qt::ToolButtonIconOnly;\n\toption.rect = item.rect;\n\toption.arrowType = Qt::NoArrow;\n\tif (!icon.availableSizes().empty())\n\t{\n\t\toption.icon = icon;\n\t\toption.iconSize = icon.actualSize(item.rect.size());\n\t} else\n\t{\n\t\toption.text = text.isEmpty() ? QStringLiteral(\"*\") : text;\n\t}\n\n\t// draw button\n\tstyle->drawComplexControl(\n\t\tQStyle::CC_ToolButton, &option, context.painter, context.widget);\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateMisc.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_MISC_H\n#define QTN_PROPERTY_DELEGATE_MISC_H\n\n#include \"QtnProperty/Delegates/PropertyDelegate.h\"\n#include <deque>\n\nclass QTN_IMPORT_EXPORT QtnInplaceInfo\n{\npublic:\n\tQEvent *activationEvent;\n\n\tQtnInplaceInfo();\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateWithValues\n\t: public QtnPropertyDelegate\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateWithValues)\n\npublic:\n\tvirtual bool isSplittable() const override;\n\nprotected:\n\tQtnPropertyDelegateWithValues(QtnPropertyBase &owner);\n\n\t// override to define value part of property item\n\tvirtual void createSubItemValuesImpl(QtnDrawContext &context,\n\t\tconst QRect &valueRect, QList<QtnSubItem> &subItems) = 0;\n\tvirtual void createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) override;\n\n\t// sub-items functions\n\tvoid addSubItemBackground(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems);\n\tvoid addSubItemSelection(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems);\n\n\tvoid addSubItemName(QtnDrawContext &context, QList<QtnSubItem> &subItems);\n\tvoid addSubItemReset(QtnDrawContext &context, QList<QtnSubItem> &subItems);\n\tvoid addSubItemValues(QtnDrawContext &context, QList<QtnSubItem> &subItems);\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateWithValue\n\t: public QtnPropertyDelegateWithValues\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateWithValue)\n\nprotected:\n\tQtnPropertyDelegateWithValue(QtnPropertyBase &owner);\n\n\t// override to define value part of property item\n\tvirtual bool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) = 0;\n\tvoid createSubItemValuesImpl(QtnDrawContext &context,\n\t\tconst QRect &valueRect, QList<QtnSubItem> &subItems) override;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateWithValueEditor\n\t: public QtnPropertyDelegateWithValue\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateWithValueEditor)\n\npublic:\n\tinline QWidget *createValueEditor(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr);\n\tinline void drawValue(QStylePainter &painter, const QRect &rect) const;\n\tinline bool acceptKeyPressedForInplaceEdit(QKeyEvent *keyEvent) const;\n\n\tbool propertyValueToStr(QString &strValue) const;\n\nprotected:\n\tQtnPropertyDelegateWithValueEditor(QtnPropertyBase &owner);\n\n\t// override if property value can be displayed as string\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const;\n\t// override if you need a custom tool tip\n\tvirtual bool toolTipImpl(QString &strValue) const;\n\n\tbool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) override;\n\n\tbool isNormalPainterState(const QStylePainter &painter) const;\n\tvirtual bool isPlaceholderColor() const;\n\t// override to draw property value or override propertyValueToStrImpl to draw value as text\n\tvirtual void drawValueImpl(QStylePainter &painter, const QRect &rect) const;\n\t// override to filter key events that will activate property Editor\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(QKeyEvent *keyEvent) const;\n\t// override to implement property Editor\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) = 0;\n\n\tQLineEdit *createValueEditorLineEdit(QWidget *parent, const QRect &rect,\n\t\tbool readOnly, QtnInplaceInfo *inplaceInfo = nullptr) const;\n};\n\nQWidget *QtnPropertyDelegateWithValueEditor::createValueEditor(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\treturn createValueEditorImpl(parent, rect, inplaceInfo);\n}\n\nvoid QtnPropertyDelegateWithValueEditor::drawValue(\n\tQStylePainter &painter, const QRect &rect) const\n{\n\treturn drawValueImpl(painter, rect);\n}\n\nbool QtnPropertyDelegateWithValueEditor::acceptKeyPressedForInplaceEdit(\n\tQKeyEvent *keyEvent) const\n{\n\treturn acceptKeyPressedForInplaceEditImpl(keyEvent);\n}\n\ntemplate <typename PropertyClass,\n\ttypename DelegateClass = QtnPropertyDelegateWithValueEditor>\nclass QtnPropertyDelegateTyped : public DelegateClass\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateTyped)\n\npublic:\n\tconst PropertyClass &owner() const\n\t{\n\t\treturn *static_cast<const PropertyClass *>(this->propertyImmutable());\n\t}\n\tPropertyClass &owner()\n\t{\n\t\treturn *static_cast<PropertyClass *>(this->property());\n\t}\n\nprotected:\n\tQtnPropertyDelegateTyped(PropertyClass &owner)\n\t\t: DelegateClass(owner)\n\t{\n\t}\n};\n\ntemplate <typename PropertyClass,\n\ttypename DelegateClass = QtnPropertyDelegateWithValueEditor>\nclass QtnPropertyDelegateTypedEx\n\t: public QtnPropertyDelegateTyped<PropertyClass, DelegateClass>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateTypedEx)\n\nprotected:\n\tQtnPropertyDelegateTypedEx(PropertyClass &owner)\n\t\t: QtnPropertyDelegateTyped<PropertyClass, DelegateClass>(owner)\n\t{\n\t}\n\n\tvirtual int subPropertyCountImpl() const override\n\t{\n\t\treturn int(m_subProperties.size());\n\t}\n\n\tvirtual QtnPropertyBase *subPropertyImpl(int index) override\n\t{\n\t\treturn m_subProperties[index].data();\n\t}\n\n\tvoid addSubProperty(QtnPropertyBase *subProperty)\n\t{\n\t\tQ_ASSERT(subProperty);\n\t\tif (!subProperty)\n\t\t\treturn;\n\n\t\tm_subProperties.emplace_back(subProperty);\n\n\t\tsubProperty->connectMasterState(this->property());\n\t}\n\nprotected:\n\tstd::deque<QScopedPointer<QtnPropertyBase>> m_subProperties;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateError\n\t: public QtnPropertyDelegateWithValue\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateError)\n\npublic:\n\tQtnPropertyDelegateError(QtnPropertyBase &owner, const QString &error);\n\nprotected:\n\tbool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) override;\n\nprivate:\n\tQString m_error;\n};\n\nQTN_IMPORT_EXPORT QtnPropertyDelegate *qtnCreateDelegateError(\n\tQtnPropertyBase &owner, QString error);\n\n#endif // QTN_PROPERTY_DELEGATE_MISC_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegatePropertySet.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegatePropertySet.h\"\n#include \"QtnProperty/Delegates/PropertyDelegateFactory.h\"\n\nQtnPropertyDelegatePropertySet::QtnPropertyDelegatePropertySet(\n\tQtnPropertySet &owner)\n\t: QtnPropertyDelegate(owner)\n\t, m_owner(owner)\n{\n}\n\nvoid QtnPropertyDelegatePropertySet::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertySet::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegatePropertySet, QtnPropertySet>,\n\t\t\"Default\");\n}\n\nint QtnPropertyDelegatePropertySet::subPropertyCountImpl() const\n{\n\treturn m_owner.childProperties().size();\n}\n\nQtnPropertyBase *QtnPropertyDelegatePropertySet::subPropertyImpl(int index)\n{\n\treturn m_owner.childProperties()[index];\n}\n\nvoid QtnPropertyDelegatePropertySet::createSubItemsImpl(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\t// background\n\t{\n\t\tQtnSubItem bgItem(context.rect);\n\n\t\tif (bgItem.rect.isValid())\n\t\t{\n\t\t\tbgItem.drawHandler = [](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t\t const QtnSubItem &item) {\n\n\t\t\t\t// fill background\n\t\t\t\tcontext.painter->fillRect(item.rect,\n\t\t\t\t\t(context.isActive)\n\t\t\t\t\t\t? context.palette().color(QPalette::Highlight)\n\t\t\t\t\t\t: context.alternateColor());\n\n\t\t\t};\n\n\t\t\tsubItems.append(bgItem);\n\t\t}\n\t}\n\n\taddSubItemBranchNode(context, subItems);\n\taddSubItemLock(context, subItems);\n\n\t// property set name\n\t{\n\t\tQtnSubItem nameItem(context.rect.marginsRemoved(context.margins));\n\t\tnameItem.setPropertyDescriptionAsTooltip(m_owner);\n\n\t\tif (nameItem.rect.isValid())\n\t\t{\n\t\t\tnameItem.drawHandler = [this](QtnDrawContext &context,\n\t\t\t\t\t\t\t\t\t   const QtnSubItem &item) {\n\t\t\t\tQFont oldFont = context.painter->font();\n\t\t\t\tQPen oldPen = context.painter->pen();\n\n\t\t\t\t// draw name\n\t\t\t\tQFont font = oldFont;\n\t\t\t\tfont.setBold(true);\n\t\t\t\tcontext.painter->setFont(font);\n\n\t\t\t\tcontext.painter->setPen(\n\t\t\t\t\tcontext.textColorFor(stateProperty()->isEditableByUser()));\n\n\t\t\t\tQString elidedName = context.painter->fontMetrics().elidedText(\n\t\t\t\t\tproperty()->displayName(), Qt::ElideRight,\n\t\t\t\t\titem.rect.width());\n\t\t\t\tcontext.painter->drawText(item.rect,\n\t\t\t\t\tQt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine,\n\t\t\t\t\telidedName);\n\n\t\t\t\tcontext.painter->setPen(oldPen);\n\t\t\t\tcontext.painter->setFont(oldFont);\n\t\t\t};\n\n\t\t\tsubItems.append(nameItem);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegatePropertySet.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_PROPERTY_SET_H\n#define QTN_PROPERTY_DELEGATE_PROPERTY_SET_H\n\n#include \"QtnProperty/Delegates/PropertyDelegate.h\"\n#include \"QtnProperty/PropertySet.h\"\n\nclass QtnPropertySet;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegatePropertySet\n\t: public QtnPropertyDelegate\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegatePropertySet)\n\npublic:\n\tQtnPropertyDelegatePropertySet(QtnPropertySet &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tint subPropertyCountImpl() const override;\n\tQtnPropertyBase *subPropertyImpl(int index) override;\n\n\tvoid createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) override;\n\nprivate:\n\tQtnPropertySet &m_owner;\n};\n\n#endif // QTN_PROPERTY_DELEGATE_PROPERTY_SET_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateSliderBox.h\"\n\n#include \"QtnProperty/PropertyView.h\"\n#include \"QtnProperty/Auxiliary/PropertyMacro.h\"\n#include \"QtnProperty/PropertyDelegateAttrs.h\"\n#include \"QtnProperty/MultiProperty.h\"\n\n#include <QMouseEvent>\n#include <QVariantAnimation>\n\nQByteArray qtnFillColorAttr()\n{\n\treturn QByteArrayLiteral(\"fillColor\");\n}\n\nQByteArray qtnLiveUpdateAttr()\n{\n\treturn QByteArrayLiteral(\"liveUpdate\");\n}\n\nQByteArray qtnDrawBorderAttr()\n{\n\treturn QByteArrayLiteral(\"drawBorder\");\n}\n\nQByteArray qtnUpdateByScrollAttr()\n{\n\treturn QByteArrayLiteral(\"updateByScroll\");\n}\n\nQByteArray qtnAnimateAttr()\n{\n\treturn QByteArrayLiteral(\"animate\");\n}\n\nQByteArray qtnToolTipAttr()\n{\n\treturn QByteArrayLiteral(\"toolTip\");\n}\n\nQtnPropertyDelegateSlideBox::QtnPropertyDelegateSlideBox(QtnPropertyBase &owner)\n\t: QtnPropertyDelegateWithValue(owner)\n\t, m_liveUpdate(false)\n\t, m_drawBorder(true)\n\t, m_updateByScroll(true)\n\t, m_animate(false)\n\t, m_precision(std::numeric_limits<double>::digits10 - 1)\n\t, m_multiplier(1.0)\n\t, m_boxFillColor(QColor::fromRgb(200, 200, 255))\n\t, m_itemToolTip(QtnPropertyView::tr(\"Drag/Scroll mouse to change value\"))\n\t, m_dragValuePart(0.0)\n\t, m_oldValuePart(0.0)\n\t, m_animateWidget(nullptr)\n{\n}\n\nQtnPropertyDelegateSlideBox::~QtnPropertyDelegateSlideBox()\n{\n\tm_animation.reset();\n}\n\nvoid QtnPropertyDelegateSlideBox::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnFillColorAttr(), m_boxFillColor);\n\tinfo.loadAttribute(qtnLiveUpdateAttr(), m_liveUpdate);\n\tinfo.loadAttribute(qtnDrawBorderAttr(), m_drawBorder);\n\tinfo.loadAttribute(qtnUpdateByScrollAttr(), m_updateByScroll);\n\tinfo.loadAttribute(qtnAnimateAttr(), m_animate);\n\tinfo.loadAttribute(qtnToolTipAttr(), m_itemToolTip);\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tinfo.loadAttribute(qtnPrecisionAttr(), m_precision);\n\tinfo.loadAttribute(qtnMultiplierAttr(), m_multiplier);\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\n\tm_precision = qBound(0, m_precision, std::numeric_limits<double>::digits10);\n\tif (!qIsFinite(m_multiplier) || qFuzzyCompare(m_multiplier, 0.0))\n\t{\n\t\tm_multiplier = 1.0;\n\t}\n}\n\nbool QtnPropertyDelegateSlideBox::createSubItemValueImpl(\n\tQtnDrawContext &context, QtnSubItem &subItemValue)\n{\n\tsubItemValue.trackState();\n\tsubItemValue.setTextAsTooltip(m_itemToolTip);\n\tsubItemValue.drawHandler =\n\t\tqtnMemFn(this, &QtnPropertyDelegateSlideBox::draw);\n\tsubItemValue.eventHandler =\n\t\tqtnMemFn(this, &QtnPropertyDelegateSlideBox::event);\n\n\tif (m_animate)\n\t{\n\t\tm_dragValuePart = propertyValuePart();\n\t\tm_animation.reset(new QVariantAnimation());\n\t\tm_animateWidget = context.widget->viewport();\n\t}\n\n\treturn true;\n}\n\nvoid QtnPropertyDelegateSlideBox::draw(\n\tQtnDrawContext &context, const QtnSubItem &item)\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tqtnDrawValueText(QtnMultiProperty::getMultiValuePlaceholder(),\n\t\t\t*context.painter, item.rect, context.style());\n\t\treturn;\n\t}\n\n\tdouble valuePart = m_dragValuePart =\n\t\t(item.state() == QtnSubItemStatePushed ||\n\t\t\t(m_animate && m_animation->state() == QVariantAnimation::Running))\n\t\t? dragValuePart()\n\t\t: propertyValuePart();\n\tif (valuePart < 0.0)\n\t\treturn;\n\n\tauto boxRect = item.rect;\n\tboxRect.adjust(2, 2, -2, -2);\n\n\tauto valueRect = boxRect;\n\tvalueRect.setWidth(int(valuePart * valueRect.width()));\n\n\tauto &painter = *context.painter;\n\n\tpainter.save();\n\n\tauto palette = painter.style()->standardPalette();\n\tauto colorGroup = stateProperty()->isEditableByUser() ? QPalette::Active\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  : QPalette::Disabled;\n\n\tpainter.fillRect(boxRect, palette.color(colorGroup, QPalette::Background));\n\tpainter.fillRect(valueRect, m_boxFillColor);\n\n\tpainter.setPen(context.textColorFor(stateProperty()->isEditableByUser()));\n\tpainter.drawRect(valueRect);\n\tif (m_drawBorder)\n\t\tpainter.drawRect(boxRect);\n\n\tpainter.restore();\n\n\tqtnDrawValueText(\n\t\tvaluePartToStr(valuePart), painter, boxRect, context.style());\n}\n\nbool QtnPropertyDelegateSlideBox::event(\n\tQtnEventContext &context, const QtnSubItem &item, QtnPropertyToEdit *toEdit)\n{\n\tswitch (context.eventType())\n\t{\n\t\tcase QEvent::KeyPress:\n\t\t{\n\t\t\tint key = context.eventAs<QKeyEvent>()->key();\n\n\t\t\tint increment = 0;\n\n\t\t\tif ((key == Qt::Key_Plus) || (key == Qt::Key_Equal))\n\t\t\t\tincrement = 1;\n\t\t\telse if ((key == Qt::Key_Minus) || (key == Qt::Key_Underscore))\n\t\t\t\tincrement = -1;\n\t\t\telse\n\t\t\t\treturn false;\n\n\t\t\ttoEdit->setup(property(), [this, increment]() -> QWidget * {\n\t\t\t\tincrementPropertyValueInternal(increment);\n\t\t\t\treturn nullptr;\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\tcase QEvent::Wheel:\n\t\t{\n\t\t\tif (m_updateByScroll)\n\t\t\t{\n\t\t\t\tint steps =\n\t\t\t\t\tcontext.eventAs<QWheelEvent>()->angleDelta().y() / 120;\n\t\t\t\ttoEdit->setup(property(), [this, steps]() -> QWidget * {\n\t\t\t\t\tincrementPropertyValueInternal(steps);\n\t\t\t\t\treturn nullptr;\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tcase QtnSubItemEvent::Activated:\n\t\t{\n\t\t\tm_oldCursor = context.widget->cursor();\n\t\t\treturn true;\n\t\t}\n\n\t\tcase QtnSubItemEvent::PressMouse:\n\t\t{\n\t\t\tif (!m_animate)\n\t\t\t{\n\t\t\t\tm_dragValuePart = toDragValuePart(\n\t\t\t\t\tcontext.eventAs<QtnSubItemEvent>()->x(), item.rect);\n\t\t\t\tcontext.updateWidget();\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase QEvent::MouseMove:\n\t\t{\n\t\t\tif (item.state() == QtnSubItemStatePushed)\n\t\t\t{\n\t\t\t\tauto dragValuePart = toDragValuePart(\n\t\t\t\t\tcontext.eventAs<QMouseEvent>()->x(), item.rect);\n\t\t\t\tif (m_liveUpdate)\n\t\t\t\t{\n\t\t\t\t\tif (m_animate)\n\t\t\t\t\t\tm_animation->stop();\n\t\t\t\t\tm_dragValuePart = dragValuePart;\n\t\t\t\t\ttoEdit->setup(\n\t\t\t\t\t\tproperty(), [this, dragValuePart]() -> QWidget * {\n\t\t\t\t\t\t\tsetPropertyValuePart(dragValuePart);\n\t\t\t\t\t\t\treturn nullptr;\n\t\t\t\t\t\t});\n\t\t\t\t} else if (!m_animate)\n\t\t\t\t{\n\t\t\t\t\tm_dragValuePart = dragValuePart;\n\t\t\t\t\tcontext.updateWidget();\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QtnSubItemEvent::ReleaseMouse:\n\t\t{\n\t\t\tcontext.widget->setCursor(m_oldCursor);\n\t\t\tauto dragValuePart = toDragValuePart(\n\t\t\t\tcontext.eventAs<QtnSubItemEvent>()->x(), item.rect);\n\t\t\ttoEdit->setup(property(), [this, dragValuePart]() -> QWidget * {\n\t\t\t\tdragTo(dragValuePart);\n\t\t\t\treturn nullptr;\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\treturn false;\n}\n\nvoid QtnPropertyDelegateSlideBox::incrementPropertyValueInternal(int steps)\n{\n\tif (m_animate)\n\t\tm_animation->stop();\n\tincrementPropertyValue(steps);\n\tm_dragValuePart = propertyValuePart();\n}\n\ndouble QtnPropertyDelegateSlideBox::toDragValuePart(int x, const QRect &rect)\n{\n\tdouble result = double(x - rect.left()) / rect.width();\n\tif (result < 0.0)\n\t\tresult = 0.0;\n\telse if (result > 1.0)\n\t\tresult = 1.0;\n\treturn result;\n}\n\nvoid QtnPropertyDelegateSlideBox::dragTo(double value)\n{\n\tif (m_animate)\n\t\tprepareAnimate();\n\tsetPropertyValuePart(value);\n\tif (m_animate)\n\t\tstartAnimate();\n\telse\n\t\tm_dragValuePart = value;\n}\n\nvoid QtnPropertyDelegateSlideBox::prepareAnimate()\n{\n\tif (m_animation->state() == QVariantAnimation::Running)\n\t{\n\t\tm_oldValuePart = m_dragValuePart;\n\t\tm_animation->stop();\n\t} else\n\t{\n\t\tm_oldValuePart = m_dragValuePart = propertyValuePart();\n\t}\n}\n\nvoid QtnPropertyDelegateSlideBox::startAnimate()\n{\n\tdouble startValue = m_oldValuePart;\n\tdouble endValue = propertyValuePart();\n\tif (endValue == startValue)\n\t\treturn;\n\tm_animation->setStartValue(startValue);\n\tm_animation->setEndValue(endValue);\n\tm_animation->setDuration(300);\n\tm_animation->setEasingCurve(QEasingCurve::OutCirc);\n\tQObject::connect(m_animation.data(), &QVariantAnimation::valueChanged,\n\t\tqtnMemFn(this, &QtnPropertyDelegateSlideBox::onAnimationChanged));\n\tm_animation->start();\n}\n\nvoid QtnPropertyDelegateSlideBox::onAnimationChanged(const QVariant &value)\n{\n\tm_dragValuePart = value.toDouble();\n\tif (m_animateWidget)\n\t\tm_animateWidget->update();\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyDelegateSliderBox.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_DELEGATE_SLIDER_BOX_H\n#define QTN_PROPERTY_DELEGATE_SLIDER_BOX_H\n\n#include \"PropertyDelegateMisc.h\"\n#include \"Delegates/PropertyDelegateAux.h\"\n#include \"PropertyDelegateAttrs.h\"\n#include \"Utils/DoubleSpinBox.h\"\n\nclass QVariantAnimation;\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateSlideBox\n\t: public QtnPropertyDelegateWithValue\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateSlideBox)\n\nprotected:\n\tQtnPropertyDelegateSlideBox(QtnPropertyBase &owner);\n\tvirtual ~QtnPropertyDelegateSlideBox() override;\n\n\tvoid applyAttributesImpl(const QtnPropertyDelegateInfo &info) override;\n\tbool createSubItemValueImpl(\n\t\tQtnDrawContext &context, QtnSubItem &subItemValue) override;\n\n\tvirtual void draw(QtnDrawContext &context, const QtnSubItem &item);\n\tvirtual bool event(QtnEventContext &context, const QtnSubItem &item,\n\t\tQtnPropertyToEdit *toEdit);\n\n\tinline double dragValuePart() const;\n\n\tvirtual double propertyValuePart() const = 0;\n\tvirtual QString valuePartToStr(double valuePart) const = 0;\n\tvirtual void incrementPropertyValue(int steps) = 0;\n\tvirtual void setPropertyValuePart(double valuePart) = 0;\n\n\tvoid prepareAnimate();\n\tvoid startAnimate();\n\n\tbool m_liveUpdate;\n\tbool m_drawBorder;\n\tbool m_updateByScroll;\n\tbool m_animate;\n\tint m_precision;\n\tdouble m_multiplier;\n\tQColor m_boxFillColor;\n\tQString m_itemToolTip;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQString m_suffix;\n\nprivate:\n\tvoid incrementPropertyValueInternal(int steps);\n\tdouble toDragValuePart(int x, const QRect &rect);\n\tvoid dragTo(double value);\n\tvoid onAnimationChanged(const QVariant &value);\n\n\tdouble m_dragValuePart;\n\tdouble m_oldValuePart;\n\n\tQWidget *m_animateWidget;\n\tQCursor m_oldCursor;\n\tQScopedPointer<QVariantAnimation> m_animation;\n};\n\ndouble QtnPropertyDelegateSlideBox::dragValuePart() const\n{\n\treturn m_dragValuePart;\n}\n\ntemplate <typename PropertyClass>\nclass QtnPropertyDelegateSlideBoxTyped\n\t: public QtnPropertyDelegateTyped<PropertyClass,\n\t\t  QtnPropertyDelegateSlideBox>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateSlideBoxTyped)\n\n\tusing ValueTypeStore = typename PropertyClass::ValueTypeStore;\n\n\tusing ParentClass =\n\t\tQtnPropertyDelegateTyped<PropertyClass, QtnPropertyDelegateSlideBox>;\n\npublic:\n\tQtnPropertyDelegateSlideBoxTyped(PropertyClass &owner)\n\t\t: ParentClass(owner)\n\t{\n\t}\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override\n\t{\n\t\tParentClass::applyAttributesImpl(info);\n\t\tfixMinMaxVariant<ValueTypeStore>(this->m_min, this->m_max);\n\t}\n\n\tValueTypeStore minValue() const\n\t{\n\t\tconst QVariant &mv = this->m_min;\n\t\treturn mv.isValid() ? mv.value<ValueTypeStore>()\n\t\t\t\t\t\t\t: this->owner().minValue();\n\t}\n\n\tValueTypeStore maxValue() const\n\t{\n\t\tconst QVariant &mv = this->m_max;\n\t\treturn mv.isValid() ? mv.value<ValueTypeStore>()\n\t\t\t\t\t\t\t: this->owner().maxValue();\n\t}\n\n\tValueTypeStore currentValue() const\n\t{\n\t\treturn qBound(minValue(), this->owner().value(), maxValue());\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<sizeof(T) < 8>::type * = nullptr>\n\tinline bool isHugeInterval() const\n\t{\n\t\treturn false;\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_integral<T>::value &&\n\t\t\tsizeof(T) == 8>::type * = nullptr>\n\tinline bool isHugeInterval() const\n\t{\n\t\tusing IntervalType = typename PropertyClass::IntervalType;\n\t\tconst quint64 originalInterval = IntervalType(maxValue() - minValue());\n\t\tconst auto maxInterval = quint64(std::numeric_limits<qint64>::max());\n\t\treturn originalInterval > maxInterval;\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_floating_point<T>::value &&\n\t\t\tsizeof(T) >= 8>::type * = nullptr>\n\tinline bool isHugeInterval() const\n\t{\n\t\tconst auto originalInterval = maxValue() - minValue();\n\t\tconst auto maxInterval = double(std::numeric_limits<qint64>::max());\n\t\treturn originalInterval > maxInterval;\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<sizeof(T) < 8>::type * = nullptr>\n\tinline double interval(T to) const\n\t{\n\t\tusing IntervalType = typename PropertyClass::IntervalType;\n\t\treturn double(IntervalType(to - minValue()));\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_integral<T>::value &&\n\t\t\tsizeof(T) == 8>::type * = nullptr>\n\tinline double interval(T to) const\n\t{\n\t\tquint64 currentInterval = quint64(to - minValue());\n\t\tif (isHugeInterval<T>())\n\t\t{\n\t\t\tif (to == maxValue())\n\t\t\t{\n\t\t\t\treturn 1.0;\n\t\t\t}\n\t\t\tusing IntervalType = typename PropertyClass::IntervalType;\n\t\t\tconst quint64 originalInterval =\n\t\t\t\tIntervalType(maxValue() - minValue());\n\n\t\t\tauto halfCurrent = double(currentInterval / 2);\n\t\t\tauto halfOriginal = double(originalInterval / 2);\n\t\t\treturn halfCurrent / halfOriginal;\n\t\t}\n\n\t\treturn double(currentInterval);\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_floating_point<T>::value &&\n\t\t\tsizeof(T) >= 8>::type * = nullptr>\n\tinline double interval(T to) const\n\t{\n\t\tif (isHugeInterval<T>())\n\t\t{\n\t\t\tif (to == maxValue())\n\t\t\t{\n\t\t\t\treturn 1.0;\n\t\t\t}\n\t\t\tauto halfMin = minValue() * 0.5;\n\t\t\tauto halfMax = maxValue() * 0.5;\n\t\t\tauto halfTo = to * 0.5;\n\n\t\t\tconst auto halfOriginal = halfMax - halfMin;\n\n\t\t\tauto halfCurrent = halfTo - halfMin;\n\n\t\t\treturn halfCurrent / halfOriginal;\n\t\t}\n\n\t\treturn double(to) - double(minValue());\n\t}\n\n\tvirtual double propertyValuePart() const override\n\t{\n\t\treturn interval(currentValue()) / interval(maxValue());\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_floating_point<T>::value>::type * =\n\t\t\tnullptr>\n\tQString valueToStr(T value) const\n\t{\n\t\tif (this->m_multiplier == 1.0)\n\t\t{\n\t\t\treturn QtnDoubleSpinBox::valueToText(value, QLocale(),\n\t\t\t\t\t   qBound(0, this->m_precision,\n\t\t\t\t\t\t   std::numeric_limits<T>::digits10),\n\t\t\t\t\t   true) +\n\t\t\t\tthis->m_suffix;\n\t\t}\n\n\t\treturn QtnDoubleSpinBox::valueToText(double(value) * this->m_multiplier,\n\t\t\t\t   QLocale(), this->m_precision, true) +\n\t\t\tthis->m_suffix;\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_integral<T>::value>::type * = nullptr>\n\tQString valueToStr(T value) const\n\t{\n\t\tif (this->m_multiplier == 1.0)\n\t\t{\n\t\t\treturn QLocale().toString(value) + this->m_suffix;\n\t\t}\n\n\t\treturn QtnDoubleSpinBox::valueToText(double(value) * this->m_multiplier,\n\t\t\t\t   QLocale(), this->m_precision, true) +\n\t\t\tthis->m_suffix;\n\t}\n\n\tvirtual QString valuePartToStr(double valuePart) const override\n\t{\n\t\treturn valueToStr(partToValue<ValueTypeStore>(valuePart));\n\t}\n\n\tvirtual void incrementPropertyValue(int steps) override\n\t{\n\t\tthis->owner().incrementValue(this->editReason(), steps);\n\t}\n\n\tvirtual void setPropertyValuePart(double valuePart) override\n\t{\n\t\tthis->owner().setValue(\n\t\t\tpartToValue<ValueTypeStore>(valuePart), this->editReason());\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_floating_point<T>::value &&\n\t\t\tsizeof(T) >= 8>::type * = nullptr>\n\tValueTypeStore partToValue(double valuePart) const\n\t{\n\t\tQ_ASSERT(valuePart >= 0.0);\n\t\tQ_ASSERT(valuePart <= 1.0);\n\n\t\tif (isHugeInterval<T>())\n\t\t{\n\t\t\tif (valuePart == 1.0)\n\t\t\t{\n\t\t\t\treturn maxValue();\n\t\t\t}\n\n\t\t\tconst auto originalInterval = maxValue() - minValue();\n\n\t\t\tauto halfOriginal = originalInterval * 0.5;\n\t\t\tauto halfMin = minValue() * 0.5;\n\t\t\tauto value = ValueTypeStore(valuePart * halfOriginal);\n\t\t\treturn (value + halfMin) * 2.0;\n\t\t}\n\t\tauto value = ValueTypeStore(valuePart * interval(maxValue()));\n\t\treturn value + minValue();\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<std::is_integral<T>::value &&\n\t\t\tsizeof(T) == 8>::type * = nullptr>\n\tValueTypeStore partToValue(double valuePart) const\n\t{\n\t\tQ_ASSERT(valuePart >= 0.0);\n\t\tQ_ASSERT(valuePart <= 1.0);\n\n\t\tValueTypeStore value;\n\t\tif (isHugeInterval<T>())\n\t\t{\n\t\t\tif (valuePart == 1.0)\n\t\t\t{\n\t\t\t\treturn maxValue();\n\t\t\t}\n\n\t\t\tusing IntervalType = typename PropertyClass::IntervalType;\n\t\t\tconst quint64 originalInterval =\n\t\t\t\tIntervalType(maxValue() - minValue());\n\n\t\t\tauto dividedInterval = originalInterval / 2;\n\t\t\tvalue = ValueTypeStore(valuePart * dividedInterval) * 2;\n\t\t} else\n\t\t{\n\t\t\tvalue = ValueTypeStore(valuePart * interval(maxValue()));\n\t\t}\n\t\treturn value + minValue();\n\t}\n\n\ttemplate <typename T,\n\t\ttypename std::enable_if<sizeof(T) < 8>::type * = nullptr>\n\tValueTypeStore partToValue(double valuePart) const\n\t{\n\t\tQ_ASSERT(valuePart >= 0.0);\n\t\tQ_ASSERT(valuePart <= 1.0);\n\n\t\tauto value = ValueTypeStore(valuePart * interval(maxValue()));\n\t\treturn value + minValue();\n\t}\n};\n\n#endif // QTN_PROPERTY_DELEGATE_SLIDER_BOX_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyEditorAux.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2019 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyEditorAux.h\"\n#include \"QtnProperty/Delegates/PropertyDelegate.h\"\n#include \"PropertyDelegateMisc.h\"\n#include \"QtnProperty/MultiProperty.h\"\n\n#include <QHBoxLayout>\n#include <QKeyEvent>\n#include <QLocale>\n#include <QCoreApplication>\n#include <QCompleter>\n\nQtnLineEditBttn::QtnLineEditBttn(\n\tQWidget *parent, const QString &bttnText, QLineEdit *lineEdit)\n\t: QWidget(parent)\n{\n\tQHBoxLayout *layout = new QHBoxLayout(this);\n\tlayout->setMargin(0);\n\tlayout->setSpacing(0);\n\n\tif (!lineEdit)\n\t\tlineEdit = new QLineEdit(this);\n\telse\n\t\tlineEdit->setParent(this);\n\tthis->lineEdit = lineEdit;\n\tlayout->addWidget(lineEdit);\n\n\ttoolButton = new QToolButton(this);\n\ttoolButton->setText(bttnText);\n\ttoolButton->setFocusPolicy(Qt::StrongFocus);\n\tlayout->addWidget(toolButton);\n\n\tsetFocusProxy(lineEdit);\n\tsetAutoFillBackground(true);\n}\n\nQtnComboBoxBttn::QtnComboBoxBttn(QWidget *parent, const QString &bttnText)\n\t: QWidget(parent)\n{\n\tQHBoxLayout *layout = new QHBoxLayout(this);\n\tlayout->setMargin(0);\n\tlayout->setSpacing(0);\n\n\tcomboBox = new QComboBox(this);\n\tlayout->addWidget(comboBox);\n\n\ttoolButton = new QToolButton(this);\n\ttoolButton->setText(bttnText);\n\ttoolButton->setFocusPolicy(Qt::StrongFocus);\n\tlayout->addWidget(toolButton);\n\n\tsetFocusProxy(comboBox);\n\tsetAutoFillBackground(true);\n}\n\nvoid QtnLineEditBttn::setTextForProperty(\n\tQtnPropertyBase *property, const QString &text)\n{\n\tif (property->isMultiValue())\n\t{\n\t\tlineEdit->clear();\n\t\tlineEdit->setPlaceholderText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\tlineEdit->setText(text);\n\t\tlineEdit->setPlaceholderText(QString());\n\t}\n}\n\nbool qtnAcceptForLineEdit(QKeyEvent *keyEvent)\n{\n\tif (keyEvent->type() != QEvent::KeyPress)\n\t\treturn false;\n\n\t// any printable key press is acceptable\n\tQString text = keyEvent->text();\n\treturn (text.size() == 1 && text[0].isPrint());\n}\n\nvoid qtnInitLineEdit(QLineEdit *lineEdit, QtnInplaceInfo *inplaceInfo)\n{\n\tif (!lineEdit || !inplaceInfo)\n\t\treturn;\n\n\tif (!lineEdit->isReadOnly() &&\n\t\t(inplaceInfo->activationEvent->type() == QEvent::KeyPress))\n\t{\n\t\tQKeyEvent *keyEvent =\n\t\t\tstatic_cast<QKeyEvent *>(inplaceInfo->activationEvent);\n\n\t\tif (qtnAcceptForLineEdit(keyEvent))\n\t\t{\n\t\t\tlineEdit->setText(keyEvent->text());\n\t\t\tauto completer = lineEdit->completer();\n\t\t\tif (completer)\n\t\t\t\tcompleter->setCompletionPrefix(lineEdit->text());\n\n\t\t\treturn;\n\t\t}\n\t} else\n\t{\n\t\tlineEdit->selectAll();\n\t}\n}\n\nbool qtnAcceptForNumEdit(QKeyEvent *keyEvent, QtnNumType type)\n{\n\tif (keyEvent->type() != QEvent::KeyPress)\n\t\treturn false;\n\n\t// any numeric key press is acceptable\n\tQString text = keyEvent->text();\n\n\tif (text.size() == 1)\n\t{\n\t\tQChar c = text.at(0);\n\n\t\tQLocale locale;\n\n\t\tswitch (type)\n\t\t{\n\t\t\tcase NUM_FLOAT:\n\t\t\t\tif (c == QLatin1Char('.') || c == locale.decimalPoint())\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// fall through\n\t\t\tcase NUM_SIGNED_INT:\n\t\t\t\tif (c == QLatin1Char('-') || c == QLatin1Char('+') ||\n\t\t\t\t\tc == locale.negativeSign() || c == locale.positiveSign())\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// fall through\n\t\t\tcase NUM_UNSIGNED_INT:\n\t\t\t\tif (c.isDigit())\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid qtnInitNumEdit(\n\tQWidget *numEdit, QtnInplaceInfo *inplaceInfo, QtnNumType type)\n{\n\tif (nullptr != inplaceInfo &&\n\t\tinplaceInfo->activationEvent->type() == QEvent::KeyPress)\n\t{\n\t\tauto keyEvent = static_cast<QKeyEvent *>(inplaceInfo->activationEvent);\n\n\t\tif (qtnAcceptForNumEdit(keyEvent, type))\n\t\t{\n\t\t\tkeyEvent = new QKeyEvent(keyEvent->type(), keyEvent->key(),\n\t\t\t\tkeyEvent->modifiers(), keyEvent->text());\n\n\t\t\tQCoreApplication::postEvent(numEdit, keyEvent);\n\t\t}\n\t}\n}\n\nQtnPropertyComboBox::QtnPropertyComboBox(\n\tQtnPropertyDelegate *delegate, QWidget *parent)\n\t: QComboBox(parent)\n\t, m_delegate(delegate)\n{\n}\n\nvoid QtnPropertyComboBox::paintEvent(QPaintEvent *event)\n{\n\tauto rect = event->rect();\n\tQComboBox::paintEvent(event);\n\n\tQPainter painter(this);\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tif (isEnabled())\n\t\t{\n#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)\n\t\t\tauto color =\n\t\t\t\tpalette().color(QPalette::Active, QPalette::PlaceholderText);\n#else\n\t\t\tauto color = palette().color(QPalette::Disabled, QPalette::Text);\n#endif\n\t\t\tpainter.setPen(color);\n\t\t}\n\t\tqtnDrawValueText(QtnMultiProperty::getMultiValuePlaceholder(), painter,\n\t\t\trect, style());\n\t} else if (currentIndex() >= 0)\n\t{\n\t\tcustomPaint(painter, rect);\n\t}\n}\n\nvoid QtnPropertyComboBox::customPaint(QPainter &, const QRect &)\n{\n\t// do nothing\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyEditorAux.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2019 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_EDITOR_AUX_H\n#define PROPERTY_EDITOR_AUX_H\n\n#include \"QtnProperty/Config.h\"\n#include \"QtnProperty/Delegates/PropertyDelegate.h\"\n\n#include <QLineEdit>\n#include <QToolButton>\n#include <QComboBox>\n\nclass QKeyEvent;\nclass QtnInplaceInfo;\n\nclass QTN_IMPORT_EXPORT QtnLineEditBttn : public QWidget\n{\npublic:\n\tQtnLineEditBttn(QWidget *parent, const QString &bttnText = \"...\",\n\t\tQLineEdit *lineEdit = nullptr);\n\n\tvoid setTextForProperty(QtnPropertyBase *property, const QString &text);\n\n\tQLineEdit *lineEdit;\n\tQToolButton *toolButton;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyComboBox : public QComboBox\n{\n\tQtnPropertyDelegate *m_delegate;\n\npublic:\n\texplicit QtnPropertyComboBox(\n\t\tQtnPropertyDelegate *delegate, QWidget *parent = Q_NULLPTR);\n\n\tinline QtnPropertyDelegate *delegate() const;\n\tinline QtnPropertyBase *property() const;\n\tinline QtnPropertyBase *stateProperty() const;\n\nprivate:\n\tvirtual void paintEvent(QPaintEvent *event) override;\n\nprotected:\n\tvirtual void customPaint(QPainter &painter, const QRect &rect);\n};\n\nQtnPropertyDelegate *QtnPropertyComboBox::delegate() const\n{\n\treturn m_delegate;\n}\n\nQtnPropertyBase *QtnPropertyComboBox::property() const\n{\n\treturn m_delegate->property();\n}\n\nQtnPropertyBase *QtnPropertyComboBox::stateProperty() const\n{\n\treturn m_delegate->stateProperty();\n}\n\nclass QTN_IMPORT_EXPORT QtnComboBoxBttn : public QWidget\n{\npublic:\n\tQtnComboBoxBttn(QWidget *parent, const QString &bttnText = \"...\");\n\n\tQComboBox *comboBox;\n\tQToolButton *toolButton;\n};\n\nenum QtnNumType\n{\n\tNUM_SIGNED_INT,\n\tNUM_UNSIGNED_INT,\n\tNUM_FLOAT\n};\n\nQTN_IMPORT_EXPORT bool qtnAcceptForLineEdit(QKeyEvent *keyEvent);\nQTN_IMPORT_EXPORT bool qtnAcceptForNumEdit(\n\tQKeyEvent *keyEvent, QtnNumType type);\n\nQTN_IMPORT_EXPORT void qtnInitLineEdit(\n\tQLineEdit *lineEdit, QtnInplaceInfo *inplaceInfo);\nQTN_IMPORT_EXPORT void qtnInitNumEdit(\n\tQWidget *numEdit, QtnInplaceInfo *inplaceInfo, QtnNumType type);\n\n#endif // PROPERTY_EDITOR_AUX_H\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyEditorHandler.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyEditorHandler.h\"\n#include \"QtnProperty/Utils/InplaceEditing.h\"\n#include \"QtnProperty/Utils/QtnConnections.h\"\n\n#include <QDebug>\n#include <QKeyEvent>\n#include <QDialog>\n\nQtnPropertyEditorHandlerBase::QtnPropertyEditorHandlerBase(\n\tQtnPropertyDelegate *delegate, QWidget &editor)\n\t: QObject(&editor)\n\t, reverted(false)\n\t, returned(false)\n\t, m_delegate(delegate)\n\t, m_editor(&editor)\n{\n\tQ_ASSERT(delegate);\n\t//Q_ASSERT(!delegate->m_editorHandler);\n\tdelegate->m_editorHandler = this;\n\tauto property = delegate->property();\n\tQ_ASSERT(property);\n\tQObject::connect(property, &QtnPropertyBase::propertyDidChange, this,\n\t\t&QtnPropertyEditorHandlerBase::onPropertyDidChange,\n\t\tQt::QueuedConnection);\n\tQObject::connect(property, &QObject::destroyed, this,\n\t\t&QtnPropertyEditorHandlerBase::onPropertyDestroyed);\n\n\tauto stateProperty = delegate->stateProperty();\n\tif (stateProperty != property)\n\t{\n\t\tQObject::connect(stateProperty, &QtnPropertyBase::propertyDidChange,\n\t\t\tthis, &QtnPropertyEditorHandlerBase::onPropertyDidChange,\n\t\t\tQt::QueuedConnection);\n\t}\n}\n\nvoid QtnPropertyEditorHandlerBase::revertInput()\n{\n\treverted = true;\n\tupdateEditor();\n}\n\nvoid QtnPropertyEditorHandlerBase::cleanup()\n{\n\tif (m_delegate)\n\t{\n\t\tm_delegate->m_editorHandler = nullptr;\n\t\tm_delegate = nullptr;\n\t}\n\tif (m_editor)\n\t\tm_editor->removeEventFilter(this);\n\tqtnStopInplaceEdit();\n}\n\nQtnPropertyEditorHandlerBase::~QtnPropertyEditorHandlerBase()\n{\n\tcleanup();\n}\n\nbool QtnPropertyEditorHandlerBase::eventFilter(QObject *obj, QEvent *event)\n{\n\tswitch (event->type())\n\t{\n\t\tcase QEvent::KeyPress:\n\t\t{\n\t\t\tauto keyEvent = static_cast<QKeyEvent *>(event);\n\n\t\t\t// revert all changes\n\t\t\tswitch (keyEvent->key())\n\t\t\t{\n\t\t\t\tcase Qt::Key_Escape:\n\t\t\t\t\trevertInput();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase Qt::Key_Enter:\n\t\t\t\tcase Qt::Key_Return:\n\t\t\t\t\treturned = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn QObject::eventFilter(obj, event);\n}\n\nbool QtnPropertyEditorHandlerBase::canApply() const\n{\n\tif (nullptr != stateProperty() && stateProperty()->isEditableByUser())\n\t\treturn (!reverted && (returned || !stateProperty()->isMultiValue()));\n\n\treturn false;\n}\n\nvoid QtnPropertyEditorHandlerBase::applyReset()\n{\n\treverted = false;\n\treturned = false;\n}\n\nQtnPropertyEditorHandlerBase::DialogContainerPtr\nQtnPropertyEditorHandlerBase::connectDialog(QDialog *dialog)\n{\n\tDialogContainerPtr result(new DialogContainer(dialog));\n\tconnectDialog(result);\n\treturn result;\n}\n\nvoid QtnPropertyEditorHandlerBase::connectDialog(\n\tconst DialogContainerPtr &containerPtr)\n{\n\tQ_ASSERT(nullptr != containerPtr);\n\tauto dialog = containerPtr->dialog;\n\tQ_ASSERT(nullptr != dialog);\n\n\tauto parent = dialog->parent();\n\tQ_ASSERT(nullptr != parent);\n\n\tQObject::connect(parent, &QObject::destroyed,\n\t\t[containerPtr]() { containerPtr->dialog->setParent(nullptr); });\n}\n\nvoid QtnPropertyEditorHandlerBase::onPropertyDestroyed()\n{\n\tcleanup();\n}\n\nvoid QtnPropertyEditorHandlerBase::onPropertyDidChange(\n\tQtnPropertyChangeReason reason)\n{\n\tif (!sender())\n\t{\n\t\treturn;\n\t}\n\tif (reason & (QtnPropertyChangeReasonValue | QtnPropertyChangeReasonState))\n\t{\n\t\tif (propertyBase() == sender() || stateProperty() == sender())\n\t\t\tupdateEditor();\n\t}\n}\n\nQtnPropertyEditorHandlerBase::DialogContainer::DialogContainer(QDialog *dialog)\n\t: dialog(dialog)\n{\n}\n\nQtnPropertyEditorHandlerBase::DialogContainer::~DialogContainer()\n{\n\tif (nullptr != dialog && nullptr == dialog->parent())\n\t\tdelete dialog;\n}\n"
  },
  {
    "path": "QtnProperty/Delegates/Utils/PropertyEditorHandler.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_EDITOR_HANDLER_H\n#define PROPERTY_EDITOR_HANDLER_H\n\n#include \"QtnProperty/Config.h\"\n#include \"QtnProperty/Property.h\"\n#include \"QtnProperty/Delegates/PropertyDelegate.h\"\n\n#include <QWidget>\n#include <QEvent>\n#include <QCoreApplication>\n\n#include <memory>\n\nclass QDialog;\n\nclass QTN_IMPORT_EXPORT QtnPropertyEditorHandlerBase : public QObject\n{\npublic:\n\tvoid cleanup();\n\tvirtual ~QtnPropertyEditorHandlerBase() override;\n\nprotected:\n\tQtnPropertyEditorHandlerBase(\n\t\tQtnPropertyDelegate *delegate, QWidget &editor);\n\n\tinline QtnPropertyDelegate *delegate() const;\n\tinline QtnPropertyBase *propertyBase() const;\n\tinline QtnPropertyBase *stateProperty() const;\n\tinline QWidget *editorBase() const;\n\tvirtual void updateEditor() = 0;\n\tvirtual void revertInput();\n\n\tvirtual bool eventFilter(QObject *obj, QEvent *event) override;\n\n\tvirtual bool canApply() const;\n\tvirtual void applyReset();\n\n\tstruct DialogContainer\n\t{\n\t\tQDialog *dialog;\n\n\t\tDialogContainer(QDialog *dialog);\n\t\t~DialogContainer();\n\t};\n\n\ttypedef std::shared_ptr<DialogContainer> DialogContainerPtr;\n\n\tstatic DialogContainerPtr connectDialog(QDialog *dialog);\n\tstatic void connectDialog(const DialogContainerPtr &containerPtr);\n\nprotected:\n\tbool reverted : 1;\n\tbool returned : 1;\n\nprivate:\n\tQtnPropertyDelegate *m_delegate;\n\tQWidget *m_editor;\n\nprivate:\n\tvoid onPropertyDestroyed();\n\tvoid onPropertyDidChange(QtnPropertyChangeReason reason);\n};\n\nQtnPropertyBase *QtnPropertyEditorHandlerBase::propertyBase() const\n{\n\tif (m_delegate)\n\t\treturn m_delegate->property();\n\n\treturn nullptr;\n}\n\nQtnPropertyDelegate *QtnPropertyEditorHandlerBase::delegate() const\n{\n\treturn m_delegate;\n}\n\nQtnPropertyBase *QtnPropertyEditorHandlerBase::stateProperty() const\n{\n\tif (m_delegate)\n\t\treturn m_delegate->stateProperty();\n\n\treturn nullptr;\n}\n\nQWidget *QtnPropertyEditorHandlerBase::editorBase() const\n{\n\treturn m_editor;\n}\n\ntemplate <typename PropertyClass, typename PropertyEditorClass>\nclass QtnPropertyEditorHandler : public QtnPropertyEditorHandlerBase\n{\nprotected:\n\ttypedef QtnPropertyEditorHandler<PropertyClass, PropertyEditorClass>\n\t\tQtnPropertyEditorHandlerType;\n\n\tQtnPropertyEditorHandler(\n\t\tQtnPropertyDelegate *delegate, PropertyEditorClass &editor)\n\t\t: QtnPropertyEditorHandlerBase(delegate, editor)\n\t{\n\t}\n\n\tPropertyClass &property() const\n\t{\n\t\treturn *static_cast<PropertyClass *>(propertyBase());\n\t}\n\n\tPropertyEditorClass &editor() const\n\t{\n\t\treturn *static_cast<PropertyEditorClass *>(editorBase());\n\t}\n};\n\ntemplate <typename PropertyClass, typename PropertyEditorClass>\nclass QtnPropertyEditorHandlerVT\n\t: public QtnPropertyEditorHandler<PropertyClass, PropertyEditorClass>\n{\nprotected:\n\tusing Inherited =\n\t\tQtnPropertyEditorHandler<PropertyClass, PropertyEditorClass>;\n\tusing ValueType = typename PropertyClass::ValueType;\n\tusing ValueTypeStore = typename PropertyClass::ValueTypeStore;\n\n\tQtnPropertyEditorHandlerVT(\n\t\tQtnPropertyDelegate *delegate, PropertyEditorClass &editor)\n\t\t: Inherited(delegate, editor)\n\t\t, updating(0)\n\t{\n\t\tnewValue = this->property().value();\n\t}\n\n\tvoid onValueChanged(ValueType value)\n\t{\n\t\tif (updating > 0)\n\t\t\treturn;\n\t\tnewValue = value;\n\t\tupdateValue();\n\t}\n\n\tvirtual void updateValue()\n\t{\n\t\tif (this->propertyBase())\n\t\t\tthis->property().setValue(newValue, this->delegate()->editReason());\n\t}\n\n\tValueTypeStore newValue;\n\tunsigned updating;\n};\n\ntemplate <typename PropertyClass, typename PropertyEditorClass>\nclass QtnPropertyEditorBttnHandler\n\t: public QtnPropertyEditorHandler<PropertyClass, PropertyEditorClass>\n{\nprivate:\n\ttypedef QtnPropertyEditorHandler<PropertyClass, PropertyEditorClass>\n\t\tInherited;\n\nprotected:\n\ttypedef QtnPropertyEditorBttnHandler QtnPropertyEditorHandlerType;\n\n\tQtnPropertyEditorBttnHandler(\n\t\tQtnPropertyDelegate *delegate, PropertyEditorClass &editor)\n\t\t: Inherited(delegate, editor)\n\t\t, double_clicked(false)\n\t{\n\t}\n\n\tvirtual void onToolButtonClick() = 0;\n\tvirtual bool eventFilter(QObject *obj, QEvent *event) override\n\t{\n\t\tif (nullptr != this->stateProperty() &&\n\t\t\tthis->stateProperty()->isEditableByUser())\n\t\t\tswitch (event->type())\n\t\t\t{\n\t\t\t\tcase QEvent::MouseButtonDblClick:\n\t\t\t\t\tdouble_clicked = true;\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase QEvent::MouseButtonRelease:\n\n\t\t\t\t\tif (double_clicked)\n\t\t\t\t\t{\n\t\t\t\t\t\tdouble_clicked = false;\n\t\t\t\t\t\tonToolButtonClick();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\treturn Inherited::eventFilter(obj, event);\n\t}\n\nprivate:\n\tbool double_clicked;\n};\n\n#endif // PROPERTY_EDITOR_HANDLER_H\n"
  },
  {
    "path": "QtnProperty/Enum.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"Enum.h\"\n\n#include <QRegExp>\n#include <QStringList>\n#include <QCoreApplication>\n\nQtnEnumInfo::QtnEnumInfo()\n\t: m_case_sensitivity(Qt::CaseInsensitive)\n{\n}\n\nQtnEnumInfo::QtnEnumInfo(const QString &name)\n\t: m_case_sensitivity(Qt::CaseInsensitive)\n\t, m_name(name)\n{\n}\n\nQtnEnumInfo::QtnEnumInfo(\n\tconst QString &name, QVector<QtnEnumValueInfo> &staticValues)\n\t: m_case_sensitivity(Qt::CaseInsensitive)\n\t, m_name(name)\n{\n\tm_values.swap(staticValues);\n}\n\nQtnEnumInfo::QtnEnumInfo(\n\tconst QString &name, const QVector<QtnEnumValueInfo> &staticValues)\n\t: m_case_sensitivity(Qt::CaseSensitive)\n\t, m_name(name)\n\t, m_values(staticValues)\n{\n}\n\nQtnEnumInfo QtnEnumInfo::withMetaEnum(const QMetaEnum &metaEnum, bool translate)\n{\n\tQtnEnumInfo enumInfo(QLatin1String(metaEnum.scope()) +\n\t\tQStringLiteral(\"::\") + QLatin1String(metaEnum.name()));\n\tauto &vec = enumInfo.getVector();\n\tint count = metaEnum.keyCount();\n\tvec.reserve(count);\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tconst char *key = metaEnum.key(i);\n\t\tQString keyStr = QLatin1String(key);\n\t\tvec.append(QtnEnumValueInfo(metaEnum.value(i), keyStr,\n\t\t\ttranslate ? QCoreApplication::translate(\n\t\t\t\t\t\t\tmetaEnum.scope(), key, metaEnum.name())\n\t\t\t\t\t  : keyStr));\n\t}\n\n\treturn enumInfo;\n}\n\nconst QtnEnumValueInfo *QtnEnumInfo::findByValue(QtnEnumValueType value) const\n{\n\tconst QtnEnumValueInfo *result = nullptr;\n\n\tforEachEnumValue(\n\t\t[&result, value](const QtnEnumValueInfo &enumValue) -> bool {\n\t\t\tif (enumValue.value() == value)\n\t\t\t{\n\t\t\t\tresult = &enumValue;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\treturn result;\n}\n\nconst QtnEnumValueInfo *QtnEnumInfo::findByName(const QString &name) const\n{\n\tconst QtnEnumValueInfo *result = nullptr;\n\n\tforEachEnumValue([&result, &name, this](\n\t\t\t\t\t\t const QtnEnumValueInfo &enumValue) -> bool {\n\t\tif (QString::compare(enumValue.name(), name, m_case_sensitivity) == 0)\n\t\t{\n\t\t\tresult = &enumValue;\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\treturn result;\n}\n\nconst QtnEnumValueInfo *QtnEnumInfo::findByDisplayName(\n\tconst QString &displayName, Qt::CaseSensitivity cs) const\n{\n\tconst QtnEnumValueInfo *result = nullptr;\n\n\tforEachEnumValue(\n\t\t[&result, &displayName, cs](const QtnEnumValueInfo &enumValue) -> bool {\n\t\t\tif (QString::compare(enumValue.displayName(), displayName, cs) == 0)\n\t\t\t{\n\t\t\t\tresult = &enumValue;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\treturn result;\n}\n\nconst QtnEnumValueInfo *QtnEnumInfo::fromStr(const QString &str) const\n{\n\treturn findByName(str.trimmed());\n}\n\nbool QtnEnumInfo::toStr(QString &str, const QtnEnumValueInfo *value) const\n{\n\tif (!value)\n\t\treturn false;\n\n\tstr = value->name();\n\treturn true;\n}\n\nQtnEnumValueInfo::QtnEnumValueInfo()\n\t: m_value(0)\n\t, m_state(QtnEnumValueStateInvalid)\n{\n}\n\nQtnEnumValueInfo::QtnEnumValueInfo(\n\tQtnEnumValueType value, const QString &name, QtnEnumValueState state)\n\t: QtnEnumValueInfo(value, name, name, state)\n{\n}\n\nQtnEnumValueInfo::QtnEnumValueInfo(QtnEnumValueType value, const QString &name,\n\tconst QString &displayName, QtnEnumValueState state)\n\t: m_value(value)\n\t, m_name(name)\n\t, m_displayName(displayName)\n\t, m_state(state)\n{\n\tif (displayName.isEmpty())\n\t\tm_displayName = name;\n}\n\nbool QtnEnumInfo::toStr(QString &str, QtnEnumValueType value) const\n{\n\treturn toStr(str, findByValue(value));\n}\n"
  },
  {
    "path": "QtnProperty/Enum.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_ENUM_H\n#define QTN_ENUM_H\n\n#include \"Config.h\"\n#include <QVector>\n#include <QSharedPointer>\n#include <QMetaEnum>\n\ntypedef qint32 QtnEnumValueType;\n\nenum QtnEnumValueStateFlag\n{\n\tQtnEnumValueStateNone = 0x0000,\n\tQtnEnumValueStateHidden = 0x0001,\n\tQtnEnumValueStateObsolete = 0x0002,\n\tQtnEnumValueStateInvalid = 0x0004\n};\n\nQ_DECLARE_FLAGS(QtnEnumValueState, QtnEnumValueStateFlag)\nQ_DECLARE_OPERATORS_FOR_FLAGS(QtnEnumValueState)\n\nclass QTN_IMPORT_EXPORT QtnEnumValueInfo\n{\npublic:\n\tQtnEnumValueInfo();\n\n\tQtnEnumValueInfo(QtnEnumValueType value, const QString &name,\n\t\tQtnEnumValueState state = QtnEnumValueStateNone);\n\n\tQtnEnumValueInfo(QtnEnumValueType value, const QString &name,\n\t\tconst QString &displayName,\n\t\tQtnEnumValueState state = QtnEnumValueStateNone);\n\n\tinline QtnEnumValueType value() const;\n\tinline void setValue(QtnEnumValueType value);\n\tinline const QString &name() const;\n\tinline const QString &displayName() const;\n\tinline QtnEnumValueState state() const;\n\nprivate:\n\tQtnEnumValueType m_value;\n\tQString m_name;\n\tQString m_displayName;\n\tQtnEnumValueState m_state;\n};\n\nQtnEnumValueType QtnEnumValueInfo::value() const\n{\n\treturn m_value;\n}\n\nvoid QtnEnumValueInfo::setValue(QtnEnumValueType value)\n{\n\tm_value = value;\n}\n\nconst QString &QtnEnumValueInfo::name() const\n{\n\treturn m_name;\n}\n\nconst QString &QtnEnumValueInfo::displayName() const\n{\n\treturn m_displayName;\n}\n\nQtnEnumValueState QtnEnumValueInfo::state() const\n{\n\treturn m_state;\n}\n\nclass QTN_IMPORT_EXPORT QtnEnumInfo\n{\npublic:\n\tQtnEnumInfo();\n\tQtnEnumInfo(const QString &name);\n\tQtnEnumInfo(const QString &name, QVector<QtnEnumValueInfo> &staticValues);\n\tQtnEnumInfo(\n\t\tconst QString &name, const QVector<QtnEnumValueInfo> &staticValues);\n\n\tinline bool isValid() const;\n\tinline const QString &name() const;\n\n\tstatic QtnEnumInfo withMetaEnum(\n\t\tconst QMetaEnum &metaEnum, bool translate = false);\n\ttemplate <typename T>\n\tstatic inline QtnEnumInfo withEnum(bool translate = false)\n\t{\n\t\treturn withMetaEnum(QMetaEnum::fromType<T>(), translate);\n\t}\n\n\ttemplate <typename Pred>\n\tbool forEachEnumValue(Pred pred) const\n\t{\n\t\tfor (const auto &value : m_values)\n\t\t{\n\t\t\tif (!pred(value))\n\t\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tconst QtnEnumValueInfo *findByValue(QtnEnumValueType value) const;\n\tconst QtnEnumValueInfo *findByName(const QString &name) const;\n\tconst QtnEnumValueInfo *findByDisplayName(const QString &displayName,\n\t\tQt::CaseSensitivity cs = Qt::CaseSensitive) const;\n\n\tconst QtnEnumValueInfo *fromStr(const QString &str) const;\n\tbool toStr(QString &str, const QtnEnumValueInfo *value) const;\n\tbool toStr(QString &str, QtnEnumValueType value) const;\n\n\tQt::CaseSensitivity getCaseSensitivity() const;\n\tvoid setCaseSensitivity(Qt::CaseSensitivity value);\n\n\tinline QVector<QtnEnumValueInfo> &getVector();\n\tinline const QVector<QtnEnumValueInfo> &getVector() const;\n\nprivate:\n\tQt::CaseSensitivity m_case_sensitivity;\n\tQString m_name;\n\tQVector<QtnEnumValueInfo> m_values;\n};\n\nbool QtnEnumInfo::isValid() const\n{\n\treturn !m_name.isEmpty() && !m_values.isEmpty();\n}\n\nconst QString &QtnEnumInfo::name() const\n{\n\treturn m_name;\n}\n\nQVector<QtnEnumValueInfo> &QtnEnumInfo::getVector()\n{\n\treturn m_values;\n}\n\nconst QVector<QtnEnumValueInfo> &QtnEnumInfo::getVector() const\n{\n\treturn m_values;\n}\n\n#endif // QTN_ENUM_H\n"
  },
  {
    "path": "QtnProperty/FunctionalHelpers.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n\n#include <functional>\n\ntemplate <typename T, typename R, class... Types>\nstd::function<R(Types...)> qtnMemFn(T *t, R (T::*memFn)(Types...) const)\n{\n\treturn [t, memFn](Types... args) {\n\t\treturn std::mem_fn(memFn)(t, std::forward<Types>(args)...);\n\t};\n}\n\ntemplate <typename T, typename R, class... Types>\nstd::function<R(Types...)> qtnMemFn(T *t, R (T::*memFn)(Types...))\n{\n\treturn [t, memFn](Types... args) {\n\t\treturn std::mem_fn(memFn)(t, std::forward<Types>(args)...);\n\t};\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyButton.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyButton.h\"\n\nQtnPropertyButton::QtnPropertyButton(QObject *parent)\n\t: QtnProperty(parent)\n{\n\tswitchState(QtnPropertyStateNonSerialized, true);\n}\n\nvoid QtnPropertyButton::invokeClick()\n{\n\temit click(this);\n}\n\nvoid QtnPropertyButton::setClickHandler(\n\tconst std::function<void(const QtnPropertyButton *)> &clickHandler)\n{\n\tQObject::connect(this, &QtnPropertyButton::click, clickHandler);\n}\n\nvoid QtnPropertyButton::invokePreDrawButton(QStyleOptionButton *option)\n{\n\tQ_ASSERT(option);\n\temit preDrawButton(this, option);\n}\n\nbool QtnPropertyButton::fromStrImpl(const QString &, QtnPropertyChangeReason)\n{\n\treturn false;\n}\n\nbool QtnPropertyButton::toStrImpl(QString &) const\n{\n\treturn false;\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyButton.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_BUTTON_H\n#define PROPERTY_BUTTON_H\n\n#include \"QtnProperty/Property.h\"\n#include <functional>\n\nclass QStyleOptionButton;\n\nclass QTN_IMPORT_EXPORT QtnPropertyButton : public QtnProperty\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QtnPropertyButton(QObject *parent);\n\n\tvoid invokeClick();\n\tvoid setClickHandler(\n\t\tconst std::function<void(const QtnPropertyButton *)> &clickHandler);\n\n\tinline QtnPropertyButton &operator=(const QtnPropertyButton &);\n\nQ_SIGNALS:\n\tvoid click(const QtnPropertyButton *property);\n\npublic:\n\tvoid invokePreDrawButton(QStyleOptionButton *option);\n\nQ_SIGNALS:\n\tvoid preDrawButton(\n\t\tconst QtnPropertyButton *property, QStyleOptionButton *option);\n\nprotected:\n\tbool fromStrImpl(const QString &, QtnPropertyChangeReason) override;\n\tbool toStrImpl(QString &str) const override;\n};\n\nQtnPropertyButton &QtnPropertyButton::operator=(const QtnPropertyButton &)\n{\n\t// do nothing\n\treturn *this;\n}\n\n#endif // PROPERTY_BUTTON_H\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQBrush.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQBrush.h\"\n#include <QMap>\n\nQtnPropertyQBrushStyle::StrBrushStyleMap\nQtnPropertyQBrushStyle::CreateStr2BrushStyle()\n{\n\tStrBrushStyleMap str2BrushStyle = { //\n\t\t{ QByteArray(QT_TR_NOOP(\"NoBrush\")), Qt::NoBrush },\n\t\t{ QByteArray(QT_TR_NOOP(\"Solid\")), Qt::SolidPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense1Pattern\")), Qt::Dense1Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense2Pattern\")), Qt::Dense2Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense3Pattern\")), Qt::Dense3Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense4Pattern\")), Qt::Dense4Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense5Pattern\")), Qt::Dense5Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense6Pattern\")), Qt::Dense6Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"Dense7Pattern\")), Qt::Dense7Pattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"HorPattern\")), Qt::HorPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"VerPattern\")), Qt::VerPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"CrossPattern\")), Qt::CrossPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"BDiagPattern\")), Qt::BDiagPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"FDiagPattern\")), Qt::FDiagPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"DiagCrossPattern\")), Qt::DiagCrossPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"LinearGradientPattern\")),\n\t\t\tQt::LinearGradientPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"RadialGradientPattern\")),\n\t\t\tQt::RadialGradientPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"ConicalGradientPattern\")),\n\t\t\tQt::ConicalGradientPattern },\n\t\t{ QByteArray(QT_TR_NOOP(\"TexturePattern\")), Qt::TexturePattern }\n\t};\n\treturn str2BrushStyle;\n}\n\nQtnPropertyQBrushStyle::BrushStyleToStrMap\nQtnPropertyQBrushStyle::CreateBrushStyle2Str()\n{\n\tBrushStyleToStrMap brushStyle2Str;\n\tauto map = CreateStr2BrushStyle();\n\tfor (auto it = map.constBegin(); it != map.constEnd(); ++it)\n\t\tbrushStyle2Str[it.value()] = it.key();\n\n\treturn brushStyle2Str;\n}\n\nbool QtnPropertyQBrushStyleBase::brushStyleToStr(\n\tQt::BrushStyle brushStyle, QByteArray &result)\n{\n\tstatic auto brushStyle2Str = QtnPropertyQBrushStyle::CreateBrushStyle2Str();\n\tauto it = brushStyle2Str.find(brushStyle);\n\tif (it != brushStyle2Str.end())\n\t{\n\t\tresult = it.value();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nQtnPropertyQBrushStyle::QtnPropertyQBrushStyle(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQBrushStyleBase>(parent)\n{\n}\n\nbool QtnPropertyQBrushStyle::translateBrushStyle(\n\tQt::BrushStyle brushStyle, QString &result)\n{\n\tQByteArray id;\n\tif (!QtnPropertyQBrushStyleBase::brushStyleToStr(brushStyle, id))\n\t\treturn false;\n\n\tresult = tr(id.data());\n\treturn true;\n}\n\nQtnPropertyQBrushStyleBase::QtnPropertyQBrushStyleBase(QObject *parent)\n\t: QtnSinglePropertyBase<Qt::BrushStyle>(parent)\n{\n}\n\nbool QtnPropertyQBrushStyleBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic auto str2BrushStyle = QtnPropertyQBrushStyle::CreateStr2BrushStyle();\n\tauto it = str2BrushStyle.find(str.toLatin1());\n\tif (it != str2BrushStyle.end())\n\t{\n\t\treturn setValue(it.value(), reason);\n\t}\n\n\treturn false;\n}\n\nbool QtnPropertyQBrushStyleBase::toStrImpl(QString &str) const\n{\n\tQByteArray id;\n\tif (!brushStyleToStr(value(), id))\n\t\treturn false;\n\n\tstr = QString::fromLatin1(id.data(), id.size());\n\treturn true;\n}\n\nQDataStream &operator<<(QDataStream &stream, Qt::BrushStyle brushStyle)\n{\n\tstream << (qint32) brushStyle;\n\treturn stream;\n}\n\nQDataStream &operator>>(QDataStream &stream, Qt::BrushStyle &brushStyle)\n{\n\tqint32 value = 0;\n\tstream >> value;\n\tbrushStyle = (Qt::BrushStyle) value;\n\treturn stream;\n}\n\nQtnPropertyQBrushStyleCallback::QtnPropertyQBrushStyleCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQBrushStyleBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQBrush.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_BRUSH_H\n#define PROPERTY_BRUSH_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/Enum.h\"\n\n#include <QBrush>\n\nQ_DECLARE_METATYPE(Qt::BrushStyle)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQBrushStyleBase\n\t: public QtnSinglePropertyBase<Qt::BrushStyle>\n{\n\tQ_OBJECT\n\tQtnPropertyQBrushStyleBase(\n\t\tconst QtnPropertyQBrushStyleBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQBrushStyleBase(QObject *parent);\n\n\tstatic bool brushStyleToStr(Qt::BrushStyle brushStyle, QByteArray &result);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQBrushStyleBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQBrushStyleBase, Qt::BrushStyle)\nQTN_IMPORT_EXPORT QDataStream &operator<<(\n\tQDataStream &stream, Qt::BrushStyle brushStyle);\nQTN_IMPORT_EXPORT QDataStream &operator>>(\n\tQDataStream &stream, Qt::BrushStyle &brushStyle);\n\nclass QTN_IMPORT_EXPORT QtnPropertyQBrushStyleCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQBrushStyleBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQBrushStyleCallback(\n\t\tconst QtnPropertyQBrushStyleCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQBrushStyleCallback(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQBrushStyleCallback, QtnPropertyQBrushStyleBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQBrushStyle\n\t: public QtnSinglePropertyValue<QtnPropertyQBrushStyleBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQBrushStyle(\n\t\tconst QtnPropertyQBrushStyle &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQBrushStyle(QObject *parent);\n\n\tstatic bool translateBrushStyle(Qt::BrushStyle brushStyle, QString &result);\n\n\tusing StrBrushStyleMap = QMap<QByteArray, Qt::BrushStyle>;\n\tusing BrushStyleToStrMap = QMap<Qt::BrushStyle, QByteArray>;\n\n\tstatic StrBrushStyleMap CreateStr2BrushStyle();\n\tstatic BrushStyleToStrMap CreateBrushStyle2Str();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQBrushStyle, QtnPropertyQBrushStyleBase)\n};\n\n#endif // PROPERTY_BRUSH_H\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQColor.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQColor.h\"\n\n#include \"QtnProperty/Auxiliary/PropertyDelegateInfo.h\"\n\nQtnPropertyQColorBase::QtnPropertyQColorBase(QObject *parent)\n\t: QtnStructPropertyBase<QColor, QtnPropertyIntCallback>(parent)\n{\n}\n\nQtnProperty *QtnPropertyQColorBase::createRedProperty()\n{\n\tauto result = createFieldProperty(&QColor::red, &QColor::setRed,\n\t\tQtnPropertyQColor::redKey(), QtnPropertyQColor::redDisplayName(),\n\t\tQtnPropertyQColor::redDescriptionFmt());\n\tresult->setMinValue(0);\n\tresult->setMaxValue(255);\n\n\tQtnPropertyDelegateInfo delegate;\n\tdelegate.name = qtnSliderBoxDelegate();\n\tdelegate.attributes[qtnLiveUpdateAttr()] = true;\n\tdelegate.attributes[qtnAnimateAttr()] = true;\n\tdelegate.attributes[qtnFillColorAttr()] = QColor(255, 100, 100);\n\tresult->setDelegateInfo(delegate);\n\treturn result;\n}\n\nQtnProperty *QtnPropertyQColorBase::createGreenProperty()\n{\n\tauto result = createFieldProperty(&QColor::green, &QColor::setGreen,\n\t\tQtnPropertyQColor::greenKey(), QtnPropertyQColor::greenDisplayName(),\n\t\tQtnPropertyQColor::greenDescriptionFmt());\n\tresult->setMinValue(0);\n\tresult->setMaxValue(255);\n\n\tQtnPropertyDelegateInfo delegate;\n\tdelegate.name = qtnSliderBoxDelegate();\n\tdelegate.attributes[qtnLiveUpdateAttr()] = true;\n\tdelegate.attributes[qtnAnimateAttr()] = true;\n\tdelegate.attributes[qtnFillColorAttr()] = QColor(100, 255, 100);\n\tresult->setDelegateInfo(delegate);\n\treturn result;\n}\n\nQtnProperty *QtnPropertyQColorBase::createBlueProperty()\n{\n\tauto result = createFieldProperty(&QColor::blue, &QColor::setBlue,\n\t\tQtnPropertyQColor::blueKey(), QtnPropertyQColor::blueDisplayName(),\n\t\tQtnPropertyQColor::blueDescriptionFmt());\n\tresult->setMinValue(0);\n\tresult->setMaxValue(255);\n\n\tQtnPropertyDelegateInfo delegate;\n\tdelegate.name = qtnSliderBoxDelegate();\n\tdelegate.attributes[qtnLiveUpdateAttr()] = true;\n\tdelegate.attributes[qtnAnimateAttr()] = true;\n\tdelegate.attributes[qtnFillColorAttr()] = QColor(100, 100, 255);\n\tresult->setDelegateInfo(delegate);\n\treturn result;\n}\n\nbool QtnPropertyQColorBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tQColor color;\n\treturn QtnPropertyQColor::colorFromStr(str, color) &&\n\t\tsetValue(color, reason);\n}\n\nbool QtnPropertyQColorBase::toStrImpl(QString &str) const\n{\n\treturn QtnPropertyQColor::strFromColor(value(), str);\n}\n\nbool QtnPropertyQColor::colorFromStr(const QString &str, QColor &color)\n{\n\tQColor newColor(str.trimmed());\n\tif (!newColor.isValid())\n\t\treturn false;\n\n\tcolor = newColor;\n\treturn true;\n}\n\nbool QtnPropertyQColor::strFromColor(const QColor &color, QString &str)\n{\n\tstr = color.name((color.alpha() < 255) ? QColor::HexArgb : QColor::HexRgb);\n\treturn true;\n}\n\nQtnPropertyQColorCallback::QtnPropertyQColorCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQColorBase>(parent)\n{\n}\n\nQtnPropertyQColor::QtnPropertyQColor(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQColorBase>(parent)\n{\n}\n\nQString QtnPropertyQColor::redKey()\n{\n\treturn QStringLiteral(\"red\");\n}\n\nQString QtnPropertyQColor::redDisplayName()\n{\n\treturn tr(\"Red\");\n}\n\nQString QtnPropertyQColor::redDescriptionFmt()\n{\n\treturn tr(\"Red component of %1\");\n}\n\nQString QtnPropertyQColor::greenKey()\n{\n\treturn QStringLiteral(\"green\");\n}\n\nQString QtnPropertyQColor::greenDisplayName()\n{\n\treturn tr(\"Green\");\n}\n\nQString QtnPropertyQColor::greenDescriptionFmt()\n{\n\treturn tr(\"Green component of %1\");\n}\n\nQString QtnPropertyQColor::blueKey()\n{\n\treturn QStringLiteral(\"blue\");\n}\n\nQString QtnPropertyQColor::blueDisplayName()\n{\n\treturn tr(\"Blue\");\n}\n\nQString QtnPropertyQColor::blueDescriptionFmt()\n{\n\treturn tr(\"Blue component of %1\");\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQColor.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_COLOR_H\n#define PROPERTY_COLOR_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n#include \"QtnProperty/Core/PropertyInt.h\"\n#include <QColor>\n\nenum QtnColorDelegateShape\n{\n\tQtnColorDelegateShapeNone = 0x1,\n\tQtnColorDelegateShapeSquare = 0x2,\n\tQtnColorDelegateShapeCircle = 0x3\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQColorBase\n\t: public QtnStructPropertyBase<QColor, QtnPropertyIntCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQColorBase(const QtnPropertyQColorBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQColorBase(QObject *parent);\n\n\tQtnProperty *createRedProperty();\n\tQtnProperty *createGreenProperty();\n\tQtnProperty *createBlueProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQColorBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQColorBase, QColor)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQColorCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQColorBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQColorCallback(\n\t\tconst QtnPropertyQColorCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQColorCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQColorCallback, QtnPropertyQColorBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQColor\n\t: public QtnSinglePropertyValue<QtnPropertyQColorBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQColor(const QtnPropertyQColor &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQColor(QObject *parent = nullptr);\n\n\tstatic QString redKey();\n\tstatic QString redDisplayName();\n\tstatic QString redDescriptionFmt();\n\tstatic QString greenKey();\n\tstatic QString greenDisplayName();\n\tstatic QString greenDescriptionFmt();\n\tstatic QString blueKey();\n\tstatic QString blueDisplayName();\n\tstatic QString blueDescriptionFmt();\n\n\tstatic bool colorFromStr(const QString &str, QColor &color);\n\tstatic bool strFromColor(const QColor &color, QString &str);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQColor, QtnPropertyQColorBase)\n};\n\n#endif // PROPERTY_COLOR_H\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQFont.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQFont.h\"\n#include <QFontDatabase>\n\nQtnPropertyQFontBase::QtnPropertyQFontBase(QObject *parent)\n\t: QtnSinglePropertyBase<QFont>(parent)\n{\n}\n\nbool QtnPropertyQFontBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tQFont font;\n\n\tif (!font.fromString(str.trimmed()))\n\t\treturn false;\n\n\treturn setValue(font, reason);\n}\n\nbool QtnPropertyQFontBase::toStrImpl(QString &str) const\n{\n\tQFont v = value();\n\tstr = v.toString();\n\treturn true;\n}\n\nQtnPropertyQFont::QtnPropertyQFont(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQFontBase>(parent)\n{\n}\n\nQString QtnPropertyQFont::getPixelStr()\n{\n\treturn tr(\"Pixel\");\n}\n\nQString QtnPropertyQFont::getPointStr()\n{\n\treturn tr(\"Point\");\n}\n\nQString QtnPropertyQFont::getPreferDefaultStr()\n{\n\treturn tr(\"PreferDefault\");\n}\n\nQString QtnPropertyQFont::getNoAntialiasStr()\n{\n\treturn tr(\"NoAntialias\");\n}\n\nQString QtnPropertyQFont::getPreferAntialiasStr()\n{\n\treturn tr(\"PreferAntialias\");\n}\n\nQString QtnPropertyQFont::getFamilyLabel()\n{\n\treturn tr(\"Family\");\n}\n\nQString QtnPropertyQFont::getFamilyDescription(const QString &ownerName)\n{\n\treturn tr(\"Family for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getStyleLabel()\n{\n\treturn tr(\"Style\");\n}\n\nQString QtnPropertyQFont::getStyleDescription(const QString &ownerName)\n{\n\treturn tr(\"Style for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getSizeLabel()\n{\n\treturn tr(\"Size\");\n}\n\nQString QtnPropertyQFont::getSizeDescription(const QString &ownerName)\n{\n\treturn tr(\"Size for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getSizeUnitLabel()\n{\n\treturn tr(\"Size Unit\");\n}\n\nQString QtnPropertyQFont::getSizeUnitDescription(const QString &ownerName)\n{\n\treturn tr(\"Size Unit for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getBoldLabel()\n{\n\treturn tr(\"Bold\");\n}\n\nQString QtnPropertyQFont::getBoldDescription(const QString &ownerName)\n{\n\treturn tr(\"Bold flag for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getItalicLabel()\n{\n\treturn tr(\"Italic\");\n}\n\nQString QtnPropertyQFont::getItalicDescription(const QString &ownerName)\n{\n\treturn tr(\"Italic flag for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getUnderlineLabel()\n{\n\treturn tr(\"Underline\");\n}\n\nQString QtnPropertyQFont::getUnderlineDescription(const QString &ownerName)\n{\n\treturn tr(\"Underline flag for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getStrikeoutLabel()\n{\n\treturn tr(\"Strikeout\");\n}\n\nQString QtnPropertyQFont::getStrikeoutDescription(const QString &ownerName)\n{\n\treturn tr(\"Strikeout flag for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getKerningLabel()\n{\n\treturn tr(\"Kerning\");\n}\n\nQString QtnPropertyQFont::getKerningDescription(const QString &ownerName)\n{\n\treturn tr(\"Kerning flag for %1\").arg(ownerName);\n}\n\nQString QtnPropertyQFont::getAntialiasingLabel()\n{\n\treturn tr(\"Antialiasing\");\n}\n\nQString QtnPropertyQFont::getAntialiasingDescription(const QString &ownerName)\n{\n\treturn tr(\"Antialiasing options for %1\").arg(ownerName);\n}\n\nQtnPropertyQFontCallback::QtnPropertyQFontCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQFontBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQFont.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_FONT_H\n#define PROPERTY_FONT_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include <QFont>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQFontBase\n\t: public QtnSinglePropertyBase<QFont>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQFontBase(const QtnPropertyQFontBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQFontBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQFontBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQFontBase, QFont)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQFontCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQFontBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQFontCallback(\n\t\tconst QtnPropertyQFontCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQFontCallback(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQFontCallback, QtnPropertyQFontBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQFont\n\t: public QtnSinglePropertyValue<QtnPropertyQFontBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQFont(const QtnPropertyQFont &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQFont(QObject *parent);\n\n\tstatic QString getPixelStr();\n\tstatic QString getPointStr();\n\tstatic QString getPreferDefaultStr();\n\tstatic QString getNoAntialiasStr();\n\tstatic QString getPreferAntialiasStr();\n\tstatic QString getFamilyLabel();\n\tstatic QString getFamilyDescription(const QString &ownerName);\n\tstatic QString getStyleLabel();\n\tstatic QString getStyleDescription(const QString &ownerName);\n\tstatic QString getSizeLabel();\n\tstatic QString getSizeDescription(const QString &ownerName);\n\tstatic QString getSizeUnitLabel();\n\tstatic QString getSizeUnitDescription(const QString &ownerName);\n\tstatic QString getBoldLabel();\n\tstatic QString getBoldDescription(const QString &ownerName);\n\tstatic QString getItalicLabel();\n\tstatic QString getItalicDescription(const QString &ownerName);\n\tstatic QString getUnderlineLabel();\n\tstatic QString getUnderlineDescription(const QString &ownerName);\n\tstatic QString getStrikeoutLabel();\n\tstatic QString getStrikeoutDescription(const QString &ownerName);\n\tstatic QString getKerningLabel();\n\tstatic QString getKerningDescription(const QString &ownerName);\n\tstatic QString getAntialiasingLabel();\n\tstatic QString getAntialiasingDescription(const QString &ownerName);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQFont, QtnPropertyQFontBase)\n};\n\n#endif // PROPERTY_FONT_H\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQPen.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQPen.h\"\n#include \"QtnProperty/GUI/PropertyQColor.h\"\n\n#include <QMap>\n#include <QMetaEnum>\n#include <QCoreApplication>\n\nstatic const char *TRANSLATIONS[] = {\n\tQT_TRANSLATE_NOOP(\"Qt\", \"NoPen\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"SolidLine\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"DashLine\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"DotLine\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"DashDotLine\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"DashDotDotLine\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"CustomDashLine\"),\n\n\tQT_TRANSLATE_NOOP(\"Qt\", \"FlatCap\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"SquareCap\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"RoundCap\"),\n\n\tQT_TRANSLATE_NOOP(\"Qt\", \"MiterJoin\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"BevelJoin\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"RoundJoin\"),\n\tQT_TRANSLATE_NOOP(\"Qt\", \"SvgMiterJoin\"),\n};\n\nQtnPropertyQPenStyleBase::QtnPropertyQPenStyleBase(QObject *parent)\n\t: QtnSinglePropertyBase<Qt::PenStyle>(parent)\n{\n\tQ_UNUSED(TRANSLATIONS);\n}\n\nbool QtnPropertyQPenStyleBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tauto metaEnum = QMetaEnum::fromType<Qt::PenStyle>();\n\tbool ok = false;\n\tint value = metaEnum.keyToValue(str.toLatin1(), &ok);\n\n\tif (ok)\n\t{\n\t\tsetValue(Qt::PenStyle(value), reason);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool QtnPropertyQPenStyleBase::toStrImpl(QString &str) const\n{\n\tauto metaEnum = QMetaEnum::fromType<Qt::PenStyle>();\n\tauto key = metaEnum.valueToKey(int(value()));\n\tif (key)\n\t{\n\t\tstr = QLatin1String(key);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nQDataStream &operator<<(QDataStream &stream, Qt::PenStyle penStyle)\n{\n\tstream << (qint32) penStyle;\n\treturn stream;\n}\n\nQDataStream &operator>>(QDataStream &stream, Qt::PenStyle &penStyle)\n{\n\tqint32 value = 0;\n\tstream >> value;\n\tpenStyle = (Qt::PenStyle) value;\n\treturn stream;\n}\n\nQtnPropertyQPenBase::QtnPropertyQPenBase(QObject *parent)\n\t: QtnSinglePropertyBase<QPen>(parent)\n{\n}\n\nconst QtnEnumInfo &QtnPropertyQPenBase::penStyleEnum()\n{\n\tstatic QtnEnumInfo enumInfo;\n\tif (!enumInfo.isValid())\n\t{\n\t\tenumInfo = QtnEnumInfo::withEnum<Qt::PenStyle>(true);\n\t\tauto &vec = enumInfo.getVector();\n\t\tfor (auto it = vec.begin(); it != vec.end(); ++it)\n\t\t{\n\t\t\tif (it->value() == Qt::MPenStyle)\n\t\t\t{\n\t\t\t\tvec.erase(it);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn enumInfo;\n}\n\nconst QtnEnumInfo &QtnPropertyQPenBase::penCapStyleEnum()\n{\n\tstatic QtnEnumInfo enumInfo;\n\tif (!enumInfo.isValid())\n\t{\n\t\tenumInfo = QtnEnumInfo::withEnum<Qt::PenCapStyle>(true);\n\t\tauto &vec = enumInfo.getVector();\n\t\tfor (auto it = vec.begin(); it != vec.end(); ++it)\n\t\t{\n\t\t\tif (it->value() == Qt::MPenCapStyle)\n\t\t\t{\n\t\t\t\tvec.erase(it);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn enumInfo;\n}\n\nconst QtnEnumInfo &QtnPropertyQPenBase::penJoinStyleEnum()\n{\n\tstatic QtnEnumInfo enumInfo;\n\tif (!enumInfo.isValid())\n\t{\n\t\tenumInfo = QtnEnumInfo::withEnum<Qt::PenJoinStyle>(true);\n\t\tauto &vec = enumInfo.getVector();\n\t\tfor (auto it = vec.begin(); it != vec.end(); ++it)\n\t\t{\n\t\t\tif (it->value() == Qt::MPenJoinStyle)\n\t\t\t{\n\t\t\t\tvec.erase(it);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn enumInfo;\n}\n\nbool QtnPropertyQPenBase::penFromStr(const QString &str, QPen &pen)\n{\n\tQStringList penParts = str.split(',');\n\tif (penParts.size() != 5)\n\t\treturn false;\n\n\tQColor color;\n\tif (!QtnPropertyQColor::colorFromStr(penParts[0], color))\n\t\treturn false;\n\n\tauto styleEnum = penStyleEnum().fromStr(penParts[1]);\n\tif (!styleEnum)\n\t\treturn false;\n\tauto style = Qt::PenStyle(styleEnum->value());\n\n\tbool ok = false;\n\tint width = penParts[2].trimmed().toInt(&ok);\n\tif (!ok)\n\t\treturn false;\n\n\tauto capStyleEnum = penCapStyleEnum().fromStr(penParts[3]);\n\tif (!capStyleEnum)\n\t\treturn false;\n\tauto capStyle = Qt::PenCapStyle(capStyleEnum->value());\n\n\tauto joinStyleEnum = penJoinStyleEnum().fromStr(penParts[4]);\n\tif (!joinStyleEnum)\n\t\treturn false;\n\tauto joinStyle = Qt::PenJoinStyle(joinStyleEnum->value());\n\n\tpen.setColor(color);\n\tpen.setStyle(style);\n\tpen.setWidth(width);\n\tpen.setCapStyle(capStyle);\n\tpen.setJoinStyle(joinStyle);\n\n\treturn true;\n}\n\nbool QtnPropertyQPenBase::strFromPen(const QPen &pen, QString &str)\n{\n\tQString color;\n\tQtnPropertyQColor::strFromColor(pen.color(), color);\n\tQString style;\n\tpenStyleEnum().toStr(style, pen.style());\n\tQString width = QString::number(pen.width());\n\tQString capStyle;\n\tpenCapStyleEnum().toStr(capStyle, pen.capStyle());\n\tQString joinStyle;\n\tpenJoinStyleEnum().toStr(joinStyle, pen.joinStyle());\n\tstr = QString(\"%1, %2, %3, %4, %5\")\n\t\t\t  .arg(color, style, width, capStyle, joinStyle);\n\treturn true;\n}\n\nbool QtnPropertyQPenBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tQPen pen;\n\tif (!penFromStr(str, pen))\n\t\treturn false;\n\n\treturn setValue(pen, reason);\n}\n\nbool QtnPropertyQPenBase::toStrImpl(QString &str) const\n{\n\treturn strFromPen(value(), str);\n}\n\nbool QtnPropertyQPenBase::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tif (!var.canConvert<QPen>())\n\t\treturn false;\n\n\tsetValue(var.value<QPen>(), reason);\n\treturn true;\n}\n\nbool QtnPropertyQPenBase::toVariantImpl(QVariant &var) const\n{\n\tvar = QVariant::fromValue<QPen>(value());\n\treturn true;\n}\n\nQtnPropertyQPenStyleCallback::QtnPropertyQPenStyleCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQPenStyleBase>(parent)\n{\n}\n\nQtnPropertyQPenStyle::QtnPropertyQPenStyle(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQPenStyleBase>(parent)\n{\n}\n\nQtnPropertyQPenCallback::QtnPropertyQPenCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQPenBase>(parent)\n{\n}\n\nQtnPropertyQPen::QtnPropertyQPen(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQPenBase>(parent)\n{\n}\n\nQString QtnPropertyQPen::rootDisplayValue()\n{\n\treturn tr(\"(Pen)\");\n}\n\nQString QtnPropertyQPen::colorKey()\n{\n\treturn QStringLiteral(\"color\");\n}\n\nQString QtnPropertyQPen::colorDisplayName()\n{\n\treturn tr(\"Color\");\n}\n\nQString QtnPropertyQPen::colorDescriptionFmt()\n{\n\treturn tr(\"Color of the %1\");\n}\n\nQString QtnPropertyQPen::styleKey()\n{\n\treturn QStringLiteral(\"style\");\n}\n\nQString QtnPropertyQPen::styleDisplayName()\n{\n\treturn tr(\"Style\");\n}\n\nQString QtnPropertyQPen::styleDescriptionFmt()\n{\n\treturn tr(\"Style of the %1\");\n}\n\nQString QtnPropertyQPen::capStyleKey()\n{\n\treturn QStringLiteral(\"capStyle\");\n}\n\nQString QtnPropertyQPen::capStyleDisplayName()\n{\n\treturn tr(\"Cap Style\");\n}\n\nQString QtnPropertyQPen::capStyleDescriptionFmt()\n{\n\treturn tr(\"Cap Style of the %1\");\n}\n\nQString QtnPropertyQPen::joinStyleKey()\n{\n\treturn QStringLiteral(\"joinStyle\");\n}\n\nQString QtnPropertyQPen::joinStyleDisplayName()\n{\n\treturn tr(\"Join Style\");\n}\n\nQString QtnPropertyQPen::joinStyleDescriptionFmt()\n{\n\treturn tr(\"Join Style of the %1\");\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQPen.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTY_PEN_H\n#define PROPERTY_PEN_H\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/Enum.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n\n#include <QPen>\n\nQ_DECLARE_METATYPE(Qt::PenStyle)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPenStyleBase\n\t: public QtnSinglePropertyBase<Qt::PenStyle>\n{\n\tQ_OBJECT\n\tQtnPropertyQPenStyleBase(\n\t\tconst QtnPropertyQPenStyleBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPenStyleBase(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQPenStyleBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQPenStyleBase, Qt::PenStyle)\nQTN_IMPORT_EXPORT QDataStream &operator<<(\n\tQDataStream &stream, Qt::PenStyle penStyle);\nQTN_IMPORT_EXPORT QDataStream &operator>>(\n\tQDataStream &stream, Qt::PenStyle &penStyle);\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPenStyleCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQPenStyleBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQPenStyleCallback(\n\t\tconst QtnPropertyQPenStyleCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPenStyleCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPenStyleCallback, QtnPropertyQPenStyleBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPenStyle\n\t: public QtnSinglePropertyValue<QtnPropertyQPenStyleBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQPenStyle(const QtnPropertyQPenStyle &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPenStyle(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPenStyle, QtnPropertyQPenStyleBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPenBase : public QtnSinglePropertyBase<QPen>\n{\n\tQ_OBJECT\n\tQtnPropertyQPenBase(const QtnPropertyQPenBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPenBase(QObject *parent);\n\n\tQtnProperty *createPenStyleProperty();\n\tQtnProperty *createCapStyleProperty();\n\tQtnProperty *createJoinStyleProperty();\n\n\tstatic const QtnEnumInfo &penStyleEnum();\n\tstatic const QtnEnumInfo &penCapStyleEnum();\n\tstatic const QtnEnumInfo &penJoinStyleEnum();\n\tstatic bool penFromStr(const QString &str, QPen &pen);\n\tstatic bool strFromPen(const QPen &pen, QString &str);\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\t// variant conversion implementation\n\tbool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\tbool toVariantImpl(QVariant &var) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQPenBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQPenBase, QPen)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPenCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQPenBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQPenCallback(\n\t\tconst QtnPropertyQPenCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPenCallback(QObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQPenCallback, QtnPropertyQPenBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQPen\n\t: public QtnSinglePropertyValue<QtnPropertyQPenBase>\n{\n\tQ_OBJECT\n\tQtnPropertyQPen(const QtnPropertyQPen &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQPen(QObject *parent = nullptr);\n\n\tstatic QString rootDisplayValue();\n\n\tstatic QString colorKey();\n\tstatic QString colorDisplayName();\n\tstatic QString colorDescriptionFmt();\n\n\tstatic QString styleKey();\n\tstatic QString styleDisplayName();\n\tstatic QString styleDescriptionFmt();\n\n\tstatic QString capStyleKey();\n\tstatic QString capStyleDisplayName();\n\tstatic QString capStyleDescriptionFmt();\n\n\tstatic QString joinStyleKey();\n\tstatic QString joinStyleDisplayName();\n\tstatic QString joinStyleDescriptionFmt();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyQPen, QtnPropertyQPenBase)\n};\n\n#endif // PROPERTY_PEN_H\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQVector3D.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#include \"PropertyQVector3D.h\"\n\n#include \"QtnProperty/Core/PropertyQPoint.h\"\n\nQtnPropertyQVector3DBase::QtnPropertyQVector3DBase(QObject *parent)\n\t: ParentClass(parent)\n{\n}\n\nQtnProperty *QtnPropertyQVector3DBase::createXProperty()\n{\n\treturn createFieldProperty(&QVector3D::x, &QVector3D::setX,\n\t\tQtnPropertyQPoint::xKey(), QtnPropertyQPoint::xDisplayName(),\n\t\tQtnPropertyQPoint::xDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQVector3DBase::createYProperty()\n{\n\treturn createFieldProperty(&QVector3D::y, &QVector3D::setY,\n\t\tQtnPropertyQPoint::yKey(), QtnPropertyQPoint::yDisplayName(),\n\t\tQtnPropertyQPoint::yDescriptionFmt());\n}\n\nQtnProperty *QtnPropertyQVector3DBase::createZProperty()\n{\n\treturn createFieldProperty(&QVector3D::z, &QVector3D::setZ,\n\t\tQtnPropertyQVector3D::zKey(), QtnPropertyQVector3D::zDisplayName(),\n\t\tQtnPropertyQVector3D::zDescriptionFmt());\n}\n\nstatic const auto sPrefix = QStringLiteral(\"QVector3D\");\n\nbool QtnPropertyQVector3DBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tauto text = str.trimmed();\n\tif (!text.startsWith(sPrefix, Qt::CaseInsensitive))\n\t{\n\t\treturn false;\n\t}\n\ttext = text.mid(sPrefix.length()).trimmed();\n\n\tif (!text.startsWith(QChar('(')) || !text.endsWith(QChar(')')))\n\t{\n\t\treturn false;\n\t}\n\n\ttext = text.mid(1, text.length() - 2).trimmed();\n\tauto params = text.split(QChar(','));\n\tif (params.size() != 3)\n\t{\n\t\treturn false;\n\t}\n\n\tbool ok = false;\n\tfloat x = params.at(0).trimmed().toFloat(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tfloat y = params.at(1).trimmed().toFloat(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\tfloat z = params.at(2).trimmed().toFloat(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(QVector3D(x, y, z), reason);\n}\n\nbool QtnPropertyQVector3DBase::toStrImpl(QString &str) const\n{\n\tQVector3D v = value();\n\tstr = QStringLiteral(\"%1(%2, %3, %4)\")\n\t\t\t  .arg(sPrefix)\n\t\t\t  .arg(v.x())\n\t\t\t  .arg(v.y())\n\t\t\t  .arg(v.z());\n\treturn true;\n}\n\nQtnPropertyQVector3D::QtnPropertyQVector3D(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQVector3DBase>(parent)\n{\n}\n\nQString QtnPropertyQVector3D::zKey()\n{\n\treturn QStringLiteral(\"z\");\n}\n\nQString QtnPropertyQVector3D::zDisplayName()\n{\n\treturn tr(\"Z\");\n}\n\nQString QtnPropertyQVector3D::zDescriptionFmt()\n{\n\treturn tr(\"Z of the %1\");\n}\n\nQString QtnPropertyQVector3D::getToStringFormat()\n{\n\treturn tr(\"[%1, %2, %3]\");\n}\n\nQtnPropertyQVector3DCallback::QtnPropertyQVector3DCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQVector3DBase>(parent)\n{\n}\n"
  },
  {
    "path": "QtnProperty/GUI/PropertyQVector3D.h",
    "content": "/*******************************************************************************\nCopyright (c) 2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#pragma once\n\n#include \"QtnProperty/Auxiliary/PropertyTemplates.h\"\n#include \"QtnProperty/Core/PropertyFloat.h\"\n#include \"QtnProperty/StructPropertyBase.h\"\n\n#include <QVector3D>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVector3DBase\n\t: public QtnStructPropertyBase<QVector3D, QtnPropertyFloatCallback>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVector3DBase(\n\t\tconst QtnPropertyQVector3DBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQVector3DBase(QObject *parent);\n\n\tQtnProperty *createXProperty();\n\tQtnProperty *createYProperty();\n\tQtnProperty *createZProperty();\n\nprotected:\n\t// string conversion implementation\n\tbool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tbool toStrImpl(QString &str) const override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyQVector3DBase)\n};\n\nP_PROPERTY_DECL_EQ_OPERATORS(QtnPropertyQVector3DBase, QVector3D)\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVector3DCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQVector3DBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVector3DCallback(\n\t\tconst QtnPropertyQVector3DCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQVector3DCallback(\n\t\tQObject *parent = nullptr);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQVector3DCallback, QtnPropertyQVector3DBase)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVector3D\n\t: public QtnSinglePropertyValue<QtnPropertyQVector3DBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVector3D(const QtnPropertyQVector3D &other) Q_DECL_EQ_DELETE;\n\npublic:\n\tQ_INVOKABLE explicit QtnPropertyQVector3D(QObject *parent = nullptr);\n\n\tstatic QString zKey();\n\tstatic QString zDisplayName();\n\tstatic QString zDescriptionFmt();\n\tstatic QString getToStringFormat();\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyQVector3D, QtnPropertyQVector3DBase)\n};\n"
  },
  {
    "path": "QtnProperty/IQtnPropertyStateProvider.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyAux.h\"\n\nstruct IQtnPropertyStateProvider\n{\n\tvirtual ~IQtnPropertyStateProvider() {}\n\n\tvirtual QtnPropertyState getPropertyState(\n\t\tconst QMetaProperty &metaProperty) const = 0;\n\n\tvirtual void setPropertyState(\n\t\tconst QMetaProperty &metaProperty, QtnPropertyState state) = 0;\n};\n"
  },
  {
    "path": "QtnProperty/Install.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"Install.h\"\n\n#include \"PropertyInt64.h\"\n#include \"PropertyUInt64.h\"\n#include \"PropertyQVariant.h\"\n#include \"PropertyQKeySequence.h\"\n#include \"Delegates/Core/PropertyDelegateBool.h\"\n#include \"Delegates/Core/PropertyDelegateDouble.h\"\n#include \"Delegates/Core/PropertyDelegateFloat.h\"\n#include \"Delegates/Core/PropertyDelegateInt.h\"\n#include \"Delegates/Core/PropertyDelegateUInt.h\"\n#include \"Delegates/Core/PropertyDelegateEnum.h\"\n#include \"Delegates/Core/PropertyDelegateEnumFlags.h\"\n#include \"Delegates/Core/PropertyDelegateQPoint.h\"\n#include \"Delegates/Core/PropertyDelegateQRect.h\"\n#include \"Delegates/Core/PropertyDelegateQSize.h\"\n#include \"Delegates/Core/PropertyDelegateQString.h\"\n#include \"Delegates/Core/PropertyDelegateQPointF.h\"\n#include \"Delegates/Core/PropertyDelegateQSizeF.h\"\n#include \"Delegates/Core/PropertyDelegateQRectF.h\"\n#include \"Delegates/GUI/PropertyDelegateQColor.h\"\n#include \"Delegates/GUI/PropertyDelegateQFont.h\"\n#include \"Delegates/GUI/PropertyDelegateQPen.h\"\n#include \"Delegates/GUI/PropertyDelegateQBrush.h\"\n#include \"Delegates/GUI/PropertyDelegateQVector3D.h\"\n#include \"MultiProperty.h\"\n#include \"QObjectPropertySet.h\"\n#include \"Utils/AccessibilityProxy.h\"\n\n#include <QCoreApplication>\n#include <QTranslator>\n#include <QLocale>\n\n#include <map>\n\ntemplate <typename QtnPropertyRealCallback>\nstatic QtnProperty *createRealNumberProperty(\n\tQObject *object, const QMetaProperty &metaProperty)\n{\n\tusing ValueTypeStore = typename QtnPropertyRealCallback::ValueTypeStore;\n\n\tauto property = new QtnPropertyRealCallback(nullptr);\n\n\tswitch (metaProperty.revision())\n\t{\n\t\tcase PERCENT_SUFFIX:\n\t\t{\n\t\t\tQtnPropertyDelegateInfo delegate;\n\t\t\tqtnInitPercentSpinBoxDelegate(delegate);\n\t\t\tproperty->setDelegateInfo(delegate);\n\n\t\t\tproperty->setCallbackValueGet(\n\t\t\t\t[object, metaProperty]() -> ValueTypeStore {\n\t\t\t\t\treturn ValueTypeStore(\n\t\t\t\t\t\tmetaProperty.read(object).toDouble() * 100.0);\n\t\t\t\t});\n\n\t\t\tproperty->setCallbackValueSet(\n\t\t\t\t[object, metaProperty](\n\t\t\t\t\tValueTypeStore value, QtnPropertyChangeReason /*reason*/) {\n\t\t\t\t\tmetaProperty.write(object, value / ValueTypeStore(100.0));\n\t\t\t\t});\n\n\t\t\treturn property;\n\t\t}\n\n\t\tcase DEGREE_SUFFIX:\n\t\t{\n\t\t\tQtnPropertyDelegateInfo delegate;\n\t\t\tqtnInitDegreeSpinBoxDelegate(delegate);\n\t\t\tproperty->setDelegateInfo(delegate);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tproperty->setCallbackValueGet([object, metaProperty]() -> ValueTypeStore {\n\t\treturn ValueTypeStore(metaProperty.read(object).toDouble());\n\t});\n\n\tproperty->setCallbackValueSet([object, metaProperty](ValueTypeStore value,\n\t\t\t\t\t\t\t\t\t  QtnPropertyChangeReason /*reason*/) {\n\t\tmetaProperty.write(object, value);\n\t});\n\n\treturn property;\n}\n\nstatic void qtnRegisterDefaultMetaPropertyFactory()\n{\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::Bool, qtnCreateFactory<QtnPropertyBoolCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QString, qtnCreateFactory<QtnPropertyQStringCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::Double, createRealNumberProperty<QtnPropertyDoubleCallback>);\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::Float, createRealNumberProperty<QtnPropertyFloatCallback>);\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::Int, qtnCreateFactory<QtnPropertyIntCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::UInt, qtnCreateFactory<QtnPropertyUIntCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::LongLong, qtnCreateFactory<QtnPropertyInt64Callback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::ULongLong, qtnCreateFactory<QtnPropertyUInt64Callback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QPoint, qtnCreateFactory<QtnPropertyQPointCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QPointF, qtnCreateFactory<QtnPropertyQPointFCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QRect, qtnCreateFactory<QtnPropertyQRectCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QRectF, qtnCreateFactory<QtnPropertyQRectFCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QSize, qtnCreateFactory<QtnPropertyQSizeCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QSizeF, qtnCreateFactory<QtnPropertyQSizeFCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QColor, qtnCreateFactory<QtnPropertyQColorCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QFont, qtnCreateFactory<QtnPropertyQFontCallback>());\n\tqtnRegisterMetaPropertyFactory(\n\t\tQMetaType::QPen, qtnCreateFactory<QtnPropertyQPenCallback>());\n\tqtnRegisterMetaPropertyFactory(qMetaTypeId<Qt::PenStyle>(),\n\t\tqtnCreateFactory<QtnPropertyQPenStyleCallback>());\n\tqtnRegisterMetaPropertyFactory(qMetaTypeId<Qt::BrushStyle>(),\n\t\tqtnCreateFactory<QtnPropertyQBrushStyleCallback>());\n\tqtnRegisterMetaPropertyFactory(qMetaTypeId<QVector3D>(),\n\t\tqtnCreateFactory<QtnPropertyQVector3DCallback>());\n\tqtnRegisterMetaPropertyFactory(QMetaType::QVariant,\n\t\t[](QObject *object,\n\t\t\tconst QMetaProperty &metaProperty) -> QtnProperty * {\n\t\t\treturn new QtnPropertyQVariantCallback(object, metaProperty);\n\t\t});\n\tqtnRegisterMetaPropertyFactory(QMetaType::QKeySequence,\n\t\tqtnCreateFactory<QtnPropertyQKeySequenceCallback>());\n}\n\nbool qtnPropertyRegister()\n{\n\tQ_INIT_RESOURCE(QtnProperty);\n\n\tqRegisterMetaType<QtnPropertyChangeReason>();\n\tqRegisterMetaType<QtnPropertyBase *>();\n\tqRegisterMetaType<QtnPropertySet *>();\n\tqRegisterMetaType<QtnAccessibilityProxy *>();\n\tqRegisterMetaType<QtnMultiVariant>();\n\n\tqtnRegisterDefaultMetaPropertyFactory();\n\treturn true;\n}\n\nvoid qtnPropertyInstallTranslations(const QLocale &locale)\n{\n\tstatic QTranslator translator;\n\tQCoreApplication::removeTranslator(&translator);\n\tif (translator.load(locale, \"QtnProperty.qm\", \"\", \":/Translations\"))\n\t{\n\t\tQCoreApplication::installTranslator(&translator);\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Install.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n\nclass QLocale;\n\nQTN_IMPORT_EXPORT void qtnPropertyInstallTranslations(const QLocale &locale);\n"
  },
  {
    "path": "QtnProperty/MultiProperty.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"MultiProperty.h\"\n\n#include \"Install.h\"\n#include \"Property.h\"\n#include \"PropertySet.h\"\n#include \"PropertyConnector.h\"\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Utils/QtnConnections.h\"\n\n#include <QStyleOption>\n#include <QKeyEvent>\n#include <QLineEdit>\n\nstruct QtnMultiPropertyDelegate::PropertyToEdit\n{\n\tQtnMultiProperty *owner;\n\tQtnProperty *property;\n\tQtnConnections connections;\n};\n\nQtnMultiProperty::QtnMultiProperty(\n\tconst QMetaObject *propertyMetaObject, QObject *parent)\n\t: QtnProperty(parent)\n\t, mPropertyMetaObject(propertyMetaObject)\n\t, m_subPropertyUpdates(0)\n\t, edited(false)\n\t, calculateMultipleValues(true)\n\t, multipleValues(false)\n{\n\tsetDelegateInfo(QtnPropertyDelegateInfo());\n}\n\nQtnMultiProperty::~QtnMultiProperty()\n{\n\tfor (auto property : properties)\n\t{\n\t\tQObject::disconnect(property, &QtnProperty::propertyValueAccept, this,\n\t\t\t&QtnMultiProperty::onPropertyValueAccept);\n\t\tQObject::disconnect(property, &QtnPropertyBase::propertyWillChange,\n\t\t\tthis, &QtnMultiProperty::onPropertyWillChange);\n\t\tQObject::disconnect(property, &QtnPropertyBase::propertyDidChange, this,\n\t\t\t&QtnMultiProperty::onPropertyDidChange);\n\t}\n}\n\nconst QMetaObject *QtnMultiProperty::propertyMetaObject() const\n{\n\treturn mPropertyMetaObject;\n}\n\nvoid QtnMultiProperty::addProperty(QtnProperty *property, bool own)\n{\n\tQ_ASSERT(nullptr != property);\n\tQ_ASSERT(nullptr != mPropertyMetaObject->cast(property));\n\n\tif (own)\n\t\tproperty->setParent(this);\n\n\tif (properties.end() !=\n\t\tstd::find(properties.begin(), properties.end(), property))\n\t{\n\t\treturn;\n\t}\n\n\tproperties.push_back(property);\n\n\tif (property->isCollapsed())\n\t\tcollapse();\n\tupdateStateFrom(property);\n\n\tQObject::connect(property, &QtnProperty::propertyValueAccept, this,\n\t\t&QtnMultiProperty::onPropertyValueAccept);\n\tQObject::connect(property, &QtnPropertyBase::propertyWillChange, this,\n\t\t&QtnMultiProperty::onPropertyWillChange);\n\tQObject::connect(property, &QtnPropertyBase::propertyDidChange, this,\n\t\t&QtnMultiProperty::onPropertyDidChange);\n}\n\nvoid QtnMultiProperty::doReset(QtnPropertyChangeReason reason)\n{\n\tQ_ASSERT(reason & QtnPropertyChangeReasonResetValue);\n\n\tm_subPropertyUpdates++;\n\temit propertyWillChange(reason, nullptr, 0);\n\n\tfor (auto property : properties)\n\t{\n\t\tproperty->reset(reason);\n\t}\n\n\temit propertyDidChange(reason);\n\tm_subPropertyUpdates--;\n\n\tupdateMultipleState(true);\n}\n\nQString QtnMultiProperty::getMultiValuePlaceholder()\n{\n\treturn tr(\"(Multiple Values)\");\n}\n\nQMetaProperty QtnMultiProperty::getMetaProperty() const\n{\n\tQ_ASSERT(!properties.empty());\n\n\tauto connector = properties.at(0)->getConnector();\n\tQ_ASSERT(nullptr != connector);\n\n\treturn connector->getMetaProperty();\n}\n\nbool QtnMultiProperty::hasMultipleValues() const\n{\n\tif (calculateMultipleValues)\n\t{\n\t\tQString dummy;\n\t\ttoStrImpl(dummy);\n\t}\n\n\treturn multipleValues;\n}\n\nvoid QtnMultiProperty::onPropertyValueAccept(\n\tQtnPropertyValuePtr valueToAccept, bool *accept)\n{\n\tif (m_subPropertyUpdates)\n\t\treturn;\n\temit propertyValueAccept(valueToAccept, accept);\n}\n\nvoid QtnMultiProperty::onPropertyWillChange(\n\tQtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId)\n{\n\tif (m_subPropertyUpdates)\n\t\treturn;\n\temit propertyWillChange(reason, newValue, typeId);\n}\n\nvoid QtnMultiProperty::onPropertyDidChange(QtnPropertyChangeReason reason)\n{\n\tif (m_subPropertyUpdates)\n\t\treturn;\n\n\tQ_ASSERT(nullptr != qobject_cast<QtnProperty *>(sender()));\n\tauto changedProperty = static_cast<QtnProperty *>(sender());\n\tif (edited && (reason & QtnPropertyChangeReasonEdit) &&\n\t\t(reason & QtnPropertyChangeReasonValue))\n\t{\n\t\tauto value = changedProperty->valueAsVariant();\n\n\t\tauto singleReason = reason & ~QtnPropertyChangeReasonMultiEdit;\n\n\t\tm_subPropertyUpdates++;\n\t\tfor (auto property : properties)\n\t\t{\n\t\t\tif (property != changedProperty && property->isEditableByUser())\n\t\t\t{\n\t\t\t\tproperty->fromVariant(value, singleReason);\n\t\t\t}\n\t\t}\n\t\tm_subPropertyUpdates--;\n\t}\n\n\tif (reason & (QtnPropertyChangeReasonState | QtnPropertyChangeReasonValue))\n\t{\n\t\tupdateStateFrom(changedProperty);\n\t\tupdateMultipleState(true);\n\t}\n\n\temit propertyDidChange(reason);\n}\n\nvoid QtnMultiProperty::updatePropertyState()\n{\n\tQtnProperty::updatePropertyState();\n\n\tif (m_subPropertyUpdates)\n\t{\n\t\treturn;\n\t}\n\n\tif (!stateLocal().testFlag(QtnPropertyStateUnlockable))\n\t{\n\t\treturn;\n\t}\n\n\tbool isImmutable = stateLocal().testFlag(QtnPropertyStateImmutable);\n\tm_subPropertyUpdates++;\n\tfor (auto property : properties)\n\t{\n\t\tif (property->stateLocal().testFlag(QtnPropertyStateUnlockable))\n\t\t{\n\t\t\tproperty->switchState(QtnPropertyStateImmutable, isImmutable);\n\t\t}\n\t}\n\tm_subPropertyUpdates--;\n}\n\nbool QtnMultiProperty::loadImpl(QDataStream &stream)\n{\n\tfor (auto property : properties)\n\t{\n\t\tQByteArray propertyData;\n\t\tstream >> propertyData;\n\t\tQDataStream propertyStream(&propertyData, QIODevice::ReadOnly);\n\n\t\tif (!property->load(propertyStream))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool QtnMultiProperty::saveImpl(QDataStream &stream) const\n{\n\tfor (auto property : properties)\n\t{\n\t\tQByteArray propertyData;\n\t\tQDataStream propertyStream(&propertyData, QIODevice::WriteOnly);\n\n\t\tif (!property->save(propertyStream))\n\t\t\treturn false;\n\n\t\tstream << propertyData;\n\t}\n\n\treturn true;\n}\n\nvoid QtnMultiProperty::masterPropertyWillChange(QtnPropertyChangeReason reason)\n{\n\tif (m_subPropertyUpdates)\n\t\treturn;\n\tQtnProperty::masterPropertyWillChange(reason);\n}\n\nvoid QtnMultiProperty::masterPropertyDidChange(QtnPropertyChangeReason reason)\n{\n\tif (m_subPropertyUpdates)\n\t\treturn;\n\tif (reason & (QtnPropertyChangeReasonState | QtnPropertyChangeReasonValue))\n\t{\n\t\tupdateMultipleState(true);\n\t}\n\tQtnProperty::masterPropertyDidChange(reason);\n}\n\nbool QtnMultiProperty::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tm_subPropertyUpdates++;\n\temit propertyWillChange(reason, nullptr, 0);\n\tint okCount = 0;\n\tfor (auto property : properties)\n\t{\n\t\tif (property->fromStr(str, reason))\n\t\t\tokCount++;\n\t}\n\temit propertyDidChange(reason);\n\tm_subPropertyUpdates--;\n\treturn okCount > 0;\n}\n\nbool QtnMultiProperty::toStrImpl(QString &str) const\n{\n\tif (calculateMultipleValues)\n\t{\n\t\tauto thiz = const_cast<QtnMultiProperty *>(this);\n\t\tthiz->calculateMultipleValues = false;\n\n\t\tsize_t sameCount = 0;\n\t\tQString temp;\n\n\t\tfor (auto property : properties)\n\t\t{\n\t\t\tif (!property->toStr(str))\n\t\t\t\tstr.clear();\n\n\t\t\tif (sameCount == 0)\n\t\t\t\ttemp = str;\n\n\t\t\tif (sameCount == 0 || str == temp)\n\t\t\t\tsameCount++;\n\t\t}\n\n\t\tthiz->multipleValues = (sameCount != properties.size());\n\t} else if (!multipleValues)\n\t{\n\t\tif (properties.empty() || !properties.at(0)->toStr(str))\n\t\t\tstr.clear();\n\t}\n\n\tif (multipleValues)\n\t\tstr.clear();\n\n\treturn true;\n}\n\nbool QtnMultiProperty::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tint okCount = 0;\n\tm_subPropertyUpdates++;\n\temit propertyWillChange(reason, nullptr, 0);\n\tif (var.userType() == qMetaTypeId<QtnMultiVariant>())\n\t{\n\t\tauto values = var.value<QtnMultiVariant>().values;\n\t\tauto count = properties.size();\n\t\tauto varCount = size_t(values.count());\n\n\t\tif (count > varCount)\n\t\t\tcount = varCount;\n\n\t\tfor (size_t i = 0; i < count; i++)\n\t\t{\n\t\t\tQtnProperty *property = properties.at(i);\n\n\t\t\tif (property->fromVariant(values.at(int(i)), reason))\n\t\t\t\tokCount++;\n\t\t}\n\t} else\n\t{\n\t\tfor (auto property : properties)\n\t\t{\n\t\t\tif (property->fromVariant(var, reason))\n\t\t\t\tokCount++;\n\t\t}\n\t}\n\temit propertyDidChange(reason);\n\tm_subPropertyUpdates--;\n\treturn okCount > 0;\n}\n\nbool QtnMultiProperty::toVariantImpl(QVariant &var) const\n{\n\tQtnMultiVariant multiVariant;\n\n\tfor (auto property : properties)\n\t{\n\t\tif (!property->toVariant(var))\n\t\t\tvar.clear();\n\n\t\tmultiVariant.values.push_back(var);\n\t}\n\n\tvar.setValue(multiVariant);\n\n\treturn true;\n}\n\nvoid QtnMultiProperty::updateStateFrom(QtnProperty *source)\n{\n\tstatic const QtnPropertyState unchangedState(QtnPropertyStateMultiValue |\n\t\tQtnPropertyStateCollapsed | QtnPropertyStateModifiedValue);\n\tauto state = stateLocal() & unchangedState;\n\tstate |= source->stateLocal() & ~unchangedState;\n\n\tstate &= ~(QtnPropertyStateImmutable | QtnPropertyStateResettable |\n\t\tQtnPropertyStateInvisible | QtnPropertyStateUnlockable);\n\n\tsize_t unlockableCount = 0;\n\tfor (auto property : properties)\n\t{\n\t\tauto childState = property->stateLocal();\n\t\tif (childState.testFlag(QtnPropertyStateInvisible))\n\t\t{\n\t\t\tstate |= QtnPropertyStateInvisible;\n\t\t}\n\n\t\tif (childState.testFlag(QtnPropertyStateImmutable))\n\t\t{\n\t\t\tstate |= QtnPropertyStateImmutable;\n\t\t}\n\n\t\tif (childState.testFlag(QtnPropertyStateResettable))\n\t\t{\n\t\t\tstate |= QtnPropertyStateResettable;\n\t\t}\n\n\t\tif (childState.testFlag(QtnPropertyStateUnlockable))\n\t\t{\n\t\t\tunlockableCount++;\n\t\t}\n\t}\n\n\tif (unlockableCount == properties.size())\n\t{\n\t\tstate |= QtnPropertyStateUnlockable;\n\t}\n\n\tm_subPropertyUpdates++;\n\tsetState(state);\n\tm_subPropertyUpdates--;\n}\n\nvoid QtnMultiProperty::updateMultipleState(bool force)\n{\n\tif (force)\n\t\tcalculateMultipleValues = true;\n\n\tbool multipleValues = hasMultipleValues();\n\tauto state = stateLocal() & ~QtnPropertyStateModifiedValue;\n\n\tstate.setFlag(QtnPropertyStateMultiValue, multipleValues);\n\n\tfor (auto property : properties)\n\t{\n\t\tif (!property->valueIsDefault())\n\t\t{\n\t\t\tstate |= QtnPropertyStateModifiedValue;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tm_subPropertyUpdates++;\n\n\tsetState(state);\n\n\tm_subPropertyUpdates--;\n}\n\nQtnMultiPropertyDelegate::QtnMultiPropertyDelegate(QtnMultiProperty &owner)\n\t: Inherited(owner)\n{\n\towner.updateMultipleState(true);\n}\n\nvoid QtnMultiPropertyDelegate::init()\n{\n\tQ_ASSERT(superDelegates.empty());\n\n\tauto &properties = owner().properties;\n\tsuperDelegates.reserve(properties.size());\n\tfor (auto property : properties)\n\t{\n\t\tauto delegate = factory()->createDelegate(*property);\n\t\tdelegate->setStateProperty(&owner());\n\t\tsuperDelegates.emplace_back(delegate);\n\t}\n}\n\nQtnMultiPropertyDelegate::~QtnMultiPropertyDelegate()\n{\n\tm_subProperties.clear();\n}\n\nvoid QtnMultiPropertyDelegate::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnMultiProperty::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnMultiPropertyDelegate, QtnMultiProperty>,\n\t\t\"MultiProperty\");\n}\n\nvoid QtnMultiPropertyDelegate::onEditedPropertyDestroyed(PropertyToEdit *data)\n{\n\tQ_ASSERT(nullptr != data);\n\tdata->owner = nullptr;\n\tdata->property = nullptr;\n\tdata->connections.clear();\n}\n\nvoid QtnMultiPropertyDelegate::onEditorDestroyed(PropertyToEdit *data)\n{\n\tauto multiProperty = data->owner;\n\tif (multiProperty)\n\t{\n\t\tmultiProperty->edited = false;\n\t}\n\n\tdelete data;\n}\n\nvoid QtnMultiPropertyDelegate::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tfor (auto &delegate : superDelegates)\n\t{\n\t\tQtnPropertyDelegateInfo mergedInfo;\n\t\tmergedInfo.attributes = info.attributes;\n\t\tauto delegateInfoPtr = delegate->propertyImmutable()->delegateInfo();\n\t\tif (delegateInfoPtr)\n\t\t{\n\t\t\tmergedInfo.name = delegateInfoPtr->name;\n\t\t\tauto &attributes = delegateInfoPtr->attributes;\n\t\t\tfor (auto it = attributes.cbegin(); it != attributes.cend(); ++it)\n\t\t\t{\n\t\t\t\tauto rootIt = mergedInfo.attributes.find(it.key());\n\t\t\t\tif (rootIt != mergedInfo.attributes.end())\n\t\t\t\t\tcontinue;\n\n\t\t\t\tmergedInfo.attributes[it.key()] = it.value();\n\t\t\t}\n\t\t}\n\t\tdelegate->applyAttributes(mergedInfo);\n\n\t\tfor (int i = 0, count = delegate->subPropertyCount(); i < count; ++i)\n\t\t{\n\t\t\tauto property = delegate->subProperty(i);\n\t\t\tauto it = std::find_if(m_subProperties.begin(),\n\t\t\t\tm_subProperties.end(),\n\t\t\t\t[property](const QScopedPointer<QtnPropertyBase> &a) -> bool {\n\t\t\t\t\treturn property->propertyMetaObject() ==\n\t\t\t\t\t\ta->propertyMetaObject() &&\n\t\t\t\t\t\tproperty->displayName() == a->displayName();\n\t\t\t\t});\n\n\t\t\tauto subSet = property->asPropertySet();\n\t\t\tif (subSet)\n\t\t\t{\n\t\t\t\tQtnPropertySet *multiSet;\n\n\t\t\t\tif (it == m_subProperties.end())\n\t\t\t\t{\n\t\t\t\t\tmultiSet = new QtnPropertySet(\n\t\t\t\t\t\tsubSet->childrenOrder(), subSet->compareFunc());\n\t\t\t\t\tmultiSet->setName(subSet->name());\n\t\t\t\t\tmultiSet->setDisplayName(subSet->displayName());\n\t\t\t\t\tmultiSet->setDescription(subSet->description());\n\t\t\t\t\tmultiSet->setId(subSet->id());\n\t\t\t\t\tmultiSet->setState(subSet->stateLocal());\n\n\t\t\t\t\taddSubProperty(multiSet);\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tmultiSet = it->data()->asPropertySet();\n\t\t\t\t}\n\n\t\t\t\tqtnPropertiesToMultiSet(multiSet, subSet, false);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tQtnMultiProperty *multiProperty;\n\n\t\t\t\tif (it == m_subProperties.end())\n\t\t\t\t{\n\t\t\t\t\tmultiProperty =\n\t\t\t\t\t\tnew QtnMultiProperty(property->metaObject());\n\t\t\t\t\tmultiProperty->setName(property->name());\n\t\t\t\t\tmultiProperty->setDisplayName(property->displayName());\n\t\t\t\t\tmultiProperty->setDescription(property->description());\n\t\t\t\t\tmultiProperty->setId(property->id());\n\n\t\t\t\t\taddSubProperty(multiProperty);\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tQ_ASSERT(qobject_cast<QtnMultiProperty *>(it->data()));\n\t\t\t\t\tmultiProperty = static_cast<QtnMultiProperty *>(it->data());\n\t\t\t\t}\n\n\t\t\t\tmultiProperty->addProperty(property->asProperty(), false);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid QtnMultiPropertyDelegate::createSubItemsImpl(\n\tQtnDrawContext &context, QList<QtnSubItem> &subItems)\n{\n\tQ_ASSERT(!superDelegates.empty());\n\tsuperDelegates.at(0)->createSubItems(context, subItems);\n\tfor (auto &item : subItems)\n\t{\n\t\tif (nullptr == item.eventHandler)\n\t\t\tcontinue;\n\n\t\tauto oldEventHandler = item.eventHandler;\n\t\titem.eventHandler = [oldEventHandler, this](QtnEventContext &context,\n\t\t\t\t\t\t\t\tconst QtnSubItem &item,\n\t\t\t\t\t\t\t\tQtnPropertyToEdit *toEdit) -> bool //\n\t\t{\n\t\t\tif (!oldEventHandler(context, item, toEdit))\n\t\t\t\treturn false;\n\n\t\t\tif (!toEdit->isValid() || toEdit->property() == property() ||\n\t\t\t\t!property()->isEditableByUser())\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tQtnPropertyToEdit oldToEdit(*toEdit);\n\t\t\ttoEdit->setup(property(),\n\t\t\t\t[this, oldToEdit]() -> QWidget * //\n\t\t\t\t{\n\t\t\t\t\tQtnMultiPropertyDelegate *thiz = this;\n\t\t\t\t\tauto &p = thiz->owner();\n\t\t\t\t\tauto propertyToEdit = p.properties.at(0);\n\t\t\t\t\tauto data = new PropertyToEdit;\n\t\t\t\t\tdata->owner = &p;\n\t\t\t\t\tdata->property = propertyToEdit;\n\t\t\t\t\tp.edited = true;\n\n\t\t\t\t\tusing namespace std::placeholders;\n\n\t\t\t\t\tdata->connections.emplace_back(\n\t\t\t\t\t\tQObject::connect(propertyToEdit, &QObject::destroyed,\n\t\t\t\t\t\t\tstd::bind(&QtnMultiPropertyDelegate::\n\t\t\t\t\t\t\t\t\t\t  onEditedPropertyDestroyed,\n\t\t\t\t\t\t\t\tdata)));\n\t\t\t\t\tauto editor = oldToEdit.createEditor();\n\t\t\t\t\tif (editor)\n\t\t\t\t\t{\n\t\t\t\t\t\tdata->connections.emplace_back(QObject::connect(editor,\n\t\t\t\t\t\t\t&QObject::destroyed,\n\t\t\t\t\t\t\tstd::bind(\n\t\t\t\t\t\t\t\t&QtnMultiPropertyDelegate::onEditorDestroyed,\n\t\t\t\t\t\t\t\tdata)));\n\t\t\t\t\t} else\n\t\t\t\t\t{\n\t\t\t\t\t\tonEditorDestroyed(data);\n\t\t\t\t\t}\n\t\t\t\t\treturn editor;\n\t\t\t\t});\n\t\t\treturn true;\n\t\t};\n\t}\n}\n\nvoid qtnPropertiesToMultiSet(\n\tQtnPropertySet *target, QtnPropertySet *source, bool takeOwnership)\n{\n\tQ_ASSERT(target);\n\tQ_ASSERT(source);\n\n\tauto &targetProperties = target->childProperties();\n\tfor (auto property : source->childProperties())\n\t{\n\t\tauto it = std::find_if(targetProperties.begin(), targetProperties.end(),\n\t\t\t[property](const QtnPropertyBase *targetProperty) -> bool {\n\t\t\t\treturn property->propertyMetaObject() ==\n\t\t\t\t\ttargetProperty->propertyMetaObject() &&\n\t\t\t\t\tproperty->displayName() == targetProperty->displayName();\n\t\t\t});\n\n\t\tauto subSet = property->asPropertySet();\n\t\tif (subSet)\n\t\t{\n\t\t\tQtnPropertySet *multiSet;\n\n\t\t\tif (it == targetProperties.end())\n\t\t\t{\n\t\t\t\tmultiSet = new QtnPropertySet(\n\t\t\t\t\tsubSet->childrenOrder(), subSet->compareFunc());\n\t\t\t\tmultiSet->setName(subSet->name());\n\t\t\t\tmultiSet->setDisplayName(subSet->displayName());\n\t\t\t\tmultiSet->setDescription(subSet->description());\n\t\t\t\tmultiSet->setId(subSet->id());\n\t\t\t\tmultiSet->setState(subSet->stateLocal());\n\n\t\t\t\ttarget->addChildProperty(multiSet, true);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tmultiSet = (*it)->asPropertySet();\n\t\t\t}\n\n\t\t\tqtnPropertiesToMultiSet(multiSet, subSet, takeOwnership);\n\t\t} else\n\t\t{\n\t\t\tQtnMultiProperty *multiProperty;\n\n\t\t\tif (it == targetProperties.end())\n\t\t\t{\n\t\t\t\tmultiProperty = new QtnMultiProperty(property->metaObject());\n\t\t\t\tmultiProperty->setName(property->name());\n\t\t\t\tmultiProperty->setDisplayName(property->displayName());\n\t\t\t\tmultiProperty->setDescription(property->description());\n\t\t\t\tmultiProperty->setId(property->id());\n\n\t\t\t\ttarget->addChildProperty(multiProperty, true);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tQ_ASSERT(qobject_cast<QtnMultiProperty *>(*it));\n\t\t\t\tmultiProperty = static_cast<QtnMultiProperty *>(*it);\n\t\t\t}\n\n\t\t\tmultiProperty->addProperty(property->asProperty(), takeOwnership);\n\t\t}\n\t}\n\tif (takeOwnership)\n\t\tsource->clearChildProperties();\n}\n"
  },
  {
    "path": "QtnProperty/MultiProperty.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Property.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\n#include <QMetaProperty>\n\n#include <set>\n#include <memory>\n\nclass QtnMultiPropertyDelegate;\nclass QtnConnections;\n\nclass QTN_IMPORT_EXPORT QtnMultiProperty : public QtnProperty\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QtnMultiProperty(\n\t\tconst QMetaObject *propertyMetaObject, QObject *parent = nullptr);\n\tvirtual ~QtnMultiProperty() override;\n\n\tvirtual const QMetaObject *propertyMetaObject() const override;\n\n\tvoid addProperty(QtnProperty *property, bool own = true);\n\n\tbool hasMultipleValues() const;\n\n\tstatic QString getMultiValuePlaceholder();\n\n\tinline const std::vector<QtnProperty *> &getProperties() const;\n\n\tQMetaProperty getMetaProperty() const;\n\nprivate:\n\tvoid onPropertyValueAccept(QtnPropertyValuePtr valueToAccept, bool *accept);\n\n\tvoid onPropertyWillChange(QtnPropertyChangeReason reason,\n\t\tQtnPropertyValuePtr newValue, int typeId);\n\n\tvoid onPropertyDidChange(QtnPropertyChangeReason reason);\n\nprotected:\n\tvirtual void updatePropertyState() override;\n\tvirtual void doReset(QtnPropertyChangeReason reason) override;\n\tvirtual bool loadImpl(QDataStream &stream) override;\n\tvirtual bool saveImpl(QDataStream &stream) const override;\n\tvirtual void masterPropertyWillChange(\n\t\tQtnPropertyChangeReason reason) override;\n\tvirtual void masterPropertyDidChange(\n\t\tQtnPropertyChangeReason reason) override;\n\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\tvirtual bool toVariantImpl(QVariant &var) const override;\n\nprivate:\n\tvoid updateStateFrom(QtnProperty *source);\n\tvoid updateMultipleState(bool force);\n\nprivate:\n\tstd::vector<QtnProperty *> properties;\n\tconst QMetaObject *mPropertyMetaObject;\n\tunsigned m_subPropertyUpdates;\n\n\tbool edited;\n\tbool calculateMultipleValues;\n\tbool multipleValues;\n\n\tfriend class QtnMultiPropertyDelegate;\n};\n\nconst std::vector<QtnProperty *> &QtnMultiProperty::getProperties() const\n{\n\treturn properties;\n}\n\nclass QtnMultiPropertyDelegate\n\t: public QtnPropertyDelegateTypedEx<QtnMultiProperty, QtnPropertyDelegate>\n{\n\tQ_DISABLE_COPY(QtnMultiPropertyDelegate)\n\n\ttypedef QtnPropertyDelegateTypedEx Inherited;\n\npublic:\n\tQtnMultiPropertyDelegate(QtnMultiProperty &owner);\n\tvirtual ~QtnMultiPropertyDelegate() override;\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprivate:\n\tvirtual void init() override;\n\n\tstruct PropertyToEdit;\n\n\tstatic void onEditedPropertyDestroyed(PropertyToEdit *data);\n\tstatic void onEditorDestroyed(PropertyToEdit *data);\n\nprotected:\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvoid createSubItemsImpl(\n\t\tQtnDrawContext &context, QList<QtnSubItem> &subItems) override;\n\nprivate:\n\ttypedef std::unique_ptr<QtnPropertyDelegate> DelegatePtr;\n\tstd::vector<DelegatePtr> superDelegates;\n};\n\nQTN_IMPORT_EXPORT void qtnPropertiesToMultiSet(\n\tQtnPropertySet *target, QtnPropertySet *source, bool takeOwnership);\n\nstruct QtnMultiVariant\n{\n\tQVariantList values;\n};\n\nQ_DECLARE_METATYPE(QtnMultiVariant)\n"
  },
  {
    "path": "QtnProperty/Property.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"Property.h\"\n\nQtnProperty::QtnProperty(QObject *parent)\n\t: QtnPropertyBase(parent)\n{\n}\n\nQtnProperty::~QtnProperty()\n{\n\t// Do not remove! Will be compile errors.\n}\n\nQtnProperty *QtnProperty::asProperty()\n{\n\treturn this;\n}\n\nconst QtnProperty *QtnProperty::asProperty() const\n{\n\treturn this;\n}\n"
  },
  {
    "path": "QtnProperty/Property.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_H\n#define QTN_PROPERTY_H\n\n#include \"PropertyBase.h\"\n\nclass QTN_IMPORT_EXPORT QtnProperty : public QtnPropertyBase\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnProperty)\n\npublic:\n\tvirtual ~QtnProperty() override;\n\n\t// casts\n\tvirtual QtnProperty *asProperty() override;\n\tvirtual const QtnProperty *asProperty() const override;\n\nsignals:\n\tvoid propertyValueAccept(QtnPropertyValuePtr valueToAccept, bool *accept);\n\nprotected:\n\texplicit QtnProperty(QObject *parent);\n};\n\n#endif // QTN_PROPERTY_H\n"
  },
  {
    "path": "QtnProperty/PropertyBase.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyBase.h\"\n\n#include \"PropertySet.h\"\n#include \"PropertyConnector.h\"\n\n#include <QScriptEngine>\n#include <QCoreApplication>\n\nconst qint32 QtnPropertyIDInvalid = -1;\nstatic quint16 qtnPropertyMagicNumber = 0x1984;\nconst quint8 QtnPropertyBase::STORAGE_VERSION = 2;\n\nclass QtnPropertyDelegateInfoGetter\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateInfoGetter)\n\npublic:\n\tvirtual QtnPropertyDelegateInfo *delegateInfo() = 0;\n\n\tvirtual ~QtnPropertyDelegateInfoGetter() = default;\n\nprotected:\n\tQtnPropertyDelegateInfoGetter() = default;\n};\n\nclass QtnPropertyDelegateInfoGetterValue : public QtnPropertyDelegateInfoGetter\n{\npublic:\n\tQtnPropertyDelegateInfoGetterValue(const QtnPropertyDelegateInfo &delegate);\n\n\tQtnPropertyDelegateInfo *delegateInfo() override;\n\nprivate:\n\tQtnPropertyDelegateInfo m_delegateInfo;\n};\n\nclass QtnPropertyDelegateInfoGetterCallback\n\t: public QtnPropertyDelegateInfoGetter\n{\npublic:\n\tQtnPropertyDelegateInfoGetterCallback(\n\t\tconst QtnPropertyBase::DelegateInfoCallback &callback);\n\n\tQtnPropertyDelegateInfo *delegateInfo() override;\n\nprivate:\n\tQtnPropertyBase::DelegateInfoCallback m_callback;\n\tQScopedPointer<QtnPropertyDelegateInfo> m_delegateInfo;\n};\n\nstatic QScriptValue qtnPropertyChangeReasonToScriptValue(\n\tQScriptEngine *engine, const QtnPropertyChangeReason &val)\n{\n\tQScriptValue obj(engine, QtnPropertyChangeReason::Int(val));\n\treturn obj;\n}\n\nstatic void qtnPropertyChangeReasonFromScriptValue(\n\tconst QScriptValue &obj, QtnPropertyChangeReason &val)\n{\n\tval = (QtnPropertyChangeReason::enum_type) obj.toInt32();\n}\n\nstatic QScriptValue qtnPropertyValuePtrToScriptValue(\n\tQScriptEngine *engine, const QtnPropertyValuePtr &val)\n{\n\tQ_UNUSED(engine);\n\tQ_UNUSED(val);\n\t// no sutable conversion\n\treturn QScriptValue();\n}\n\nstatic void qtnPropertyValuePtrFromScriptValue(\n\tconst QScriptValue &obj, QtnPropertyValuePtr &val)\n{\n\tQ_UNUSED(obj);\n\tQ_UNUSED(val);\n\t// no sutable conversion\n}\n\ntypedef const QtnPropertyBase *QtnPropertyBasePtr_t;\n\nstatic QScriptValue qtnPropertyBasePtrToScriptValue(\n\tQScriptEngine *engine, const QtnPropertyBasePtr_t &val)\n{\n\tQtnPropertyBasePtr_t value = val;\n\tQScriptValue obj = engine->newQObject(const_cast<QtnPropertyBase *>(value));\n\treturn obj;\n}\n\nstatic void qtnPropertyBasePtrFromScriptValue(\n\tconst QScriptValue &obj, QtnPropertyBasePtr_t &val)\n{\n\tval = qobject_cast<const QtnPropertyBase *>(obj.toQObject());\n}\n\nvoid qtnScriptRegisterPropertyTypes(QScriptEngine *engine)\n{\n\tqScriptRegisterMetaType(engine, qtnPropertyChangeReasonToScriptValue,\n\t\tqtnPropertyChangeReasonFromScriptValue);\n\tqScriptRegisterMetaType(engine, qtnPropertyValuePtrToScriptValue,\n\t\tqtnPropertyValuePtrFromScriptValue);\n\tqScriptRegisterMetaType(engine, qtnPropertyBasePtrToScriptValue,\n\t\tqtnPropertyBasePtrFromScriptValue);\n\n\tQScriptValue obj = engine->globalObject();\n\n\tobj.setProperty(\"QtnPropertyStateNone\", QtnPropertyStateNone,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyStateNonSimple\", QtnPropertyStateNonSimple,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyStateInvisible\", QtnPropertyStateInvisible,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyStateImmutable\", QtnPropertyStateImmutable,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyStateCollapsed\", QtnPropertyStateCollapsed,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyStateNonSerialized\",\n\t\tQtnPropertyStateNonSerialized,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\n\tobj.setProperty(\"QtnPropertyChangeReasonNewValue\",\n\t\tQtnPropertyChangeReasonNewValue,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonLoadedValue\",\n\t\tQtnPropertyChangeReasonLoadedValue,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonValue\",\n\t\tQtnPropertyChangeReasonValue,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonName\", QtnPropertyChangeReasonName,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonDescription\",\n\t\tQtnPropertyChangeReasonDescription,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonId\", QtnPropertyChangeReasonId,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonStateLocal\",\n\t\tQtnPropertyChangeReasonStateLocal,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonStateInherited\",\n\t\tQtnPropertyChangeReasonStateInherited,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonState\",\n\t\tQtnPropertyChangeReasonState,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonChildPropertyAdd\",\n\t\tQtnPropertyChangeReasonChildPropertyAdd,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonChildPropertyRemove\",\n\t\tQtnPropertyChangeReasonChildPropertyRemove,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n\tobj.setProperty(\"QtnPropertyChangeReasonChildren\",\n\t\tQtnPropertyChangeReasonChildren,\n\t\tQScriptValue::ReadOnly | QScriptValue::Undeletable);\n}\n\nextern bool qtnPropertyRegister();\n\nQtnPropertyBase::QtnPropertyBase(QObject *parent)\n\t: QObject(parent)\n\t, mPropertyConnector(nullptr)\n\t, m_masterProperty(nullptr)\n\t, m_id(QtnPropertyIDInvalid)\n\t, m_stateLocal(QtnPropertyStateNone)\n\t, m_stateInherited(QtnPropertyStateNone)\n\t, changeReasons(0)\n\t, timer(0)\n\t, updateEvent(nullptr)\n{\n\tstatic const bool static_reg = qtnPropertyRegister();\n\tQ_UNUSED(static_reg);\n}\n\nbool QtnPropertyBase::event(QEvent *e)\n{\n\tif (e == updateEvent)\n\t{\n\t\tupdateEvent = nullptr;\n\n\t\tif (changeReasons != 0)\n\t\t{\n\t\t\temit propertyDidChange(QtnPropertyChangeReason(changeReasons));\n\t\t\tchangeReasons = 0;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tif (e->type() == QEvent::Timer &&\n\t\tstatic_cast<QTimerEvent *>(e)->timerId() == timer)\n\t{\n\t\tkillTimer(timer);\n\t\ttimer = 0;\n\n\t\tif (changeReasons != 0)\n\t\t{\n\t\t\temit propertyDidChange(QtnPropertyChangeReason(changeReasons));\n\t\t\tchangeReasons = 0;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\treturn QObject::event(e);\n}\n\nQtnPropertyBase::~QtnPropertyBase()\n{\n\tdisconnectMasterState();\n\tqtnRemovePropertyAsChild(parent(), this);\n}\n\nconst QMetaObject *QtnPropertyBase::propertyMetaObject() const\n{\n\treturn metaObject();\n}\n\nvoid QtnPropertyBase::setName(const QString &name)\n{\n\tif (objectName() == name)\n\t\treturn;\n\n\tQtnPropertyChangeReason reason(QtnPropertyChangeReasonName);\n\tif (m_displayName.isEmpty() && !name.isEmpty())\n\t{\n\t\tm_displayName = name;\n\t\treason |= QtnPropertyChangeReasonDisplayName;\n\t}\n\n\temit propertyWillChange(\n\t\treason, QtnPropertyValuePtr(&name), qMetaTypeId<QString>());\n\n\tsetObjectName(name);\n\n\temit propertyDidChange(reason);\n}\n\nvoid QtnPropertyBase::setDisplayName(const QString &displayName)\n{\n\tif (displayName == m_displayName)\n\t\treturn;\n\n\temit propertyWillChange(QtnPropertyChangeReasonDisplayName,\n\t\tQtnPropertyValuePtr(&displayName), qMetaTypeId<QString>());\n\n\tm_displayName = displayName;\n\n\temit propertyDidChange(QtnPropertyChangeReasonDisplayName);\n}\n\nvoid QtnPropertyBase::setDescription(const QString &description)\n{\n\tif (m_description == description)\n\t\treturn;\n\n\temit propertyWillChange(QtnPropertyChangeReasonDescription,\n\t\tQtnPropertyValuePtr(&description), qMetaTypeId<QString>());\n\n\tm_description = description;\n\n\temit propertyDidChange(QtnPropertyChangeReasonDescription);\n}\n\nvoid QtnPropertyBase::setId(QtnPropertyID id)\n{\n\tif (m_id == id)\n\t\treturn;\n\n\temit propertyWillChange(QtnPropertyChangeReasonId, QtnPropertyValuePtr(&id),\n\t\tqMetaTypeId<QtnPropertyID>());\n\n\tm_id = id;\n\n\temit propertyDidChange(QtnPropertyChangeReasonId);\n}\n\nbool QtnPropertyBase::isExpanded() const\n{\n\treturn (0 == (m_stateLocal & QtnPropertyStateCollapsed));\n}\n\nvoid QtnPropertyBase::setState(QtnPropertyState stateToSet, bool force)\n{\n\tsetStateInternal(stateToSet, force);\n}\n\nvoid QtnPropertyBase::updatePropertyState()\n{\n\tauto connector = getConnector();\n\tif (connector)\n\t{\n\t\tconnector->updatePropertyState();\n\t}\n}\n\nvoid QtnPropertyBase::setStateInternal(\n\tQtnPropertyState stateToSet, bool force, QtnPropertyChangeReason reason)\n{\n\tif (!force && (m_stateLocal == stateToSet))\n\t\treturn;\n\n\treason |= QtnPropertyChangeReasonStateLocal;\n\treason &= ~QtnPropertyChangeReasonLockToggled;\n\n\tif (m_stateLocal.testFlag(QtnPropertyStateUnlockable) &&\n\t\tstateToSet.testFlag(QtnPropertyStateUnlockable))\n\t{\n\t\tif (m_stateLocal.testFlag(QtnPropertyStateImmutable) !=\n\t\t\tstateToSet.testFlag(QtnPropertyStateImmutable))\n\t\t{\n\t\t\treason |= QtnPropertyChangeReasonLockToggled;\n\t\t}\n\t}\n\n\temit propertyWillChange(reason, QtnPropertyValuePtr(&stateToSet),\n\t\tqMetaTypeId<QtnPropertyState>());\n\n\tm_stateLocal = stateToSet;\n\n\tupdatePropertyState();\n\n\temit propertyDidChange(reason);\n\n\tupdateStateInherited(force);\n}\n\nvoid QtnPropertyBase::addState(QtnPropertyState stateToAdd, bool force)\n{\n\tsetState(m_stateLocal | stateToAdd, force);\n}\n\nvoid QtnPropertyBase::removeState(QtnPropertyState stateToRemove, bool force)\n{\n\tsetState(m_stateLocal & ~stateToRemove, force);\n}\n\nvoid QtnPropertyBase::switchState(\n\tQtnPropertyState stateToSwitch, bool switchOn, bool force)\n{\n\tif (switchOn)\n\t\taddState(stateToSwitch, force);\n\telse\n\t\tremoveState(stateToSwitch, force);\n}\n\nvoid QtnPropertyBase::toggleState(QtnPropertyState stateToSwitch, bool force)\n{\n\tswitchState(stateToSwitch, !(stateLocal() & stateToSwitch), force);\n}\n\nbool QtnPropertyBase::isEditableByUser() const\n{\n\treturn !(state() & (QtnPropertyStateImmutable | QtnPropertyStateInvisible));\n}\n\nbool QtnPropertyBase::isVisible() const\n{\n\treturn !(state() & QtnPropertyStateInvisible);\n}\n\nbool QtnPropertyBase::isMultiValue() const\n{\n\treturn 0 != (m_stateLocal & QtnPropertyStateMultiValue);\n}\n\nbool QtnPropertyBase::valueIsDefault() const\n{\n\treturn 0 == (m_stateLocal & QtnPropertyStateModifiedValue);\n}\n\nbool QtnPropertyBase::isSimple() const\n{\n\treturn !m_stateLocal.testFlag(QtnPropertyStateNonSimple);\n}\n\nbool QtnPropertyBase::isLocked() const\n{\n\treturn m_stateLocal.testFlag(QtnPropertyStateImmutable);\n}\n\nbool QtnPropertyBase::load(QDataStream &stream)\n{\n\tif (stream.status() != QDataStream::Ok)\n\t\treturn false;\n\n\tquint16 magicNumber = 0;\n\tstream >> magicNumber;\n\n\t// consistency corrupted\n\tif (magicNumber != qtnPropertyMagicNumber)\n\t\treturn false;\n\n\tquint8 version = 0;\n\tstream >> version;\n\n\t// version incorrect\n\tif (version != STORAGE_VERSION)\n\t\treturn false;\n\n\tqint32 contentSize = 0;\n\tstream >> contentSize;\n\n#ifndef QT_NO_DEBUG\n\tqint64 posBeforeLoadContent = 0;\n\tQIODevice *device = stream.device();\n\n\tif (device)\n\t\tposBeforeLoadContent = device->pos();\n\n#endif\n\n\tif (!loadImpl(stream))\n\t\treturn false;\n\n#ifndef QT_NO_DEBUG\n\tqint64 posAfterLoadContent = 0;\n\n\tif (device)\n\t\tposAfterLoadContent = device->pos();\n\n\tif (posBeforeLoadContent != 0 && posAfterLoadContent != 0 &&\n\t\t(qint32(posAfterLoadContent - posBeforeLoadContent) != contentSize))\n\t{\n\t\tQ_ASSERT(false && \"contentSize and loadContentImpl inconsistency.\");\n\t}\n\n#endif\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertyBase::save(QDataStream &stream) const\n{\n\tif (stream.status() != QDataStream::Ok)\n\t\treturn false;\n\n\t// for better consistency\n\tstream << qtnPropertyMagicNumber;\n\n\t// for compatibility\n\tstream << STORAGE_VERSION;\n\n\tQByteArray data;\n\tQDataStream contentStream(&data, QIODevice::WriteOnly);\n\tcontentStream.setVersion(stream.version());\n\tcontentStream.setByteOrder(stream.byteOrder());\n\tcontentStream.setFloatingPointPrecision(stream.floatingPointPrecision());\n\n\tif (!saveImpl(contentStream))\n\t\treturn false;\n\n\t// size of data to save\n\tstream << (qint32) data.size();\n\n\t// save content\n\tint savedSize = stream.writeRawData(data.constData(), data.size());\n\n\tif (savedSize != data.size())\n\t\treturn false;\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertyBase::skipLoad(QDataStream &stream)\n{\n\tif (stream.status() != QDataStream::Ok)\n\t\treturn false;\n\n\tquint16 magicNumber = 0;\n\tstream >> magicNumber;\n\n\t// consistency corrupted\n\tif (magicNumber != qtnPropertyMagicNumber)\n\t\treturn false;\n\n\tquint8 version = 0;\n\tstream >> version;\n\n\t// version incorrect\n\tif (version != STORAGE_VERSION)\n\t\treturn false;\n\n\tqint32 contentSize = 0;\n\tstream >> contentSize;\n\n\t{\n\t\tint read = stream.skipRawData(contentSize);\n\n\t\t// corrupted data\n\t\tif (read != contentSize)\n\t\t\treturn false;\n\t}\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertyBase::loadImpl(QDataStream &stream)\n{\n\tQ_ASSERT(stream.status() == QDataStream::Ok);\n\n\tqint16 version = 0;\n\tstream >> version;\n\n\t// incorrect version\n\tif (version != STORAGE_VERSION)\n\t\treturn false;\n\n\tQtnPropertyState::Int stateLocal = QtnPropertyStateNone;\n\tQtnPropertyState::Int stateInherited = QtnPropertyStateNone;\n\tstream >> stateLocal;\n\tstream >> stateInherited;\n\tm_stateLocal = QtnPropertyState(stateLocal);\n\tm_stateInherited = QtnPropertyState(stateInherited);\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertyBase::saveImpl(QDataStream &stream) const\n{\n\tQ_ASSERT(stream.status() == QDataStream::Ok);\n\n\tqint16 version = STORAGE_VERSION;\n\tstream << version;\n\n\tstream << (QtnPropertyState::Int) m_stateLocal;\n\tstream << (QtnPropertyState::Int) m_stateInherited;\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertyBase::fromStrImpl(const QString &, QtnPropertyChangeReason)\n{\n\treturn false;\n}\n\nbool QtnPropertyBase::toStrImpl(QString &str) const\n{\n\tQ_UNUSED(str);\n\treturn false;\n}\n\nbool QtnPropertyBase::fromStr(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tif (!isWritable())\n\t\treturn false;\n\n\tQString trimmedStr = str.trimmed();\n\treturn fromStrImpl(trimmedStr, reason);\n}\n\nbool QtnPropertyBase::toStr(QString &str) const\n{\n\treturn toStrImpl(str);\n}\n\nbool QtnPropertyBase::fromVariant(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tif (!isWritable())\n\t\treturn false;\n\n\treturn fromVariantImpl(var, reason);\n}\n\nbool QtnPropertyBase::toVariant(QVariant &var) const\n{\n\treturn toVariantImpl(var);\n}\n\nQtnProperty *QtnPropertyBase::asProperty()\n{\n\treturn nullptr;\n}\n\nconst QtnProperty *QtnPropertyBase::asProperty() const\n{\n\treturn nullptr;\n}\n\nQtnPropertySet *QtnPropertyBase::asPropertySet()\n{\n\treturn nullptr;\n}\n\nconst QtnPropertySet *QtnPropertyBase::asPropertySet() const\n{\n\treturn nullptr;\n}\n\nQtnPropertyBase *QtnPropertyBase::getRootProperty()\n{\n\tauto result = this;\n\n\tdo\n\t{\n\t\tauto mp = result->getMasterProperty();\n\n\t\tif (nullptr == mp)\n\t\t\tbreak;\n\n\t\tresult = mp;\n\t} while (true);\n\n\treturn result;\n}\n\nQtnPropertySet *QtnPropertyBase::getRootPropertySet()\n{\n\tauto p = this;\n\n\twhile (p != nullptr)\n\t{\n\t\tauto set = p->asPropertySet();\n\n\t\tauto mp = p->getRootProperty();\n\n\t\tif (set && mp == p &&\n\t\t\tqobject_cast<QtnPropertySet *>(set->parent()) == nullptr)\n\t\t{\n\t\t\treturn set;\n\t\t}\n\n\t\tif (mp != p)\n\t\t{\n\t\t\tp = mp;\n\t\t} else\n\t\t{\n\t\t\tp = qobject_cast<QtnPropertyBase *>(p->parent());\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n\nbool QtnPropertyBase::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tif (var.canConvert<QString>())\n\t\treturn fromStr(var.value<QString>(), reason);\n\telse\n\t\treturn false;\n}\n\nbool QtnPropertyBase::toVariantImpl(QVariant &var) const\n{\n\tQString str;\n\n\tif (!toStr(str))\n\t\treturn false;\n\n\tvar.setValue<QString>(str);\n\treturn true;\n}\n\nvoid QtnPropertyBase::updateStateInherited(bool force)\n{\n\tQ_UNUSED(force);\n\t/* does nothing by default */\n}\n\nvoid QtnPropertyBase::connectMasterState(QtnPropertyBase *masterProperty)\n{\n\tQ_ASSERT(nullptr != masterProperty);\n\n\tdisconnectMasterState();\n\n\tm_masterProperty = masterProperty;\n\n\tbeforeUpdateStateFromMasterProperty();\n\tdoUpdateStateFromMasterProperty();\n\n\tQObject::connect(masterProperty, &QObject::destroyed, this,\n\t\t&QtnPropertyBase::onMasterPropertyDestroyed);\n\tQObject::connect(masterProperty, &QtnPropertyBase::propertyWillChange, this,\n\t\t&QtnPropertyBase::masterPropertyWillChange);\n\tQObject::connect(masterProperty, &QtnPropertyBase::propertyDidChange, this,\n\t\t&QtnPropertyBase::masterPropertyDidChange);\n}\n\nvoid QtnPropertyBase::disconnectMasterState()\n{\n\tif (nullptr != m_masterProperty)\n\t{\n\t\tQObject::disconnect(m_masterProperty, &QObject::destroyed, this,\n\t\t\t&QtnPropertyBase::onMasterPropertyDestroyed);\n\t\tQObject::disconnect(m_masterProperty,\n\t\t\t&QtnPropertyBase::propertyWillChange, this,\n\t\t\t&QtnPropertyBase::masterPropertyWillChange);\n\t\tQObject::disconnect(m_masterProperty,\n\t\t\t&QtnPropertyBase::propertyDidChange, this,\n\t\t\t&QtnPropertyBase::masterPropertyDidChange);\n\n\t\tm_masterProperty = nullptr;\n\t}\n}\n\nvoid QtnPropertyBase::postUpdateEvent(\n\tQtnPropertyChangeReason reason, int afterMS)\n{\n\tchangeReasons |= reason;\n\n\tif (afterMS > 0)\n\t{\n\t\tif (timer == 0)\n\t\t{\n\t\t\ttimer = startTimer(afterMS);\n\t\t}\n\t} else if (nullptr == updateEvent)\n\t{\n\t\tupdateEvent = new QEvent(QEvent::User);\n\t\tQCoreApplication::postEvent(this, updateEvent);\n\t}\n}\n\nvoid QtnPropertyBase::setStateInherited(QtnPropertyState stateToSet, bool force)\n{\n\tif (!force && (m_stateInherited == stateToSet))\n\t\treturn;\n\n\temit propertyWillChange(QtnPropertyChangeReasonStateInherited,\n\t\tQtnPropertyValuePtr(&stateToSet), qMetaTypeId<QtnPropertyState>());\n\n\tm_stateInherited = stateToSet;\n\n\temit propertyDidChange(QtnPropertyChangeReasonStateInherited);\n\n\tupdateStateInherited(force);\n}\n\nQtnPropertyState QtnPropertyBase::masterPropertyState() const\n{\n\treturn !(stateLocal() & QtnPropertyStateIgnoreDirectParentState)\n\t\t? m_masterProperty->state()\n\t\t: m_masterProperty->stateInherited();\n}\n\nvoid QtnPropertyBase::masterPropertyWillChange(QtnPropertyChangeReason reason)\n{\n\tif (reason & QtnPropertyChangeReasonState)\n\t{\n\t\tQ_ASSERT(sender() == m_masterProperty);\n\t\tbeforeUpdateStateFromMasterProperty();\n\t}\n}\n\nvoid QtnPropertyBase::masterPropertyDidChange(QtnPropertyChangeReason reason)\n{\n\tif (reason & QtnPropertyChangeReasonState)\n\t{\n\t\tQ_ASSERT(sender() == m_masterProperty);\n\t\tdoUpdateStateFromMasterProperty();\n\t}\n}\n\nvoid QtnPropertyBase::beforeUpdateStateFromMasterProperty()\n{\n\tauto newState = masterPropertyState();\n\tif (m_stateInherited == newState)\n\t\treturn;\n\n\temit propertyWillChange(QtnPropertyChangeReasonStateInherited,\n\t\tQtnPropertyValuePtr(&newState), qMetaTypeId<QtnPropertyState>());\n}\n\nvoid QtnPropertyBase::doUpdateStateFromMasterProperty()\n{\n\tauto newState = masterPropertyState();\n\tif (m_stateInherited == newState)\n\t\treturn;\n\n\tm_stateInherited = newState;\n\temit propertyDidChange(QtnPropertyChangeReasonStateInherited);\n\n\tupdateStateInherited(false);\n}\n\nQVariant QtnPropertyBase::valueAsVariant() const\n{\n\tQVariant result;\n\ttoVariant(result);\n\treturn result;\n}\n\nvoid QtnPropertyBase::onMasterPropertyDestroyed(QObject *object)\n{\n\tQ_ASSERT(object == m_masterProperty);\n\tQ_UNUSED(object);\n\tm_masterProperty = nullptr;\n}\n\nQDataStream &operator<<(QDataStream &stream, const QtnPropertyBase &property)\n{\n\tproperty.save(stream);\n\treturn stream;\n}\n\nQDataStream &operator>>(QDataStream &stream, QtnPropertyBase &property)\n{\n\tproperty.load(stream);\n\treturn stream;\n}\n\nvoid QtnPropertyBase::setExpanded(bool expanded)\n{\n\tif (expanded)\n\t\texpand();\n\telse\n\t\tcollapse();\n}\n\nbool QtnPropertyBase::isResettable() const\n{\n\treturn isWritable() && 0 != (stateLocal() & QtnPropertyStateResettable);\n}\n\nvoid QtnPropertyBase::reset(QtnPropertyChangeReason reason)\n{\n\tif (!isResettable())\n\t\treturn;\n\n\treason |= QtnPropertyChangeReasonResetValue;\n\tdoReset(reason);\n}\n\nvoid QtnPropertyBase::doReset(QtnPropertyChangeReason reason)\n{\n\tauto connector = getConnector();\n\tif (connector)\n\t{\n\t\tconnector->resetPropertyValue(reason);\n\t}\n}\n\nbool QtnPropertyBase::isWritable() const\n{\n\treturn (0 == (state() & QtnPropertyStateImmutable));\n}\n\nbool QtnPropertyBase::isUnlockable() const\n{\n\treturn !m_stateInherited.testFlag(QtnPropertyStateImmutable) &&\n\t\tm_stateLocal.testFlag(QtnPropertyStateUnlockable);\n}\n\nvoid QtnPropertyBase::setLocked(bool locked, QtnPropertyChangeReason reason)\n{\n\tQ_ASSERT(m_stateLocal & QtnPropertyStateUnlockable);\n\n\tauto state = m_stateLocal;\n\tstate.setFlag(QtnPropertyStateImmutable, locked);\n\tsetStateInternal(state, false, reason);\n}\n\nvoid QtnPropertyBase::toggleLock(QtnPropertyChangeReason reason)\n{\n\tsetLocked(!isLocked(), reason);\n}\n\nbool QtnPropertyBase::isCollapsed() const\n{\n\treturn (0 != (m_stateLocal & QtnPropertyStateCollapsed));\n}\n\nvoid QtnPropertyBase::setCollapsed(bool collapsed)\n{\n\tif (collapsed)\n\t\tcollapse();\n\telse\n\t\texpand();\n}\n\nQtnPropertyState QtnPropertyBase::state() const\n{\n\treturn m_stateLocal | m_stateInherited;\n}\n\nconst QtnPropertyDelegateInfo *QtnPropertyBase::delegateInfo() const\n{\n\tif (m_delegateInfoGetter.isNull())\n\t\treturn 0;\n\n\treturn m_delegateInfoGetter->delegateInfo();\n}\n\nvoid QtnPropertyBase::setDelegateInfo(const QtnPropertyDelegateInfo &delegate)\n{\n\tm_delegateInfoGetter.reset(\n\t\tnew QtnPropertyDelegateInfoGetterValue(delegate));\n}\n\nvoid QtnPropertyBase::setDelegateInfoCallback(\n\tconst DelegateInfoCallback &callback)\n{\n\tm_delegateInfoGetter.reset((callback != nullptr)\n\t\t\t? new QtnPropertyDelegateInfoGetterCallback(callback)\n\t\t\t: nullptr);\n}\n\nvoid QtnPropertyBase::setDelegateAttribute(\n\tconst QByteArray &attributeName, const QVariant &attributeValue)\n{\n\tif (m_delegateInfoGetter.isNull())\n\t{\n\t\tsetDelegateInfo(QtnPropertyDelegateInfo());\n\t}\n\tQ_ASSERT(!m_delegateInfoGetter.isNull());\n\n\tauto delegate = m_delegateInfoGetter->delegateInfo();\n\tQ_ASSERT(delegate);\n\tdelegate->attributes[attributeName] = attributeValue;\n}\n\nQtnPropertyDelegateInfoGetterValue::QtnPropertyDelegateInfoGetterValue(\n\tconst QtnPropertyDelegateInfo &delegate)\n\t: m_delegateInfo(delegate)\n{\n}\n\nQtnPropertyDelegateInfo *QtnPropertyDelegateInfoGetterValue::delegateInfo()\n{\n\treturn &m_delegateInfo;\n}\n\nQtnPropertyDelegateInfoGetterCallback::QtnPropertyDelegateInfoGetterCallback(\n\tconst QtnPropertyBase::DelegateInfoCallback &callback)\n\t: m_callback(callback)\n{\n\tQ_ASSERT(callback != nullptr);\n}\n\nQtnPropertyDelegateInfo *QtnPropertyDelegateInfoGetterCallback::delegateInfo()\n{\n\tif (m_delegateInfo.isNull())\n\t{\n\t\tm_delegateInfo.reset(new QtnPropertyDelegateInfo(m_callback()));\n\t}\n\n\treturn m_delegateInfo.data();\n}\n"
  },
  {
    "path": "QtnProperty/PropertyBase.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_BASE_H\n#define QTN_PROPERTY_BASE_H\n\n#include \"Auxiliary/PropertyAux.h\"\n#include \"Auxiliary/PropertyDelegateInfo.h\"\n#include <QDataStream>\n#include <QVariant>\n#include <functional>\n\nclass QScriptEngine;\nclass QtnPropertySet;\nclass QtnProperty;\nclass QtnPropertyConnector;\nclass QtnPropertyDelegateInfoGetter;\n\nclass QTN_IMPORT_EXPORT QtnPropertyBase : public QObject\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnPropertyBase)\n\n\tQ_PROPERTY(QString name READ name)\n\tQ_PROPERTY(QString displayName READ displayName)\n\tQ_PROPERTY(QString description READ description)\n\tQ_PROPERTY(qint32 id READ id)\n\tQ_PROPERTY(bool isEditable READ isWritable)\n\tQ_PROPERTY(bool isEditableByUser READ isEditableByUser)\n\tQ_PROPERTY(quint32 state READ state)\n\tQ_PROPERTY(QVariant value READ valueAsVariant WRITE fromVariant)\n\n\tfriend class QtnPropertyConnector;\n\tfriend class QtnPropertySet;\n\n\tinline void setConnector(QtnPropertyConnector *connector);\n\npublic:\n\tstatic const quint8 STORAGE_VERSION;\n\n\tusing DelegateInfoCallback = std::function<QtnPropertyDelegateInfo()>;\n\n\tvirtual ~QtnPropertyBase() override;\n\n\tvirtual const QMetaObject *propertyMetaObject() const;\n\n\tinline QString name() const;\n\tvoid setName(const QString &name);\n\n\tinline QString displayName() const;\n\tvoid setDisplayName(const QString &displayName);\n\n\tinline QString description() const;\n\tvoid setDescription(const QString &description);\n\n\tinline QtnPropertyID id() const;\n\tvoid setId(QtnPropertyID id);\n\n\tbool isExpanded() const;\n\tvoid setExpanded(bool expanded);\n\n\tbool isCollapsed() const;\n\tvoid setCollapsed(bool collapsed);\n\n\tbool isResettable() const;\n\tvoid reset(QtnPropertyChangeReason reason = QtnPropertyChangeReason());\n\n\tbool isWritable() const;\n\n\tbool isUnlockable() const;\n\n\tinline void expand();\n\tinline void collapse();\n\n\tinline QtnPropertyConnector *getConnector() const;\n\tinline bool isQObjectProperty() const;\n\n\tvoid setLocked(bool locked,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReason());\n\tvoid toggleLock(QtnPropertyChangeReason reason = QtnPropertyChangeReason());\n\n\t// states\n\tQtnPropertyState state() const;\n\tinline QtnPropertyState stateLocal() const;\n\tinline QtnPropertyState stateInherited() const;\n\n\tvoid setState(QtnPropertyState stateToSet, bool force = false);\n\tvoid addState(QtnPropertyState stateToAdd, bool force = false);\n\tvoid removeState(QtnPropertyState stateToRemove, bool force = false);\n\tvoid switchState(\n\t\tQtnPropertyState stateToSwitch, bool switchOn, bool force = false);\n\tvoid toggleState(QtnPropertyState stateToSwitch, bool force = false);\n\n\tbool isEditableByUser() const;\n\tbool isVisible() const;\n\tbool isMultiValue() const;\n\tbool valueIsDefault() const;\n\tbool isSimple() const;\n\tbool isLocked() const;\n\n\t// serialization\n\tbool load(QDataStream &stream);\n\tbool save(QDataStream &stream) const;\n\tstatic bool skipLoad(QDataStream &stream);\n\n\t// string conversion\n\tbool fromStr(const QString &str,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonNewValue);\n\tbool toStr(QString &str) const;\n\n\t// variant conversion\n\tbool fromVariant(const QVariant &var,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonNewValue);\n\tbool toVariant(QVariant &var) const;\n\n\t// casts\n\tvirtual QtnProperty *asProperty();\n\tvirtual const QtnProperty *asProperty() const;\n\tvirtual QtnPropertySet *asPropertySet();\n\tvirtual const QtnPropertySet *asPropertySet() const;\n\n\tinline QtnPropertyBase *getMasterProperty() const;\n\tQtnPropertyBase *getRootProperty();\n\tQtnPropertySet *getRootPropertySet();\n\tvoid connectMasterState(QtnPropertyBase *masterProperty);\n\tvoid disconnectMasterState();\n\tvoid postUpdateEvent(QtnPropertyChangeReason reason, int afterMS = 0);\n\n\t// getter/setter for \"value\" property\n\tQVariant valueAsVariant() const;\n\t// delegates\n\tconst QtnPropertyDelegateInfo *delegateInfo() const;\n\tvoid setDelegateInfo(const QtnPropertyDelegateInfo &delegateInfo);\n\tvoid setDelegateInfoCallback(const DelegateInfoCallback &callback);\n\n\tvoid setDelegateAttribute(\n\t\tconst QByteArray &attributeName, const QVariant &attributeValue);\n\nQ_SIGNALS:\n\tvoid propertyWillChange(QtnPropertyChangeReason reason,\n\t\tQtnPropertyValuePtr newValue, int typeId);\n\tvoid propertyDidChange(QtnPropertyChangeReason reason);\n\nprotected:\n\tQtnPropertyBase(QObject *parent);\n\n\tvirtual void doReset(QtnPropertyChangeReason reason);\n\tvirtual bool event(QEvent *e) override;\n\n\t// serialization implementation\n\tvirtual bool loadImpl(QDataStream &stream);\n\tvirtual bool saveImpl(QDataStream &stream) const;\n\n\t// string conversion implementation\n\tvirtual bool fromStrImpl(const QString &, QtnPropertyChangeReason reason);\n\tvirtual bool toStrImpl(QString &str) const;\n\n\t// variant conversion implementation\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason);\n\tvirtual bool toVariantImpl(QVariant &var) const;\n\n\t// inherited states support\n\tvirtual void updateStateInherited(bool force);\n\tvoid setStateInherited(QtnPropertyState stateToSet, bool force = false);\n\n\tvoid setStateInternal(QtnPropertyState stateToSet, bool force = false,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReason());\n\n\tvirtual void masterPropertyWillChange(QtnPropertyChangeReason reason);\n\tvirtual void masterPropertyDidChange(QtnPropertyChangeReason reason);\n\n\tvirtual void updatePropertyState();\n\nprivate:\n\tQtnPropertyState masterPropertyState() const;\n\tvoid onMasterPropertyDestroyed(QObject *object);\n\tvoid beforeUpdateStateFromMasterProperty();\n\tvoid doUpdateStateFromMasterProperty();\n\nprivate:\n\tQtnPropertyConnector *mPropertyConnector;\n\tQtnPropertyBase *m_masterProperty;\n\n\tQString m_displayName;\n\tQString m_description;\n\tQtnPropertyID m_id;\n\n\tQtnPropertyState m_stateLocal;\n\tQtnPropertyState m_stateInherited;\n\n\tint changeReasons;\n\tint timer;\n\tQEvent *updateEvent;\n\tQScopedPointer<QtnPropertyDelegateInfoGetter> m_delegateInfoGetter;\n};\n\nQString QtnPropertyBase::name() const\n{\n\treturn objectName();\n}\n\nQString QtnPropertyBase::displayName() const\n{\n\treturn m_displayName;\n}\n\nQString QtnPropertyBase::description() const\n{\n\treturn m_description;\n}\n\nQtnPropertyID QtnPropertyBase::id() const\n{\n\treturn m_id;\n}\n\nvoid QtnPropertyBase::expand()\n{\n\tremoveState(QtnPropertyStateCollapsed);\n}\n\nvoid QtnPropertyBase::collapse()\n{\n\taddState(QtnPropertyStateCollapsed);\n}\n\nvoid QtnPropertyBase::setConnector(QtnPropertyConnector *connector)\n{\n\tmPropertyConnector = connector;\n}\n\nQtnPropertyConnector *QtnPropertyBase::getConnector() const\n{\n\treturn mPropertyConnector;\n}\n\nbool QtnPropertyBase::isQObjectProperty() const\n{\n\treturn (nullptr != getConnector());\n}\n\nQtnPropertyState QtnPropertyBase::stateLocal() const\n{\n\treturn m_stateLocal;\n}\n\nQtnPropertyState QtnPropertyBase::stateInherited() const\n{\n\treturn m_stateInherited;\n}\n\nQtnPropertyBase *QtnPropertyBase::getMasterProperty() const\n{\n\treturn m_masterProperty;\n}\n\nQTN_IMPORT_EXPORT QDataStream &operator<<(\n\tQDataStream &stream, const QtnPropertyBase &property);\nQTN_IMPORT_EXPORT QDataStream &operator>>(\n\tQDataStream &stream, QtnPropertyBase &property);\n\nQTN_IMPORT_EXPORT void qtnScriptRegisterPropertyTypes(QScriptEngine *engine);\n\nQ_DECLARE_METATYPE(const QtnPropertyBase *)\nQ_DECLARE_METATYPE(QtnPropertyBase *)\n\n#endif // QTN_PROPERTY_BASE_H\n"
  },
  {
    "path": "QtnProperty/PropertyConnector.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyConnector.h\"\n\n#include \"PropertyBase.h\"\n#include \"Property.h\"\n#include \"QObjectPropertySet.h\"\n#include \"IQtnPropertyStateProvider.h\"\n\nQtnPropertyConnector::QtnPropertyConnector(QtnPropertyBase *property)\n\t: QObject(property)\n\t, property(property)\n\t, object(nullptr)\n\t, ignoreStateChangeCounter(0)\n{\n\tQ_ASSERT(nullptr != property);\n\tQ_ASSERT(nullptr == property->getConnector());\n\tproperty->setConnector(this);\n}\n\nvoid QtnPropertyConnector::connectProperty(\n\tQObject *object, const QMetaProperty &metaProperty)\n{\n\tthis->object = object;\n\tthis->metaProperty = metaProperty;\n\tauto metaObject = this->metaObject();\n\tif (metaProperty.hasNotifySignal())\n\t{\n\t\tauto slot =\n\t\t\tmetaObject->method(metaObject->indexOfSlot(\"onValueChanged()\"));\n\t\tQObject::connect(object, metaProperty.notifySignal(), this, slot);\n\t}\n\n\tauto stateProvider = dynamic_cast<IQtnPropertyStateProvider *>(object);\n\n\tif (nullptr != stateProvider)\n\t{\n\t\tauto srcMetaObject = object->metaObject();\n\t\tauto signal = srcMetaObject->method(\n\t\t\tsrcMetaObject->indexOfSignal(\"modifiedSetChanged()\"));\n\t\tif (signal.isValid())\n\t\t{\n\t\t\tauto slot = metaObject->method(\n\t\t\t\tmetaObject->indexOfSlot(\"onModifiedSetChanged()\"));\n\t\t\tQObject::connect(object, signal, this, slot);\n\t\t}\n\n\t\tsignal = srcMetaObject->method(srcMetaObject->indexOfSignal(\n\t\t\t\"propertyStateChanged(QMetaProperty)\"));\n\t\tif (signal.isValid())\n\t\t{\n\t\t\tauto slot = metaObject->method(metaObject->indexOfSlot(\n\t\t\t\t\"onPropertyStateChanged(QMetaProperty)\"));\n\t\t\tQObject::connect(object, signal, this, slot);\n\t\t}\n\t} else\n\t{\n\t\tproperty->switchState(\n\t\t\tQtnPropertyStateResettable, metaProperty.isResettable());\n\t}\n}\n\nvoid QtnPropertyConnector::updatePropertyState()\n{\n\tif (!property || !object || !metaProperty.isValid())\n\t{\n\t\treturn;\n\t}\n\n\tauto stateProvider = dynamic_cast<IQtnPropertyStateProvider *>(object);\n\tif (!stateProvider)\n\t{\n\t\treturn;\n\t}\n\n\tignoreStateChangeCounter++;\n\tstateProvider->setPropertyState(metaProperty, property->stateLocal());\n\tignoreStateChangeCounter--;\n}\n\nbool QtnPropertyConnector::isResettablePropertyValue() const\n{\n\treturn metaProperty.isResettable();\n}\n\nvoid QtnPropertyConnector::resetPropertyValue(QtnPropertyChangeReason reason)\n{\n\tif (nullptr != object && nullptr != property && metaProperty.isResettable())\n\t{\n\t\tif (property->isResettable())\n\t\t{\n\t\t\treason |= QtnPropertyChangeReasonResetValue;\n\n\t\t\temit property->propertyWillChange(reason, nullptr, 0);\n\t\t\tmetaProperty.reset(object);\n\t\t\temit property->propertyDidChange(reason);\n\t\t}\n\t}\n}\n\nvoid QtnPropertyConnector::onValueChanged()\n{\n\tif (nullptr != property)\n\t{\n\t\tproperty->postUpdateEvent(QtnPropertyChangeReasonNewValue, 20);\n\t}\n}\n\nvoid QtnPropertyConnector::onPropertyStateChanged(\n\tconst QMetaProperty &metaProperty)\n{\n\tif (ignoreStateChangeCounter == 0 && nullptr != property &&\n\t\tmetaProperty.propertyIndex() == this->metaProperty.propertyIndex())\n\t{\n\t\tonModifiedSetChanged();\n\t}\n}\n\nvoid QtnPropertyConnector::onModifiedSetChanged()\n{\n\tif (nullptr != property)\n\t{\n\t\tauto stateProvider = dynamic_cast<IQtnPropertyStateProvider *>(object);\n\n\t\tif (nullptr == stateProvider)\n\t\t\treturn;\n\n\t\tQtnPropertyState state;\n\t\tstate = stateProvider->getPropertyState(metaProperty);\n\t\tstate |= qtnPropertyStateToAdd(metaProperty);\n\t\tstate.setFlag(QtnPropertyStateCollapsed, property->isCollapsed());\n\t\tstate.setFlag(QtnPropertyStateResettable, metaProperty.isResettable());\n\n\t\tproperty->setState(state);\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/PropertyConnector.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n#include \"Auxiliary/PropertyAux.h\"\n\n#include <QMetaProperty>\n#include <QObject>\n\nclass QtnPropertyBase;\nclass QtnPropertySet;\n\nclass QTN_IMPORT_EXPORT QtnPropertyConnector : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QtnPropertyConnector(QtnPropertyBase *property);\n\n\tvoid connectProperty(QObject *object, const QMetaProperty &metaProperty);\n\tvoid updatePropertyState();\n\n\tbool isResettablePropertyValue() const;\n\tvoid resetPropertyValue(QtnPropertyChangeReason reason);\n\n\tinline QObject *getObject() const;\n\tinline const QMetaProperty &getMetaProperty() const;\n\nprivate slots:\n\tvoid onValueChanged();\n\tvoid onModifiedSetChanged();\n\tvoid onPropertyStateChanged(const QMetaProperty &metaProperty);\n\nprivate:\n\tQtnPropertyBase *property;\n\tQObject *object;\n\tQMetaProperty metaProperty;\n\tunsigned ignoreStateChangeCounter;\n};\n\nQObject *QtnPropertyConnector::getObject() const\n{\n\treturn object;\n}\n\nconst QMetaProperty &QtnPropertyConnector::getMetaProperty() const\n{\n\treturn metaProperty;\n}\n"
  },
  {
    "path": "QtnProperty/PropertyCore.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYCORE_H\n#define PROPERTYCORE_H\n\n#include \"PropertySet.h\"\n#include \"Core/PropertyBool.h\"\n#include \"Core/PropertyInt.h\"\n#include \"Core/PropertyUInt.h\"\n#include \"Core/PropertyFloat.h\"\n#include \"Core/PropertyDouble.h\"\n#include \"Core/PropertyEnum.h\"\n#include \"Core/PropertyEnumFlags.h\"\n#include \"Core/PropertyQString.h\"\n#include \"Core/PropertyQRect.h\"\n#include \"Core/PropertyQRectF.h\"\n#include \"Core/PropertyQPoint.h\"\n#include \"Core/PropertyQPointF.h\"\n#include \"Core/PropertyQSize.h\"\n#include \"Core/PropertyQSizeF.h\"\n\n#endif // PROPERTYCORE_H\n"
  },
  {
    "path": "QtnProperty/PropertyDelegateAttrs.h",
    "content": "/*******************************************************************************\nCopyright 2017-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\")();\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n\n#include <QByteArray>\n\nQTN_IMPORT_EXPORT QByteArray qtnPrecisionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnMinAttr();\nQTN_IMPORT_EXPORT QByteArray qtnMaxAttr();\nQTN_IMPORT_EXPORT QByteArray qtnStepAttr();\nQTN_IMPORT_EXPORT QByteArray qtnMultiplierAttr();\nQTN_IMPORT_EXPORT QByteArray qtnMultiLineEditAttr();\nQTN_IMPORT_EXPORT QByteArray qtnMaxLengthAttr();\nQTN_IMPORT_EXPORT QByteArray qtnPlaceholderAttr();\nQTN_IMPORT_EXPORT QByteArray qtnItemsAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditableAttr();\nQTN_IMPORT_EXPORT QByteArray qtnInvalidColorAttr();\nQTN_IMPORT_EXPORT QByteArray qtnShowRelativePathAttr();\nQTN_IMPORT_EXPORT QByteArray qtnFileModeAttr();\nQTN_IMPORT_EXPORT QByteArray qtnFileNameFilterAttr();\nQTN_IMPORT_EXPORT QByteArray qtnFileNameFiltersAttr();\nQTN_IMPORT_EXPORT QByteArray qtnDefaultDirAttr();\nQTN_IMPORT_EXPORT QByteArray qtnOptionsAttr();\nQTN_IMPORT_EXPORT QByteArray qtnViewModeAttr();\nQTN_IMPORT_EXPORT QByteArray qtnAcceptModeAttr();\nQTN_IMPORT_EXPORT QByteArray qtnDefaultSuffixAttr();\nQTN_IMPORT_EXPORT QByteArray qtnSuffixAttr();\nQTN_IMPORT_EXPORT QByteArray qtnGetCandidatesFnAttr();\nQTN_IMPORT_EXPORT QByteArray qtnCreateCandidateFnAttr();\nQTN_IMPORT_EXPORT QByteArray qtnCreateCandidateIconAttr();\nQTN_IMPORT_EXPORT QByteArray qtnCreateCandidateToolTipAttr();\nQTN_IMPORT_EXPORT QByteArray qtnLabelFalseAttr();\nQTN_IMPORT_EXPORT QByteArray qtnLabelTrueAttr();\nQTN_IMPORT_EXPORT QByteArray qtnShapeAttr();\nQTN_IMPORT_EXPORT QByteArray qtnRgbSubItemsAttr();\n\nQTN_IMPORT_EXPORT QByteArray qtnFillColorAttr();\nQTN_IMPORT_EXPORT QByteArray qtnLiveUpdateAttr();\nQTN_IMPORT_EXPORT QByteArray qtnDrawBorderAttr();\nQTN_IMPORT_EXPORT QByteArray qtnUpdateByScrollAttr();\nQTN_IMPORT_EXPORT QByteArray qtnAnimateAttr();\nQTN_IMPORT_EXPORT QByteArray qtnToolTipAttr();\n\nQTN_IMPORT_EXPORT QByteArray qtnXDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnXDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnYDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnYDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnZDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnZDescriptionAttr();\n\nQTN_IMPORT_EXPORT QByteArray qtnLeftDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnLeftDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnTopDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnTopDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnRightDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnRightDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnBottomDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnBottomDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnWidthDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnWidthDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnHeightDisplayNameAttr();\nQTN_IMPORT_EXPORT QByteArray qtnHeightDescriptionAttr();\nQTN_IMPORT_EXPORT QByteArray qtnCoordinateModeAttr();\nQTN_IMPORT_EXPORT QByteArray qtnFieldDelegateNameAttr();\n\nQTN_IMPORT_EXPORT QByteArray qtnLineEditDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnSelectFileDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnSelectFontDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnSelectColorDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnCallbackDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnComboBoxDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnCheckBoxDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnLTWHDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnLTRBDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnGeoCoordDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnGeoPointDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnSliderBoxDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnSpinBoxDelegate();\nQTN_IMPORT_EXPORT QByteArray qtnSolidDelegateName();\nQTN_IMPORT_EXPORT QByteArray qtnLinkDelegateName();\n\nQTN_IMPORT_EXPORT QByteArray qtnShowAllAttr();\nQTN_IMPORT_EXPORT QByteArray qtnShowNoPenAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditColorAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditStyleAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditCapStyleAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditJoinStyleAttr();\nQTN_IMPORT_EXPORT QByteArray qtnEditWidthAttr();\nQTN_IMPORT_EXPORT QByteArray qtnTitleAttr();\n\nQTN_IMPORT_EXPORT QByteArray qtnTranslateAttribute();\n\nstruct QtnPropertyDelegateInfo;\n\nQTN_IMPORT_EXPORT void qtnInitPercentSpinBoxDelegate(\n\tQtnPropertyDelegateInfo &delegate);\nQTN_IMPORT_EXPORT void qtnInitDegreeSpinBoxDelegate(\n\tQtnPropertyDelegateInfo &delegate);\n\nQTN_IMPORT_EXPORT double qtnHundredPercent(double value);\n\ntemplate <typename T>\ninline T qtnDefaultGet(T value)\n{\n\treturn value;\n}\n"
  },
  {
    "path": "QtnProperty/PropertyDelegateMetaEnum.cpp",
    "content": "/*******************************************************************************\nCopyright 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyDelegateMetaEnum.h\"\n\n#include \"Delegates/Utils/PropertyEditorHandler.h\"\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Property.h\"\n#include \"PropertyDelegateAttrs.h\"\n#include \"QtnProperty/Delegates/Utils/PropertyEditorAux.h\"\n\n#include <QCoreApplication>\n#include <QComboBox>\n#include <QLineEdit>\n\nclass QtnPropertyDelegateMetaEnum::EditorHandler\n\t: public QtnPropertyEditorHandlerBase\n{\n\tQtnPropertyDelegateMetaEnum *mOwner;\n\npublic:\n\tEditorHandler(QtnPropertyDelegateMetaEnum *delegate, QComboBox &editor);\n\n\tQComboBox &comboBox() const;\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvoid updateValue(int value);\n\nprivate:\n\tvoid onCurrentIndexChanged(int index);\n\n\tunsigned updating;\n};\n\nQtnPropertyDelegateMetaEnum::QtnPropertyDelegateMetaEnum(\n\tconst QMetaEnum &metaEnum, QtnPropertyBase *property, bool translate)\n\t: QtnPropertyDelegateWithValueEditor(*property)\n\t, mMetaEnum(metaEnum)\n\t, mShouldTranslate(translate)\n{\n}\n\nvoid QtnPropertyDelegateMetaEnum::Register(\n\tQMetaEnum metaEnum, QtnPropertyDelegateFactory *factory, bool translate)\n{\n\tif (!factory)\n\t\tfactory = &QtnPropertyDelegateFactory::staticInstance();\n\n\tfactory->registerDelegate(&QtnProperty::staticMetaObject,\n\t\t[metaEnum, translate](QtnPropertyBase &owner) -> QtnPropertyDelegate * {\n\t\t\treturn new QtnPropertyDelegateMetaEnum(metaEnum, &owner, translate);\n\t\t},\n\t\tdelegateName(metaEnum));\n}\n\nQtnPropertyDelegateInfo QtnPropertyDelegateMetaEnum::delegateInfo(\n\tconst QMetaEnum &metaEnum)\n{\n\tQtnPropertyDelegateInfo result;\n\tresult.name = delegateName(metaEnum);\n\treturn result;\n}\n\nQByteArray QtnPropertyDelegateMetaEnum::delegateName(const QMetaEnum &metaEnum)\n{\n\tconst char *cscope = metaEnum.scope();\n\tconst char *cname = metaEnum.name();\n\tauto scope = QByteArray::fromRawData(cscope, qstrlen(cscope));\n\tauto name = QByteArray::fromRawData(cname, qstrlen(cname));\n\treturn scope + \".\" + name;\n}\n\nint QtnPropertyDelegateMetaEnum::currentValue() const\n{\n\tQVariant v;\n\tpropertyImmutable()->toVariant(v);\n\treturn int(v.toLongLong());\n}\n\nbool QtnPropertyDelegateMetaEnum::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tstrValue = valueToStr(currentValue());\n\treturn !strValue.isNull();\n}\n\nQString QtnPropertyDelegateMetaEnum::valueToStr(int value) const\n{\n\tauto key = mMetaEnum.valueToKey(value);\n\tif (!key)\n\t\treturn QString();\n\n\treturn keyToStr(key);\n}\n\nQString QtnPropertyDelegateMetaEnum::keyToStr(const char *key) const\n{\n\treturn mShouldTranslate\n\t\t? QCoreApplication::translate(mMetaEnum.scope(), key, mMetaEnum.name())\n\t\t: QString(QLatin1String(key));\n}\n\nQByteArray qtnTranslateAttribute()\n{\n\treturn QByteArrayLiteral(\"translate\");\n}\n\nQWidget *QtnPropertyDelegateMetaEnum::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tQComboBox *combo = new QtnPropertyComboBox(this, parent);\n\tfor (int i = 0, count = mMetaEnum.keyCount(); i < count; i++)\n\t{\n\t\tcombo->addItem(\n\t\t\tkeyToStr(mMetaEnum.key(i)), QVariant(mMetaEnum.value(i)));\n\t}\n\n\tcombo->setGeometry(rect);\n\n\tnew EditorHandler(this, *combo);\n\n\tif (inplaceInfo && stateProperty()->isEditableByUser())\n\t\tcombo->showPopup();\n\n\treturn combo;\n}\n\nvoid QtnPropertyDelegateMetaEnum::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnTranslateAttribute(), mShouldTranslate);\n}\n\nQtnPropertyDelegateMetaEnum::EditorHandler::EditorHandler(\n\tQtnPropertyDelegateMetaEnum *delegate, QComboBox &editor)\n\t: QtnPropertyEditorHandlerBase(delegate, editor)\n\t, mOwner(delegate)\n\t, updating(0)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),\n\t\tthis, &EditorHandler::onCurrentIndexChanged);\n}\n\nQComboBox &QtnPropertyDelegateMetaEnum::EditorHandler::comboBox() const\n{\n\treturn *static_cast<QComboBox *>(editorBase());\n}\n\nvoid QtnPropertyDelegateMetaEnum::EditorHandler::updateEditor()\n{\n\t++updating;\n\n\tif (stateProperty()->isMultiValue())\n\t\tcomboBox().setCurrentIndex(-1);\n\telse\n\t{\n\t\tint index = comboBox().findData(mOwner->currentValue());\n\n\t\tif (index >= 0)\n\t\t\tcomboBox().setCurrentIndex(index);\n\t}\n\n\t--updating;\n}\n\nvoid QtnPropertyDelegateMetaEnum::EditorHandler::updateValue(int value)\n{\n\tif (updating > 0)\n\t\treturn;\n\n\tif (propertyBase())\n\t\tpropertyBase()->fromVariant(value, delegate()->editReason());\n}\n\nvoid QtnPropertyDelegateMetaEnum::EditorHandler::onCurrentIndexChanged(\n\tint index)\n{\n\tif (index < 0)\n\t\treturn;\n\n\tQVariant data = comboBox().itemData(index);\n\n\tif (data.canConvert<int>())\n\t\tupdateValue(data.toInt());\n}\n"
  },
  {
    "path": "QtnProperty/PropertyDelegateMetaEnum.h",
    "content": "/*******************************************************************************\nCopyright (c) 2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"QtnProperty/Delegates/Utils/PropertyDelegateMisc.h\"\n\n#include <QMetaEnum>\n\nclass QtnPropertyDelegateFactory;\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateMetaEnum\n\t: public QtnPropertyDelegateWithValueEditor\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateMetaEnum)\n\n\tQMetaEnum mMetaEnum;\n\tbool mShouldTranslate;\n\tclass EditorHandler;\n\npublic:\n\texplicit QtnPropertyDelegateMetaEnum(const QMetaEnum &metaEnum,\n\t\tQtnPropertyBase *property, bool translate = false);\n\n\tstatic void Register(QMetaEnum metaEnum,\n\t\tQtnPropertyDelegateFactory *factory, bool translate = false);\n\n\ttemplate <typename T>\n\tstatic void Register(\n\t\tQtnPropertyDelegateFactory *factory, bool translate = false)\n\t{\n\t\tRegister(QMetaEnum::fromType<T>(), factory, translate);\n\t}\n\n\tstatic QtnPropertyDelegateInfo delegateInfo(const QMetaEnum &metaEnum);\n\ttemplate <typename T>\n\tstatic inline QtnPropertyDelegateInfo delegateInfo()\n\t{\n\t\treturn delegateInfo(QMetaEnum::fromType<T>());\n\t}\n\n\tstatic QByteArray delegateName(const QMetaEnum &metaEnum);\n\ttemplate <typename T>\n\tstatic inline QByteArray delegateName()\n\t{\n\t\treturn delegateName(QMetaEnum::fromType<T>());\n\t}\n\n\tint currentValue() const;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\n\tQString valueToStr(int value) const;\n\tQString keyToStr(const char *key) const;\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n};\n"
  },
  {
    "path": "QtnProperty/PropertyGUI.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef PROPERTYGUI_H\n#define PROPERTYGUI_H\n\n#include \"PropertySet.h\"\n#include \"GUI/PropertyQColor.h\"\n#include \"GUI/PropertyQFont.h\"\n#include \"GUI/PropertyQPen.h\"\n#include \"GUI/PropertyQBrush.h\"\n#include \"GUI/PropertyQVector3D.h\"\n#include \"GUI/PropertyButton.h\"\n\n#endif // PROPERTYGUI_H\n"
  },
  {
    "path": "QtnProperty/PropertyInt64.cpp",
    "content": "﻿/*******************************************************************************\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyInt64.h\"\n\n#include \"QObjectPropertySet.h\"\n\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Delegates/Utils/PropertyEditorAux.h\"\n#include \"Delegates/Utils/PropertyEditorHandler.h\"\n#include \"Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"Utils/QtnInt64SpinBox.h\"\n#include \"MultiProperty.h\"\n#include \"PropertyDelegateAttrs.h\"\n\n#include <QLocale>\n#include <QKeyEvent>\n\nclass QtnPropertyInt64SpinBoxHandler\n\t: public QtnPropertyEditorHandlerVT<QtnPropertyInt64Base, QtnInt64SpinBox>\n{\npublic:\n\tQtnPropertyInt64SpinBoxHandler(\n\t\tQtnPropertyDelegateInt64 *delegate, QtnInt64SpinBox &editor);\n\nprivate:\n\tvirtual void updateEditor() override;\n\nprivate:\n\tQtnPropertyDelegateInt64 *m_delegate;\n};\n\nQtnPropertyInt64Base::QtnPropertyInt64Base(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<qint64>>(parent)\n{\n}\n\nbool QtnPropertyInt64Base::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toLongLong(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyInt64Base::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value());\n\treturn true;\n}\n\nbool QtnPropertyInt64Base::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = var.toLongLong(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nQtnPropertyInt64::QtnPropertyInt64(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyInt64Base>(parent)\n{\n}\n\nvoid QtnPropertyDelegateInt64::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyInt64Base::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateInt64, QtnPropertyInt64Base>,\n\t\tqtnSpinBoxDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyInt64Base::staticMetaObject,\n\t\t&qtnCreateDelegate<\n\t\t\tQtnPropertyDelegateSlideBoxTyped<QtnPropertyInt64Base>,\n\t\t\tQtnPropertyInt64Base>,\n\t\tqtnSliderBoxDelegate());\n}\n\nqint64 QtnPropertyDelegateInt64::stepValue() const\n{\n\treturn m_step.isValid() ? m_step.toLongLong() : owner().stepValue();\n}\n\nqint64 QtnPropertyDelegateInt64::minValue() const\n{\n\treturn m_min.isValid() ? m_min.toLongLong() : owner().minValue();\n}\n\nqint64 QtnPropertyDelegateInt64::maxValue() const\n{\n\treturn m_max.isValid() ? m_max.toLongLong() : owner().maxValue();\n}\n\nqint64 QtnPropertyDelegateInt64::currentValue() const\n{\n\treturn qBound(minValue(), owner().value(), maxValue());\n}\n\nQtnPropertyDelegateInt64::QtnPropertyDelegateInt64(QtnPropertyInt64Base &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyInt64Base>(owner)\n{\n}\n\nbool QtnPropertyDelegateInt64::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<\n\t\t\tQtnPropertyInt64Base>::acceptKeyPressedForInplaceEditImpl(keyEvent))\n\t\treturn true;\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_SIGNED_INT);\n}\n\nQWidget *QtnPropertyDelegateInt64::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto spinBox = new QtnInt64SpinBox(parent);\n\tspinBox->setSuffix(m_suffix);\n\tspinBox->setGeometry(rect);\n\n\tnew QtnPropertyInt64SpinBoxHandler(this, *spinBox);\n\n\tspinBox->selectAll();\n\n\tif (stateProperty()->isEditableByUser())\n\t\tqtnInitNumEdit(spinBox, inplaceInfo, NUM_SIGNED_INT);\n\n\treturn spinBox;\n}\n\nvoid QtnPropertyDelegateInt64::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\tm_step = info.attributes.value(qtnStepAttr());\n\tif (m_step.isValid())\n\t{\n\t\tbool ok;\n\t\tqint64 step = m_step.toLongLong(&ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tm_step = QVariant();\n\t\t} else\n\t\t{\n\t\t\tm_step = step;\n\t\t}\n\t}\n\tfixMinMaxVariant<qint64>(m_min, m_max);\n}\n\nbool QtnPropertyDelegateInt64::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QLocale().toString(currentValue());\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nQtnPropertyInt64Callback::QtnPropertyInt64Callback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyInt64Base>(parent)\n{\n}\n\nQtnPropertyInt64SpinBoxHandler::QtnPropertyInt64SpinBoxHandler(\n\tQtnPropertyDelegateInt64 *delegate, QtnInt64SpinBox &editor)\n\t: QtnPropertyEditorHandlerVT(delegate, editor)\n\t, m_delegate(delegate)\n{\n\tupdateEditor();\n\n\teditor.setKeyboardTracking(false);\n\teditor.installEventFilter(this);\n\tQObject::connect(&editor,\n\t\tstatic_cast<void (QtnInt64SpinBox::*)(qint64)>(\n\t\t\t&QtnInt64SpinBox::valueChanged),\n\t\tthis, &QtnPropertyInt64SpinBoxHandler::onValueChanged);\n}\n\nvoid QtnPropertyInt64SpinBoxHandler::updateEditor()\n{\n\tupdating++;\n\n\teditor().setReadOnly(!stateProperty()->isEditableByUser());\n\teditor().setSingleStep(m_delegate->stepValue());\n\teditor().setRange(m_delegate->minValue(), m_delegate->maxValue());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().setValue(editor().minimum());\n\t\teditor().setSpecialValueText(\n\t\t\tQtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\teditor().setValue(m_delegate->currentValue());\n\t\teditor().setSpecialValueText(QString());\n\t}\n\n\teditor().selectAll();\n\n\tupdating--;\n}\n"
  },
  {
    "path": "QtnProperty/PropertyInt64.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyTemplates.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyInt64Base\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<qint64>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyInt64Base(const QtnPropertyInt64Base &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyInt64Base(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\n\t// variant conversion implementation\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyInt64Base)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyInt64\n\t: public QtnNumericPropertyValue<QtnPropertyInt64Base>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyInt64(const QtnPropertyInt64 &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyInt64(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyInt64, QtnPropertyInt64Base)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyInt64Base, qint64)\n\nclass QTN_IMPORT_EXPORT QtnPropertyInt64Callback\n\t: public QtnSinglePropertyCallback<QtnPropertyInt64Base>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyInt64Callback(\n\t\tconst QtnPropertyInt64Callback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyInt64Callback(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyInt64Callback, QtnPropertyInt64Base)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateInt64\n\t: public QtnPropertyDelegateTyped<QtnPropertyInt64Base>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateInt64)\n\n\tQString m_suffix;\n\tQVariant m_min;\n\tQVariant m_max;\n\tQVariant m_step;\n\npublic:\n\tQtnPropertyDelegateInt64(QtnPropertyInt64Base &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tqint64 stepValue() const;\n\tqint64 minValue() const;\n\tqint64 maxValue() const;\n\tqint64 currentValue() const;\n\nprotected:\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n"
  },
  {
    "path": "QtnProperty/PropertyQKeySequence.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2017-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQKeySequence.h\"\n\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Delegates/Utils/PropertyEditorAux.h\"\n#include \"Delegates/Utils/PropertyEditorHandler.h\"\n\n#include \"Core/PropertyQString.h\"\n#include \"MultiProperty.h\"\n\n#include <QKeySequenceEdit>\n#include <QHBoxLayout>\n\nclass QtnPropertyQKeySequenceEditHandler\n\t: public QtnPropertyEditorHandler<QtnPropertyQKeySequenceBase,\n\t\t  QKeySequenceEdit>\n{\npublic:\n\tQtnPropertyQKeySequenceEditHandler(\n\t\tQtnPropertyDelegate *delegate, QKeySequenceEdit &editor);\n\nprotected:\n\tvirtual void updateEditor() override;\n\tvoid updateValue(const QKeySequence &seq);\n};\n\nQtnPropertyQKeySequenceBase::QtnPropertyQKeySequenceBase(QObject *parent)\n\t: QtnSinglePropertyBase(parent)\n{\n}\n\nbool QtnPropertyQKeySequenceBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\treturn setValue(\n\t\tQKeySequence::fromString(str, QKeySequence::PortableText), reason);\n}\n\nbool QtnPropertyQKeySequenceBase::toStrImpl(QString &str) const\n{\n\tstr = value().toString(QKeySequence::PortableText);\n\treturn true;\n}\n\nbool QtnPropertyQKeySequenceBase::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tQKeySequence keySequence;\n\tswitch (var.type())\n\t{\n\t\tcase QVariant::String:\n\t\t\treturn fromStrImpl(var.toString(), reason);\n\n\t\tcase QVariant::KeySequence:\n\t\t\tkeySequence = var.value<QKeySequence>();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn setValue(keySequence, reason);\n}\n\nbool QtnPropertyQKeySequenceBase::toVariantImpl(QVariant &var) const\n{\n\tvar.setValue(value());\n\treturn var.isValid();\n}\n\nQtnPropertyQKeySequenceCallback::QtnPropertyQKeySequenceCallback(\n\tQObject *parent)\n\t: QtnSinglePropertyCallback(parent)\n{\n}\n\nQtnPropertyQKeySequence::QtnPropertyQKeySequence(QObject *parent)\n\t: QtnSinglePropertyValue(parent)\n{\n}\n\nQtnPropertyDelegateQKeySequence::QtnPropertyDelegateQKeySequence(\n\tQtnPropertyQKeySequenceBase &owner)\n\t: QtnPropertyDelegateTyped(owner)\n{\n}\n\nvoid QtnPropertyDelegateQKeySequence::Register(\n\tQtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(\n\t\t&QtnPropertyQKeySequenceBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQKeySequence,\n\t\t\tQtnPropertyQKeySequenceBase>,\n\t\t\"QKeySequence\");\n}\n\nQWidget *QtnPropertyDelegateQKeySequence::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *)\n{\n\tif (!stateProperty()->isEditableByUser())\n\t{\n\t\tauto lineEdit = new QLineEdit(parent);\n\t\tlineEdit->setGeometry(rect);\n\t\tlineEdit->setReadOnly(true);\n\t\tauto text = owner().value().toString(QKeySequence::NativeText);\n\t\tlineEdit->setText(text);\n\t\tlineEdit->setPlaceholderText(\n\t\t\tQtnPropertyQString::getEmptyPlaceholderStr());\n\t\tlineEdit->selectAll();\n\t\treturn lineEdit;\n\t}\n\n\tauto editor = new QKeySequenceEdit(parent);\n\teditor->setGeometry(rect);\n\tnew QtnPropertyQKeySequenceEditHandler(this, *editor);\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQKeySequence::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tstrValue = owner().value().toString(QKeySequence::NativeText);\n\n\tif (strValue.isEmpty())\n\t\tstrValue = QtnPropertyQString::getEmptyPlaceholderStr();\n\n\treturn true;\n}\n\nQtnPropertyQKeySequenceEditHandler::QtnPropertyQKeySequenceEditHandler(\n\tQtnPropertyDelegate *delegate, QKeySequenceEdit &editor)\n\t: QtnPropertyEditorHandler(delegate, editor)\n{\n\tupdateEditor();\n\n\tQObject::connect(&editor, &QKeySequenceEdit::keySequenceChanged, this,\n\t\t&QtnPropertyQKeySequenceEditHandler::updateValue);\n}\n\nvoid QtnPropertyQKeySequenceEditHandler::updateEditor()\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor().clear();\n\t} else\n\t{\n\t\teditor().setKeySequence(property().value());\n\t}\n}\n\nvoid QtnPropertyQKeySequenceEditHandler::updateValue(const QKeySequence &seq)\n{\n\tif (propertyBase())\n\t\tproperty().setValue(seq, delegate()->editReason());\n}\n"
  },
  {
    "path": "QtnProperty/PropertyQKeySequence.h",
    "content": "/*******************************************************************************\nCopyright (c) 2017-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyTemplates.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\n#include <QKeySequence>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQKeySequenceBase\n\t: public QtnSinglePropertyBase<QKeySequence>\n{\n\tQ_OBJECT\n\n\tQtnPropertyQKeySequenceBase(\n\t\tconst QtnPropertyQKeySequenceBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQKeySequenceBase(QObject *parent);\n\nprotected:\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\tvirtual bool toVariantImpl(QVariant &var) const override;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQKeySequenceCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQKeySequenceBase>\n{\n\tQ_OBJECT\n\n\tQtnPropertyQKeySequenceCallback(\n\t\tconst QtnPropertyQKeySequenceCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQKeySequenceCallback(QObject *parent = nullptr);\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQKeySequence\n\t: public QtnSinglePropertyValue<QtnPropertyQKeySequenceBase>\n{\n\tQ_OBJECT\n\n\tQtnPropertyQKeySequence(\n\t\tconst QtnPropertyQKeySequence &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQKeySequence(QObject *parent = nullptr);\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQKeySequence\n\t: public QtnPropertyDelegateTyped<QtnPropertyQKeySequenceBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQKeySequence)\n\npublic:\n\ttypedef QtnPropertyDelegateTyped<QtnPropertyQKeySequenceBase> Inherited;\n\n\tQtnPropertyDelegateQKeySequence(QtnPropertyQKeySequenceBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n};\n"
  },
  {
    "path": "QtnProperty/PropertyQVariant.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyQVariant.h\"\n\n#include \"QObjectPropertySet.h\"\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Delegates/Utils/PropertyEditorAux.h\"\n#include \"Delegates/Utils/PropertyEditorHandler.h\"\n#include \"MultiProperty.h\"\n#include \"Core/PropertyQString.h\"\n\n#include \"CustomPropertyEditorDialog.h\"\n\n#include <QEvent>\n#include <QKeyEvent>\n\nbool qtnCompareQVariants(const QVariant &left, const QVariant &right)\n{\n\tif (left.userType() != right.userType())\n\t{\n\t\treturn false;\n\t}\n\n\tswitch (left.type())\n\t{\n\t\tcase QVariant::Hash:\n\t\t{\n\t\t\tconst auto leftMap = left.toHash();\n\t\t\tconst auto rightMap = right.toHash();\n\t\t\tif (leftMap.size() != rightMap.size())\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tauto leftIt = leftMap.cbegin();\n\t\t\tfor (; leftIt != leftMap.cend(); ++leftIt)\n\t\t\t{\n\t\t\t\tauto rightIt = rightMap.find(leftIt.key());\n\t\t\t\tif (rightIt == rightMap.end())\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!qtnCompareQVariants(leftIt.value(), rightIt.value()))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase QVariant::Map:\n\t\t{\n\t\t\tconst auto leftMap = left.toMap();\n\t\t\tconst auto rightMap = right.toMap();\n\t\t\tif (leftMap.size() != rightMap.size())\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tauto leftIt = leftMap.cbegin();\n\t\t\tauto rightIt = rightMap.cbegin();\n\t\t\tfor (; leftIt != leftMap.cend(); ++leftIt, ++rightIt)\n\t\t\t{\n\t\t\t\tif (leftIt.key() != rightIt.key())\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!qtnCompareQVariants(leftIt.value(), rightIt.value()))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase QVariant::List:\n\t\t{\n\t\t\tconst auto leftList = left.toList();\n\t\t\tconst auto rightList = left.toList();\n\t\t\tint count = leftList.size();\n\t\t\tif (count != rightList.size())\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tif (!qtnCompareQVariants(leftList.at(i), rightList.at(i)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\treturn left == right;\n}\n\nclass QtnPropertyQVariantEditBttnHandler\n\t: public QtnPropertyEditorBttnHandler<QtnPropertyQVariantBase,\n\t\t  QtnLineEditBttn>\n{\npublic:\n\tQtnPropertyQVariantEditBttnHandler(\n\t\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor);\n\nprotected:\n\tvirtual void revertInput() override;\n\tvirtual void onToolButtonClick() override;\n\tvirtual void updateEditor() override;\n\nprivate:\n\tvoid onEditingFinished();\n\tvoid onToolButtonClicked(bool);\n\tvoid onApplyData(const QVariant &data);\n\n\tCustomPropertyEditorDialog *dialog;\n\tDialogContainerPtr dialogContainer;\n\tbool is_object;\n};\n\nQtnPropertyQVariantBase::QtnPropertyQVariantBase(QObject *parent)\n\t: QtnSinglePropertyBase(parent)\n{\n}\n\nbool QtnPropertyQVariantBase::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\treturn setValue(str, reason);\n}\n\nbool QtnPropertyQVariantBase::toStrImpl(QString &str) const\n{\n\tstr = value().toString();\n\treturn true;\n}\n\nbool QtnPropertyQVariantBase::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\treturn setValue(var, reason);\n}\n\nbool QtnPropertyQVariantBase::toVariantImpl(QVariant &var) const\n{\n\tvar = value();\n\treturn var.isValid();\n}\n\nQtnPropertyQVariantCallback::QtnPropertyQVariantCallback(\n\tQObject *object, const QMetaProperty &metaProperty, QObject *parent)\n\t: QtnSinglePropertyCallback(parent)\n{\n\tsetCallbackValueGet([object, metaProperty]() -> QVariant {\n\t\treturn metaProperty.read(object);\n\t});\n\n\tsetCallbackValueSet([object, metaProperty](QVariant value,\n\t\t\t\t\t\t\tQtnPropertyChangeReason /*reason*/) {\n\t\tmetaProperty.write(object, value);\n\t});\n\n\tsetCallbackValueEqual([object, metaProperty](QVariant value) -> bool {\n\t\tauto thisValue = metaProperty.read(object);\n\n\t\treturn qtnCompareQVariants(thisValue, value);\n\t});\n}\n\nQtnPropertyQVariantCallback::QtnPropertyQVariantCallback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyQVariantBase>(parent)\n{\n}\n\nQtnPropertyQVariant::QtnPropertyQVariant(QObject *parent)\n\t: QtnSinglePropertyValue<QtnPropertyQVariantBase>(parent)\n{\n}\n\nQString QtnPropertyQVariant::valueToString(const QVariant &value)\n{\n\treturn !variantIsObject(value.type()) ? value.toString() : QString();\n}\n\nbool QtnPropertyQVariant::variantIsObject(QVariant::Type type)\n{\n\tswitch (type)\n\t{\n\t\tcase QVariant::Hash:\n\t\tcase QVariant::Map:\n\t\tcase QVariant::StringList:\n\t\tcase QVariant::List:\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nQString QtnPropertyQVariant::getPlaceholderStr(QVariant::Type type)\n{\n\tswitch (type)\n\t{\n\t\tcase QVariant::Hash:\n\t\tcase QVariant::Map:\n\t\t\treturn tr(\"(Dictionary)\");\n\n\t\tcase QVariant::StringList:\n\t\tcase QVariant::List:\n\t\t\treturn tr(\"(List)\");\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn QtnPropertyQString::getEmptyPlaceholderStr();\n}\n\nQtnPropertyDelegateQVariant::QtnPropertyDelegateQVariant(\n\tQtnPropertyQVariantBase &owner)\n\t: QtnPropertyDelegateTyped<QtnPropertyQVariantBase>(owner)\n{\n}\n\nvoid QtnPropertyDelegateQVariant::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyQVariantBase::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateQVariant,\n\t\t\tQtnPropertyQVariantBase>,\n\t\t\"QVariant\");\n}\n\nbool QtnPropertyDelegateQVariant::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<QtnPropertyQVariantBase>::\n\t\t\tacceptKeyPressedForInplaceEditImpl(keyEvent))\n\t\treturn true;\n\n\t// accept any printable key\n\treturn qtnAcceptForLineEdit(keyEvent);\n}\n\nQWidget *QtnPropertyDelegateQVariant::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\tauto editor = new QtnLineEditBttn(parent);\n\teditor->setGeometry(rect);\n\n\tnew QtnPropertyQVariantEditBttnHandler(this, *editor);\n\n\tqtnInitLineEdit(editor->lineEdit, inplaceInfo);\n\treturn editor;\n}\n\nbool QtnPropertyDelegateQVariant::propertyValueToStrImpl(\n\tQString &strValue) const\n{\n\tauto value = owner().value();\n\tstrValue = QtnPropertyQVariant::valueToString(value);\n\n\tif (strValue.isEmpty())\n\t\tstrValue = QtnPropertyQVariant::getPlaceholderStr(value.type());\n\n\treturn true;\n}\n\nbool QtnPropertyDelegateQVariant::isPlaceholderColor() const\n{\n\treturn QtnPropertyQVariant::valueToString(owner().value()).isEmpty();\n}\n\nQtnPropertyQVariantEditBttnHandler::QtnPropertyQVariantEditBttnHandler(\n\tQtnPropertyDelegate *delegate, QtnLineEditBttn &editor)\n\t: QtnPropertyEditorHandlerType(delegate, editor)\n\t, dialog(new CustomPropertyEditorDialog(&editor))\n\t, is_object(false)\n{\n\tdialogContainer = connectDialog(dialog);\n\tupdateEditor();\n\n\teditor.lineEdit->installEventFilter(this);\n\n\tQObject::connect(editor.toolButton, &QToolButton::clicked, this,\n\t\t&QtnPropertyQVariantEditBttnHandler::onToolButtonClicked);\n\n\tQObject::connect(editor.lineEdit, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyQVariantEditBttnHandler::onEditingFinished);\n\n\tQObject::connect(dialog, &CustomPropertyEditorDialog::apply, this,\n\t\t&QtnPropertyQVariantEditBttnHandler::onApplyData);\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::revertInput()\n{\n\treverted = true;\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::onToolButtonClick()\n{\n\tonToolButtonClicked(false);\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::updateEditor()\n{\n\tauto edit = editor().lineEdit;\n\tedit->setReadOnly(!stateProperty()->isEditableByUser());\n\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\tedit->clear();\n\t\tedit->setPlaceholderText(QtnMultiProperty::getMultiValuePlaceholder());\n\t} else\n\t{\n\t\tQVariant value;\n\t\tvalue = property().value();\n\n\t\tif (QtnPropertyQVariant::variantIsObject(value.type()))\n\t\t{\n\t\t\tis_object = true;\n\t\t\tedit->setText(QString());\n\t\t} else\n\t\t{\n\t\t\tis_object = false;\n\t\t\tedit->setText(value.toString());\n\t\t}\n\n\t\tedit->setPlaceholderText(\n\t\t\tQtnPropertyQVariant::getPlaceholderStr(value.type()));\n\t\tedit->selectAll();\n\t}\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::onEditingFinished()\n{\n\tif (canApply())\n\t{\n\t\tauto text = editor().lineEdit->text();\n\n\t\tif (!is_object || !text.isEmpty())\n\t\t{\n\t\t\tif (is_object || text != property().value().toString())\n\t\t\t\tproperty().setValue(text, delegate()->editReason());\n\n\t\t\tupdateEditor();\n\t\t}\n\t}\n\n\tapplyReset();\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::onToolButtonClicked(bool)\n{\n\tQVariant data;\n\tauto text = editor().lineEdit->text();\n\n\tauto property = &this->property();\n\tauto value = property->value();\n\n\tif (!is_object && text != value.toString())\n\t{\n\t\tdata = text;\n\t} else\n\t\tdata = value;\n\n\tauto dialogContainer = this->dialogContainer;\n\treverted = true;\n\tdialog->setReadOnly(!stateProperty()->isEditableByUser());\n\n\tvolatile bool destroyed = false;\n\tauto connection = QObject::connect(this, &QObject::destroyed,\n\t\t[&destroyed]() mutable { destroyed = true; });\n\n\tif (dialog->execute(property->name(), data) && !destroyed)\n\t\tproperty->setValue(data, delegate()->editReason());\n\n\tif (!destroyed)\n\t{\n\t\tQObject::disconnect(connection);\n\t\tupdateEditor();\n\t}\n\n\tQ_UNUSED(dialogContainer);\n}\n\nvoid QtnPropertyQVariantEditBttnHandler::onApplyData(const QVariant &data)\n{\n\tproperty().setValue(data, delegate()->editReason());\n\tupdateEditor();\n}\n"
  },
  {
    "path": "QtnProperty/PropertyQVariant.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyTemplates.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\n#include <QVariant>\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVariantBase\n\t: public QtnSinglePropertyBase<QVariant>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVariantBase(\n\t\tconst QtnPropertyQVariantBase &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQVariantBase(QObject *parent);\n\nprotected:\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\tvirtual bool toVariantImpl(QVariant &var) const override;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVariantCallback\n\t: public QtnSinglePropertyCallback<QtnPropertyQVariantBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVariantCallback(\n\t\tconst QtnPropertyQVariantCallback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQVariantCallback(QObject *object,\n\t\tconst QMetaProperty &metaProperty, QObject *parent = nullptr);\n\texplicit QtnPropertyQVariantCallback(QObject *parent = nullptr);\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyQVariant\n\t: public QtnSinglePropertyValue<QtnPropertyQVariantBase>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyQVariant(const QtnPropertyQVariant &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyQVariant(QObject *parent);\n\n\tstatic QString valueToString(const QVariant &value);\n\tstatic bool variantIsObject(QVariant::Type type);\n\tstatic QString getPlaceholderStr(QVariant::Type type);\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateQVariant\n\t: public QtnPropertyDelegateTyped<QtnPropertyQVariantBase>\n{\n\tQ_DISABLE_COPY(QtnPropertyDelegateQVariant)\n\npublic:\n\ttypedef QtnPropertyDelegateTyped<QtnPropertyQVariantBase> Inherited;\n\n\tQtnPropertyDelegateQVariant(QtnPropertyQVariantBase &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\nprotected:\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\tvirtual bool isPlaceholderColor() const override;\n};\n\nQTN_IMPORT_EXPORT bool qtnCompareQVariants(\n\tconst QVariant &left, const QVariant &right);\n"
  },
  {
    "path": "QtnProperty/PropertySet.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertySet.h\"\n\n#include <QRegularExpression>\n#include <QJsonObject>\n#include <QDebug>\n\nvoid qtnAddPropertyAsChild(\n\tQObject *parent, QtnPropertyBase *child, bool moveOwnership)\n{\n\tQtnPropertySet *propertySet = qobject_cast<QtnPropertySet *>(parent);\n\n\tif (propertySet)\n\t\tpropertySet->addChildProperty(child, moveOwnership);\n}\n\nvoid qtnRemovePropertyAsChild(QObject *parent, QtnPropertyBase *child)\n{\n\tQtnPropertySet *propertySet = qobject_cast<QtnPropertySet *>(parent);\n\n\tif (propertySet)\n\t\tpropertySet->removeChildProperty(child);\n}\n\nQtnPropertySet::QtnPropertySet(QObject *parent)\n\t: QtnPropertyBase(parent)\n\t, m_childrenOrder(NoSort)\n{\n}\n\nQtnPropertySet::QtnPropertySet(\n\tSortOrder childrenOrder, const CompareFunc &compareFunc)\n\t: QtnPropertyBase(nullptr)\n\t, m_compareFunc(compareFunc)\n\t, m_childrenOrder(childrenOrder)\n{\n}\n\nQtnPropertySet::~QtnPropertySet()\n{\n\tclearChildProperties();\n}\n\nint QtnPropertySet::compareByName(\n\tconst QtnPropertyBase *a, const QtnPropertyBase *b)\n{\n\treturn QString::localeAwareCompare(a->name(), b->name());\n}\n\nQList<QtnPropertyBase *> QtnPropertySet::findChildProperties(\n\tQString name, Qt::FindChildOptions options)\n{\n\tQList<QtnPropertyBase *> result;\n\n\t// normilize name\n\tname = name.trimmed();\n\n\t// if name is dot separated property path\n\tif (name.contains('.'))\n\t{\n\t\tQString nameHead = name.section('.', 0, 0);\n\n\t\tif (nameHead.isEmpty())\n\t\t\treturn result;\n\n\t\tQString nameTail = name.section('.', 1);\n\n\t\tif (nameTail.isEmpty())\n\t\t\treturn result;\n\n\t\tQList<QtnPropertyBase *> headResult =\n\t\t\tfindChildProperties(nameHead, options);\n\n\t\tfor (auto headProperty : headResult)\n\t\t{\n\t\t\tQtnPropertySet *headPropertySet = headProperty->asPropertySet();\n\n\t\t\tif (!headPropertySet)\n\t\t\t\tcontinue;\n\n\t\t\tresult.append(\n\t\t\t\theadPropertySet->findChildProperties(nameTail, options));\n\t\t}\n\t} else\n\t{\n\t\tfor (auto childProperty : m_childProperties)\n\t\t{\n\t\t\tif (childProperty->name() == name)\n\t\t\t\tresult.append(childProperty);\n\t\t}\n\n\t\tif (options & Qt::FindChildrenRecursively)\n\t\t{\n\t\t\tfor (auto childProperty : m_childProperties)\n\t\t\t{\n\t\t\t\tQtnPropertySet *propertySet = childProperty->asPropertySet();\n\n\t\t\t\tif (propertySet)\n\t\t\t\t\tpropertySet->findChildPropertiesRecursive(name, result);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nQList<QtnPropertyBase *> QtnPropertySet::findChildProperties(\n\tconst QRegularExpression &re, Qt::FindChildOptions options)\n{\n\tQList<QtnPropertyBase *> result;\n\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tif (re.match(childProperty->name()).isValid())\n\t\t\tresult.append(childProperty);\n\t}\n\n\tif (options & Qt::FindChildrenRecursively)\n\t{\n\t\tfor (auto childProperty : m_childProperties)\n\t\t{\n\t\t\tQtnPropertySet *propertySet = childProperty->asPropertySet();\n\n\t\t\tif (propertySet)\n\t\t\t\tpropertySet->findChildPropertiesRecursive(re, result);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nQtnPropertyBase *QtnPropertySet::findChildProperty(QtnPropertyID id)\n{\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tif (childProperty->id() == id)\n\t\t\treturn childProperty;\n\t}\n\n\treturn nullptr;\n}\n\nvoid QtnPropertySet::clearChildProperties()\n{\n\tif (m_childProperties.isEmpty())\n\t\treturn;\n\n\temit propertyWillChange(\n\t\tQtnPropertyChangeReasonChildPropertyRemove, nullptr, 0);\n\n\t// Original list is cleared to avoid interference with property destructors,\n\t// where properties are removed from the parent's list.\n\tauto childProperties = std::move(m_childProperties);\n\tfor (auto p : childProperties)\n\t{\n\t\tif (p->parent() == this)\n\t\t\tdelete p;\n\t}\n\n\temit propertyDidChange(QtnPropertyChangeReasonChildPropertyRemove);\n}\n\nbool QtnPropertySet::addChildProperty(\n\tQtnPropertyBase *childProperty, bool moveOwnership, int index)\n{\n\tQ_CHECK_PTR(childProperty);\n\n\temit propertyWillChange(QtnPropertyChangeReasonChildPropertyAdd,\n\t\tQtnPropertyValuePtr(childProperty), qMetaTypeId<QtnPropertyBase *>());\n\n\tswitch (m_childrenOrder)\n\t{\n\t\tcase NoSort:\n\t\t\tbreak;\n\n\t\tcase Ascend:\n\t\tcase Descend:\n\t\t\tindex = 0;\n\t\t\tfor (int i = m_childProperties.size() - 1; i >= 0; --i)\n\t\t\t{\n\t\t\t\tauto p = m_childProperties.at(i);\n\t\t\t\tint compare = m_compareFunc(childProperty, p);\n\t\t\t\tif (compare == 0 ||\n\t\t\t\t\t(m_childrenOrder == Ascend && compare > 0) ||\n\t\t\t\t\t(m_childrenOrder == Descend && compare < 0))\n\t\t\t\t{\n\t\t\t\t\tindex = i + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (index < 0)\n\t\tm_childProperties.append(childProperty);\n\telse\n\t\tm_childProperties.insert(index, childProperty);\n\n\tif (moveOwnership)\n\t\tchildProperty->setParent(this);\n\n\temit propertyDidChange(QtnPropertyChangeReasonChildPropertyAdd);\n\n\tchildProperty->setStateInherited(state());\n\treturn true;\n}\n\nbool QtnPropertySet::removeChildProperty(QtnPropertyBase *childProperty)\n{\n\tQ_CHECK_PTR(childProperty);\n\n\tint childPropertyIndex = m_childProperties.indexOf(childProperty);\n\n\tif (childPropertyIndex < 0)\n\t\treturn false;\n\n\temit propertyWillChange(QtnPropertyChangeReasonChildPropertyRemove,\n\t\tQtnPropertyValuePtr(childProperty), qMetaTypeId<QtnPropertyBase *>());\n\n\tm_childProperties.erase(m_childProperties.begin() + childPropertyIndex);\n\n\tif (childProperty->parent() == this)\n\t\tchildProperty->setParent(nullptr);\n\n\temit propertyDidChange(QtnPropertyChangeReasonChildPropertyRemove);\n\n\treturn true;\n}\n\nQtnPropertySet *QtnPropertySet::createNew(QObject *parentForNew) const\n{\n\treturn createNewImpl(parentForNew);\n}\n\nQtnPropertySet *QtnPropertySet::createCopy(QObject *parentForCopy) const\n{\n\treturn createCopyImpl(parentForCopy);\n}\n\nbool QtnPropertySet::copyValues(\n\tQtnPropertySet *propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n\treturn copyValuesImpl(propertySetCopyFrom, ignoreMask);\n}\n\nQtnPropertySet *QtnPropertySet::asPropertySet()\n{\n\treturn this;\n}\n\nconst QtnPropertySet *QtnPropertySet::asPropertySet() const\n{\n\treturn this;\n}\n\nvoid QtnPropertySet::doReset(QtnPropertyChangeReason reason)\n{\n\tQ_ASSERT(reason & QtnPropertyChangeReasonResetValue);\n\tfor (auto &p : childProperties())\n\t{\n\t\tp->reset(reason);\n\t}\n}\n\nvoid QtnPropertySet::updateStateInherited(bool force)\n{\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tchildProperty->setStateInherited(state(), force);\n\t}\n}\n\nQtnPropertySet *QtnPropertySet::createNewImpl(QObject *parentForNew) const\n{\n\tQ_UNUSED(parentForNew);\n\treturn nullptr;\n}\n\nQtnPropertySet *QtnPropertySet::createCopyImpl(QObject *parentForCopy) const\n{\n\tQ_UNUSED(parentForCopy);\n\treturn nullptr;\n}\n\nbool QtnPropertySet::copyValuesImpl(\n\tQtnPropertySet *propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n\tQ_UNUSED(propertySetCopyFrom);\n\tQ_UNUSED(ignoreMask);\n\treturn false;\n}\n\nbool QtnPropertySet::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tstatic QRegExp parserLine(QStringLiteral(\"^\\\\s*([^=]+)=(.*)$\"));\n\n\tQStringList lines = str.split(QChar::LineFeed, QString::SkipEmptyParts);\n\n\tif (lines.isEmpty())\n\t\treturn true;\n\n\tbool ok = true;\n\n\tfor (const auto &line : lines)\n\t{\n\t\tif (!parserLine.exactMatch(line))\n\t\t{\n\t\t\tqDebug() << \"Cannot parse string: \" << line;\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tQStringList params = parserLine.capturedTexts();\n\t\tif (params.size() != 3)\n\t\t{\n\t\t\tqDebug() << \"Cannot parse string: \" << line;\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tQString propertyPath = params[1];\n\t\tQString propertyStrValue = params[2];\n\n\t\tQList<QtnPropertyBase *> subProperties =\n\t\t\tfindChildProperties(propertyPath, Qt::FindChildrenRecursively);\n\t\tif (subProperties.size() != 1)\n\t\t{\n\t\t\tqDebug() << \"Ambiguous property path: \" << propertyPath;\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (subProperties[0]->state() & QtnPropertyStateNonSerialized)\n\t\t\tcontinue;\n\n\t\tpropertyStrValue = propertyStrValue.trimmed();\n\t\tif (propertyStrValue.startsWith('\"') && propertyStrValue.endsWith('\"'))\n\t\t{\n\t\t\tpropertyStrValue =\n\t\t\t\tpropertyStrValue.mid(1, propertyStrValue.length() - 2);\n\t\t}\n\n\t\tif (!subProperties[0]->fromStr(propertyStrValue, reason))\n\t\t{\n\t\t\tqDebug() << QString(\n\t\t\t\t\"Cannot convert property %1<%2> from string \\\"%3\\\"\")\n\t\t\t\t\t\t\t.arg(subProperties[0]->name(),\n\t\t\t\t\t\t\t\tsubProperties[0]->metaObject()->className(),\n\t\t\t\t\t\t\t\tpropertyStrValue);\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\treturn ok;\n}\n\nbool QtnPropertySet::fromJson(\n\tconst QJsonObject &jsonObject, QtnPropertyChangeReason reason)\n{\n\tbool ok = true;\n\n\tfor (auto it = jsonObject.begin(), end = jsonObject.end(); it != end; ++it)\n\t{\n\t\tif (it.value().type() != QJsonValue::Object)\n\t\t{\n\t\t\tqDebug() << \"Json object expected\";\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tQString cppName = it.key();\n\t\tauto childProperties =\n\t\t\tfindChildProperties(cppName, Qt::FindDirectChildrenOnly);\n\t\tif (childProperties.isEmpty())\n\t\t{\n\t\t\tqDebug() << \"Cannot find property \" << cppName;\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t} else if (childProperties.size() > 1)\n\t\t{\n\t\t\tqDebug() << \"Ambiguous property \" << cppName;\n\t\t\tok = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (childProperties[0]->state() & QtnPropertyStateNonSerialized)\n\t\t\tcontinue;\n\n\t\tauto childPropertySet = childProperties[0]->asPropertySet();\n\t\tif (childPropertySet)\n\t\t{\n\t\t\tif (!childPropertySet->fromJson(it.value().toObject(), reason))\n\t\t\t{\n\t\t\t\tqDebug() << \"Cannot load \\\"\" << childPropertySet->name()\n\t\t\t\t\t\t << \"\\\" from JSON\";\n\t\t\t\tok = false;\n\t\t\t}\n\t\t} else\n\t\t{\n\t\t\tauto childProperty = childProperties[0]->asProperty();\n\t\t\tif (childProperty)\n\t\t\t{\n\t\t\t\tauto jsonProperty = it.value().toObject();\n\t\t\t\tif (!jsonProperty.contains(\"value\"))\n\t\t\t\t{\n\t\t\t\t\tqDebug() << \"Cannot parse \\\"value\\\" attribute\";\n\t\t\t\t\tok = false;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tQString propertyValue = jsonProperty.value(\"value\").toString();\n\t\t\t\tif (!childProperty->fromStr(propertyValue, reason))\n\t\t\t\t{\n\t\t\t\t\tqDebug() << \"Cannot convert value\" << propertyValue\n\t\t\t\t\t\t\t << \"to property\" << childProperty->name();\n\t\t\t\t\tok = false;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t{\n\t\t\t\tQ_ASSERT(false && \"Cannot recognize property type\");\n\t\t\t\tok = false;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ok;\n}\n\nbool QtnPropertySet::toJson(QJsonObject &jsonObject) const\n{\n\tbool ok = true;\n\n\tfor (auto childPropertyBase : childProperties())\n\t{\n\t\tif (childPropertyBase->state() & QtnPropertyStateNonSerialized)\n\t\t\tcontinue;\n\n\t\tQJsonObject jsonSubObject;\n\n\t\tauto childPropertySet = childPropertyBase->asPropertySet();\n\t\tif (childPropertySet)\n\t\t{\n\t\t\tif (!childPropertySet->toJson(jsonSubObject))\n\t\t\t{\n\t\t\t\tqDebug() << \"Cannot save \\\"\" << childPropertySet->name()\n\t\t\t\t\t\t << \"\\\" to JSON\";\n\t\t\t\tok = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else\n\t\t{\n\t\t\tauto childProperty = childPropertyBase->asProperty();\n\t\t\tif (childProperty)\n\t\t\t{\n\t\t\t\tQString value;\n\t\t\t\tif (!childProperty->toStr(value))\n\t\t\t\t{\n\t\t\t\t\tqDebug() << \"Cannot convert property \\\"\"\n\t\t\t\t\t\t\t << childProperty->name() << \"\\\" to QString\";\n\t\t\t\t\tok = false;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tjsonSubObject.insert(\"value\", value);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tQ_ASSERT(false && \"Cannot recognize property type\");\n\t\t\t\tok = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tjsonObject.insert(childPropertyBase->name(), jsonSubObject);\n\t}\n\n\treturn ok;\n}\n\nbool QtnPropertySet::toStrImpl(QString &str) const\n{\n\treturn toStrWithPrefix(str, QString());\n}\n\nbool QtnPropertySet::fromVariantImpl(\n\tconst QVariant &v, QtnPropertyChangeReason reason)\n{\n\tif (!v.isValid() || v.type() == QVariant::Map)\n\t{\n\t\treturn fromJson(QJsonObject::fromVariantMap(v.toMap()), reason);\n\t}\n\treturn false;\n}\n\nbool QtnPropertySet::toVariantImpl(QVariant &v) const\n{\n\tQJsonObject json;\n\tbool ok = toJson(json);\n\tif (ok)\n\t\tv = json.toVariantMap();\n\treturn ok;\n}\n\nbool QtnPropertySet::loadImpl(QDataStream &stream)\n{\n\tif (!QtnPropertyBase::loadImpl(stream))\n\t\treturn false;\n\n\tif (stream.status() != QDataStream::Ok)\n\t\treturn false;\n\n\tquint8 version = 0;\n\tstream >> version;\n\t// version incorrect\n\tif (version != STORAGE_VERSION)\n\t\treturn false;\n\n\tforever\n\t{\n\t\tQtnPropertyID id = QtnPropertyIDInvalid;\n\t\tstream >> id;\n\n\t\t// no child properties any more\n\t\tif (id == QtnPropertyIDInvalid)\n\t\t\tbreak;\n\n\t\tQtnPropertyBase *childProperty = findChildProperty(id);\n\t\tif (!childProperty)\n\t\t{\n\t\t\t// cannot find subproperty -> skip\n\t\t\tif (!skipLoad(stream))\n\t\t\t\treturn false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (childProperty->state() & QtnPropertyStateNonSerialized)\n\t\t{\n\t\t\t// should not load such subproperty\n\t\t\tif (!skipLoad(stream))\n\t\t\t\treturn false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!childProperty->load(stream))\n\t\t\treturn false;\n\t}\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nbool QtnPropertySet::saveImpl(QDataStream &stream) const\n{\n\tif (!QtnPropertyBase::saveImpl(stream))\n\t\treturn false;\n\n\tif (stream.status() != QDataStream::Ok)\n\t\treturn false;\n\n\t// for compatibility\n\tstream << STORAGE_VERSION;\n\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tif (childProperty->state() & QtnPropertyStateNonSerialized)\n\t\t\tcontinue;\n\n\t\tif (childProperty->id() == QtnPropertyIDInvalid)\n\t\t{\n\t\t\t// serializable properties should have unique ids\n\t\t\tQ_ASSERT(false && \"serializable properties should have unique ids\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t// save child property id\n\t\tstream << childProperty->id();\n\t\t// save child property\n\t\tif (!childProperty->save(stream))\n\t\t\treturn false;\n\t}\n\n\t// mark end of children list\n\tstream << QtnPropertyIDInvalid;\n\n\treturn stream.status() == QDataStream::Ok;\n}\n\nvoid QtnPropertySet::findChildPropertiesRecursive(\n\tconst QString &name, QList<QtnPropertyBase *> &result)\n{\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tif (childProperty->name() == name)\n\t\t\tresult.append(childProperty);\n\n\t\tQtnPropertySet *propertySet = childProperty->asPropertySet();\n\n\t\tif (propertySet)\n\t\t\tpropertySet->findChildPropertiesRecursive(name, result);\n\t}\n}\n\nvoid QtnPropertySet::findChildPropertiesRecursive(\n\tconst QRegularExpression &re, QList<QtnPropertyBase *> &result)\n{\n\tfor (auto childProperty : m_childProperties)\n\t{\n\t\tif (re.match(childProperty->name()).isValid())\n\t\t\tresult.append(childProperty);\n\n\t\tQtnPropertySet *propertySet = childProperty->asPropertySet();\n\n\t\tif (propertySet)\n\t\t\tpropertySet->findChildPropertiesRecursive(re, result);\n\t}\n}\n\nbool QtnPropertySet::toStrWithPrefix(QString &str, const QString &prefix) const\n{\n\tfor (auto childPropertyBase : m_childProperties)\n\t{\n\t\tif (childPropertyBase->state() & QtnPropertyStateNonSerialized)\n\t\t\tcontinue;\n\t\tQtnProperty *childProperty = childPropertyBase->asProperty();\n\n\t\tif (childProperty)\n\t\t{\n\t\t\tQString strValue;\n\n\t\t\tif (!childProperty->toStr(strValue))\n\t\t\t\treturn false;\n\n\t\t\tstr.append(QStringLiteral(\"%1%2 = %3\\n\")\n\t\t\t\t\t\t   .arg(prefix, childProperty->name(), strValue));\n\t\t} else\n\t\t{\n\t\t\tauto childPropertySet = childPropertyBase->asPropertySet();\n\n\t\t\tif (childPropertySet)\n\t\t\t{\n\t\t\t\tif (!childPropertySet->toStrWithPrefix(str,\n\t\t\t\t\t\tQStringLiteral(\"%1%2.\").arg(\n\t\t\t\t\t\t\tprefix, childPropertySet->name())))\n\t\t\t\t\treturn false;\n\t\t\t} else\n\t\t\t{\n\t\t\t\t// neither property no propertyset\n\t\t\t\tQ_UNREACHABLE();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/PropertySet.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTY_SET_H\n#define QTN_PROPERTY_SET_H\n\n#include \"Property.h\"\n\nclass QJsonObject;\n\nclass QTN_IMPORT_EXPORT QtnPropertySet : public QtnPropertyBase\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnPropertySet)\n\npublic:\n\tenum SortOrder\n\t{\n\t\tNoSort,\n\t\tAscend,\n\t\tDescend,\n\t};\n\n\tstatic int compareByName(\n\t\tconst QtnPropertyBase *a, const QtnPropertyBase *b);\n\n\tusing CompareFunc =\n\t\tstd::function<int(const QtnPropertyBase *, const QtnPropertyBase *)>;\n\n\texplicit QtnPropertySet(QObject *parent = nullptr);\n\texplicit QtnPropertySet(SortOrder childrenOrder,\n\t\tconst CompareFunc &compareFunc = compareByName);\n\tvirtual ~QtnPropertySet() override;\n\n\tinline SortOrder childrenOrder() const;\n\tinline const CompareFunc &compareFunc() const;\n\npublic slots:\n\t// sub properties\n\tinline bool hasChildProperties() const;\n\tinline const QList<QtnPropertyBase *> &childProperties() const;\n\n\tQList<QtnPropertyBase *> findChildProperties(QString name,\n\t\tQt::FindChildOptions options = Qt::FindChildrenRecursively);\n\n\tQList<QtnPropertyBase *> findChildProperties(const QRegularExpression &re,\n\t\tQt::FindChildOptions options = Qt::FindChildrenRecursively);\n\n\tQtnPropertyBase *findChildProperty(QtnPropertyID id);\n\tvoid clearChildProperties();\n\tbool addChildProperty(QtnPropertyBase *childProperty,\n\t\tbool moveOwnership = true, int index = -1);\n\tbool removeChildProperty(QtnPropertyBase *childProperty);\n\n\t// cloning\n\tQtnPropertySet *createNew(QObject *parentForNew) const;\n\tQtnPropertySet *createCopy(QObject *parentForCopy) const;\n\n\t// copy values\n\tbool copyValues(QtnPropertySet *propertySetCopyFrom,\n\t\tQtnPropertyState ignoreMask = QtnPropertyStateNone);\n\n\t// JSON support\n\tbool fromJson(const QJsonObject &jsonObject,\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonChildren);\n\tbool toJson(QJsonObject &jsonObject) const;\n\npublic:\n\t// casts\n\tvirtual QtnPropertySet *asPropertySet() override;\n\tvirtual const QtnPropertySet *asPropertySet() const override;\n\nprotected:\n\tvirtual void doReset(QtnPropertyChangeReason reason) override;\n\tvirtual void updateStateInherited(bool force) override;\n\n\t// cloning implementation\n\tvirtual QtnPropertySet *createNewImpl(QObject *parentForNew) const;\n\tvirtual QtnPropertySet *createCopyImpl(QObject *parentForCopy) const;\n\n\t// copy values\n\tvirtual bool copyValuesImpl(\n\t\tQtnPropertySet *propertySetCopyFrom, QtnPropertyState ignoreMask);\n\n\t// string conversion implementation\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &v, QtnPropertyChangeReason reason) override;\n\tvirtual bool toVariantImpl(QVariant &v) const override;\n\n\t// serialization implementation\n\tvirtual bool loadImpl(QDataStream &stream) override;\n\tvirtual bool saveImpl(QDataStream &stream) const override;\n\nprivate:\n\tvoid findChildPropertiesRecursive(\n\t\tconst QString &name, QList<QtnPropertyBase *> &result);\n\tvoid findChildPropertiesRecursive(\n\t\tconst QRegularExpression &re, QList<QtnPropertyBase *> &result);\n\n\tbool toStrWithPrefix(QString &str, const QString &prefix) const;\n\nprivate:\n\tCompareFunc m_compareFunc;\n\tQList<QtnPropertyBase *> m_childProperties;\n\n\tSortOrder m_childrenOrder;\n};\n\nQtnPropertySet::SortOrder QtnPropertySet::childrenOrder() const\n{\n\treturn m_childrenOrder;\n}\n\nconst QtnPropertySet::CompareFunc &QtnPropertySet::compareFunc() const\n{\n\treturn m_compareFunc;\n}\n\nbool QtnPropertySet::hasChildProperties() const\n{\n\treturn !m_childProperties.empty();\n}\n\nconst QList<QtnPropertyBase *> &QtnPropertySet::childProperties() const\n{\n\treturn m_childProperties;\n}\n\nQ_DECLARE_METATYPE(QtnPropertySet *)\n\ntemplate <typename T>\nT *qtnCreateProperty(QtnPropertySet *parent, QString name)\n{\n\tauto property = new T(parent);\n\tproperty->setName(name);\n\tparent->addChildProperty(property);\n\treturn property;\n}\n\ntemplate <typename T>\nT *qtnCreateProperty(QtnPropertySet *parent)\n{\n\tauto property = new T(parent);\n\tparent->addChildProperty(property);\n\treturn property;\n}\n\nQTN_IMPORT_EXPORT void qtnAddPropertyAsChild(\n\tQObject *parent, QtnPropertyBase *child, bool moveOwnership);\nQTN_IMPORT_EXPORT void qtnRemovePropertyAsChild(\n\tQObject *parent, QtnPropertyBase *child);\n\n#endif // QTN_PROPERTY_SET_H\n"
  },
  {
    "path": "QtnProperty/PropertyUInt64.cpp",
    "content": "﻿/*******************************************************************************\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyUInt64.h\"\n\n#include \"QObjectPropertySet.h\"\n#include \"Delegates/Utils/PropertyEditorAux.h\"\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Delegates/Utils/PropertyDelegateSliderBox.h\"\n#include \"PropertyDelegateAttrs.h\"\n\n#include <QLocale>\n#include <QKeyEvent>\n#include <QLineEdit>\n\nQtnPropertyUInt64Base::QtnPropertyUInt64Base(QObject *parent)\n\t: QtnNumericPropertyBase<QtnSinglePropertyBase<quint64>>(parent)\n{\n}\n\nbool QtnPropertyUInt64Base::fromStrImpl(\n\tconst QString &str, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = str.toULongLong(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nbool QtnPropertyUInt64Base::toStrImpl(QString &str) const\n{\n\tstr = QString::number(value());\n\treturn true;\n}\n\nbool QtnPropertyUInt64Base::fromVariantImpl(\n\tconst QVariant &var, QtnPropertyChangeReason reason)\n{\n\tbool ok = false;\n\tValueType value = var.toULongLong(&ok);\n\n\tif (!ok)\n\t\treturn false;\n\n\treturn setValue(value, reason);\n}\n\nQtnPropertyUInt64Callback::QtnPropertyUInt64Callback(QObject *parent)\n\t: QtnSinglePropertyCallback<QtnPropertyUInt64Base>(parent)\n{\n}\n\nQtnPropertyUInt64::QtnPropertyUInt64(QObject *parent)\n\t: QtnNumericPropertyValue<QtnPropertyUInt64Base>(parent)\n{\n}\n\nvoid QtnPropertyDelegateUInt64::Register(QtnPropertyDelegateFactory &factory)\n{\n\tfactory.registerDelegateDefault(&QtnPropertyUInt64Base::staticMetaObject,\n\t\t&qtnCreateDelegate<QtnPropertyDelegateUInt64, QtnPropertyUInt64Base>,\n\t\tqtnLineEditDelegate());\n\n\tfactory.registerDelegate(&QtnPropertyUInt64Base::staticMetaObject,\n\t\t&qtnCreateDelegate<\n\t\t\tQtnPropertyDelegateSlideBoxTyped<QtnPropertyUInt64Base>,\n\t\t\tQtnPropertyUInt64Base>,\n\t\tqtnSliderBoxDelegate());\n}\n\nquint64 QtnPropertyDelegateUInt64::minValue() const\n{\n\treturn m_min.isValid() ? m_min.toULongLong() : owner().minValue();\n}\n\nquint64 QtnPropertyDelegateUInt64::maxValue() const\n{\n\treturn m_max.isValid() ? m_max.toULongLong() : owner().maxValue();\n}\n\nquint64 QtnPropertyDelegateUInt64::currentValue() const\n{\n\treturn qBound(minValue(), owner().value(), maxValue());\n}\n\nQtnPropertyDelegateUInt64::QtnPropertyDelegateUInt64(\n\tQtnPropertyUInt64Base &owner)\n\t: QObject(nullptr)\n\t, QtnPropertyDelegateTyped<QtnPropertyUInt64Base>(owner)\n\t, editor(nullptr)\n\t, reverted(false)\n\t, applied(false)\n{\n}\n\nbool QtnPropertyDelegateUInt64::eventFilter(QObject *obj, QEvent *event)\n{\n\tif (event->type() == QEvent::KeyPress)\n\t{\n\t\tauto keyEvent = static_cast<QKeyEvent *>(event);\n\n\t\tswitch (keyEvent->key())\n\t\t{\n\t\t\tcase Qt::Key_Escape:\n\t\t\t\treverted = true;\n\t\t\t\tupdateEditor();\n\t\t\t\tbreak;\n\n\t\t\tcase Qt::Key_Enter:\n\t\t\tcase Qt::Key_Return:\n\t\t\t\tapplied = true;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn QObject::eventFilter(obj, event);\n}\n\nbool QtnPropertyDelegateUInt64::acceptKeyPressedForInplaceEditImpl(\n\tQKeyEvent *keyEvent) const\n{\n\tif (QtnPropertyDelegateTyped<QtnPropertyUInt64Base>::\n\t\t\tacceptKeyPressedForInplaceEditImpl(keyEvent))\n\t\treturn true;\n\n\treturn qtnAcceptForNumEdit(keyEvent, NUM_UNSIGNED_INT);\n}\n\nQWidget *QtnPropertyDelegateUInt64::createValueEditorImpl(\n\tQWidget *parent, const QRect &rect, QtnInplaceInfo *inplaceInfo)\n{\n\teditor = createValueEditorLineEdit(\n\t\tparent, rect, !stateProperty()->isEditableByUser(), inplaceInfo);\n\n\tupdateEditor();\n\treverted = false;\n\tapplied = false;\n\n\teditor->installEventFilter(this);\n\tQObject::connect(editor, &QLineEdit::editingFinished, this,\n\t\t&QtnPropertyDelegateUInt64::onEditingFinished);\n\n\treturn editor;\n}\n\nbool QtnPropertyDelegateUInt64::propertyValueToStrImpl(QString &strValue) const\n{\n\tstrValue = QLocale().toString(currentValue());\n\tstrValue.append(m_suffix);\n\treturn true;\n}\n\nvoid QtnPropertyDelegateUInt64::applyAttributesImpl(\n\tconst QtnPropertyDelegateInfo &info)\n{\n\tinfo.loadAttribute(qtnSuffixAttr(), m_suffix);\n\tm_min = info.attributes.value(qtnMinAttr());\n\tm_max = info.attributes.value(qtnMaxAttr());\n\tfixMinMaxVariant<quint64>(m_min, m_max);\n}\n\nvoid QtnPropertyDelegateUInt64::onEditingFinished()\n{\n\tbool ok = false;\n\n\tif (!reverted && (applied || !stateProperty()->isMultiValue()))\n\t{\n\t\tauto str = editor->text().trimmed();\n\t\tif (!m_suffix.isEmpty() && str.endsWith(m_suffix))\n\t\t{\n\t\t\tstr = str.left(str.length() - m_suffix.length()).trimmed();\n\t\t}\n\t\tQLocale locale;\n\t\tstr.remove(locale.groupSeparator());\n\t\tauto value = locale.toULongLong(str, &ok);\n\t\tif (!ok)\n\t\t{\n\t\t\tvalue = str.toULongLong(&ok);\n\t\t}\n\t\tok = ok && value >= minValue() && value <= maxValue();\n\n\t\tif (ok)\n\t\t\towner().setValue(value, editReason());\n\t}\n\n\tif (!ok)\n\t\tupdateEditor();\n\n\treverted = false;\n\tapplied = false;\n}\n\nvoid QtnPropertyDelegateUInt64::updateEditor()\n{\n\tif (stateProperty()->isMultiValue())\n\t{\n\t\teditor->clear();\n\t} else\n\t{\n\t\tQString str;\n\t\tpropertyValueToStrImpl(str);\n\t\tstr.remove(QLocale().groupSeparator());\n\t\teditor->setText(str);\n\n\t\teditor->selectAll();\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/PropertyUInt64.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyTemplates.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\nclass QTN_IMPORT_EXPORT QtnPropertyUInt64Base\n\t: public QtnNumericPropertyBase<QtnSinglePropertyBase<quint64>>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUInt64Base(const QtnPropertyUInt64Base &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyUInt64Base(QObject *parent);\n\nprotected:\n\t// string conversion implementation\n\tvirtual bool fromStrImpl(\n\t\tconst QString &str, QtnPropertyChangeReason reason) override;\n\tvirtual bool toStrImpl(QString &str) const override;\n\n\t// variant conversion implementation\n\tvirtual bool fromVariantImpl(\n\t\tconst QVariant &var, QtnPropertyChangeReason reason) override;\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS(QtnPropertyUInt64Base)\n};\n\nP_PROPERTY_DECL_ALL_OPERATORS(QtnPropertyUInt64Base, quint64)\n\nclass QTN_IMPORT_EXPORT QtnPropertyUInt64Callback\n\t: public QtnSinglePropertyCallback<QtnPropertyUInt64Base>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUInt64Callback(\n\t\tconst QtnPropertyUInt64Callback &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyUInt64Callback(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(\n\t\tQtnPropertyUInt64Callback, QtnPropertyUInt64Base)\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyUInt64\n\t: public QtnNumericPropertyValue<QtnPropertyUInt64Base>\n{\n\tQ_OBJECT\n\nprivate:\n\tQtnPropertyUInt64(const QtnPropertyUInt64 &other) Q_DECL_EQ_DELETE;\n\npublic:\n\texplicit QtnPropertyUInt64(QObject *parent);\n\n\tP_PROPERTY_DECL_MEMBER_OPERATORS2(QtnPropertyUInt64, QtnPropertyUInt64Base)\n};\n\nclass QLineEdit;\nclass QTN_IMPORT_EXPORT QtnPropertyDelegateUInt64\n\t: public QObject\n\t, public QtnPropertyDelegateTyped<QtnPropertyUInt64Base>\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnPropertyDelegateUInt64)\n\n\tQString m_suffix;\n\tQVariant m_min;\n\tQVariant m_max;\n\npublic:\n\tQtnPropertyDelegateUInt64(QtnPropertyUInt64Base &owner);\n\n\tstatic void Register(QtnPropertyDelegateFactory &factory);\n\n\tquint64 minValue() const;\n\tquint64 maxValue() const;\n\tquint64 currentValue() const;\n\nprotected:\n\tvirtual bool eventFilter(QObject *obj, QEvent *event) override;\n\n\tvirtual bool acceptKeyPressedForInplaceEditImpl(\n\t\tQKeyEvent *keyEvent) const override;\n\tvirtual QWidget *createValueEditorImpl(QWidget *parent, const QRect &rect,\n\t\tQtnInplaceInfo *inplaceInfo = nullptr) override;\n\tvirtual bool propertyValueToStrImpl(QString &strValue) const override;\n\n\tvirtual void applyAttributesImpl(\n\t\tconst QtnPropertyDelegateInfo &info) override;\n\nprivate:\n\tvoid onEditingFinished();\n\nprivate:\n\tvoid updateEditor();\n\n\tQLineEdit *editor;\n\tbool reverted;\n\tbool applied;\n};\n"
  },
  {
    "path": "QtnProperty/PropertyView.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016, 2020 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyView.h\"\n\n#include \"Utils/InplaceEditing.h\"\n#include \"Utils/QtnConnections.h\"\n#include \"Delegates/Utils/PropertyDelegateMisc.h\"\n\n#include <QApplication>\n#include <QScrollBar>\n#include <QHelpEvent>\n#include <QToolTip>\n\nstruct QtnPropertyView::Item\n{\n\tQtnPropertyBase *property;\n\tstd::unique_ptr<QtnPropertyDelegate> delegate;\n\tint level;\n\n\tItem *parent;\n\tstd::vector<std::unique_ptr<Item>> children;\n\tQtnConnections connections;\n\n\tItem();\n\n\tinline bool collapsed() const;\n};\n\nstruct QtnPropertyView::VisibleItem\n{\n\tItem *item;\n\tint level;\n\tbool hasChildren;\n\n\tmutable QList<QtnSubItem> subItems;\n\tmutable bool subItemsValid;\n\n\tVisibleItem();\n};\n\nclass QtnPainterState\n{\npublic:\n\tQtnPainterState(QPainter &p);\n\t~QtnPainterState();\n\nprivate:\n\tQPainter &m_p;\n};\n\nextern void set_smaller_text_osx(QWidget *w);\n\nQtnPropertyView::QtnPropertyView(QWidget *parent, QtnPropertySet *propertySet)\n\t: QAbstractScrollArea(parent)\n\t, m_propertySet(propertySet)\n\t, m_activeProperty(nullptr)\n\t, m_delegateFactory(&QtnPropertyDelegateFactory::staticInstance())\n\t, m_visibleItemsValid(false)\n\t, m_grabMouseSubItem(nullptr)\n\t, m_style(QtnPropertyViewStyleLiveSplit)\n\t, m_itemHeight(0)\n\t, m_itemHeightSpacing(6)\n\t, m_valueLeftMargin(0)\n\t, m_splitRatio(0.5f)\n\t, m_lastChangeReason(0)\n\t, m_stopInvalidate(0)\n\t, m_mouseAtSplitter(false)\n\t, m_mouseCaptured(false)\n\t, m_accessibilityProxy(nullptr)\n{\n\tset_smaller_text_osx(this);\n\n\tsetFocusPolicy(Qt::StrongFocus);\n\tviewport()->setMouseTracking(true);\n\n\tupdateStyleStuff();\n\n\tupdateItemsTree();\n}\n\nQtnPropertyView::~QtnPropertyView()\n{\n\t// destruct everything\n}\n\nQtnAccessibilityProxy *QtnPropertyView::accessibilityProxy()\n{\n\tif (!m_accessibilityProxy)\n\t\tm_accessibilityProxy = new QtnAccessibilityProxy(this);\n\n\treturn m_accessibilityProxy;\n}\n\nvoid QtnPropertyView::onActivePropertyDestroyed()\n{\n\tm_activeProperty = nullptr;\n\temit activePropertyChanged(m_activeProperty);\n\tviewport()->update();\n}\n\nvoid QtnPropertyView::onEditedPropertyWillChange(\n\tQtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId)\n{\n\tif (!(reason & QtnPropertyChangeReasonEdit))\n\t{\n\t\treturn;\n\t}\n\n\tQ_ASSERT(nullptr != qobject_cast<QtnPropertyBase *>(sender()));\n\n\tif (reason & QtnPropertyChangeReasonValue)\n\t{\n\t\tauto property = static_cast<QtnPropertyBase *>(sender());\n\n\t\temit beforePropertyEdited(property, newValue, typeId);\n\t}\n\n\tif (reason & QtnPropertyChangeReasonLockToggled)\n\t{\n\t\tauto property = static_cast<QtnPropertyBase *>(sender());\n\t\temit beforePropertyLockToggled(property);\n\t}\n}\n\nvoid QtnPropertyView::onEditedPropertyDidChange(QtnPropertyChangeReason reason)\n{\n\tif (!(reason & QtnPropertyChangeReasonEdit))\n\t{\n\t\treturn;\n\t}\n\n\tQ_ASSERT(nullptr != qobject_cast<QtnPropertyBase *>(sender()));\n\n\tif (reason & QtnPropertyChangeReasonValue)\n\t{\n\t\tauto property = static_cast<QtnPropertyBase *>(sender());\n\n\t\temit propertyEdited(property);\n\t}\n\n\tif (reason & QtnPropertyChangeReasonLockToggled)\n\t{\n\t\tauto property = static_cast<QtnPropertyBase *>(sender());\n\n\t\temit propertyLockToggled(property);\n\t}\n}\n\nvoid QtnPropertyView::setPropertySet(QtnPropertySet *newPropertySet)\n{\n\tif (newPropertySet == m_propertySet)\n\t\treturn;\n\tif (m_propertySet)\n\t{\n\t\tQObject::disconnect(m_propertySet, &QtnPropertyBase::destroyed, this,\n\t\t\t&QtnPropertyView::onPropertySetDestroyed);\n\t}\n\n\tm_propertySet = newPropertySet;\n\n\tif (m_propertySet)\n\t{\n\t\tQObject::connect(m_propertySet, &QtnPropertyBase::destroyed, this,\n\t\t\t&QtnPropertyView::onPropertySetDestroyed);\n\t}\n\n\tupdateItemsTree();\n}\n\nQtnPropertyBase *QtnPropertyView::getPropertyParent(\n\tconst QtnPropertyBase *property) const\n{\n\tauto item = findItem(m_itemsTree.get(), property);\n\n\tif (nullptr != item && nullptr != item->parent)\n\t\treturn item->parent->property;\n\n\treturn nullptr;\n}\n\nbool QtnPropertyView::setActiveProperty(\n\tQtnPropertyBase *newActiveProperty, bool ensureVisible)\n{\n\tif (m_activeProperty == newActiveProperty)\n\t\treturn false;\n\n\tqtnStopInplaceEdit();\n\n\tif (ensureVisible)\n\t\tthis->ensureVisible(newActiveProperty);\n\n\tif (!newActiveProperty)\n\t{\n\t\tsetActivePropertyInternal(nullptr);\n\t\treturn true;\n\t}\n\n\tint index = visibleItemIndexByProperty(newActiveProperty);\n\n\tif (index < 0)\n\t\treturn false;\n\n\tsetActivePropertyInternal(newActiveProperty);\n\treturn true;\n}\n\nbool QtnPropertyView::setActiveProperty(int index, bool ensureVisible)\n{\n\tif (index < 0)\n\t\tindex = 0;\n\n\tif (nullptr == m_propertySet)\n\t\treturn false;\n\n\tauto &cp = m_propertySet->childProperties();\n\tif (cp.isEmpty())\n\t\treturn false;\n\n\tif (index >= cp.size())\n\t\tindex = cp.size() - 1;\n\n\treturn setActiveProperty(cp.at(index), ensureVisible);\n}\n\nbool QtnPropertyView::ensureVisible(const QtnPropertyBase *property)\n{\n\tif (!property)\n\t\treturn false;\n\n\tint index = visibleItemIndexByProperty(property);\n\treturn ensureVisibleItemByIndex(index);\n}\n\nbool QtnPropertyView::setItemHeightSpacing(quint32 itemHeightSpacing)\n{\n\tm_itemHeightSpacing = itemHeightSpacing;\n\tupdateStyleStuff();\n\treturn true;\n}\n\nvoid QtnPropertyView::setPropertyViewStyle(QtnPropertyViewStyle style)\n{\n\tm_style = style;\n}\n\nvoid QtnPropertyView::addPropertyViewStyle(QtnPropertyViewStyle style)\n{\n\tsetPropertyViewStyle(propertyViewStyle() | style);\n}\n\nvoid QtnPropertyView::removePropertyViewStyle(QtnPropertyViewStyle style)\n{\n\tsetPropertyViewStyle(propertyViewStyle() & ~style);\n}\n\nQtnPropertyBase *QtnPropertyView::getPropertyAt(\n\tconst QPoint &position, QRect *out_rect)\n{\n\tint index = visibleItemIndexByPoint(position);\n\n\tif (index >= 0)\n\t{\n\t\tif (nullptr != out_rect)\n\t\t{\n\t\t\t*out_rect = visibleItemRect(index);\n\t\t}\n\n\t\treturn m_visibleItems[index].item->property;\n\t}\n\n\treturn nullptr;\n}\n\nint QtnPropertyView::valueLeftMargin() const\n{\n\treturn m_valueLeftMargin;\n}\n\nbool QtnPropertyView::isMouseCaptured() const\n{\n\treturn m_mouseCaptured || m_rubberBand;\n}\n\nvoid QtnPropertyView::connectPropertyToEdit(\n\tQtnPropertyBase *property, QtnConnections &outConnections)\n{\n\tQ_ASSERT(nullptr != property);\n\n\toutConnections.push_back(\n\t\tQObject::connect(property, &QtnPropertyBase::propertyWillChange, this,\n\t\t\t&QtnPropertyView::onEditedPropertyWillChange));\n\n\toutConnections.push_back(\n\t\tQObject::connect(property, &QtnPropertyBase::propertyDidChange, this,\n\t\t\t&QtnPropertyView::onEditedPropertyDidChange));\n}\n\nvoid QtnPropertyView::paintEvent(QPaintEvent *e)\n{\n\tQ_UNUSED(e);\n\n\tvalidateVisibleItems();\n\n\tif (m_visibleItems.isEmpty())\n\t{\n\t\treturn;\n\t}\n\n\tint firstVisibleItemIndex =\n\t\tqMin(verticalScrollBar()->value() / m_itemHeight,\n\t\t\t(m_visibleItems.size() - 1));\n\tint lastVisibleItemIndex = qMin(\n\t\t((verticalScrollBar()->value() + viewport()->height()) / m_itemHeight) +\n\t\t\t1,\n\t\t(m_visibleItems.size() - 1));\n\n\tauto viewPortRect = viewport()->rect();\n\tQRect itemRect = viewPortRect;\n\titemRect.setTop(\n\t\tfirstVisibleItemIndex * m_itemHeight - verticalScrollBar()->value());\n\titemRect.setBottom(itemRect.top() + m_itemHeight);\n\n\tQStylePainter painter(viewport());\n\n\tQPen splitterPen;\n\tsplitterPen.setColor(this->palette().color(QPalette::Mid));\n\tsplitterPen.setStyle(Qt::DotLine);\n\n\tfor (int i = firstVisibleItemIndex; i <= lastVisibleItemIndex; ++i)\n\t{\n\t\tconst VisibleItem &vItem = m_visibleItems[i];\n\n\t\tdrawItem(painter, itemRect, vItem);\n\t\tauto delegate = vItem.item->delegate.get();\n\t\tQ_ASSERT(delegate); // cannot be null\n\n\t\tif (delegate->isSplittable())\n\t\t{\n\t\t\tpainter.save();\n\t\t\tsplitterPen.setDashOffset(itemRect.top());\n\t\t\tpainter.setPen(splitterPen);\n\t\t\tpainter.drawLine(splitPosition(), itemRect.top(), splitPosition(),\n\t\t\t\titemRect.bottom());\n\t\t\tpainter.restore();\n\t\t}\n\t\titemRect.translate(0, m_itemHeight);\n\t}\n}\n\nvoid QtnPropertyView::drawItem(\n\tQStylePainter &painter, const QRect &rect, const VisibleItem &vItem) const\n{\n\tauto delegate = vItem.item->delegate.get();\n\tQ_ASSERT(delegate); // cannot be null\n\n\tQMargins margins(m_valueLeftMargin + rect.height() * vItem.level, 0, 0, 0);\n\tbool isActive = (m_activeProperty == vItem.item->property);\n\n\tQtnDrawContext drawContext{ &painter, this, rect, margins, splitPosition(),\n\t\tisActive, vItem.hasChildren };\n\n\t// create sub-items if not initialized\n\tif (!vItem.subItemsValid)\n\t{\n\t\tQ_ASSERT(vItem.subItems.isEmpty());\n\t\tdelegate->createSubItems(drawContext, vItem.subItems);\n\t\tvItem.subItemsValid = true;\n\t}\n\n\t// draw sub-items\n\tfor (const auto &subItem : vItem.subItems)\n\t{\n\t\tsubItem.draw(drawContext);\n\t}\n}\n\nvoid QtnPropertyView::changeActivePropertyByIndex(int index)\n{\n\tQtnPropertyBase *newActiveProperty =\n\t\t(index < 0) ? nullptr : m_visibleItems[index].item->property;\n\tsetActiveProperty(newActiveProperty);\n\tensureVisibleItemByIndex(index);\n}\n\nQtnPropertyBase *QtnPropertyView::visiblePropertyAtPoint(\n\tconst QPoint &pos) const\n{\n\tint index = visibleItemIndexByPoint(pos);\n\n\tif (index < 0)\n\t\treturn nullptr;\n\n\treturn m_visibleItems[index].item->property;\n}\n\nint QtnPropertyView::visibleItemIndexByPoint(const QPoint &pos) const\n{\n\tint index = (verticalScrollBar()->value() + pos.y()) / m_itemHeight;\n\tif (index >= m_visibleItems.size())\n\t\treturn -1;\n\n\treturn index;\n}\n\nint QtnPropertyView::visibleItemIndexByProperty(\n\tconst QtnPropertyBase *property) const\n{\n\tvalidateVisibleItems();\n\n\tfor (int i = 0, n = m_visibleItems.size(); i < n; ++i)\n\t\tif (m_visibleItems[i].item->property == property)\n\t\t\treturn i;\n\n\treturn -1;\n}\n\nQRect QtnPropertyView::visibleItemRect(int index) const\n{\n\tQ_ASSERT(index >= 0 && index < m_visibleItems.size());\n\n\tQRect rect = viewport()->rect();\n\trect.setTop(index * m_itemHeight - verticalScrollBar()->value());\n\trect.setHeight(m_itemHeight);\n\n\treturn rect;\n}\n\nQRect QtnPropertyView::propertyActionRect(\n\tQtnPropertyBase *property, int actionIndex)\n{\n\tif (!property)\n\t\treturn QRect();\n\n\tint index = visibleItemIndexByProperty(property);\n\n\tif (index < 0)\n\t\treturn QRect();\n\n\tconst auto &item = m_visibleItems[index];\n\n\tif (!item.subItemsValid)\n\t\treturn QRect();\n\n\tif (actionIndex < 0 || actionIndex >= item.subItems.size())\n\t\treturn QRect();\n\n\treturn item.subItems[actionIndex].rect;\n}\n\nbool QtnPropertyView::handleMouseEvent(int index, QEvent *e, QPoint mousePos)\n{\n\tif (index < 0)\n\t{\n\t\tdeactivateSubItems();\n\t\treturn false;\n\t}\n\n\tQtnEventContext context{ e, this };\n\treturn handleEvent(context, m_visibleItems[index], mousePos);\n}\n\nvoid QtnPropertyView::resizeEvent(QResizeEvent *e)\n{\n\tQ_UNUSED(e);\n\n\tqtnStopInplaceEdit();\n\tinvalidateSubItems();\n\tupdateVScrollbar();\n}\n\nstatic const int TOLERANCE = 3;\n\nvoid QtnPropertyView::mousePressEvent(QMouseEvent *e)\n{\n\tm_mouseCaptured = false;\n\tif (e->button() == Qt::RightButton)\n\t{\n\t\tauto property = getPropertyAt(e->pos());\n\t\tsetActiveProperty(property, true);\n\t\tQAbstractScrollArea::mousePressEvent(e);\n\t\treturn;\n\t}\n\n\tif (e->button() != Qt::LeftButton)\n\t{\n\t\tQAbstractScrollArea::mousePressEvent(e);\n\t\treturn;\n\t}\n\n\tint index = visibleItemIndexByPoint(e->pos());\n\tbool isSplittableItem = index >= 0\n\t\t? m_visibleItems.at(index).item->delegate->isSplittable()\n\t\t: false;\n\tif (isSplittableItem && qAbs(e->x() - splitPosition()) < TOLERANCE)\n\t{\n\t\tm_rubberBand.reset(new QRubberBand(QRubberBand::Line, this));\n\n\t\tQRect rect = viewport()->rect();\n\t\trect.setLeft(e->x());\n\t\trect.setRight(e->x());\n\t\tm_rubberBand->setGeometry(rect);\n\t\tm_rubberBand->show();\n\t} else\n\t{\n\t\tif (index >= 0)\n\t\t{\n\t\t\tchangeActivePropertyByIndex(index);\n\t\t\tm_mouseCaptured = handleMouseEvent(index, e, e->pos());\n\t\t}\n\t}\n\tQAbstractScrollArea::mousePressEvent(e);\n}\n\nvoid QtnPropertyView::mouseReleaseEvent(QMouseEvent *e)\n{\n\tif (e->button() != Qt::LeftButton)\n\t{\n\t\tQAbstractScrollArea::mouseReleaseEvent(e);\n\t\treturn;\n\t}\n\n\tif (m_rubberBand)\n\t{\n\t\tm_rubberBand = nullptr;\n\n\t\t// update split ratio\n\t\tQRect rect = viewport()->rect();\n\t\tupdateSplitRatio((float) (e->x() - rect.left()) / (float) rect.width());\n\t} else\n\t{\n\t\thandleMouseEvent(visibleItemIndexByPoint(e->pos()), e, e->pos());\n\t\temit mouseReleased(e);\n\t}\n\n\tQAbstractScrollArea::mouseReleaseEvent(e);\n\tm_mouseCaptured = false;\n}\n\nvoid QtnPropertyView::mouseMoveEvent(QMouseEvent *e)\n{\n\tif (m_rubberBand)\n\t{\n\t\tif (e->buttons() == Qt::LeftButton)\n\t\t{\n\t\t\tQRect rect = viewport()->rect();\n\t\t\trect.setLeft(e->x());\n\t\t\trect.setRight(e->x());\n\t\t\tm_rubberBand->setGeometry(rect);\n\n\t\t\tif (m_style & QtnPropertyViewStyleLiveSplit)\n\t\t\t{\n\t\t\t\t// update split ratio\n\t\t\t\tQRect rect = viewport()->rect();\n\t\t\t\tupdateSplitRatio(\n\t\t\t\t\t(float) (e->x() - rect.left()) / (float) rect.width());\n\t\t\t}\n\t\t}\n\t} else\n\t{\n\t\tint index = visibleItemIndexByPoint(e->pos());\n\t\tbool isSplittable = index >= 0\n\t\t\t? m_visibleItems.at(index).item->delegate->isSplittable()\n\t\t\t: false;\n\t\tbool atSplitterPos =\n\t\t\tisSplittable && qAbs(e->x() - splitPosition()) < TOLERANCE;\n\t\tif (!handleMouseEvent(index, e, e->pos()))\n\t\t{\n\t\t\tif (atSplitterPos)\n\t\t\t{\n\t\t\t\tif (!m_mouseAtSplitter)\n\t\t\t\t{\n\t\t\t\t\tm_mouseAtSplitter = true;\n\t\t\t\t\tsetCursor(Qt::SplitHCursor);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (e->buttons() & Qt::LeftButton)\n\t\t\t\tchangeActivePropertyByIndex(index);\n\t\t}\n\t\tif (!atSplitterPos && m_mouseAtSplitter)\n\t\t{\n\t\t\tm_mouseAtSplitter = false;\n\t\t\tunsetCursor();\n\t\t}\n\t}\n\tQAbstractScrollArea::mouseMoveEvent(e);\n}\n\nvoid QtnPropertyView::mouseDoubleClickEvent(QMouseEvent *e)\n{\n\tif (!m_rubberBand)\n\t{\n\t\thandleMouseEvent(visibleItemIndexByPoint(e->pos()), e, e->pos());\n\t\tQAbstractScrollArea::mouseDoubleClickEvent(e);\n\t}\n}\n\nbool QtnPropertyView::viewportEvent(QEvent *e)\n{\n\tswitch (e->type())\n\t{\n\t\tcase QEvent::StyleChange:\n\t\t\tupdateStyleStuff();\n\t\t\tbreak;\n\n\t\tcase QEvent::ToolTip:\n\t\t{\n\t\t\tQHelpEvent *helpEvent = static_cast<QHelpEvent *>(e);\n\t\t\ttooltipEvent(helpEvent);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QEvent::Leave:\n\t\t\tdeactivateSubItems();\n\t\t\tbreak;\n\n\t\tdefault:; // do nothing\n\t}\n\n\treturn QAbstractScrollArea::viewportEvent(e);\n}\n\nvoid QtnPropertyView::scrollContentsBy(int dx, int dy)\n{\n\tif (dx != 0 || dy != 0)\n\t{\n\t\tqtnStopInplaceEdit();\n\t\tinvalidateSubItems();\n\t}\n\n\tQAbstractScrollArea::scrollContentsBy(dx, dy);\n}\n\nvoid QtnPropertyView::keyPressEvent(QKeyEvent *e)\n{\n\tvalidateVisibleItems();\n\n\tif (m_visibleItems.empty())\n\t{\n\t\tQAbstractScrollArea::keyPressEvent(e);\n\t\treturn;\n\t}\n\n\tQWidget *inplaceEditor = qtnGetInplaceEdit();\n\tif (inplaceEditor)\n\t{\n\t\tint key = e->key();\n\t\tif (key == Qt::Key_Escape || key == Qt::Key_Return ||\n\t\t\tkey == Qt::Key_Enter)\n\t\t{\n\t\t\tqtnStopInplaceEdit();\n\t\t\t// eat event\n\t\t\te->accept();\n\t\t}\n\t\treturn;\n\t}\n\n\tswitch (e->key())\n\t{\n\t\tcase Qt::Key_Home:\n\t\t{\n\t\t\t// go to first item\n\t\t\tchangeActivePropertyByIndex(0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_End:\n\t\t{\n\t\t\t// go to last item\n\t\t\tchangeActivePropertyByIndex(m_visibleItems.size() - 1);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_Up:\n\t\t{\n\t\t\t// go to previous item\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t\tchangeActivePropertyByIndex(qMax(0, index - 1));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_Down:\n\t\t{\n\t\t\t// go to next item\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t\tchangeActivePropertyByIndex(\n\t\t\t\t\tqMin(m_visibleItems.size() - 1, index + 1));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_PageUp:\n\t\t{\n\t\t\t// go to previous page\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t{\n\t\t\t\tint itemsPerPage =\n\t\t\t\t\tqMax(viewport()->rect().height() / m_itemHeight, 1);\n\t\t\t\tchangeActivePropertyByIndex(qMax(0, index - itemsPerPage));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_PageDown:\n\t\t{\n\t\t\t// go to next page\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t{\n\t\t\t\tint itemsPerPage =\n\t\t\t\t\tqMax(viewport()->rect().height() / m_itemHeight, 1);\n\t\t\t\tchangeActivePropertyByIndex(\n\t\t\t\t\tqMin(m_visibleItems.size() - 1, index + itemsPerPage));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_Left:\n\t\t{\n\t\t\t// go to parent item or collapse\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst VisibleItem &vItem = m_visibleItems[index];\n\t\t\t\tif (vItem.hasChildren && !vItem.item->collapsed())\n\t\t\t\t{\n\t\t\t\t\t// collapse opened property\n\t\t\t\t\tvItem.item->property->addState(QtnPropertyStateCollapsed);\n\t\t\t\t} else if (vItem.item->parent)\n\t\t\t\t{\n\t\t\t\t\t// activate parent property\n\t\t\t\t\tsetActiveProperty(vItem.item->parent->property, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Qt::Key_Right:\n\t\t{\n\t\t\t// go to child item or expand\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\t\t\tif (index < 0)\n\t\t\t\tchangeActivePropertyByIndex(0);\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst VisibleItem &vItem = m_visibleItems[index];\n\t\t\t\tif (vItem.hasChildren && vItem.item->collapsed())\n\t\t\t\t{\n\t\t\t\t\t// expand closed property\n\t\t\t\t\tvItem.item->property->removeState(\n\t\t\t\t\t\tQtnPropertyStateCollapsed);\n\t\t\t\t} else if (vItem.hasChildren)\n\t\t\t\t{\n\t\t\t\t\t// activate child property\n\t\t\t\t\tsetActiveProperty(\n\t\t\t\t\t\tvItem.item->children.front()->property, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t{\n\t\t\tint index = visibleItemIndexByProperty(activeProperty());\n\n\t\t\tif (index >= 0)\n\t\t\t{\n\t\t\t\tQtnEventContext context{ e, this };\n\t\t\t\tif (handleEvent(context, m_visibleItems[index], QPoint()))\n\t\t\t\t{\n\t\t\t\t\t// eat event\n\t\t\t\t\te->accept();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// process by default\n\t\t\tQAbstractScrollArea::keyPressEvent(e);\n\t\t}\n\t}\n}\n\nvoid QtnPropertyView::wheelEvent(QWheelEvent *e)\n{\n\tbool processed =\n\t\thandleMouseEvent(visibleItemIndexByPoint(e->pos()), e, e->pos());\n\tif (processed)\n\t\treturn;\n\n\tQAbstractScrollArea::wheelEvent(e);\n}\n\nvoid QtnPropertyView::tooltipEvent(QHelpEvent *e)\n{\n\tif (!handleMouseEvent(visibleItemIndexByPoint(e->pos()), e, e->pos()))\n\t{\n\t\tQToolTip::hideText();\n\t}\n}\n\nbool QtnPropertyView::handleEvent(\n\tQtnEventContext &context, VisibleItem &vItem, QPoint mousePos)\n{\n\tif (!vItem.subItemsValid)\n\t\treturn false;\n\n\tif (0 == m_stopInvalidate++)\n\t\tm_lastChangeReason = QtnPropertyChangeReason(0);\n\tbool result;\n\t// process event\n\tif (m_grabMouseSubItem)\n\t\tresult = m_grabMouseSubItem->event(context);\n\telse\n\t{\n\t\tresult = false;\n\t\t// update list of sub items under cursor\n\t\tQList<QtnSubItem *> activeSubItems;\n\n\t\t// make list of new active sub items\n\t\tfor (auto &subItem : vItem.subItems)\n\t\t{\n\t\t\tif (mousePos.isNull() || subItem.rect.contains(mousePos))\n\t\t\t{\n\t\t\t\tsubItem.activate(this, mousePos);\n\t\t\t\tactiveSubItems.append(&subItem);\n\t\t\t}\n\t\t}\n\n\t\t// deactivate old sub items\n\t\tfor (auto activeSubItem : m_activeSubItems)\n\t\t{\n\t\t\tactiveSubItem->deactivate(this, mousePos);\n\t\t}\n\n\t\t// adopt new active sub items\n\t\tm_activeSubItems.swap(activeSubItems);\n\n\t\t// process event\n\t\tfor (auto activeSubItem : m_activeSubItems)\n\t\t{\n\t\t\tif (activeSubItem->event(context))\n\t\t\t{\n\t\t\t\tresult = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (--m_stopInvalidate == 0)\n\t\tupdateWithReason(m_lastChangeReason);\n\n\treturn result;\n}\n\nQtnPropertyView::Item::Item()\n\t: property(nullptr)\n\t, level(0)\n\t, parent(nullptr)\n{\n}\n\nbool QtnPropertyView::Item::collapsed() const\n{\n\treturn property->isCollapsed();\n}\n\nbool QtnPropertyView::grabMouseForSubItem(QtnSubItem *subItem, QPoint mousePos)\n{\n\tQ_ASSERT(!m_grabMouseSubItem);\n\tif (m_grabMouseSubItem)\n\t\treturn false;\n\n\tviewport()->grabMouse();\n\tm_grabMouseSubItem = subItem;\n\tm_grabMouseSubItem->grabMouse(this, mousePos);\n\n\treturn true;\n}\n\nbool QtnPropertyView::releaseMouseForSubItem(\n\tQtnSubItem *subItem, QPoint mousePos)\n{\n\tQ_UNUSED(subItem);\n\tQ_ASSERT(m_grabMouseSubItem == subItem);\n\tif (!m_grabMouseSubItem)\n\t\treturn false;\n\n\tm_grabMouseSubItem->releaseMouse(this, mousePos);\n\tm_grabMouseSubItem = nullptr;\n\tviewport()->releaseMouse();\n\n\treturn true;\n}\n\nvoid QtnPropertyView::updateItemsTree()\n{\n\tm_itemsTree.reset(createItemsTree(m_propertySet));\n\tinvalidateVisibleItems();\n}\n\nQtnPropertyView::Item *QtnPropertyView::createItemsTree(\n\tQtnPropertyBase *rootProperty)\n{\n\tif (!rootProperty)\n\t\treturn nullptr;\n\n\tauto item = new Item;\n\titem->property = rootProperty;\n\tauto &connections = item->connections;\n\n\tconnections.push_back(\n\t\tQObject::connect(rootProperty, &QtnPropertyBase::propertyDidChange,\n\t\t\tthis, [item, this](QtnPropertyChangeReason reason) {\n\t\t\t\tonPropertyDidChange(reason, item);\n\t\t\t}));\n\n\tsetupItemDelegate(item);\n\n\treturn item;\n}\n\nvoid QtnPropertyView::setActivePropertyInternal(QtnPropertyBase *property)\n{\n\tdisconnectActiveProperty();\n\n\tm_activeProperty = property;\n\temit activePropertyChanged(m_activeProperty);\n\tviewport()->update();\n\n\tconnectActiveProperty();\n}\n\nvoid QtnPropertyView::invalidateVisibleItems()\n{\n\tdeactivateSubItems();\n\tm_visibleItemsValid = false;\n\tm_visibleItems.clear();\n\tviewport()->update();\n}\n\nvoid QtnPropertyView::validateVisibleItems() const\n{\n\tif (m_visibleItemsValid)\n\t\treturn;\n\n\tfillVisibleItems(\n\t\tm_itemsTree.get(), (m_style & QtnPropertyViewStyleShowRoot) ? 0 : -1);\n\n\tupdateVScrollbar();\n\n\tm_visibleItemsValid = true;\n}\n\nvoid QtnPropertyView::fillVisibleItems(Item *item, int level) const\n{\n\tif (!item)\n\t\treturn;\n\n\t// process children only for negative levels\n\tif (level < 0)\n\t{\n\t\t// process children\n\t\tfor (auto &child : item->children)\n\t\t{\n\t\t\tfillVisibleItems(child.get(), level + 1);\n\t\t}\n\n\t\treturn;\n\t}\n\n\t// skip not accepted items\n\tif (!acceptItem(*item))\n\t\treturn;\n\n\tVisibleItem vItem;\n\tvItem.item = item;\n\tvItem.level = level;\n\n\tif (item->collapsed())\n\t{\n\t\t// check if item has any child\n\t\tfor (auto &child : item->children)\n\t\t{\n\t\t\tif (acceptItem(*child.get()))\n\t\t\t{\n\t\t\t\tvItem.hasChildren = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// add item and quit\n\t\tm_visibleItems.append(vItem);\n\t\treturn;\n\t}\n\n\t// add item\n\tm_visibleItems.append(vItem);\n\n\t// save just added item index\n\tint index = m_visibleItems.size() - 1;\n\n\t// process children\n\tfor (auto &child : item->children)\n\t{\n\t\tfillVisibleItems(child.get(), level + 1);\n\t}\n\n\t// if we add something -> current item has children\n\tif (index < (m_visibleItems.size() - 1))\n\t\tm_visibleItems[index].hasChildren = true;\n}\n\nbool QtnPropertyView::acceptItem(const Item &item) const\n{\n\treturn item.property->isVisible();\n}\n\nvoid QtnPropertyView::updateVScrollbar() const\n{\n\tint viewportHeight = viewport()->height();\n\tint virtualHeight = m_itemHeight * m_visibleItems.size();\n\n\tverticalScrollBar()->setSingleStep(m_itemHeight);\n\tverticalScrollBar()->setPageStep(viewportHeight);\n\tverticalScrollBar()->setRange(\n\t\t0, qMax(0, virtualHeight - viewportHeight + 2));\n}\n\nvoid QtnPropertyView::updateStyleStuff()\n{\n\tQFontMetrics fm(font());\n\tm_itemHeight = fm.height() + m_itemHeightSpacing;\n\n\tm_propertySetBackdroundColor = m_linesColor =\n\t\tpalette().color(QPalette::Button);\n\n\tm_valueLeftMargin = style()->pixelMetric(QStyle::PM_ButtonMargin);\n}\n\nbool QtnPropertyView::ensureVisibleItemByIndex(int index)\n{\n\tif (index < 0)\n\t\treturn false;\n\n\tint vItemTop = index * m_itemHeight;\n\tint vItemBottom = vItemTop + m_itemHeight;\n\n\tQRect rect = viewport()->rect();\n\tint scrollPos = verticalScrollBar()->value();\n\n\tif (vItemTop < scrollPos)\n\t\tscrollPos = vItemTop;\n\telse if (vItemBottom > scrollPos + rect.height())\n\t\tscrollPos = vItemBottom - rect.height();\n\telse\n\t\treturn false;\n\n\tverticalScrollBar()->setValue(scrollPos);\n\treturn true;\n}\n\nvoid QtnPropertyView::invalidateSubItems()\n{\n\tdeactivateSubItems();\n\n\tfor (auto &item : m_visibleItems)\n\t{\n\t\titem.subItemsValid = false;\n\t\titem.subItems.clear();\n\t}\n}\n\nvoid QtnPropertyView::deactivateSubItems()\n{\n\tif (m_grabMouseSubItem)\n\t{\n\t\tviewport()->releaseMouse();\n\t\tm_grabMouseSubItem = nullptr;\n\t}\n\n\tfor (auto subItem : m_activeSubItems)\n\t\tsubItem->deactivate(this, QPoint());\n\n\tm_activeSubItems.clear();\n\n\tQToolTip::hideText();\n}\n\nint QtnPropertyView::splitPosition() const\n{\n\treturn (int) ((float) viewport()->rect().width() * m_splitRatio);\n}\n\nvoid QtnPropertyView::updateSplitRatio(float splitRatio)\n{\n\tm_splitRatio = qBound(0.f, splitRatio, 1.f);\n\t// firce to regenerate sub-items\n\tinvalidateSubItems();\n\t// repaint\n\tviewport()->update();\n}\n\nvoid QtnPropertyView::connectActiveProperty()\n{\n\tif (nullptr != m_activeProperty)\n\t{\n\t\tQObject::connect(m_activeProperty, &QObject::destroyed, this,\n\t\t\t&QtnPropertyView::onActivePropertyDestroyed);\n\t}\n}\n\nvoid QtnPropertyView::disconnectActiveProperty()\n{\n\tif (nullptr != m_activeProperty)\n\t{\n\t\tQObject::disconnect(m_activeProperty, &QObject::destroyed, this,\n\t\t\t&QtnPropertyView::onActivePropertyDestroyed);\n\t}\n}\n\nvoid QtnPropertyView::onPropertyDidChange(\n\tQtnPropertyChangeReason reason, Item *item)\n{\n\tif (!reason)\n\t\treturn;\n\n\tif (reason & QtnPropertyChangeReasonUpdateDelegate)\n\t{\n\t\tsetupItemDelegate(item);\n\t}\n\n\tif (m_stopInvalidate)\n\t{\n\t\tm_lastChangeReason |= reason;\n\t} else\n\t{\n\t\tupdateWithReason(reason);\n\t}\n\n\temit propertiesChanged(reason);\n}\n\nQtnPropertyView::Item *QtnPropertyView::findItem(\n\tItem *currentItem, const QtnPropertyBase *property) const\n{\n\tif (nullptr != currentItem && nullptr != property)\n\t{\n\t\tif (property == currentItem->property)\n\t\t\treturn currentItem;\n\n\t\tfor (auto &item : currentItem->children)\n\t\t{\n\t\t\tauto found = findItem(item.get(), property);\n\n\t\t\tif (nullptr != found)\n\t\t\t\treturn found;\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n\nvoid QtnPropertyView::setupItemDelegate(Item *item)\n{\n\tauto property = item->property;\n\tauto delegate = m_delegateFactory.createDelegate(*property);\n\tQ_ASSERT(delegate); // should always return non-null\n\n\titem->delegate.reset(delegate);\n\titem->children.clear();\n\n\t// apply attributes\n\tauto delegateInfo = property->delegateInfo();\n\tif (delegateInfo)\n\t{\n\t\tdelegate->applyAttributes(*delegateInfo);\n\t}\n\n\t// process delegate subproperties\n\tfor (int i = 0, n = delegate->subPropertyCount(); i < n; ++i)\n\t{\n\t\tauto child = delegate->subProperty(i);\n\t\tQ_ASSERT(child);\n\n\t\tauto childItem = createItemsTree(child);\n\t\tchildItem->parent = item;\n\t\titem->children.emplace_back(childItem);\n\t}\n}\n\nQtnPropertyView::VisibleItem::VisibleItem()\n\t: item(nullptr)\n\t, level(0)\n\t, hasChildren(false)\n\t, subItemsValid(false)\n{\n}\n\nvoid QtnPropertyView::onPropertySetDestroyed()\n{\n\tm_propertySet = nullptr;\n\tupdateItemsTree();\n}\n\nvoid QtnPropertyView::updateWithReason(QtnPropertyChangeReason reason)\n{\n\tif (reason & QtnPropertyChangeReasonChildren)\n\t{\n\t\tupdateItemsTree();\n\t} else if (reason &\n\t\t(QtnPropertyChangeReasonState | QtnPropertyChangeReasonUpdateDelegate))\n\t{\n\t\tinvalidateVisibleItems();\n\t} else\n\t{\n\t\tviewport()->update();\n\t}\n}\n\nQtnPainterState::QtnPainterState(QPainter &p)\n\t: m_p(p)\n{\n\tm_p.save();\n}\n\nQtnPainterState::~QtnPainterState()\n{\n\tm_p.restore();\n}\n"
  },
  {
    "path": "QtnProperty/PropertyView.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTYVIEW_H\n#define QTN_PROPERTYVIEW_H\n\n#include \"FunctionalHelpers.h\"\n#include \"Delegates/PropertyDelegateFactory.h\"\n#include \"Utils/AccessibilityProxy.h\"\n\n#include <QAbstractScrollArea>\n\n#include <memory>\n\nclass QRubberBand;\nclass QHelpEvent;\nclass QtnConnections;\n\nenum QtnPropertyViewStyleFlag\n{\n\tQtnPropertyViewStyleNone = 0x0000,\n\tQtnPropertyViewStyleShowRoot = 0x0001,\n\tQtnPropertyViewStyleLiveSplit = 0x0002,\n\tQtnPropertyViewStyleDblClickActivation = 0x0004\n};\n\nQ_DECLARE_FLAGS(QtnPropertyViewStyle, QtnPropertyViewStyleFlag)\nQ_DECLARE_OPERATORS_FOR_FLAGS(QtnPropertyViewStyle)\n\nclass QTN_IMPORT_EXPORT QtnPropertyView : public QAbstractScrollArea\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnPropertyView)\n\npublic:\n\texplicit QtnPropertyView(\n\t\tQWidget *parent = nullptr, QtnPropertySet *propertySet = nullptr);\n\tvirtual ~QtnPropertyView() override;\n\n\tinline QtnPropertyDelegateFactory *delegateFactory();\n\n\tinline const QtnPropertySet *propertySet() const;\n\tinline QtnPropertySet *propertySet();\n\tvoid setPropertySet(QtnPropertySet *newPropertySet);\n\n\tQtnPropertyBase *getPropertyParent(const QtnPropertyBase *property) const;\n\tinline QtnPropertyBase *activeProperty();\n\tinline const QtnPropertyBase *activeProperty() const;\n\tbool setActiveProperty(\n\t\tQtnPropertyBase *newActiveProperty, bool ensureVisible = false);\n\tbool setActiveProperty(int index, bool ensureVisible = false);\n\n\tbool ensureVisible(const QtnPropertyBase *property);\n\n\tinline int itemHeight() const;\n\n\tinline quint32 itemHeightSpacing() const;\n\tbool setItemHeightSpacing(quint32 itemHeightSpacing);\n\n\tinline QtnPropertyViewStyle propertyViewStyle() const;\n\tvoid setPropertyViewStyle(QtnPropertyViewStyle style);\n\tvoid addPropertyViewStyle(QtnPropertyViewStyle style);\n\tvoid removePropertyViewStyle(QtnPropertyViewStyle style);\n\n\tQtnPropertyBase *getPropertyAt(\n\t\tconst QPoint &position, QRect *out_rect = nullptr);\n\n\tvoid connectPropertyToEdit(\n\t\tQtnPropertyBase *property, QtnConnections &outConnections);\n\tint valueLeftMargin() const;\n\n\tbool isMouseCaptured() const;\n\npublic slots:\n\tQtnAccessibilityProxy *accessibilityProxy();\n\nsignals:\n\tvoid propertiesChanged(QtnPropertyChangeReason reason);\n\t// emits when active property has changed\n\tvoid activePropertyChanged(QtnPropertyBase *activeProperty);\n\tvoid mouseReleased(QMouseEvent *e);\n\tvoid beforePropertyEdited(\n\t\tQtnPropertyBase *property, QtnPropertyValuePtr newValue, int typeId);\n\tvoid propertyEdited(QtnPropertyBase *property);\n\n\tvoid beforePropertyLockToggled(QtnPropertyBase *property);\n\tvoid propertyLockToggled(QtnPropertyBase *property);\n\nprivate:\n\tvoid onActivePropertyDestroyed();\n\tvoid onEditedPropertyWillChange(QtnPropertyChangeReason reason,\n\t\tQtnPropertyValuePtr newValue, int typeId);\n\tvoid onEditedPropertyDidChange(QtnPropertyChangeReason reason);\n\nprotected:\n\tvoid paintEvent(QPaintEvent *e) override;\n\tvoid resizeEvent(QResizeEvent *e) override;\n\tvoid mousePressEvent(QMouseEvent *e) override;\n\tvoid mouseReleaseEvent(QMouseEvent *e) override;\n\tvoid mouseMoveEvent(QMouseEvent *e) override;\n\tvoid mouseDoubleClickEvent(QMouseEvent *e) override;\n\tbool viewportEvent(QEvent *e) override;\n\tvoid scrollContentsBy(int dx, int dy) override;\n\tvoid keyPressEvent(QKeyEvent *e) override;\n\tvoid wheelEvent(QWheelEvent *e) override;\n\tvoid tooltipEvent(QHelpEvent *e);\n\nprivate:\n\tstruct Item;\n\tstruct VisibleItem;\n\nprivate:\n\tvoid updateItemsTree();\n\tItem *createItemsTree(QtnPropertyBase *rootProperty);\n\n\tvoid setActivePropertyInternal(QtnPropertyBase *property);\n\n\tvoid invalidateVisibleItems();\n\tvoid validateVisibleItems() const;\n\tvoid fillVisibleItems(Item *item, int level) const;\n\tbool acceptItem(const Item &item) const;\n\n\tvoid drawItem(QStylePainter &painter, const QRect &rect,\n\t\tconst VisibleItem &vItem) const;\n\n\tvoid changeActivePropertyByIndex(int index);\n\tQtnPropertyBase *visiblePropertyAtPoint(const QPoint &pos) const;\n\tint visibleItemIndexByPoint(const QPoint &pos) const;\n\tint visibleItemIndexByProperty(const QtnPropertyBase *property) const;\n\tQRect visibleItemRect(int index) const;\n\tQRect propertyActionRect(QtnPropertyBase *property, int actionIndex);\n\n\tbool handleMouseEvent(int index, QEvent *e, QPoint mousePos);\n\tbool handleEvent(\n\t\tQtnEventContext &context, VisibleItem &vItem, QPoint mousePos);\n\tbool grabMouseForSubItem(QtnSubItem *subItem, QPoint mousePos);\n\tbool releaseMouseForSubItem(QtnSubItem *subItem, QPoint mousePos);\n\n\tvoid updateVScrollbar() const;\n\tvoid updateStyleStuff();\n\n\tbool ensureVisibleItemByIndex(int index);\n\tvoid invalidateSubItems();\n\tvoid deactivateSubItems();\n\n\tint splitPosition() const;\n\tvoid updateSplitRatio(float splitRatio);\n\n\tvoid connectActiveProperty();\n\tvoid disconnectActiveProperty();\n\n\tvoid onPropertyDidChange(QtnPropertyChangeReason reason, Item *item);\n\tvoid onPropertySetDestroyed();\n\tvoid updateWithReason(QtnPropertyChangeReason reason);\n\n\tItem *findItem(Item *currentItem, const QtnPropertyBase *property) const;\n\tvoid setupItemDelegate(Item *item);\n\nprivate:\n\tQtnPropertySet *m_propertySet;\n\tQtnPropertyBase *m_activeProperty;\n\n\tQtnPropertyDelegateFactory m_delegateFactory;\n\n\tstd::unique_ptr<Item> m_itemsTree;\n\n\tmutable QList<VisibleItem> m_visibleItems;\n\tmutable bool m_visibleItemsValid;\n\n\tQList<QtnSubItem *> m_activeSubItems;\n\tQtnSubItem *m_grabMouseSubItem;\n\n\tQtnPropertyViewStyle m_style;\n\tint m_itemHeight;\n\tquint32 m_itemHeightSpacing;\n\tint m_valueLeftMargin;\n\tQColor m_linesColor;\n\tQColor m_propertySetBackdroundColor;\n\n\tfloat m_splitRatio;\n\tstd::unique_ptr<QRubberBand> m_rubberBand;\n\tQtnPropertyChangeReason m_lastChangeReason;\n\tunsigned m_stopInvalidate;\n\tbool m_mouseAtSplitter;\n\tbool m_mouseCaptured;\n\n\tfriend class QtnAccessibilityProxy;\n\tQtnAccessibilityProxy *m_accessibilityProxy;\n\tfriend struct QtnEventContext;\n};\n\nQtnPropertyDelegateFactory *QtnPropertyView::delegateFactory()\n{\n\treturn &m_delegateFactory;\n}\n\nconst QtnPropertySet *QtnPropertyView::propertySet() const\n{\n\treturn m_propertySet;\n}\n\nQtnPropertySet *QtnPropertyView::propertySet()\n{\n\treturn m_propertySet;\n}\n\nQtnPropertyBase *QtnPropertyView::activeProperty()\n{\n\treturn m_activeProperty;\n}\n\nconst QtnPropertyBase *QtnPropertyView::activeProperty() const\n{\n\treturn m_activeProperty;\n}\n\nint QtnPropertyView::itemHeight() const\n{\n\treturn m_itemHeight;\n}\n\nquint32 QtnPropertyView::itemHeightSpacing() const\n{\n\treturn m_itemHeightSpacing;\n}\n\nQtnPropertyViewStyle QtnPropertyView::propertyViewStyle() const\n{\n\treturn m_style;\n}\n\n#endif // QTN_PROPERTYVIEW_H\n"
  },
  {
    "path": "QtnProperty/PropertyWidget.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyWidget.h\"\n\n#include \"PropertyView.h\"\n\n#include <QVBoxLayout>\n#include <QLabel>\n#include <QSplitter>\n#include <QMouseEvent>\n\nclass QtnSplitterEventsHandler : public QObject\n{\npublic:\n\tQtnSplitterEventsHandler(QObject *parent);\n\nprotected:\n\tvirtual bool eventFilter(QObject *obj, QEvent *event) override;\n};\n\n// It's safe to call this function on any platform.\n// It will only have an effect on the Mac.\nvoid set_smaller_text_osx(QWidget *w)\n{\n\tQ_ASSERT(w != 0);\n\n\t// By default, none of these size attributes are set.\n\t// If any has been set explicitly, we'll leave the widget alone.\n\tif (!w->testAttribute(Qt::WA_MacMiniSize) &&\n\t\t!w->testAttribute(Qt::WA_MacSmallSize) &&\n\t\t!w->testAttribute(Qt::WA_MacNormalSize) &&\n\t\t!w->testAttribute(Qt::WA_MacVariableSize))\n\t{\n\t\t// make the text the 'normal' size\n\t\tw->setAttribute(Qt::WA_MacSmallSize);\n\t}\n}\n\nQtnPropertyWidget::QtnPropertyWidget(QWidget *parent)\n\t: QWidget(parent)\n\t, m_parts(QtnPropertyWidgetPartsNone)\n\t, m_layout(new QVBoxLayout(this))\n\t, m_toolbar(0)\n\t, m_propertyView(new QtnPropertyView(this))\n\t, m_descriptionSplitter(0)\n\t, m_descriptionPanel(0)\n{\n\tm_layout->setContentsMargins(0, 0, 0, 0);\n\tm_layout->setMargin(0);\n\tm_layout->setSpacing(0);\n\tset_smaller_text_osx(this);\n\n\tQObject::connect(m_propertyView, &QtnPropertyView::activePropertyChanged,\n\t\tthis, &QtnPropertyWidget::setActiveProperty);\n\n\tupdateParts();\n}\n\nQtnPropertyWidget::~QtnPropertyWidget()\n{\n\tQObject::disconnect(m_propertyView, &QtnPropertyView::activePropertyChanged,\n\t\tthis, &QtnPropertyWidget::setActiveProperty);\n}\n\nvoid QtnPropertyWidget::setParts(QtnPropertyWidgetParts newParts)\n{\n\tif (m_parts == newParts)\n\t\treturn;\n\n\tm_parts = newParts;\n\tupdateParts();\n}\n\nconst QtnPropertySet *QtnPropertyWidget::propertySet() const\n{\n\treturn m_propertyView->propertySet();\n}\n\nQtnPropertySet *QtnPropertyWidget::propertySet()\n{\n\treturn m_propertyView->propertySet();\n}\n\nvoid QtnPropertyWidget::setPropertySet(QtnPropertySet *newPropertySet)\n{\n\tif (newPropertySet == propertySet())\n\t\treturn;\n\n\tm_propertyView->setPropertySet(newPropertySet);\n\temit propertySetChanged();\n}\n\nvoid QtnPropertyWidget::updateParts()\n{\n\t// clear layout\n\twhile (!m_layout->isEmpty())\n\t{\n\t\tm_layout->takeAt(0);\n\t}\n\n\t// check toolbar\n\n\t// check description panel\n\tif (m_parts & QtnPropertyWidgetPartsDescriptionPanel)\n\t{\n\t\tif (!m_descriptionSplitter)\n\t\t{\n\t\t\t// create splitter\n\t\t\tQ_ASSERT(!m_descriptionPanel);\n\t\t\tQSplitter *splitter = new QSplitter(Qt::Vertical, this);\n\n\t\t\t// add property view\n\t\t\tsplitter->addWidget(m_propertyView);\n\n\t\t\t// create description panel\n\t\t\tm_descriptionPanel = new QLabel(splitter);\n\t\t\tm_descriptionPanel->setTextFormat(Qt::RichText);\n\t\t\tm_descriptionPanel->setAlignment(Qt::AlignTop);\n\t\t\tm_descriptionPanel->setWordWrap(true);\n\t\t\tm_descriptionPanel->setFrameStyle(QFrame::Box | QFrame::Sunken);\n\t\t\tm_descriptionPanel->setMinimumSize(\n\t\t\t\t0, 5 * QFontMetrics(font()).height() / 2);\n\t\t\tQSizePolicy p = m_descriptionPanel->sizePolicy();\n\t\t\tp.setVerticalPolicy(QSizePolicy::Ignored);\n\t\t\tp.setHorizontalPolicy(QSizePolicy::Ignored);\n\t\t\tm_descriptionPanel->setSizePolicy(p);\n\n\t\t\t// set desctiption panel fixed size\n\t\t\tsplitter->setStretchFactor(0, 1);\n\t\t\tsplitter->setStretchFactor(1, 0);\n\n\t\t\t// setup DblClick handler\n\t\t\tsplitter->handle(1)->installEventFilter(\n\t\t\t\tnew QtnSplitterEventsHandler(splitter));\n\n\t\t\tm_descriptionSplitter = splitter;\n\t\t}\n\n\t\tm_layout->addWidget(m_descriptionSplitter);\n\t} else\n\t{\n\t\tm_layout->addWidget(m_propertyView);\n\n\t\tif (m_descriptionSplitter)\n\t\t{\n\t\t\tdelete m_descriptionSplitter;\n\t\t\tm_descriptionSplitter = nullptr;\n\t\t\tm_descriptionPanel = nullptr;\n\t\t}\n\t}\n}\n\nvoid QtnPropertyWidget::setActiveProperty(const QtnPropertyBase *activeProperty)\n{\n\tif (m_descriptionPanel)\n\t{\n\t\tif (!activeProperty)\n\t\t{\n\t\t\tm_descriptionPanel->setText(QString());\n\t\t} else\n\t\t{\n\t\t\tm_descriptionPanel->setText(QStringLiteral(\"<b>%1</b><br>%2\")\n\t\t\t\t\t\t\t\t\t\t\t.arg(activeProperty->displayName(),\n\t\t\t\t\t\t\t\t\t\t\t\tactiveProperty->description()));\n\t\t}\n\t}\n}\n\nQtnSplitterEventsHandler::QtnSplitterEventsHandler(QObject *parent)\n\t: QObject(parent)\n{\n}\n\nbool QtnSplitterEventsHandler::eventFilter(QObject *obj, QEvent *event)\n{\n\t// check input\n\tif (event->type() != QEvent::MouseButtonDblClick)\n\t\treturn false;\n\n\tQMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);\n\n\tif (mouseEvent->button() != Qt::LeftButton)\n\t\treturn false;\n\n\tQSplitterHandle *splitterHandle = qobject_cast<QSplitterHandle *>(obj);\n\n\tif (!splitterHandle)\n\t\treturn false;\n\n\tQSplitter *splitter = splitterHandle->splitter();\n\n\tif (!splitter || splitter->count() < 2)\n\t\treturn false;\n\n\t// change splitter sizes to make description panel occupy ideal height\n\tQWidget *bottomWidget = splitter->widget(1);\n\tQList<int> sizes = splitter->sizes();\n\n\tif (sizes.size() != 2)\n\t\treturn false;\n\n\tsizes[0] += sizes[1];\n\tsizes[1] = bottomWidget->heightForWidth(bottomWidget->size().width());\n\tsizes[0] -= qMax(sizes[1], 0);\n\n\tsplitter->setSizes(sizes);\n\n\treturn true;\n}\n"
  },
  {
    "path": "QtnProperty/PropertyWidget.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_PROPERTYWIDGET_H\n#define QTN_PROPERTYWIDGET_H\n\n#include \"Config.h\"\n\n#include <QWidget>\n\nenum QtnPropertyWidgetPartsFlag\n{\n\tQtnPropertyWidgetPartsNone = 0x0000,\n\tQtnPropertyWidgetPartsToolbar = 0x0001,\n\tQtnPropertyWidgetPartsDescriptionPanel = 0x0002\n};\n\nclass QtnPropertyView;\nclass QtnPropertySet;\nclass QtnPropertyBase;\nclass QVBoxLayout;\nclass QLabel;\n\nQ_DECLARE_FLAGS(QtnPropertyWidgetParts, QtnPropertyWidgetPartsFlag)\nQ_DECLARE_OPERATORS_FOR_FLAGS(QtnPropertyWidgetParts)\n\nclass QTN_IMPORT_EXPORT QtnPropertyWidget : public QWidget\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnPropertyWidget)\n\npublic:\n\texplicit QtnPropertyWidget(QWidget *parent = 0);\n\tvirtual ~QtnPropertyWidget() override;\n\n\tinline QtnPropertyWidgetParts parts() const;\n\tvoid setParts(QtnPropertyWidgetParts newParts);\n\n\tconst QtnPropertySet *propertySet() const;\n\tQtnPropertySet *propertySet();\n\tvoid setPropertySet(QtnPropertySet *newPropertySet);\n\n\tinline QtnPropertyView *propertyView() const;\n\nsignals:\n\tvoid propertySetChanged();\n\nprivate:\n\tvoid updateParts();\n\tvoid setActiveProperty(const QtnPropertyBase *activeProperty);\n\nprivate:\n\tQtnPropertyWidgetParts m_parts;\n\n\tQVBoxLayout *m_layout;\n\tQLabel *m_toolbar;\n\tQtnPropertyView *m_propertyView;\n\tQWidget *m_descriptionSplitter;\n\tQLabel *m_descriptionPanel;\n};\n\nQtnPropertyWidgetParts QtnPropertyWidget::parts() const\n{\n\treturn m_parts;\n}\n\nQtnPropertyView *QtnPropertyWidget::propertyView() const\n{\n\treturn m_propertyView;\n}\n\n#endif // QTN_PROPERTYWIDGET_H\n"
  },
  {
    "path": "QtnProperty/PropertyWidgetEx.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"PropertyWidgetEx.h\"\n\n#include \"PropertyView.h\"\n#include \"Utils/QtnConnections.h\"\n\n#include <QMouseEvent>\n#include <QApplication>\n#include <QMimeData>\n#include <QDrag>\n#include <QShortcut>\n#include <QClipboard>\n#include <QAction>\n#include <QColor>\n#include <QMenu>\n#include <QContextMenuEvent>\n\nQtnPropertyWidgetEx::QtnPropertyWidgetEx(QWidget *parent)\n\t: QtnPropertyWidget(parent)\n\t, draggedProperty(nullptr)\n\t, mDrag(nullptr)\n\t, dropAction(Qt::IgnoreAction)\n\t, canRemove(false)\n{\n\tsetAcceptDrops(true);\n\tpropertyView()->installEventFilter(this);\n\n\tQObject::connect(propertyView(), &QtnPropertyView::mouseReleased, this,\n\t\t&QtnPropertyWidgetEx::onMouseReleased);\n}\n\nvoid QtnPropertyWidgetEx::connectDeleteAction(QAction *action, bool connect)\n{\n\tinternalConnect(\n\t\taction, &QtnPropertyWidgetEx::deleteActiveProperty, connect);\n}\n\nvoid QtnPropertyWidgetEx::connectCutAction(QAction *action, bool connect)\n{\n\tinternalConnect(action, &QtnPropertyWidgetEx::cutToClipboard, connect);\n}\n\nvoid QtnPropertyWidgetEx::connectCopyAction(QAction *action, bool connect)\n{\n\tinternalConnect(action, &QtnPropertyWidgetEx::copyToClipboard, connect);\n}\n\nvoid QtnPropertyWidgetEx::connectPasteAction(QAction *action, bool connect)\n{\n\tinternalConnect(action, &QtnPropertyWidgetEx::pasteFromClipboard, connect);\n}\n\nbool QtnPropertyWidgetEx::canDeleteActiveProperty()\n{\n\treturn canDeleteProperty(getActiveProperty());\n}\n\nbool QtnPropertyWidgetEx::canDeleteProperty(QtnPropertyBase *)\n{\n\treturn false;\n}\n\nbool QtnPropertyWidgetEx::canCutToClipboard()\n{\n\treturn false;\n}\n\nbool QtnPropertyWidgetEx::canCopyToClipboard()\n{\n\treturn (nullptr != getActiveProperty());\n}\n\nbool QtnPropertyWidgetEx::canPasteFromClipboard()\n{\n\treturn dataHasSupportedFormats(QApplication::clipboard()->mimeData()) &&\n\t\t(nullptr != getActiveProperty());\n}\n\nQtnPropertyBase *QtnPropertyWidgetEx::getActiveProperty() const\n{\n\treturn propertyView()->activeProperty();\n}\n\nvoid QtnPropertyWidgetEx::addShortcutForAction(const QKeySequence &seq,\n\tQAction *action, QWidget *parent, Qt::ShortcutContext shortcutContext)\n{\n\tif (seq.isEmpty())\n\t\treturn;\n\n\tQ_ASSERT(nullptr != action);\n\tQ_ASSERT(nullptr != parent);\n\n\tauto shortcut =\n\t\tnew QShortcut(seq, parent, nullptr, nullptr, shortcutContext);\n\tQObject::connect(\n\t\tshortcut, &QShortcut::activated, action, &QAction::trigger);\n}\n\nvoid QtnPropertyWidgetEx::onMouseReleased()\n{\n\tdraggedProperty = nullptr;\n}\n\nvoid QtnPropertyWidgetEx::onResetTriggered()\n{\n\tauto activeProperty = getActiveProperty();\n\tif (activeProperty && activeProperty->isResettable() &&\n\t\tactiveProperty->isEditableByUser())\n\t{\n\t\tQtnConnections connections;\n\t\tpropertyView()->connectPropertyToEdit(activeProperty, connections);\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonEdit;\n\t\tactiveProperty->reset(reason);\n\t}\n}\n\nvoid QtnPropertyWidgetEx::onLockToggleTriggered()\n{\n\tauto activeProperty = getActiveProperty();\n\tif (activeProperty && activeProperty->isUnlockable() &&\n\t\tactiveProperty->isVisible())\n\t{\n\t\tQtnConnections connections;\n\t\tpropertyView()->connectPropertyToEdit(activeProperty, connections);\n\t\tQtnPropertyChangeReason reason = QtnPropertyChangeReasonEdit;\n\t\tactiveProperty->toggleLock(reason);\n\t}\n}\n\nbool QtnPropertyWidgetEx::dataHasSupportedFormats(const QMimeData *data)\n{\n\tif (nullptr != data)\n\t{\n\t\treturn data->hasText() || data->hasUrls() || data->hasColor();\n\t}\n\n\treturn false;\n}\n\nvoid QtnPropertyWidgetEx::deleteActiveProperty()\n{\n\tdeleteProperty(getActiveProperty());\n}\n\nvoid QtnPropertyWidgetEx::cutToClipboard()\n{\n\tcopyToClipboard();\n\tdeleteActiveProperty();\n}\n\nvoid QtnPropertyWidgetEx::copyToClipboard()\n{\n\tauto property = getActiveProperty();\n\n\tif (nullptr != property)\n\t{\n\t\tauto mime = getPropertyDataForAction(property, Qt::IgnoreAction);\n\n\t\tif (nullptr != mime)\n\t\t\tQApplication::clipboard()->setMimeData(mime);\n\t}\n}\n\nvoid QtnPropertyWidgetEx::pasteFromClipboard()\n{\n\tauto data = QApplication::clipboard()->mimeData();\n\n\tif (dataHasSupportedFormats(data))\n\t{\n\t\tapplyPropertyData(data, getActiveProperty(), QtnApplyPosition::None);\n\t}\n}\n\nvoid QtnPropertyWidgetEx::contextMenuEvent(QContextMenuEvent *event)\n{\n\tauto property = getActiveProperty();\n\tif (!property)\n\t\treturn;\n\n\tauto menu = new QMenu;\n\tint actionCount = 0;\n\n\tif (property->isResettable() && property->isVisible() &&\n\t\t!property->valueIsDefault() &&\n\t\t(!property->isUnlockable() || !property->isLocked()))\n\t{\n\t\tauto action = menu->addAction(tr(\"Reset to default\"));\n\t\taction->setIcon(QtnPropertyDelegate::resetIcon());\n\t\taction->setStatusTip(\n\t\t\ttr(\"Reset value of %1 to default\").arg(property->displayName()));\n\n\t\tQObject::connect(action, &QAction::triggered, this,\n\t\t\t&QtnPropertyWidgetEx::onResetTriggered);\n\n\t\tactionCount++;\n\t}\n\n\tif (property->isUnlockable() && property->isVisible())\n\t{\n\t\tauto action = menu->addAction(\n\t\t\tproperty->isLocked() ? tr(\"Unlock property\") : tr(\"Lock property\"));\n\t\tauto statusFmt = property->isLocked() ? tr(\"Unlock %1\") : tr(\"Lock %1\");\n\t\taction->setStatusTip(statusFmt.arg(property->displayName()));\n\n\t\tQObject::connect(action, &QAction::triggered, this,\n\t\t\t&QtnPropertyWidgetEx::onLockToggleTriggered);\n\n\t\tactionCount++;\n\t}\n\n\tif (actionCount == 0)\n\t{\n\t\tdelete menu;\n\t\treturn;\n\t}\n\n\tmenu->setAttribute(Qt::WA_DeleteOnClose);\n\tmenu->popup(event->globalPos());\n}\n\nvoid QtnPropertyWidgetEx::deleteProperty(QtnPropertyBase *)\n{\n\t// do nothing\n}\n\nQMimeData *QtnPropertyWidgetEx::getPropertyDataForAction(\n\tQtnPropertyBase *property, Qt::DropAction)\n{\n\tQ_ASSERT(nullptr != property);\n\n\tQString str;\n\n\tif (property->toStr(str))\n\t{\n\t\tauto mime = new QMimeData;\n\t\tmime->setText(str);\n\t\treturn mime;\n\t}\n\n\treturn nullptr;\n}\n\nbool QtnPropertyWidgetEx::applyPropertyData(\n\tconst QMimeData *data, QtnPropertyBase *destination, QtnApplyPosition)\n{\n\tif (nullptr != destination && destination->isWritable())\n\t{\n\t\tQtnConnections connections;\n\n\t\tpropertyView()->connectPropertyToEdit(destination, connections);\n\n\t\tQ_ASSERT(nullptr != data);\n\n\t\tQString str;\n\t\tif (data->hasUrls())\n\t\t{\n\t\t\tQStringList list;\n\n\t\t\tfor (auto &url : data->urls())\n\t\t\t{\n\t\t\t\tif (url.isLocalFile())\n\t\t\t\t\tlist.push_back(url.toLocalFile());\n\t\t\t\telse\n\t\t\t\t\tlist.push_back(url.toString());\n\t\t\t}\n\n\t\t\tstr = list.join('\\n');\n\t\t} else if (data->hasColor())\n\t\t{\n\t\t\tauto color = data->colorData().value<QColor>();\n\t\t\tstr = color.name(\n\t\t\t\t(color.alpha() < 255) ? QColor::HexArgb : QColor::HexRgb);\n\t\t} else if (data->hasText())\n\t\t{\n\t\t\tstr = data->text();\n\t\t} else\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\treturn destination->fromStr(str, QtnPropertyChangeReasonEdit);\n\t}\n\n\treturn false;\n}\n\nbool QtnPropertyWidgetEx::eventFilter(QObject *obj, QEvent *event)\n{\n\tswitch (event->type())\n\t{\n\t\tcase QEvent::MouseButtonPress:\n\t\t{\n\t\t\tif (draggedProperty)\n\t\t\t\tbreak;\n\n\t\t\tauto mevent = static_cast<QMouseEvent *>(event);\n\n\t\t\tif (mevent->button() == Qt::LeftButton)\n\t\t\t{\n\t\t\t\tif (propertyView()->isMouseCaptured())\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdragStartPos = mevent->pos();\n\t\t\t\tdraggedProperty = propertyView()->getPropertyAt(dragStartPos);\n\t\t\t\tcanRemove = canDeleteProperty(draggedProperty);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QEvent::MouseMove:\n\t\t{\n\t\t\tif (mDrag)\n\t\t\t\tbreak;\n\n\t\t\tif (propertyView()->isMouseCaptured())\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tauto mevent = static_cast<QMouseEvent *>(event);\n\n\t\t\tif (nullptr != draggedProperty &&\n\t\t\t\t0 != (mevent->buttons() & Qt::LeftButton))\n\t\t\t{\n\t\t\t\tif ((mevent->pos() - dragStartPos).manhattanLength() >=\n\t\t\t\t\tQApplication::startDragDistance())\n\t\t\t\t{\n\t\t\t\t\tdragAndDrop();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn QtnPropertyWidget::eventFilter(obj, event);\n}\n\nvoid QtnPropertyWidgetEx::dragEnterEvent(QDragEnterEvent *event)\n{\n\tif (dataHasSupportedFormats(event->mimeData()))\n\t\tevent->acceptProposedAction();\n}\n\nvoid QtnPropertyWidgetEx::dragMoveEvent(QDragMoveEvent *event)\n{\n\tif (Qt::ControlModifier == QApplication::keyboardModifiers() || !canRemove)\n\t{\n\t\tevent->setDropAction(Qt::CopyAction);\n\t\tdropAction = Qt::CopyAction;\n\t} else\n\t{\n\t\tevent->setDropAction(Qt::MoveAction);\n\t\tdropAction = Qt::MoveAction;\n\t}\n\n\tevent->accept();\n}\n\nvoid QtnPropertyWidgetEx::dropEvent(QDropEvent *event)\n{\n\tswitch (event->dropAction())\n\t{\n\t\tcase Qt::MoveAction:\n\t\tcase Qt::CopyAction:\n\t\t{\n\t\t\tauto view = propertyView();\n\t\t\tauto pos = view->mapFrom(this, event->pos());\n\t\t\tQRect rect;\n\t\t\tauto destination = view->getPropertyAt(pos, &rect);\n\n\t\t\tif (destination == draggedProperty)\n\t\t\t{\n\t\t\t\tdraggedProperty = nullptr;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tQtnApplyPosition applyPosition;\n\n\t\t\tif (destination == nullptr)\n\t\t\t{\n\t\t\t\tapplyPosition = QtnApplyPosition::After;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tint partHeight = view->itemHeight() / 3;\n\n\t\t\t\tif (QRect(rect.left(), rect.top(), rect.width(), partHeight)\n\t\t\t\t\t\t.contains(pos))\n\t\t\t\t\tapplyPosition = QtnApplyPosition::Before;\n\t\t\t\telse if (QRect(rect.left(), rect.bottom() - partHeight,\n\t\t\t\t\t\t\t rect.width(), partHeight)\n\t\t\t\t\t\t\t .contains(pos))\n\t\t\t\t\tapplyPosition = QtnApplyPosition::After;\n\t\t\t\telse\n\t\t\t\t\tapplyPosition = QtnApplyPosition::Over;\n\t\t\t}\n\n\t\t\tauto data = event->mimeData();\n\n\t\t\tif (dataHasSupportedFormats(data) &&\n\t\t\t\tdrop(data, destination, applyPosition))\n\t\t\t{\n\t\t\t\tevent->accept();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nbool QtnPropertyWidgetEx::drop(const QMimeData *data, QtnPropertyBase *property,\n\tQtnApplyPosition applyPosition)\n{\n\treturn applyPropertyData(data, property, applyPosition);\n}\n\nvoid QtnPropertyWidgetEx::dropEnd()\n{\n\tif (nullptr != draggedProperty)\n\t{\n\t\tif (Qt::MoveAction == dropAction)\n\t\t\tdeleteProperty(draggedProperty);\n\t}\n}\n\nvoid QtnPropertyWidgetEx::onDropFinished(Qt::DropAction)\n{\n\tdropEnd();\n\tdraggedProperty = nullptr;\n\tmDrag = nullptr;\n}\n\nbool QtnPropertyWidgetEx::dragAndDrop()\n{\n\tdropAction = Qt::IgnoreAction;\n\tauto data = getPropertyDataForAction(draggedProperty, Qt::CopyAction);\n\n\tif (nullptr != data)\n\t{\n\t\tmDrag = new QDrag(this);\n\n\t\tmDrag->setMimeData(data);\n\n\t\t// TODO generate cursor\n\n#ifdef Q_OS_WASM\n\t\tQObject::connect(mDrag, &QDrag::finished, this,\n\t\t\t&QtnPropertyWidgetEx::onDropFinished);\n\t\tmDrag->exec(Qt::CopyAction | Qt::MoveAction);\n#else\n\t\tonDropFinished(mDrag->exec(Qt::CopyAction | Qt::MoveAction));\n#endif\n\n\t\treturn true;\n\t}\n\n\tdraggedProperty = nullptr;\n\treturn false;\n}\n\nvoid QtnPropertyWidgetEx::internalConnect(\n\tQAction *action, void (QtnPropertyWidgetEx::*slot)(), bool connect)\n{\n\tif (connect)\n\t\tQObject::connect(action, &QAction::triggered, this, slot);\n\telse\n\t\tQObject::disconnect(action, &QAction::triggered, this, slot);\n}\n\nQtnPropertyWidgetExDelegate::~QtnPropertyWidgetExDelegate() {}\n"
  },
  {
    "path": "QtnProperty/PropertyWidgetEx.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"PropertyWidget.h\"\n\nclass QMimeData;\nclass QShortcut;\nclass QDrag;\n\nenum class QtnApplyPosition\n{\n\tNone,\n\tBefore,\n\tOver,\n\tAfter\n};\n\nstruct QTN_IMPORT_EXPORT QtnPropertyWidgetExDelegate\n{\n\tvirtual ~QtnPropertyWidgetExDelegate();\n\n\tvirtual bool canDeleteProperty(QtnPropertyBase *property) = 0;\n\tvirtual bool canCutToClipboard() = 0;\n\tvirtual bool canCopyToClipboard() = 0;\n\tvirtual bool canPasteFromClipboard() = 0;\n\tvirtual bool dataHasSupportedFormats(const QMimeData *data) = 0;\n\tvirtual void deleteProperty(QtnPropertyBase *property) = 0;\n\tvirtual QMimeData *getPropertyDataForAction(\n\t\tQtnPropertyBase *property, Qt::DropAction action) = 0;\n\tvirtual bool applyPropertyData(const QMimeData *data,\n\t\tQtnPropertyBase *destination, QtnApplyPosition position) = 0;\n};\n\nclass QTN_IMPORT_EXPORT QtnPropertyWidgetEx\n\t: public QtnPropertyWidget\n\t, public QtnPropertyWidgetExDelegate\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QtnPropertyWidgetEx(QWidget *parent = nullptr);\n\n\tvoid connectDeleteAction(QAction *dropAction, bool connect);\n\tvoid connectCutAction(QAction *dropAction, bool connect);\n\tvoid connectCopyAction(QAction *dropAction, bool connect);\n\tvoid connectPasteAction(QAction *dropAction, bool connect);\n\n\tbool canDeleteActiveProperty();\n\n\tvirtual bool canDeleteProperty(QtnPropertyBase *property) override;\n\tvirtual bool canCutToClipboard() override;\n\tvirtual bool canCopyToClipboard() override;\n\tvirtual bool canPasteFromClipboard() override;\n\n\tQtnPropertyBase *getActiveProperty() const;\n\n\tstatic void addShortcutForAction(const QKeySequence &seq, QAction *action,\n\t\tQWidget *parent,\n\t\tQt::ShortcutContext shortcutContext = Qt::WidgetWithChildrenShortcut);\n\nprivate:\n\tvoid onMouseReleased();\n\tvoid onResetTriggered();\n\tvoid onLockToggleTriggered();\n\npublic slots:\n\tvoid deleteActiveProperty();\n\tvoid cutToClipboard();\n\tvoid copyToClipboard();\n\tvoid pasteFromClipboard();\n\nprotected:\n\tvirtual void contextMenuEvent(QContextMenuEvent *event) override;\n\n\tvirtual bool dataHasSupportedFormats(const QMimeData *data) override;\n\tvirtual void deleteProperty(QtnPropertyBase *property) override;\n\n\tvirtual QMimeData *getPropertyDataForAction(\n\t\tQtnPropertyBase *property, Qt::DropAction dropAction) override;\n\n\tvirtual bool applyPropertyData(const QMimeData *data,\n\t\tQtnPropertyBase *destination, QtnApplyPosition position) override;\n\n\tvirtual bool eventFilter(QObject *obj, QEvent *event) override;\n\n\tvirtual void dragEnterEvent(QDragEnterEvent *event) override;\n\tvirtual void dragMoveEvent(QDragMoveEvent *event) override;\n\tvirtual void dropEvent(QDropEvent *event) override;\n\tvirtual bool drop(const QMimeData *data, QtnPropertyBase *property,\n\t\tQtnApplyPosition applyPosition);\n\tvirtual void dropEnd();\n\nprivate:\n\tvoid onDropFinished(Qt::DropAction action);\n\tbool dragAndDrop();\n\tvoid internalConnect(\n\t\tQAction *dropAction, void (QtnPropertyWidgetEx::*slot)(), bool connect);\n\n\tQPoint dragStartPos;\n\tQtnPropertyBase *draggedProperty;\n\tQDrag *mDrag;\n\tQt::DropAction dropAction;\n\tbool canRemove;\n};\n"
  },
  {
    "path": "QtnProperty/QObjectPropertySet.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"QObjectPropertySet.h\"\n#include \"PropertyCore.h\"\n#include \"PropertyGUI.h\"\n#include \"PropertyConnector.h\"\n#include \"MultiProperty.h\"\n#include \"IQtnPropertyStateProvider.h\"\n#include \"Install.h\"\n#include \"PropertyDelegateAttrs.h\"\n\n#include <QCoreApplication>\n#include <QMetaObject>\n#include <QMetaProperty>\n#include <QMap>\n#include <QLocale>\n\nstatic QMap<int, QtnMetaPropertyFactory_t> &qtnFactoryMap()\n{\n\tstatic QMap<int, QtnMetaPropertyFactory_t> result;\n\treturn result;\n};\n\nbool qtnRegisterMetaPropertyFactory(\n\tint metaPropertyType, const QtnMetaPropertyFactory_t &factory, bool force)\n{\n\tQ_ASSERT(factory);\n\n\tauto &map = qtnFactoryMap();\n\tif (!force && map.contains(metaPropertyType))\n\t\treturn false;\n\n\tmap.insert(metaPropertyType, factory);\n\treturn true;\n}\n\nQtnPropertyState qtnPropertyStateToAdd(const QMetaProperty &metaProperty)\n{\n\tQtnPropertyState toAdd;\n\n\tif (!metaProperty.isDesignable())\n\t\ttoAdd |= QtnPropertyStateInvisible;\n\n\tif (metaProperty.isConstant() ||\n\t\t(!metaProperty.isWritable() && !metaProperty.isResettable()))\n\t{\n\t\ttoAdd |= QtnPropertyStateImmutable;\n\t}\n\n\treturn toAdd;\n}\n\nvoid qtnUpdatePropertyState(\n\tQtnPropertyBase *property, const QMetaProperty &metaProperty)\n{\n\tproperty->addState(qtnPropertyStateToAdd(metaProperty));\n}\n\nQtnProperty *qtnCreateQObjectProperty(QObject *object,\n\tconst QMetaProperty &metaProperty, bool connect, const char *className)\n{\n\tif (!object)\n\t\treturn nullptr;\n\n\tauto &map = qtnFactoryMap();\n\n\tauto it = map.find(metaProperty.type());\n\n\tif (it == map.end())\n\t\tit = map.find(metaProperty.userType());\n\n\tif (it == map.end())\n\t\treturn nullptr;\n\n\tif (!metaProperty.isDesignable(object) || !metaProperty.isReadable())\n\t\treturn nullptr;\n\n\tQtnProperty *property = it.value()(object, metaProperty);\n\n\tif (!property)\n\t\treturn property;\n\n\tproperty->setName(metaProperty.name());\n\tif (className)\n\t{\n\t\tproperty->setDisplayName(\n\t\t\tQCoreApplication::translate(className, metaProperty.name()));\n\t}\n\n\tauto stateProvider = dynamic_cast<IQtnPropertyStateProvider *>(object);\n\n\tif (nullptr != stateProvider)\n\t{\n\t\tauto state = stateProvider->getPropertyState(metaProperty);\n\t\tproperty->setState(state);\n\t}\n\n\tqtnUpdatePropertyState(property, metaProperty);\n\n\tif (connect)\n\t{\n\t\tauto connector = new QtnPropertyConnector(property);\n\t\tconnector->connectProperty(object, metaProperty);\n\t}\n\n\treturn property;\n}\n\nQtnProperty *qtnCreateQObjectProperty(\n\tQObject *object, const char *propertyName, bool connect)\n{\n\tif (!object)\n\t\treturn nullptr;\n\n\tconst QMetaObject *metaObject = object->metaObject();\n\tint propertyIndex = -1;\n\n\twhile (metaObject)\n\t{\n\t\tpropertyIndex = object->metaObject()->indexOfProperty(propertyName);\n\n\t\tif (propertyIndex != -1)\n\t\t\tbreak;\n\n\t\tmetaObject = metaObject->superClass();\n\t}\n\n\tif (!metaObject)\n\t\treturn nullptr;\n\n\tif (propertyIndex == -1)\n\t\treturn nullptr;\n\n\tQ_ASSERT(propertyIndex >= 0 && propertyIndex < metaObject->propertyCount());\n\n\treturn qtnCreateQObjectProperty(object, metaObject->property(propertyIndex),\n\t\tconnect, metaObject->className());\n}\n\nQtnPropertySet *qtnCreateQObjectPropertySet(QObject *object, bool backwards)\n{\n\tif (!object)\n\t\treturn nullptr;\n\n\t// collect property sets by object's classes\n\tQStringList classNames;\n\tstd::map<QString, QtnPropertySet *> propertySetsByClass;\n\n\tauto metaObject = object->metaObject();\n\n\twhile (nullptr != metaObject)\n\t{\n\t\tif (metaObject->propertyCount() > 0)\n\t\t{\n\t\t\tQList<QtnProperty *> properties;\n\n\t\t\tfor (int propertyIndex = metaObject->propertyOffset(),\n\t\t\t\t\t n = metaObject->propertyCount();\n\t\t\t\t propertyIndex < n; ++propertyIndex)\n\t\t\t{\n\t\t\t\tauto metaProperty = metaObject->property(propertyIndex);\n\t\t\t\tauto property = qtnCreateQObjectProperty(\n\t\t\t\t\tobject, metaProperty, true, metaObject->className());\n\n\t\t\t\tif (nullptr != property)\n\t\t\t\t\tproperties.append(property);\n\t\t\t}\n\n\t\t\tif (!properties.isEmpty())\n\t\t\t{\n\t\t\t\tauto className = QCoreApplication::translate(\n\t\t\t\t\t\"ClassName\", metaObject->className());\n\t\t\t\tauto it = propertySetsByClass.find(className);\n\n\t\t\t\tQtnPropertySet *propertySetByClass;\n\n\t\t\t\tif (it != propertySetsByClass.end())\n\t\t\t\t{\n\t\t\t\t\tpropertySetByClass = it->second;\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tpropertySetByClass = new QtnPropertySet;\n\t\t\t\t\tpropertySetByClass->setName(className);\n\t\t\t\t\tpropertySetsByClass[className] = propertySetByClass;\n\n\t\t\t\t\tclassNames.push_back(className);\n\t\t\t\t}\n\n\t\t\t\tfor (auto property : properties)\n\t\t\t\t{\n\t\t\t\t\tpropertySetByClass->addChildProperty(property);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// move up in class hierarchy\n\t\tmetaObject = metaObject->superClass();\n\t}\n\n\tif (propertySetsByClass.empty())\n\t\treturn nullptr;\n\n\t// move collected property sets to object's property set\n\tauto propertySet = new QtnPropertySet;\n\tpropertySet->setName(object->objectName());\n\n\tint addIndex = backwards ? 0 : -1;\n\n\tfor (auto &class_name : classNames)\n\t{\n\t\tpropertySet->addChildProperty(\n\t\t\tpropertySetsByClass[class_name], true, addIndex);\n\t}\n\n\treturn propertySet;\n}\n\nQtnPropertySet *qtnCreateQObjectMultiPropertySet(\n\tconst std::set<QObject *> &objects, bool backwards)\n{\n\tif (objects.empty())\n\t\treturn nullptr;\n\n\tauto result = new QtnPropertySet(nullptr);\n\n\tfor (auto object : objects)\n\t{\n\t\tauto propertySet = qtnCreateQObjectPropertySet(object, backwards);\n\n\t\tif (nullptr == propertySet)\n\t\t\tcontinue;\n\n\t\tqtnPropertiesToMultiSet(result, propertySet, true);\n\n\t\tdelete propertySet;\n\t}\n\n\treturn result;\n}\n"
  },
  {
    "path": "QtnProperty/QObjectPropertySet.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_QOBJECT_PROPERTY_SET_H\n#define QTN_QOBJECT_PROPERTY_SET_H\n\n#include \"Config.h\"\n#include \"Auxiliary/PropertyAux.h\"\n\n#include <QMetaProperty>\n#include <QVariant>\n\n#include <functional>\n#include <set>\n\nclass QtnPropertyBase;\nclass QtnProperty;\nclass QtnPropertySet;\nstruct QtnPropertyDelegateInfo;\n\ntypedef std::function<QtnProperty *(QObject *, const QMetaProperty &)>\n\tQtnMetaPropertyFactory_t;\nQTN_IMPORT_EXPORT bool qtnRegisterMetaPropertyFactory(int metaPropertyType,\n\tconst QtnMetaPropertyFactory_t &factory, bool force = false);\n\nQTN_IMPORT_EXPORT QtnProperty *qtnCreateQObjectProperty(QObject *object,\n\tconst QMetaProperty &metaProperty, bool connect = false,\n\tconst char *className = nullptr);\nQTN_IMPORT_EXPORT QtnProperty *qtnCreateQObjectProperty(\n\tQObject *object, const char *propertyName, bool connect = false);\nQTN_IMPORT_EXPORT QtnPropertySet *qtnCreateQObjectPropertySet(\n\tQObject *object, bool backwards = false);\nQTN_IMPORT_EXPORT QtnPropertySet *qtnCreateQObjectMultiPropertySet(\n\tconst std::set<QObject *> &objects, bool backwards);\n\nQTN_IMPORT_EXPORT QtnPropertyState qtnPropertyStateToAdd(\n\tconst QMetaProperty &metaProperty);\nQTN_IMPORT_EXPORT void qtnUpdatePropertyState(\n\tQtnPropertyBase *property, const QMetaProperty &metaProperty);\n\ntemplate <typename PropertyCallbackType,\n\ttypename ValueType = typename PropertyCallbackType::ValueTypeStore>\nQtnMetaPropertyFactory_t qtnCreateFactory()\n{\n\tusing CallbackValueType = typename PropertyCallbackType::ValueType;\n\tusing CallbackValueTypeStore =\n\t\ttypename PropertyCallbackType::ValueTypeStore;\n\n\tauto result = [](QObject *object,\n\t\t\t\t\t  const QMetaProperty &metaProperty) -> QtnProperty * {\n\t\tauto property = new PropertyCallbackType(nullptr);\n\n\t\tproperty->setCallbackValueGet(\n\t\t\t[object, metaProperty]() -> CallbackValueTypeStore {\n\t\t\t\tauto variantValue = metaProperty.read(object);\n\t\t\t\treturn CallbackValueTypeStore(variantValue.value<ValueType>());\n\t\t\t});\n\n\t\tproperty->setCallbackValueSet(\n\t\t\t[object, metaProperty](CallbackValueType value, QtnPropertyChangeReason /*reason*/) {\n\t\t\t\tauto variantValue =\n\t\t\t\t\tQVariant::fromValue<ValueType>(ValueType(value));\n\t\t\t\tmetaProperty.write(object, variantValue);\n\t\t\t});\n\n\t\treturn property;\n\t};\n\treturn result;\n}\n\n#endif // QTN_QOBJECT_PROPERTY_SET_H\n"
  },
  {
    "path": "QtnProperty/QObjectPropertyWidget.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"QObjectPropertyWidget.h\"\n\n#include \"QObjectPropertySet.h\"\n#include \"PropertyConnector.h\"\n#include \"MultiProperty.h\"\n#include \"Utils/QtnConnections.h\"\n#include \"PropertySet.h\"\n\nQObjectPropertyWidget::QObjectPropertyWidget(QWidget *parent)\n\t: QtnPropertyWidgetEx(parent)\n\t, mListInheritanceBackwards(true)\n{\n}\n\nvoid QObjectPropertyWidget::setListInheritanceBackwards(bool value)\n{\n\tif (mListInheritanceBackwards == value)\n\t{\n\t\treturn;\n\t}\n\n\tdisconnectObjects();\n\tmListInheritanceBackwards = value;\n\tconnectObjects();\n}\n\nvoid QObjectPropertyWidget::deselectAllObjects()\n{\n\tdisconnectObjects();\n\n\tselectedObjects.clear();\n}\n\nvoid QObjectPropertyWidget::selectObject(QObject *object, bool addSelection)\n{\n\tauto it = selectedObjects.find(object);\n\n\tif (it == selectedObjects.end() ||\n\t\t(!addSelection && selectedObjects.size() > 1))\n\t{\n\t\tif (addSelection)\n\t\t\tdisconnectObjects();\n\t\telse\n\t\t\tdeselectAllObjects();\n\n\t\tselectedObjects.insert(object);\n\n\t\tconnectObjects();\n\t}\n}\n\nvoid QObjectPropertyWidget::selectObjects(\n\tconst Objects &objects, bool addSelection)\n{\n\tif (objects != selectedObjects)\n\t{\n\t\tif (addSelection)\n\t\t{\n\t\t\tdisconnectObjects();\n\n\t\t\tselectedObjects.insert(objects.begin(), objects.end());\n\t\t} else\n\t\t{\n\t\t\tdeselectAllObjects();\n\n\t\t\tselectedObjects = objects;\n\t\t}\n\n\t\tconnectObjects();\n\t}\n}\n\nvoid QObjectPropertyWidget::deselectObject(QObject *object, bool destroyed)\n{\n\tif (destroyed)\n\t\tonObjectDestroyed(object);\n\telse\n\t{\n\t\tauto it = selectedObjects.find(object);\n\n\t\tif (it != selectedObjects.end())\n\t\t{\n\t\t\tdisconnectObjects();\n\n\t\t\tselectedObjects.erase(it);\n\n\t\t\tconnectObjects();\n\t\t}\n\t}\n}\n\nvoid QObjectPropertyWidget::onObjectDestroyed(QObject *object)\n{\n\tauto it = selectedObjects.find(object);\n\n\tif (it != selectedObjects.end())\n\t{\n\t\tselectedObjects.erase(it);\n\n\t\tdisconnectObjects();\n\t\tconnectObjects();\n\t}\n}\n\nQtnMultiProperty *QObjectPropertyWidget::getMultiProperty() const\n{\n\treturn dynamic_cast<QtnMultiProperty *>(getActiveProperty());\n}\n\nQtnPropertyConnector *QObjectPropertyWidget::getPropertyConnector() const\n{\n\tauto property = getActiveProperty();\n\n\tif (nullptr != property)\n\t{\n\t\treturn property->getConnector();\n\t}\n\n\treturn nullptr;\n}\n\nvoid QObjectPropertyWidget::connectObjects()\n{\n\tif (selectedObjects.size() == 1)\n\t{\n\t\tauto object = *selectedObjects.begin();\n\t\tauto set =\n\t\t\tqtnCreateQObjectPropertySet(object, mListInheritanceBackwards);\n\n\t\tif (nullptr != set)\n\t\t\tset->setParent(this);\n\n\t\tsetPropertySet(set);\n\n\t\tconnectObject(object);\n\t} else if (selectedObjects.size() > 1)\n\t{\n\t\tauto set = qtnCreateQObjectMultiPropertySet(\n\t\t\tselectedObjects, mListInheritanceBackwards);\n\n\t\tif (nullptr != set)\n\t\t\tset->setParent(this);\n\n\t\tsetPropertySet(set);\n\n\t\tfor (auto object : selectedObjects)\n\t\t{\n\t\t\tconnectObject(object);\n\t\t}\n\t}\n}\n\nvoid QObjectPropertyWidget::connectObject(QObject *object)\n{\n\tQ_ASSERT(nullptr != object);\n\n\tQObject::connect(object, &QObject::destroyed, this,\n\t\t&QObjectPropertyWidget::onObjectDestroyed);\n}\n\nvoid QObjectPropertyWidget::disconnectObjects()\n{\n\tauto set = propertySet();\n\tsetPropertySet(nullptr);\n\tdelete set;\n\n\tfor (auto object : selectedObjects)\n\t{\n\t\tdisconnectObject(object);\n\t}\n}\n\nvoid QObjectPropertyWidget::disconnectObject(QObject *object)\n{\n\tQ_ASSERT(nullptr != object);\n\n\tQObject::disconnect(object, &QObject::destroyed, this,\n\t\t&QObjectPropertyWidget::onObjectDestroyed);\n}\n"
  },
  {
    "path": "QtnProperty/QObjectPropertyWidget.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"PropertyWidgetEx.h\"\n\n#include <QMetaObject>\n#include <set>\n\nclass QtnPropertyConnector;\n\nclass QtnMultiProperty;\n\nclass QTN_IMPORT_EXPORT QObjectPropertyWidget : public QtnPropertyWidgetEx\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QObjectPropertyWidget(QWidget *parent = nullptr);\n\n\ttypedef std::set<QObject *> Objects;\n\n\tinline const Objects &getSelectedObjects() const;\n\n\tbool isListInheritanceBackwards() const;\n\tvoid setListInheritanceBackwards(bool value);\n\npublic slots:\n\tvoid deselectAllObjects();\n\tvoid selectObject(QObject *object, bool addSelection = true);\n\tvoid selectObjects(const Objects &objects, bool addSelection = true);\n\tvoid deselectObject(QObject *object, bool destroyed = false);\n\nprivate:\n\tvoid onObjectDestroyed(QObject *object);\n\nprotected:\n\tQtnMultiProperty *getMultiProperty() const;\n\tQtnPropertyConnector *getPropertyConnector() const;\n\n\tvoid connectObjects();\n\tvoid disconnectObjects();\n\n\tvoid disconnectObject(QObject *object);\n\tvoid connectObject(QObject *object);\n\n\tObjects selectedObjects;\n\tbool mListInheritanceBackwards;\n};\n\nconst QObjectPropertyWidget::Objects & //\nQObjectPropertyWidget::getSelectedObjects() const\n{\n\treturn selectedObjects;\n}\n\ninline bool QObjectPropertyWidget::isListInheritanceBackwards() const\n{\n\treturn mListInheritanceBackwards;\n}\n"
  },
  {
    "path": "QtnProperty/QtnProperty.pri",
    "content": "\nQT += core gui widgets script\n\nSOURCES +=\\\n    $$PWD/PropertyBase.cpp \\\n    $$PWD/Property.cpp \\\n    $$PWD/PropertySet.cpp \\\n    $$PWD/Enum.cpp \\\n    $$PWD/QObjectPropertySet.cpp \\\n    $$PWD/Core/PropertyBool.cpp \\\n    $$PWD/Core/PropertyInt.cpp \\\n    $$PWD/Core/PropertyUInt.cpp \\\n    $$PWD/Core/PropertyDouble.cpp \\\n    $$PWD/Core/PropertyFloat.cpp \\\n    $$PWD/Core/PropertyQString.cpp \\\n    $$PWD/Core/PropertyQRect.cpp \\\n    $$PWD/Core/PropertyEnum.cpp \\\n    $$PWD/Core/PropertyEnumFlags.cpp \\\n    $$PWD/Core/PropertyQSize.cpp \\\n    $$PWD/Core/PropertyQPoint.cpp \\\n    $$PWD/GUI/PropertyQColor.cpp \\\n    $$PWD/GUI/PropertyQFont.cpp \\\n    $$PWD/GUI/PropertyQBrush.cpp \\\n    $$PWD/GUI/PropertyQPen.cpp \\\n    $$PWD/GUI/PropertyButton.cpp \\\n    $$PWD/PropertyWidget.cpp \\\n    $$PWD/PropertyView.cpp \\\n    $$PWD/Utils/InplaceEditing.cpp \\\n    $$PWD/Delegates/PropertyDelegate.cpp \\\n    $$PWD/Delegates/PropertyDelegateAux.cpp \\\n    $$PWD/Delegates/PropertyDelegateFactory.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateBool.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateInt.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateUInt.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQString.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateDouble.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateFloat.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateEnum.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQRect.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQRectF.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateEnumFlags.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQSize.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQSizeF.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQPoint.cpp \\\n    $$PWD/Delegates/Core/PropertyDelegateQPointF.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateQColor.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateQBrush.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateQPen.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateQFont.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateButton.cpp \\\n    $$PWD/Delegates/Utils/PropertyEditorHandler.cpp \\\n    $$PWD/Delegates/Utils/PropertyEditorAux.cpp \\\n    $$PWD/Delegates/Utils/PropertyDelegateMisc.cpp \\\n    $$PWD/Delegates/Utils/PropertyDelegatePropertySet.cpp \\\n    $$PWD/Delegates/Utils/PropertyDelegateSliderBox.cpp \\\n    $$PWD/Delegates/Utils/PropertyDelegateGeoCoord.cpp \\\n    $$PWD/Delegates/Utils/PropertyDelegateGeoPoint.cpp \\\n    $$PWD/Utils/AccessibilityProxy.cpp \\\n    $$PWD/Utils/DoubleSpinBox.cpp \\\n    $$PWD/Utils/MultilineTextDialog.cpp \\\n    $$PWD/PropertyInt64.cpp \\\n    $$PWD/PropertyUInt64.cpp \\\n    $$PWD/Core/PropertyQRectF.cpp \\\n    $$PWD/Core/PropertyQPointF.cpp \\\n    $$PWD/Core/PropertyQSizeF.cpp \\\n    $$PWD/PropertyWidgetEx.cpp \\\n    $$PWD/CustomPropertyEditorDialog.cpp \\\n    $$PWD/CustomPropertyOptionsDialog.cpp \\\n    $$PWD/VarProperty.cpp \\\n    $$PWD/PropertyQVariant.cpp \\\n    $$PWD/CustomPropertyWidget.cpp \\\n    $$PWD/QObjectPropertyWidget.cpp \\\n    $$PWD/MultiProperty.cpp \\\n    $$PWD/PropertyConnector.cpp \\\n    $$PWD/Utils/QtnConnections.cpp \\\n    $$PWD/Utils/QtnInt64SpinBox.cpp \\\n    $$PWD/Auxiliary/PropertyDelegateInfo.cpp \\\n    $$PWD/PropertyQKeySequence.cpp \\\n    $$PWD/PropertyDelegateMetaEnum.cpp \\\n    $$PWD/Install.cpp \\\n    $$PWD/Utils/QtnCompleterLineEdit.cpp \\\n    $$PWD/Utils/QtnCompleterItemDelegate.cpp \\\n    $$PWD/GUI/PropertyQVector3D.cpp \\\n    $$PWD/Delegates/GUI/PropertyDelegateQVector3D.cpp\n\nHEADERS +=\\\n    $$PWD/PropertyBase.h \\\n    $$PWD/Property.h\\\n    $$PWD/PropertySet.h\\\n    $$PWD/Enum.h\\\n    $$PWD/QObjectPropertySet.h \\\n    $$PWD/PropertyCore.h \\\n    $$PWD/PropertyGUI.h \\\n    $$PWD/Auxiliary/PropertyTemplates.h \\\n    $$PWD/Auxiliary/PropertyMacro.h \\\n    $$PWD/Auxiliary/PropertyAux.h \\\n    $$PWD/Auxiliary/PropertyDelegateInfo.h \\\n    $$PWD/Core/PropertyBool.h \\\n    $$PWD/Core/PropertyInt.h \\\n    $$PWD/Core/PropertyUInt.h \\\n    $$PWD/Core/PropertyDouble.h \\\n    $$PWD/Core/PropertyFloat.h \\\n    $$PWD/Core/PropertyQString.h \\\n    $$PWD/Core/PropertyQRect.h \\\n    $$PWD/Core/PropertyEnum.h \\\n    $$PWD/Core/PropertyEnumFlags.h \\\n    $$PWD/Core/PropertyQSize.h \\\n    $$PWD/Core/PropertyQPoint.h \\\n    $$PWD/GUI/PropertyQColor.h \\\n    $$PWD/GUI/PropertyQFont.h \\\n    $$PWD/GUI/PropertyQBrush.h \\\n    $$PWD/GUI/PropertyQPen.h \\\n    $$PWD/GUI/PropertyButton.h \\\n    $$PWD/PropertyWidget.h \\\n    $$PWD/PropertyView.h \\\n    $$PWD/Utils/InplaceEditing.h \\\n    $$PWD/Delegates/PropertyDelegate.h \\\n    $$PWD/Delegates/PropertyDelegateAux.h \\\n    $$PWD/Delegates/PropertyDelegateFactory.h \\\n    $$PWD/Delegates/Core/PropertyDelegateBool.h \\\n    $$PWD/Delegates/Core/PropertyDelegateInt.h \\\n    $$PWD/Delegates/Core/PropertyDelegateUInt.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQString.h \\\n    $$PWD/Delegates/Core/PropertyDelegateDouble.h \\\n    $$PWD/Delegates/Core/PropertyDelegateFloat.h \\\n    $$PWD/Delegates/Core/PropertyDelegateEnum.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQRect.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQRectF.h \\\n    $$PWD/Delegates/Core/PropertyDelegateEnumFlags.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQSize.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQSizeF.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQPoint.h \\\n    $$PWD/Delegates/Core/PropertyDelegateQPointF.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateQColor.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateQFont.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateQBrush.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateQPen.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateButton.h \\\n    $$PWD/Delegates/Utils/PropertyEditorHandler.h \\\n    $$PWD/Delegates/Utils/PropertyEditorAux.h \\\n    $$PWD/Delegates/Utils/PropertyDelegateMisc.h \\\n    $$PWD/Delegates/Utils/PropertyDelegatePropertySet.h \\\n    $$PWD/Delegates/Utils/PropertyDelegateSliderBox.h \\\n    $$PWD/Delegates/Utils/PropertyDelegateGeoCoord.h \\\n    $$PWD/Delegates/Utils/PropertyDelegateGeoPoint.h \\\n    $$PWD/Utils/AccessibilityProxy.h \\\n    $$PWD/Utils/DoubleSpinBox.h \\\n    $$PWD/Utils/MultilineTextDialog.h \\\n    $$PWD/PropertyInt64.h \\\n    $$PWD/PropertyUInt64.h \\\n    $$PWD/Core/PropertyQRectF.h \\\n    $$PWD/Core/PropertyQPointF.h \\\n    $$PWD/Core/PropertyQSizeF.h \\\n    $$PWD/PropertyWidgetEx.h \\\n    $$PWD/CustomPropertyEditorDialog.h \\\n    $$PWD/CustomPropertyOptionsDialog.h \\\n    $$PWD/VarProperty.h \\\n    $$PWD/PropertyQVariant.h \\\n    $$PWD/CustomPropertyWidget.h \\\n    $$PWD/QObjectPropertyWidget.h \\\n    $$PWD/IQtnPropertyStateProvider.h \\\n    $$PWD/MultiProperty.h \\\n    $$PWD/StructPropertyBase.h \\\n    $$PWD/PropertyConnector.h \\\n    $$PWD/Utils/QtnConnections.h \\\n    $$PWD/Utils/QtnInt64SpinBox.h \\\n    $$PWD/PropertyDelegateAttrs.h \\\n    $$PWD/PropertyQKeySequence.h \\\n    $$PWD/PropertyDelegateMetaEnum.h \\\n    $$PWD/Install.h \\\n    $$PWD/Config.h \\\n    $$PWD/FunctionalHelpers.h \\\n    $$PWD/Utils/QtnCompleterLineEdit.h \\\n    $$PWD/Utils/QtnCompleterItemDelegate.h \\\n    $$PWD/GUI/PropertyQVector3D.h \\\n    $$PWD/Delegates/GUI/PropertyDelegateQVector3D.h\n\nTRANSLATIONS += \\\n    $$PWD/Translations/en.ts \\\n    $$PWD/Translations/ru.ts\n\nfor(tr, TRANSLATIONS):system($$[QT_INSTALL_BINS]/lrelease $${tr})\n\nRESOURCES += $$PWD/QtnProperty.qrc\n\nFORMS += \\\n    $$PWD/CustomPropertyEditorDialog.ui \\\n    $$PWD/CustomPropertyOptionsDialog.ui \\\n    $$PWD/Utils/MultilineTextDialog.ui\n\nINCLUDEPATH += $$PWD/..\n"
  },
  {
    "path": "QtnProperty/QtnProperty.pro",
    "content": "include(../Internal/TargetConfig.pri)\n\nTARGET = QtnProperty\nTEMPLATE = lib\nVERSION = 2.0.3\n\nqtnproperty_dynamic {\n    DEFINES += QTN_DYNAMIC_LIBRARY\n    macx {\n        QMAKE_SONAME_PREFIX = @rpath\n    }\n\n    CONFIG += shared\n} else {\n    CONFIG += static\n}\n\ninclude(./QtnProperty.pri)\n"
  },
  {
    "path": "QtnProperty/QtnProperty.qrc",
    "content": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource lang=\"en\" prefix=\"/Translations\">\n    <file alias=\"QtnProperty.qm\">Translations/en.qm</file>    \n</qresource>\n<qresource lang=\"ru\" prefix=\"/Translations\">\n    <file alias=\"QtnProperty.qm\">Translations/ru.qm</file>    \n</qresource>\n</RCC>"
  },
  {
    "path": "QtnProperty/StructPropertyBase.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Auxiliary/PropertyTemplates.h\"\n\ntemplate <typename FIELD_T, typename CLASS_T, typename SETTER_T>\nvoid qtnSetFieldValue(CLASS_T &to, SETTER_T setter, FIELD_T value,\n\ttypename std::enable_if<\n\t\tstd::is_member_function_pointer<SETTER_T>::value>::type * = nullptr)\n{\n\t(to.*setter)(value);\n}\n\ntemplate <typename FIELD_T, typename CLASS_T, typename SETTER_T>\nvoid qtnSetFieldValue(CLASS_T &to, SETTER_T field, FIELD_T value,\n\ttypename std::enable_if<\n\t\tstd::is_member_object_pointer<SETTER_T>::value>::type * = nullptr)\n{\n\tto.*field = value;\n}\n\ntemplate <typename FIELD_T, typename CLASS_T, typename GETTER_T>\nFIELD_T qtnGetFieldValue(CLASS_T from, GETTER_T getter,\n\ttypename std::enable_if<\n\t\tstd::is_member_function_pointer<GETTER_T>::value>::type * = nullptr)\n{\n\treturn (from.*getter)();\n}\n\ntemplate <typename FIELD_T, typename CLASS_T, typename GETTER_T>\nFIELD_T qtnGetFieldValue(const CLASS_T &from, GETTER_T field,\n\ttypename std::enable_if<\n\t\tstd::is_member_object_pointer<GETTER_T>::value>::type * = nullptr)\n{\n\treturn from.*field;\n}\n\ntemplate <typename FIELD_PROP_T, typename VALUE_T, typename GETTER_T,\n\ttypename SETTER_T>\nFIELD_PROP_T *qtnCreateFieldProperty(QtnSinglePropertyBase<VALUE_T> *property,\n\tGETTER_T getter, SETTER_T setter, const QString &name = QString(),\n\tconst QString &displayName = QString(), const QString &desc_fmt = QString())\n{\n\tusing CallbackValueType = typename FIELD_PROP_T::ValueType;\n\tusing CallbackValueTypeStore = typename FIELD_PROP_T::ValueTypeStore;\n\tusing ValueTypeStore =\n\t\ttypename QtnSinglePropertyBase<VALUE_T>::ValueTypeStore;\n\n\tQ_ASSERT(property);\n\n\tauto result = new FIELD_PROP_T(nullptr);\n\n\tif (!displayName.isEmpty())\n\t\tresult->setDisplayName(displayName);\n\tif (!name.isEmpty())\n\t\tresult->setName(name);\n\tif (!desc_fmt.isEmpty())\n\t\tresult->setDescription(desc_fmt.arg(property->displayName()));\n\n\tresult->setCallbackValueGet([property, getter]() -> CallbackValueTypeStore {\n\t\treturn qtnGetFieldValue<CallbackValueTypeStore>(\n\t\t\tproperty->value(), getter);\n\t});\n\tresult->setCallbackValueSet(\n\t\t[property, setter](CallbackValueType new_value, QtnPropertyChangeReason reason) {\n\t\t\tauto v = property->value();\n\t\t\tqtnSetFieldValue(v, setter, new_value);\n\t\t\tproperty->setValue(v, reason);\n\t\t});\n\n\tif (!property->isQObjectProperty() && property->isResettable())\n\t{\n\t\tresult->addState(QtnPropertyStateResettable);\n\t\tresult->setCallbackValueDefault(\n\t\t\t[property, getter]() -> CallbackValueTypeStore {\n\t\t\t\tValueTypeStore value;\n\t\t\t\tif (!property->readDefaultValue(value))\n\t\t\t\t{\n\t\t\t\t\tvalue = property->value();\n\t\t\t\t}\n\t\t\t\treturn qtnGetFieldValue<CallbackValueTypeStore>(value, getter);\n\t\t\t});\n\t}\n\n\tauto delegateInfoCallback = [property]() -> QtnPropertyDelegateInfo {\n\t\tauto baseDelegate = property->delegateInfo();\n\t\tQtnPropertyDelegateInfo result;\n\t\tif (baseDelegate)\n\t\t{\n\t\t\tresult.attributes = baseDelegate->attributes;\n\t\t\tauto it = result.attributes.find(qtnFieldDelegateNameAttr());\n\t\t\tif (it != result.attributes.end())\n\t\t\t{\n\t\t\t\tresult.name = it.value().toByteArray();\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t};\n\tresult->setDelegateInfoCallback(delegateInfoCallback);\n\treturn result;\n}\n\ntemplate <typename VALUE_T, typename FIELD_PROP_T>\nclass QtnStructPropertyBase : public QtnSinglePropertyBase<VALUE_T>\n{\n\ttypedef QtnSinglePropertyBase<VALUE_T> Inherited;\n\npublic:\n\ttypedef QtnStructPropertyBase ParentClass;\n\n\ttemplate <typename GETTER_T, typename SETTER_T>\n\tinline FIELD_PROP_T *createFieldProperty(GETTER_T getter, SETTER_T setter,\n\t\tconst QString &name = QString(), const QString &displayName = QString(),\n\t\tconst QString &desc_fmt = QString())\n\t{\n\t\treturn qtnCreateFieldProperty<FIELD_PROP_T>(\n\t\t\tthis, getter, setter, name, displayName, desc_fmt);\n\t}\n\nprotected:\n\texplicit QtnStructPropertyBase(QObject *parent)\n\t\t: Inherited(parent)\n\t{\n\t}\n};\n"
  },
  {
    "path": "QtnProperty/Translations/en.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"en_US\">\n<context>\n    <name>BasePropertyDialog</name>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"96\"/>\n        <source>Property with name &apos;%1&apos; is already exist.</source>\n        <translation>Property with name &quot;%1&quot; is already exist.</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyEditorDialog</name>\n    <message>\n        <source>Custom Property Editor</source>\n        <translation type=\"vanished\">Custom Property Editor</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</source>\n        <translation type=\"vanished\">Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</translation>\n    </message>\n    <message>\n        <source>Add Element</source>\n        <translation type=\"vanished\">Add Element</translation>\n    </message>\n    <message>\n        <source>Duplicate Element</source>\n        <translation type=\"vanished\">Duplicate Element</translation>\n    </message>\n    <message>\n        <source>Element Options</source>\n        <translation type=\"vanished\">Element Options</translation>\n    </message>\n    <message>\n        <source>Add...</source>\n        <translation type=\"vanished\">Add...</translation>\n    </message>\n    <message>\n        <source>Add Property...</source>\n        <translation type=\"vanished\">Add Property...</translation>\n    </message>\n    <message>\n        <source>Add Element...</source>\n        <translation type=\"vanished\">Add Element...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"207\"/>\n        <source>New...</source>\n        <translation>New...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"216\"/>\n        <source>New Property...</source>\n        <translation>New Property...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"220\"/>\n        <source>New Element...</source>\n        <translation>New Element...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"253\"/>\n        <source>Edit Custom Properties</source>\n        <translation>Edit Custom Properties</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"252\"/>\n        <source>Read-only Properties</source>\n        <translation>Read-only Properties</translation>\n    </message>\n    <message>\n        <source>Add Child Property...</source>\n        <translation type=\"vanished\">Add Child Property...</translation>\n    </message>\n    <message>\n        <source>Add Child Property</source>\n        <translation type=\"vanished\">Add Child Property</translation>\n    </message>\n    <message>\n        <source>Remove</source>\n        <translation type=\"vanished\">Remove</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"78\"/>\n        <source>Delete</source>\n        <translation>Delete</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"89\"/>\n        <source>Duplicate...</source>\n        <translation>Duplicate...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"97\"/>\n        <source>Options...</source>\n        <translation>Options...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"114\"/>\n        <source>Cut</source>\n        <translation>Cut</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"125\"/>\n        <source>Copy</source>\n        <translation>Copy</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"136\"/>\n        <source>Paste</source>\n        <translation>Paste</translation>\n    </message>\n    <message>\n        <source>Remove Property</source>\n        <translation type=\"vanished\">Remove Property</translation>\n    </message>\n    <message>\n        <source>Duplicate Property</source>\n        <translation type=\"vanished\">Duplicate Property</translation>\n    </message>\n    <message>\n        <source>Property Options</source>\n        <translation type=\"vanished\">Property Options</translation>\n    </message>\n    <message>\n        <source>Add Property</source>\n        <translation type=\"vanished\">Add Property</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyOptionsDialog</name>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"53\"/>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"137\"/>\n        <source>Name:</source>\n        <translation>Name:</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"105\"/>\n        <source>Type</source>\n        <translation>Type</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"111\"/>\n        <source>Numeric</source>\n        <translation>Numeric</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"121\"/>\n        <source>String</source>\n        <translation>String</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"131\"/>\n        <source>Boolean</source>\n        <translation>Boolean</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"138\"/>\n        <source>Dictionary</source>\n        <translation>Dictionary</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"145\"/>\n        <source>List</source>\n        <translation>List</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"152\"/>\n        <source>Null</source>\n        <translation>Null</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"136\"/>\n        <source>Index:</source>\n        <translation>Index:</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyWidget</name>\n    <message>\n        <source>Add Element</source>\n        <translation type=\"vanished\">Add Element</translation>\n    </message>\n    <message>\n        <source>Add Property</source>\n        <translation type=\"vanished\">Add Property</translation>\n    </message>\n    <message>\n        <source>New Element</source>\n        <translation type=\"vanished\">New Element</translation>\n    </message>\n    <message>\n        <source>New Property</source>\n        <translation type=\"vanished\">New Property</translation>\n    </message>\n    <message>\n        <source>Duplicate Element</source>\n        <translation type=\"vanished\">Duplicate Element</translation>\n    </message>\n    <message>\n        <source>Duplicate Property</source>\n        <translation type=\"vanished\">Duplicate Property</translation>\n    </message>\n    <message>\n        <source>Property Options</source>\n        <translation type=\"vanished\">Property Options</translation>\n    </message>\n    <message>\n        <source>Element Options</source>\n        <translation type=\"vanished\">Element Options</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard or to replace the selected one?</source>\n        <translation type=\"vanished\">Do you want to insert new property from clipboard or to replace the selected one?</translation>\n    </message>\n    <message>\n        <source>Insert</source>\n        <comment>Paste</comment>\n        <translation type=\"vanished\">Insert</translation>\n    </message>\n    <message>\n        <source>Replace</source>\n        <comment>Paste</comment>\n        <translation type=\"vanished\">Replace</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</source>\n        <translation type=\"vanished\">Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</translation>\n    </message>\n</context>\n<context>\n    <name>QObjectPropertyWidget</name>\n    <message>\n        <source>Reset to default</source>\n        <translation type=\"vanished\">Reset to default</translation>\n    </message>\n    <message>\n        <source>Reset value of %1 to default</source>\n        <translation type=\"vanished\">Reset value of %1 to default</translation>\n    </message>\n</context>\n<context>\n    <name>Qt</name>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"26\"/>\n        <source>NoPen</source>\n        <translation>Nothing</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"27\"/>\n        <source>SolidLine</source>\n        <translation>Solid Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"28\"/>\n        <source>DashLine</source>\n        <translation>Dash Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"29\"/>\n        <source>DotLine</source>\n        <translation>Dot Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"30\"/>\n        <source>DashDotLine</source>\n        <translation>Dash-Dot Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"31\"/>\n        <source>DashDotDotLine</source>\n        <translation>Dash-Dot-Dot Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"32\"/>\n        <source>CustomDashLine</source>\n        <translation>Custom Dash Line</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"34\"/>\n        <source>FlatCap</source>\n        <translation>Flat Cap</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"35\"/>\n        <source>SquareCap</source>\n        <translation>Square Cap</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"36\"/>\n        <source>RoundCap</source>\n        <translation>Round Cap</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"38\"/>\n        <source>MiterJoin</source>\n        <translation>Miter Join</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"39\"/>\n        <source>BevelJoin</source>\n        <translation>Bevel Join</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"40\"/>\n        <source>RoundJoin</source>\n        <translation>Round Join</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"41\"/>\n        <source>SvgMiterJoin</source>\n        <translation>SVG Miter Join</translation>\n    </message>\n</context>\n<context>\n    <name>QtnCustomPropertyWidget</name>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"145\"/>\n        <source>New Element</source>\n        <translation>New Element</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"152\"/>\n        <source>New Property</source>\n        <translation>New Property</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"192\"/>\n        <source>Duplicate Element</source>\n        <translation>Duplicate Element</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"200\"/>\n        <source>Duplicate Property</source>\n        <translation>Duplicate Property</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"232\"/>\n        <source>Property Options</source>\n        <translation>Property Options</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"243\"/>\n        <source>Element Options</source>\n        <translation>Element Options</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"493\"/>\n        <source>Do you want to insert new property from clipboard or to replace the selected one?</source>\n        <translation>Do you want to insert new property from clipboard or to replace the selected one?</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"498\"/>\n        <source>Insert</source>\n        <comment>Paste</comment>\n        <translation>Insert</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"500\"/>\n        <source>Replace</source>\n        <comment>Paste</comment>\n        <translation>Replace</translation>\n    </message>\n</context>\n<context>\n    <name>QtnMultiProperty</name>\n    <message>\n        <location filename=\"../MultiProperty.cpp\" line=\"115\"/>\n        <source>(Multiple Values)</source>\n        <translation>(Multiple Values)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyBool</name>\n    <message>\n        <location filename=\"../Core/PropertyBool.cpp\" line=\"73\"/>\n        <source>True</source>\n        <translation>True</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyBool.cpp\" line=\"72\"/>\n        <source>False</source>\n        <translation>False</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyEnumFlags</name>\n    <message>\n        <location filename=\"../Core/PropertyEnumFlags.cpp\" line=\"112\"/>\n        <source>%1 flag for %2</source>\n        <translation>%1 flag for %2</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQBrushStyle</name>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"25\"/>\n        <source>NoBrush</source>\n        <translation>Nothing</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"26\"/>\n        <source>Solid</source>\n        <translation>Solid</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"27\"/>\n        <source>Dense1Pattern</source>\n        <translation>Dense1 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"28\"/>\n        <source>Dense2Pattern</source>\n        <translation>Dense 2 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"29\"/>\n        <source>Dense3Pattern</source>\n        <translation>Dense 3 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"30\"/>\n        <source>Dense4Pattern</source>\n        <translation>Dense 4 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"31\"/>\n        <source>Dense5Pattern</source>\n        <translation>Dense 5 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"32\"/>\n        <source>Dense6Pattern</source>\n        <translation>Dense 6 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"33\"/>\n        <source>Dense7Pattern</source>\n        <translation>Dense 7 Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"34\"/>\n        <source>HorPattern</source>\n        <translation>Horizontal Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"35\"/>\n        <source>VerPattern</source>\n        <translation>Vertical Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"36\"/>\n        <source>CrossPattern</source>\n        <translation>Cross Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"37\"/>\n        <source>BDiagPattern</source>\n        <translation>Backward Diagonal Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"38\"/>\n        <source>FDiagPattern</source>\n        <translation>Forward Diagonal Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"39\"/>\n        <source>DiagCrossPattern</source>\n        <translation>Diagonal Cross Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"40\"/>\n        <source>LinearGradientPattern</source>\n        <translation>Linear Gradient Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"42\"/>\n        <source>RadialGradientPattern</source>\n        <translation>Radial Gradient Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"44\"/>\n        <source>ConicalGradientPattern</source>\n        <translation>Conical Gradient Pattern</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"46\"/>\n        <source>TexturePattern</source>\n        <translation>Texture Pattern</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQColor</name>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"124\"/>\n        <source>Red</source>\n        <translation>Red</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"129\"/>\n        <source>Red component of %1</source>\n        <translation>Red component of %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"139\"/>\n        <source>Green</source>\n        <translation>Green</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"144\"/>\n        <source>Green component of %1</source>\n        <translation>Green component of %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"154\"/>\n        <source>Blue</source>\n        <translation>Blue</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"159\"/>\n        <source>Blue component of %1</source>\n        <translation>Blue component of %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQFont</name>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"61\"/>\n        <source>PreferDefault</source>\n        <translation>Default</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"66\"/>\n        <source>NoAntialias</source>\n        <translation>Disabled</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"71\"/>\n        <source>PreferAntialias</source>\n        <translation>Enabled</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"76\"/>\n        <source>Family</source>\n        <translation>Family</translation>\n    </message>\n    <message>\n        <source>Font Family for %1</source>\n        <translation type=\"vanished\">Font Family for %1</translation>\n    </message>\n    <message>\n        <source>PointSize</source>\n        <translation type=\"vanished\">Point size</translation>\n    </message>\n    <message>\n        <source>Point size for %1</source>\n        <translation type=\"vanished\">Point size for %1</translation>\n    </message>\n    <message>\n        <source>Pixels</source>\n        <translation type=\"vanished\">Pixels</translation>\n    </message>\n    <message>\n        <source>Points</source>\n        <translation type=\"vanished\">Points</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"81\"/>\n        <source>Family for %1</source>\n        <translation>Font Family for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"96\"/>\n        <source>Size</source>\n        <translation>Size</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"101\"/>\n        <source>Size for %1</source>\n        <translation>Size for %1</translation>\n    </message>\n    <message>\n        <source>Size Units</source>\n        <translation type=\"vanished\">Size Units</translation>\n    </message>\n    <message>\n        <source>Size units for %1</source>\n        <translation type=\"vanished\">Size units for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"51\"/>\n        <source>Pixel</source>\n        <translation>Pixel</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"56\"/>\n        <source>Point</source>\n        <translation>Point</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"86\"/>\n        <source>Style</source>\n        <translation>Style</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"91\"/>\n        <source>Style for %1</source>\n        <translation>Style for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"106\"/>\n        <source>Size Unit</source>\n        <translation>Size Unit</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"111\"/>\n        <source>Size Unit for %1</source>\n        <translation>Size Unit for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"116\"/>\n        <source>Bold</source>\n        <translation>Bold</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"121\"/>\n        <source>Bold flag for %1</source>\n        <translation>Bold flag for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"126\"/>\n        <source>Italic</source>\n        <translation>Italic</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"131\"/>\n        <source>Italic flag for %1</source>\n        <translation>Italic flag for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"136\"/>\n        <source>Underline</source>\n        <translation>Underline</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"141\"/>\n        <source>Underline flag for %1</source>\n        <translation>Underline flag for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"146\"/>\n        <source>Strikeout</source>\n        <translation>Strikeout</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"151\"/>\n        <source>Strikeout flag for %1</source>\n        <translation>Strikeout flag for %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"156\"/>\n        <source>Kerning</source>\n        <translation>Kerning</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"161\"/>\n        <source>Kerning flag for %1</source>\n        <translation>Kerning flag %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"166\"/>\n        <source>Antialiasing</source>\n        <translation>Antialiasing</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"171\"/>\n        <source>Antialiasing options for %1</source>\n        <translation>Antialiasing options for %1</translation>\n    </message>\n    <message>\n        <source>Antialiasing flag for %1</source>\n        <translation type=\"vanished\">Antialiasing flag for %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPen</name>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"263\"/>\n        <source>(Pen)</source>\n        <translation>(Pen)</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"273\"/>\n        <source>Color</source>\n        <translation>Color</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"278\"/>\n        <source>Color of the %1</source>\n        <translation>Color of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"288\"/>\n        <source>Style</source>\n        <translation>Style</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"293\"/>\n        <source>Style of the %1</source>\n        <translation>Style of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"303\"/>\n        <source>Cap Style</source>\n        <translation>Cap Style</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"308\"/>\n        <source>Cap Style of the %1</source>\n        <translation>Cap Style of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"318\"/>\n        <source>Join Style</source>\n        <translation>Join Style</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"323\"/>\n        <source>Join Style of the %1</source>\n        <translation>Join Style of the %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPoint</name>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"102\"/>\n        <source>X</source>\n        <translation>X</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"107\"/>\n        <source>X of the %1</source>\n        <translation>X of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"122\"/>\n        <source>Y of the %1</source>\n        <translation>Y of the %1</translation>\n    </message>\n    <message>\n        <source>X coordinate of the %1</source>\n        <translation type=\"vanished\">X coordinate of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"117\"/>\n        <source>Y</source>\n        <translation>Y</translation>\n    </message>\n    <message>\n        <source>Y coordinate of the %1</source>\n        <translation type=\"vanished\">Y coordinate of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"92\"/>\n        <source>[%1, %2]</source>\n        <translation>[%1, %2]</translation>\n    </message>\n    <message>\n        <source>%1, %2</source>\n        <translation type=\"vanished\">%1, %2</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPointF</name>\n    <message>\n        <source>X</source>\n        <translation type=\"vanished\">X</translation>\n    </message>\n    <message>\n        <source>X of the %1</source>\n        <translation type=\"vanished\">X of the %1</translation>\n    </message>\n    <message>\n        <source>Y</source>\n        <translation type=\"vanished\">Y</translation>\n    </message>\n    <message>\n        <source>Y of the %1</source>\n        <translation type=\"vanished\">Y of the %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQRect</name>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"155\"/>\n        <source>Left</source>\n        <translation>Left</translation>\n    </message>\n    <message>\n        <source>Left side of the %1</source>\n        <translation type=\"vanished\">Left offset of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"185\"/>\n        <source>Right</source>\n        <translation>Right</translation>\n    </message>\n    <message>\n        <source>Right side of the %1</source>\n        <translation type=\"vanished\">Right offset of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"170\"/>\n        <source>Top</source>\n        <translation>Top</translation>\n    </message>\n    <message>\n        <source>Top of the %1</source>\n        <translation type=\"vanished\">Top offset of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"200\"/>\n        <source>Bottom</source>\n        <translation>Bottom</translation>\n    </message>\n    <message>\n        <source>Bottom of the %1</source>\n        <translation type=\"vanished\">Bottom offset of the %1</translation>\n    </message>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Width</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">Width of the %1</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Height</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">Height of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"145\"/>\n        <source>[(%1, %2), (%3, %4)]</source>\n        <translation>[(%1, %2), (%3, %4)]</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"145\"/>\n        <source>[(%1, %2) %3 x %4]</source>\n        <translation>[(%1, %2) %3 x %4]</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"160\"/>\n        <source>Left position of the %1</source>\n        <translation>Left position of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"175\"/>\n        <source>Top position of the %1</source>\n        <translation>Top position of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"190\"/>\n        <source>Right position of the %1</source>\n        <translation>Right position of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"205\"/>\n        <source>Bottom position of the %1</source>\n        <translation>Bottom position of the %1</translation>\n    </message>\n    <message>\n        <source>(%1, %2) %3 x %4</source>\n        <translation type=\"vanished\">(%1, %2) %3 x %4</translation>\n    </message>\n    <message>\n        <source>(%1, %2), (%3, %4)</source>\n        <translation type=\"vanished\">(%1, %2), (%3, %4)</translation>\n    </message>\n    <message>\n        <source>(%1, %2), %3 x %4</source>\n        <translation type=\"vanished\">(%1, %2), %3 x %4</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQRectF</name>\n    <message>\n        <source>Left</source>\n        <translation type=\"vanished\">Left</translation>\n    </message>\n    <message>\n        <source>Left position of the %1</source>\n        <translation type=\"vanished\">Left position of the %1</translation>\n    </message>\n    <message>\n        <source>Top</source>\n        <translation type=\"vanished\">Top</translation>\n    </message>\n    <message>\n        <source>Top position of the %1</source>\n        <translation type=\"vanished\">Top position of the %1</translation>\n    </message>\n    <message>\n        <source>Right</source>\n        <translation type=\"vanished\">Right</translation>\n    </message>\n    <message>\n        <source>Right position of the %1</source>\n        <translation type=\"vanished\">Right position of the %1</translation>\n    </message>\n    <message>\n        <source>Bottom</source>\n        <translation type=\"vanished\">Bottom</translation>\n    </message>\n    <message>\n        <source>Bottom position of the %1</source>\n        <translation type=\"vanished\">Bottom position of the %1</translation>\n    </message>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Width</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">Width of the %1</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Height</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">Height of the %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQSize</name>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"103\"/>\n        <source>Width</source>\n        <translation>Width</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"108\"/>\n        <source>Width of the %1</source>\n        <translation>Width of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"118\"/>\n        <source>Height</source>\n        <translation>Height</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"123\"/>\n        <source>Height of the %1</source>\n        <translation>Height of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"93\"/>\n        <source>[%1 x %2]</source>\n        <translation>[%1 x %2]</translation>\n    </message>\n    <message>\n        <source>%1 x %2</source>\n        <translation type=\"vanished\">%1 x %2</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQSizeF</name>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Width</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">Width of the %1</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Height</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">Height of the %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQString</name>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"68\"/>\n        <source>(Multiline Text)</source>\n        <translation>(Multiline Text)</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"61\"/>\n        <source>(Empty)</source>\n        <translation>(Empty)</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"78\"/>\n        <source>%1 (Read only)</source>\n        <translation>%1 (Read only)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQVariant</name>\n    <message>\n        <location filename=\"../PropertyQVariant.cpp\" line=\"225\"/>\n        <source>(Dictionary)</source>\n        <translation>(Dictionary)</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyQVariant.cpp\" line=\"229\"/>\n        <source>(List)</source>\n        <translation>(List)</translation>\n    </message>\n    <message>\n        <source>(Empty)</source>\n        <translation type=\"vanished\">(Empty)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQVector3D</name>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"111\"/>\n        <source>Z</source>\n        <translation>Z</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"116\"/>\n        <source>Z of the %1</source>\n        <translation>Z of the %1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"121\"/>\n        <source>[%1, %2, %3]</source>\n        <translation>[%1, %2, %3]</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyView</name>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"153\"/>\n        <source>Lock</source>\n        <translation>📕Lock</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"152\"/>\n        <source>Unlock</source>\n        <translation>📖Unlock</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"275\"/>\n        <source>Click to expand</source>\n        <translation>Click to expand</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"276\"/>\n        <source>Click to collapse</source>\n        <translation>Click to collapse</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateMisc.cpp\" line=\"250\"/>\n        <source>Reset to default value</source>\n        <translation>Reset to default value</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateMisc.cpp\" line=\"256\"/>\n        <source>R</source>\n        <comment>Reset button text</comment>\n        <translation>R</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateSliderBox.cpp\" line=\"67\"/>\n        <source>Drag/Scroll mouse to change value</source>\n        <translation>Drag/Scroll mouse to change value</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyWidgetEx</name>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"202\"/>\n        <source>Reset to default</source>\n        <translation>Reset to default value</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"205\"/>\n        <source>Reset value of %1 to default</source>\n        <translation>Reset value of %1 to default</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"216\"/>\n        <source>Unlock property</source>\n        <translation>📖Unlock property</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"216\"/>\n        <source>Lock property</source>\n        <translation>📕Lock property</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"217\"/>\n        <source>Unlock %1</source>\n        <translation>Unlock %1</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"217\"/>\n        <source>Lock %1</source>\n        <translation>Lock %1</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "QtnProperty/Translations/ru.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"ru_RU\">\n<context>\n    <name>BasePropertyDialog</name>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"96\"/>\n        <source>Property with name &apos;%1&apos; is already exist.</source>\n        <translation>Свойство с именем &quot;%1&quot; уже существует.</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyEditorDialog</name>\n    <message>\n        <source>Custom Property Editor</source>\n        <translation type=\"vanished\">Настраиваемые свойства</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</source>\n        <translation type=\"vanished\">Хотите вставить новое свойство из буфера обмена?\nЕсли вы нажмёте &quot;Нет&quot;, то выбранное свойство будет заменено.</translation>\n    </message>\n    <message>\n        <source>Add Element</source>\n        <translation type=\"vanished\">Добавить элемент</translation>\n    </message>\n    <message>\n        <source>Duplicate Element</source>\n        <translation type=\"vanished\">Дублировать элемент</translation>\n    </message>\n    <message>\n        <source>Element Options</source>\n        <translation type=\"vanished\">Настройки элемента</translation>\n    </message>\n    <message>\n        <source>Add...</source>\n        <translation type=\"vanished\">Добавить...</translation>\n    </message>\n    <message>\n        <source>Add Property...</source>\n        <translation type=\"vanished\">Добавить свойство...</translation>\n    </message>\n    <message>\n        <source>Add Element...</source>\n        <translation type=\"vanished\">Добавить элемент...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"207\"/>\n        <source>New...</source>\n        <translation>Создать...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"216\"/>\n        <source>New Property...</source>\n        <translation>Новое свойство...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"220\"/>\n        <source>New Element...</source>\n        <translation>Новый элемент...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"253\"/>\n        <source>Edit Custom Properties</source>\n        <translation>Редактировать свойства</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.cpp\" line=\"252\"/>\n        <source>Read-only Properties</source>\n        <translation>Свойства только для чтения</translation>\n    </message>\n    <message>\n        <source>Add Child Property...</source>\n        <translation type=\"vanished\">Добавить свойство...</translation>\n    </message>\n    <message>\n        <source>Add Child Property</source>\n        <translation type=\"vanished\">Добавить свойство</translation>\n    </message>\n    <message>\n        <source>Remove</source>\n        <translation type=\"vanished\">Удалить</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"78\"/>\n        <source>Delete</source>\n        <translation>Удалить</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"89\"/>\n        <source>Duplicate...</source>\n        <translation>Дублировать...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"97\"/>\n        <source>Options...</source>\n        <translation>Настройки...</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"114\"/>\n        <source>Cut</source>\n        <translation>Вырезать</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"125\"/>\n        <source>Copy</source>\n        <translation>Копировать</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyEditorDialog.ui\" line=\"136\"/>\n        <source>Paste</source>\n        <translation>Вставить</translation>\n    </message>\n    <message>\n        <source>Remove Property</source>\n        <translation type=\"vanished\">Удалить свойство</translation>\n    </message>\n    <message>\n        <source>Duplicate Property</source>\n        <translation type=\"vanished\">Дублировать свойство</translation>\n    </message>\n    <message>\n        <source>Property Options</source>\n        <translation type=\"vanished\">Настройки свойства</translation>\n    </message>\n    <message>\n        <source>Add Property</source>\n        <translation type=\"vanished\">Добавить свойство</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyOptionsDialog</name>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"53\"/>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"137\"/>\n        <source>Name:</source>\n        <translation>Название:</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"105\"/>\n        <source>Type</source>\n        <translation>Тип</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"111\"/>\n        <source>Numeric</source>\n        <translation>Числовой</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"121\"/>\n        <source>String</source>\n        <translation>Строковый</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"131\"/>\n        <source>Boolean</source>\n        <translation>Логический</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"138\"/>\n        <source>Dictionary</source>\n        <translation>Словарь</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"145\"/>\n        <source>List</source>\n        <translation>Список</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.ui\" line=\"152\"/>\n        <source>Null</source>\n        <translation>Пусто</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyOptionsDialog.cpp\" line=\"136\"/>\n        <source>Index:</source>\n        <translation>Индекс:</translation>\n    </message>\n</context>\n<context>\n    <name>CustomPropertyWidget</name>\n    <message>\n        <source>Add Element</source>\n        <translation type=\"vanished\">Добавить элемент</translation>\n    </message>\n    <message>\n        <source>Add Property</source>\n        <translation type=\"vanished\">Добавить свойство</translation>\n    </message>\n    <message>\n        <source>New Element</source>\n        <translation type=\"vanished\">Новый элемент</translation>\n    </message>\n    <message>\n        <source>New Property</source>\n        <translation type=\"vanished\">Новое свойство</translation>\n    </message>\n    <message>\n        <source>Duplicate Element</source>\n        <translation type=\"vanished\">Дублировать элемент</translation>\n    </message>\n    <message>\n        <source>Duplicate Property</source>\n        <translation type=\"vanished\">Дублировать свойство</translation>\n    </message>\n    <message>\n        <source>Property Options</source>\n        <translation type=\"vanished\">Настройки свойства</translation>\n    </message>\n    <message>\n        <source>Element Options</source>\n        <translation type=\"vanished\">Настройки элемента</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard or to replace the selected one?</source>\n        <translation type=\"vanished\">Хотите вставить новое свойство или заменить выбранное?</translation>\n    </message>\n    <message>\n        <source>Insert</source>\n        <comment>Paste</comment>\n        <translation type=\"vanished\">Вставить</translation>\n    </message>\n    <message>\n        <source>Replace</source>\n        <comment>Paste</comment>\n        <translation type=\"vanished\">Заменить</translation>\n    </message>\n    <message>\n        <source>Do you want to insert new property from clipboard?\nIf you press &apos;No&apos;, selected property will be replaced.</source>\n        <translation type=\"vanished\">Хотите вставить новое свойство из буфера обмена?\nЕсли вы нажмёте &quot;Нет&quot;, то выбранное свойство будет заменено.</translation>\n    </message>\n</context>\n<context>\n    <name>QObjectPropertyWidget</name>\n    <message>\n        <source>Reset to default</source>\n        <translation type=\"vanished\">Сбросить значение</translation>\n    </message>\n    <message>\n        <source>Reset value of %1 to default</source>\n        <translation type=\"vanished\">%1: Установить значение по умолчанию</translation>\n    </message>\n</context>\n<context>\n    <name>Qt</name>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"26\"/>\n        <source>NoPen</source>\n        <translation>Ничего</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"27\"/>\n        <source>SolidLine</source>\n        <translation>Сплошная линия</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"28\"/>\n        <source>DashLine</source>\n        <translation>Штриховой пунктир</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"29\"/>\n        <source>DotLine</source>\n        <translation>Пунктирная линия</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"30\"/>\n        <source>DashDotLine</source>\n        <translation>Смешанный пунктир</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"31\"/>\n        <source>DashDotDotLine</source>\n        <translation>Двойной смешанный пунктир</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"32\"/>\n        <source>CustomDashLine</source>\n        <translation>Настраиваемый пунктир</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"34\"/>\n        <source>FlatCap</source>\n        <translation>Плоская крышка</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"35\"/>\n        <source>SquareCap</source>\n        <translation>Квадратная крышка</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"36\"/>\n        <source>RoundCap</source>\n        <translation>Круглая крышка</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"38\"/>\n        <source>MiterJoin</source>\n        <translation>Угловое соединение</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"39\"/>\n        <source>BevelJoin</source>\n        <translation>Квадратное соединение</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"40\"/>\n        <source>RoundJoin</source>\n        <translation>Круглое соединение</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"41\"/>\n        <source>SvgMiterJoin</source>\n        <translation>Угловое соединение (SWG)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnCustomPropertyWidget</name>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"145\"/>\n        <source>New Element</source>\n        <translation>Новый элемент</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"152\"/>\n        <source>New Property</source>\n        <translation>Новое свойство</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"192\"/>\n        <source>Duplicate Element</source>\n        <translation>Дублировать элемент</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"200\"/>\n        <source>Duplicate Property</source>\n        <translation>Дублировать свойство</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"232\"/>\n        <source>Property Options</source>\n        <translation>Настройки свойства</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"243\"/>\n        <source>Element Options</source>\n        <translation>Настройки элемента</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"493\"/>\n        <source>Do you want to insert new property from clipboard or to replace the selected one?</source>\n        <translation>Хотите вставить новое свойство или заменить выбранное?</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"498\"/>\n        <source>Insert</source>\n        <comment>Paste</comment>\n        <translation>Вставить</translation>\n    </message>\n    <message>\n        <location filename=\"../CustomPropertyWidget.cpp\" line=\"500\"/>\n        <source>Replace</source>\n        <comment>Paste</comment>\n        <translation>Заменить</translation>\n    </message>\n</context>\n<context>\n    <name>QtnMultiProperty</name>\n    <message>\n        <location filename=\"../MultiProperty.cpp\" line=\"115\"/>\n        <source>(Multiple Values)</source>\n        <translation>(Несколько значений)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyBool</name>\n    <message>\n        <location filename=\"../Core/PropertyBool.cpp\" line=\"73\"/>\n        <source>True</source>\n        <translation>Включено</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyBool.cpp\" line=\"72\"/>\n        <source>False</source>\n        <translation>Выключено</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyEnumFlags</name>\n    <message>\n        <location filename=\"../Core/PropertyEnumFlags.cpp\" line=\"112\"/>\n        <source>%1 flag for %2</source>\n        <translation>%2: %1</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQBrushStyle</name>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"25\"/>\n        <source>NoBrush</source>\n        <translation>Нет</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"26\"/>\n        <source>Solid</source>\n        <translation>Сплошная заливка</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"27\"/>\n        <source>Dense1Pattern</source>\n        <translation>Плотный узор №1</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"28\"/>\n        <source>Dense2Pattern</source>\n        <translation>Плотный узор №2</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"29\"/>\n        <source>Dense3Pattern</source>\n        <translation>Плотный узор №3</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"30\"/>\n        <source>Dense4Pattern</source>\n        <translation>Плотный узор №4</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"31\"/>\n        <source>Dense5Pattern</source>\n        <translation>Плотный узор №5</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"32\"/>\n        <source>Dense6Pattern</source>\n        <translation>Плотный узор №6</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"33\"/>\n        <source>Dense7Pattern</source>\n        <translation>Плотный узор №7</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"34\"/>\n        <source>HorPattern</source>\n        <translation>Горизонтальный узор</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"35\"/>\n        <source>VerPattern</source>\n        <translation>Вертикальный узор</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"36\"/>\n        <source>CrossPattern</source>\n        <translation>Узор крестиком</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"37\"/>\n        <source>BDiagPattern</source>\n        <translation>Обратно-диагональный узор</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"38\"/>\n        <source>FDiagPattern</source>\n        <translation>Прямо-диагональный узор</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"39\"/>\n        <source>DiagCrossPattern</source>\n        <translation>Узор диагональным крестиком</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"40\"/>\n        <source>LinearGradientPattern</source>\n        <translation>Линейный градиент</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"42\"/>\n        <source>RadialGradientPattern</source>\n        <translation>Радиальный градиент</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"44\"/>\n        <source>ConicalGradientPattern</source>\n        <translation>Конический градиент</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQBrush.cpp\" line=\"46\"/>\n        <source>TexturePattern</source>\n        <translation>Текстура</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQColor</name>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"124\"/>\n        <source>Red</source>\n        <translation>Красный</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"129\"/>\n        <source>Red component of %1</source>\n        <translation>%1 - красный компонент</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"139\"/>\n        <source>Green</source>\n        <translation>Зелёный</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"144\"/>\n        <source>Green component of %1</source>\n        <translation>%1 - зелёный компонент</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"154\"/>\n        <source>Blue</source>\n        <translation>Синий</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQColor.cpp\" line=\"159\"/>\n        <source>Blue component of %1</source>\n        <translation>%1 - синий компонент</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQFont</name>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"61\"/>\n        <source>PreferDefault</source>\n        <translation>По умолчанию</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"66\"/>\n        <source>NoAntialias</source>\n        <translation>Выключено</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"71\"/>\n        <source>PreferAntialias</source>\n        <translation>Включено</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"76\"/>\n        <source>Family</source>\n        <translation>Семейство</translation>\n    </message>\n    <message>\n        <source>Font Family for %1</source>\n        <translation type=\"vanished\">%1: Семейство шрифтов</translation>\n    </message>\n    <message>\n        <source>PointSize</source>\n        <translation type=\"vanished\">Размер точки</translation>\n    </message>\n    <message>\n        <source>Point size for %1</source>\n        <translation type=\"vanished\">%1: Размер точки</translation>\n    </message>\n    <message>\n        <source>Pixels</source>\n        <translation type=\"vanished\">Пиксели</translation>\n    </message>\n    <message>\n        <source>Points</source>\n        <translation type=\"vanished\">Точки</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"81\"/>\n        <source>Family for %1</source>\n        <translation>%1: Семейство шрифтов</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"96\"/>\n        <source>Size</source>\n        <translation>Размер</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"101\"/>\n        <source>Size for %1</source>\n        <translation>%1: Размер</translation>\n    </message>\n    <message>\n        <source>Size Units</source>\n        <translation type=\"vanished\">Единицы измерения</translation>\n    </message>\n    <message>\n        <source>Size units for %1</source>\n        <translation type=\"vanished\">%1: Единицы измерения размера</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"51\"/>\n        <source>Pixel</source>\n        <translation>Пиксель</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"56\"/>\n        <source>Point</source>\n        <translation>Точка</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"86\"/>\n        <source>Style</source>\n        <translation>Стиль</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"91\"/>\n        <source>Style for %1</source>\n        <translation>%1: Стиль</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"106\"/>\n        <source>Size Unit</source>\n        <translation>Единица измерения</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"111\"/>\n        <source>Size Unit for %1</source>\n        <translation>%1: Единица измерения размера</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"116\"/>\n        <source>Bold</source>\n        <translation>Полужирный</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"121\"/>\n        <source>Bold flag for %1</source>\n        <translation>%1: Будет ли текст полужирным</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"126\"/>\n        <source>Italic</source>\n        <translation>Курсив</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"131\"/>\n        <source>Italic flag for %1</source>\n        <translation>%1: Будет ли текст курсивным</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"136\"/>\n        <source>Underline</source>\n        <translation>Подчёркнутый</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"141\"/>\n        <source>Underline flag for %1</source>\n        <translation>%1: Будет ли текст подчёркнутым</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"146\"/>\n        <source>Strikeout</source>\n        <translation>Зачёркнутый</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"151\"/>\n        <source>Strikeout flag for %1</source>\n        <translation>%1: Будет ли текст зачёркнутым</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"156\"/>\n        <source>Kerning</source>\n        <translation>Кернинг</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"161\"/>\n        <source>Kerning flag for %1</source>\n        <translation>%1: Кернинг</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"166\"/>\n        <source>Antialiasing</source>\n        <translation>Сглаживание</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQFont.cpp\" line=\"171\"/>\n        <source>Antialiasing options for %1</source>\n        <translation>%1: Опции сглаживания</translation>\n    </message>\n    <message>\n        <source>Antialiasing flag for %1</source>\n        <translation type=\"vanished\">%1: Сглаживание</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPen</name>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"263\"/>\n        <source>(Pen)</source>\n        <translation>(Карандаш)</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"273\"/>\n        <source>Color</source>\n        <translation>Цвет</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"278\"/>\n        <source>Color of the %1</source>\n        <translation>%1 - цвет</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"288\"/>\n        <source>Style</source>\n        <translation>Стиль</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"293\"/>\n        <source>Style of the %1</source>\n        <translation>%1 - стиль</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"303\"/>\n        <source>Cap Style</source>\n        <translation>Стиль крышки</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"308\"/>\n        <source>Cap Style of the %1</source>\n        <translation>%1 - стиль крышки</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"318\"/>\n        <source>Join Style</source>\n        <translation>Стиль соединения</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQPen.cpp\" line=\"323\"/>\n        <source>Join Style of the %1</source>\n        <translation>%1 - стиль соединения</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPoint</name>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"102\"/>\n        <source>X</source>\n        <translation>X</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"107\"/>\n        <source>X of the %1</source>\n        <translation>Координата X от &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"122\"/>\n        <source>Y of the %1</source>\n        <translation>Координата Y от &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <source>X coordinate of the %1</source>\n        <translation type=\"vanished\">Координата X точки &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"117\"/>\n        <source>Y</source>\n        <translation>Y</translation>\n    </message>\n    <message>\n        <source>Y coordinate of the %1</source>\n        <translation type=\"vanished\">Координата Y точки &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQPoint.cpp\" line=\"92\"/>\n        <source>[%1, %2]</source>\n        <translation>[%1; %2]</translation>\n    </message>\n    <message>\n        <source>%1, %2</source>\n        <translation type=\"vanished\">%1; %2</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQPointF</name>\n    <message>\n        <source>X</source>\n        <translation type=\"vanished\">X</translation>\n    </message>\n    <message>\n        <source>X of the %1</source>\n        <translation type=\"vanished\">Координата X точки &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <source>Y</source>\n        <translation type=\"vanished\">Y</translation>\n    </message>\n    <message>\n        <source>Y of the %1</source>\n        <translation type=\"vanished\">Координата Y точки &quot;%1&quot;</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQRect</name>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"155\"/>\n        <source>Left</source>\n        <translation>Отступ слева</translation>\n    </message>\n    <message>\n        <source>Left side of the %1</source>\n        <translation type=\"vanished\">Отступ слева для прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"185\"/>\n        <source>Right</source>\n        <translation>Отступ справа</translation>\n    </message>\n    <message>\n        <source>Right side of the %1</source>\n        <translation type=\"vanished\">Отступ справа для прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"170\"/>\n        <source>Top</source>\n        <translation>Отступ сверху</translation>\n    </message>\n    <message>\n        <source>Top of the %1</source>\n        <translation type=\"vanished\">Отступ сверху для прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"200\"/>\n        <source>Bottom</source>\n        <translation>Отступ снизу</translation>\n    </message>\n    <message>\n        <source>Bottom of the %1</source>\n        <translation type=\"vanished\">Отступ снизу для прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Ширина</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">Ширина прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Высота</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">Высота прямоугольника &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"145\"/>\n        <source>[(%1, %2), (%3, %4)]</source>\n        <translation>[(%1; %2), (%3; %4)]</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"145\"/>\n        <source>[(%1, %2) %3 x %4]</source>\n        <translation>[(%1; %2) %3 x %4]</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"160\"/>\n        <source>Left position of the %1</source>\n        <translation>%1: Координата X левой стороны</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"175\"/>\n        <source>Top position of the %1</source>\n        <translation>%1: Координата Y верхней стороны</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"190\"/>\n        <source>Right position of the %1</source>\n        <translation>%1: Координата X правой стороны</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQRect.cpp\" line=\"205\"/>\n        <source>Bottom position of the %1</source>\n        <translation>%1: Координата Y нижней стороны</translation>\n    </message>\n    <message>\n        <source>(%1, %2) %3 x %4</source>\n        <translation type=\"vanished\">(%1; %2) %3 x %4</translation>\n    </message>\n    <message>\n        <source>(%1, %2), (%3, %4)</source>\n        <translation type=\"vanished\">(%1; %2), (%3; %4)</translation>\n    </message>\n    <message>\n        <source>(%1, %2), %3 x %4</source>\n        <translation type=\"vanished\">(%1; %2), %3 x %4</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQRectF</name>\n    <message>\n        <source>Left</source>\n        <translation type=\"vanished\">Слева</translation>\n    </message>\n    <message>\n        <source>Left position of the %1</source>\n        <translation type=\"vanished\">%1: Координата X левой стороны</translation>\n    </message>\n    <message>\n        <source>Top</source>\n        <translation type=\"vanished\">Сверху</translation>\n    </message>\n    <message>\n        <source>Top position of the %1</source>\n        <translation type=\"vanished\">%1: Координата Y верхней стороны</translation>\n    </message>\n    <message>\n        <source>Right</source>\n        <translation type=\"vanished\">Справа</translation>\n    </message>\n    <message>\n        <source>Right position of the %1</source>\n        <translation type=\"vanished\">%1: Координата X правой стороны</translation>\n    </message>\n    <message>\n        <source>Bottom</source>\n        <translation type=\"vanished\">Снизу</translation>\n    </message>\n    <message>\n        <source>Bottom position of the %1</source>\n        <translation type=\"vanished\">%1: Координата Y нижней стороны</translation>\n    </message>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Ширина</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">%1: Ширина</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Высота</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">%1: Высота</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQSize</name>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"103\"/>\n        <source>Width</source>\n        <translation>Ширина</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"108\"/>\n        <source>Width of the %1</source>\n        <translation>%1: Ширина</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"118\"/>\n        <source>Height</source>\n        <translation>Высота</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"123\"/>\n        <source>Height of the %1</source>\n        <translation>%1: Высота</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQSize.cpp\" line=\"93\"/>\n        <source>[%1 x %2]</source>\n        <translation>[%1 x %2]</translation>\n    </message>\n    <message>\n        <source>%1 x %2</source>\n        <translation type=\"vanished\">%1 x %2</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQSizeF</name>\n    <message>\n        <source>Width</source>\n        <translation type=\"vanished\">Ширина</translation>\n    </message>\n    <message>\n        <source>Width of the %1</source>\n        <translation type=\"vanished\">%1: Ширина</translation>\n    </message>\n    <message>\n        <source>Height</source>\n        <translation type=\"vanished\">Высота</translation>\n    </message>\n    <message>\n        <source>Height of the %1</source>\n        <translation type=\"vanished\">%1: Высота</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQString</name>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"68\"/>\n        <source>(Multiline Text)</source>\n        <translation>(Многострочный текст)</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"61\"/>\n        <source>(Empty)</source>\n        <translation>(Пусто)</translation>\n    </message>\n    <message>\n        <location filename=\"../Core/PropertyQString.cpp\" line=\"78\"/>\n        <source>%1 (Read only)</source>\n        <translation>%1 (Только чтение)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQVariant</name>\n    <message>\n        <location filename=\"../PropertyQVariant.cpp\" line=\"225\"/>\n        <source>(Dictionary)</source>\n        <translation>(Словарь)</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyQVariant.cpp\" line=\"229\"/>\n        <source>(List)</source>\n        <translation>(Список)</translation>\n    </message>\n    <message>\n        <source>(Empty)</source>\n        <translation type=\"vanished\">(Пусто)</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyQVector3D</name>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"111\"/>\n        <source>Z</source>\n        <translation>Z</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"116\"/>\n        <source>Z of the %1</source>\n        <translation>Координата Z от &quot;%1&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../GUI/PropertyQVector3D.cpp\" line=\"121\"/>\n        <source>[%1, %2, %3]</source>\n        <translation>[%1; %2; %3]</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyView</name>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"153\"/>\n        <source>Lock</source>\n        <translation>📕Заблокировать</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"152\"/>\n        <source>Unlock</source>\n        <translation>📖Разблокировать</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"275\"/>\n        <source>Click to expand</source>\n        <translation>Щёлкните, чтобы развернуть</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/PropertyDelegate.cpp\" line=\"276\"/>\n        <source>Click to collapse</source>\n        <translation>Щёлкните, чтобы свернуть</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateMisc.cpp\" line=\"250\"/>\n        <source>Reset to default value</source>\n        <translation>Вернуть значение по умолчанию</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateMisc.cpp\" line=\"256\"/>\n        <source>R</source>\n        <comment>Reset button text</comment>\n        <translation>С</translation>\n    </message>\n    <message>\n        <location filename=\"../Delegates/Utils/PropertyDelegateSliderBox.cpp\" line=\"67\"/>\n        <source>Drag/Scroll mouse to change value</source>\n        <translation>Меняйте значение с помощью колёсика или левой кнопки мыши</translation>\n    </message>\n</context>\n<context>\n    <name>QtnPropertyWidgetEx</name>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"202\"/>\n        <source>Reset to default</source>\n        <translation>Сбросить значение</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"205\"/>\n        <source>Reset value of %1 to default</source>\n        <translation>%1: Установить значение по умолчанию</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"216\"/>\n        <source>Unlock property</source>\n        <translation>📖Разблокировать свойство</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"216\"/>\n        <source>Lock property</source>\n        <translation>📕Заблокировать свойство</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"217\"/>\n        <source>Unlock %1</source>\n        <translation>Разблокировать %1</translation>\n    </message>\n    <message>\n        <location filename=\"../PropertyWidgetEx.cpp\" line=\"217\"/>\n        <source>Lock %1</source>\n        <translation>Заблокировать %1</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "QtnProperty/Utils/AccessibilityProxy.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"AccessibilityProxy.h\"\n#include \"QtnProperty/PropertyView.h\"\n#include <QMessageBox>\n\nQtnAccessibilityProxy::QtnAccessibilityProxy(QtnPropertyView *owner)\n\t: QObject(owner)\n\t, m_owner(owner)\n{\n}\n\nQtnPropertyView *QtnAccessibilityProxy::owner()\n{\n\treturn m_owner;\n}\n\nQtnPropertySet *QtnAccessibilityProxy::propertySet()\n{\n\treturn m_owner->propertySet();\n}\n\nQtnPropertyBase *QtnAccessibilityProxy::activeProperty()\n{\n\treturn m_owner->activeProperty();\n}\n\nQtnPropertyBase *QtnAccessibilityProxy::findProperty(QString nameOrPath)\n{\n\tauto root = m_owner->propertySet();\n\n\tif (!root)\n\t\treturn nullptr;\n\n\tauto properties = root->findChildProperties(nameOrPath);\n\n\tif (properties.size() != 1)\n\t\treturn nullptr;\n\n\treturn properties[0];\n}\n\nQtnPropertyBase *QtnAccessibilityProxy::propertyUnderPoint(QPoint point)\n{\n\treturn m_owner->visiblePropertyAtPoint(point);\n}\n\nvoid QtnAccessibilityProxy::ensureVisibleProperty(QtnPropertyBase *property)\n{\n\tif (!property)\n\t\treturn;\n\n\tauto currentProperty = property;\n\n\twhile (true)\n\t{\n\t\tQtnPropertyBase *propertyParent =\n\t\t\tqobject_cast<QtnPropertySet *>(currentProperty->parent());\n\t\tif (!propertyParent)\n\t\t\tpropertyParent = currentProperty->getMasterProperty();\n\t\tif (!propertyParent)\n\t\t\tbreak;\n\t\tpropertyParent->removeState(QtnPropertyStateCollapsed);\n\t\tcurrentProperty = propertyParent;\n\t}\n\n\tm_owner->ensureVisible(property);\n}\n\nQRect QtnAccessibilityProxy::propertyNameRect(QtnPropertyBase *property)\n{\n\tif (!property)\n\t\treturn QRect();\n\n\tint index = m_owner->visibleItemIndexByProperty(property);\n\n\tif (index < 0)\n\t\treturn QRect();\n\n\tQRect rect = m_owner->visibleItemRect(index);\n\trect.setRight(m_owner->splitPosition());\n\treturn rect;\n}\n\nQRect QtnAccessibilityProxy::propertyValueRect(QtnPropertyBase *property)\n{\n\tif (!property)\n\t\treturn QRect();\n\n\tint index = m_owner->visibleItemIndexByProperty(property);\n\n\tif (index < 0)\n\t\treturn QRect();\n\n\tQRect rect = m_owner->visibleItemRect(index);\n\trect.setLeft(m_owner->splitPosition() + 1);\n\treturn rect;\n}\n\nQRect QtnAccessibilityProxy::propertyActionRect(\n\tQtnPropertyBase *property, int actionIndex)\n{\n\treturn m_owner->propertyActionRect(property, actionIndex);\n}\n\nQString QtnAccessibilityProxy::propertyDelegateName(QtnPropertyBase *property)\n{\n\tif (!property)\n\t\treturn QString();\n\n\tif (!property->delegateInfo())\n\t\treturn QString(\"<default>\");\n\n\treturn property->delegateInfo()->name;\n}\n"
  },
  {
    "path": "QtnProperty/Utils/AccessibilityProxy.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef QTN_ACCESSIBILITY_PROXY_H\n#define QTN_ACCESSIBILITY_PROXY_H\n\n#include \"QtnProperty/Config.h\"\n#include \"QtnProperty/PropertySet.h\"\n#include <QObject>\n#include <QRect>\n\nclass QtnPropertyView;\n\nclass QTN_IMPORT_EXPORT QtnAccessibilityProxy : public QObject\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnAccessibilityProxy)\n\npublic:\n\texplicit QtnAccessibilityProxy(QtnPropertyView *owner = 0);\n\npublic slots:\n\tQtnPropertyView *owner();\n\tQtnPropertyBase *activeProperty();\n\tQtnPropertySet *propertySet();\n\tQtnPropertyBase *findProperty(QString nameOrPath);\n\tQtnPropertyBase *propertyUnderPoint(QPoint point);\n\tvoid ensureVisibleProperty(QtnPropertyBase *property);\n\n\tQRect propertyNameRect(QtnPropertyBase *property);\n\tQRect propertyValueRect(QtnPropertyBase *property);\n\tQRect propertyActionRect(QtnPropertyBase *property, int actionIndex);\n\n\tQString propertyDelegateName(QtnPropertyBase *property);\n\nprivate:\n\tQtnPropertyView *m_owner;\n};\n\nQ_DECLARE_METATYPE(QtnAccessibilityProxy *)\n\n#endif // QTN_ACCESSIBILITY_PROXY_H\n"
  },
  {
    "path": "QtnProperty/Utils/DoubleSpinBox.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2020 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"DoubleSpinBox.h\"\n\nQtnDoubleSpinBox::QtnDoubleSpinBox(QWidget *parent)\n\t: QDoubleSpinBox(parent)\n{\n}\n\nQString QtnDoubleSpinBox::textFromValue(double val) const\n{\n\treturn valueToText(val, locale(), decimals(), isGroupSeparatorShown());\n}\n\nQValidator::State QtnDoubleSpinBox::validate(QString& text, int& pos) const\n{\n\tfor (auto& chr : text)\n\t\tif (chr == QLatin1Char('.') || chr == QLatin1Char(','))\n\t\t\tchr = locale().decimalPoint();\n\treturn QDoubleSpinBox::validate(text, pos);\n}\n\nQString QtnDoubleSpinBox::valueToText(\n\tdouble value, const QLocale &locale, int decimals, bool groupSeparatorShown)\n{\n\tif (!qIsFinite(value))\n\t{\n\t\treturn locale.toString(value);\n\t}\n\n\tauto str = QByteArray::number(quint64(qAbs(value)));\n\n\tint i = str.length();\n\tif (!str.startsWith('0'))\n\t{\n\t\ti++;\n\t}\n\n\tint maxDecimals = std::numeric_limits<double>::digits10 - i;\n\tdecimals = std::max(0, std::min(maxDecimals, decimals));\n\n\tstr = QByteArray::number(value, 'f', decimals);\n\tif (decimals >= 2 && decimals == maxDecimals &&\n\t\t(str.endsWith(\"99\") || str.endsWith(\"01\")))\n\t{\n\t\tdecimals--;\n\t}\n\n\tauto result = locale.toString(value, 'f', decimals);\n\tauto decimalPoint = locale.decimalPoint();\n\tauto groupSeparator = locale.groupSeparator();\n\tif (!groupSeparatorShown)\n\t\tresult.remove(groupSeparator);\n\n\ti = result.indexOf(decimalPoint);\n\tif (i >= 0)\n\t{\n\t\tauto zeroDigit = locale.zeroDigit();\n\t\tauto begin = result.constData();\n\t\tauto data = &begin[result.length() - 1];\n\t\tauto decBegin = &begin[i];\n\n\t\twhile (data >= decBegin &&\n\t\t\t(*data == zeroDigit || *data == decimalPoint ||\n\t\t\t\t*data == groupSeparator))\n\t\t{\n\t\t\tdata--;\n\t\t}\n\n\t\tresult.resize(int(data + 1 - begin));\n\t}\n\n\treturn result;\n}\n"
  },
  {
    "path": "QtnProperty/Utils/DoubleSpinBox.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n#pragma once\n\n#include <QDoubleSpinBox>\n\n#include \"QtnProperty/Config.h\"\n\nclass QTN_IMPORT_EXPORT QtnDoubleSpinBox : public QDoubleSpinBox\n{\npublic:\n\texplicit QtnDoubleSpinBox(QWidget *parent = nullptr);\n\n\tvirtual QString textFromValue(double val) const override;\n\tvirtual QValidator::State validate(QString &text, int &pos) const override;\n\n\tstatic QString valueToText(double value, const QLocale &locale = QLocale(),\n\t\tint decimals = 15, bool groupSeparatorShown = false);\n};\n"
  },
  {
    "path": "QtnProperty/Utils/InplaceEditing.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"InplaceEditing.h\"\n#include <QApplication>\n#include <QKeyEvent>\n#include <QDebug>\n\nclass QtnInplaceEditorHandler : public QObject\n{\npublic:\n\tbool eventFilter(QObject *watched, QEvent *event) override;\n\tvoid OnEditorDestroyed(QObject *obj);\n};\n\nstatic unsigned g_inplaceEditorRetainCount = 0;\nstatic QWidget *g_inplaceEditor = 0;\nstatic QtnInplaceEditorHandler *g_inplaceEditorHandler = 0;\n\nbool qtnStartInplaceEdit(QWidget *editor)\n{\n\tif (!editor)\n\t\treturn false;\n\n\tQ_ASSERT(g_inplaceEditorRetainCount == 0);\n\n\tif (g_inplaceEditor)\n\t{\n\t\tqtnStopInplaceEdit(false);\n\t}\n\n\tQ_ASSERT(QCoreApplication::instance());\n\n\tif (editor->objectName().isEmpty())\n\t\teditor->setObjectName(\"QtnPropertyValueEditor\");\n\n\tif (!editor->isVisible())\n\t\teditor->show();\n\n\tg_inplaceEditor = editor;\n\tg_inplaceEditorHandler = new QtnInplaceEditorHandler();\n\n\t// move focus to editor\n\tif (QApplication::focusWidget() != g_inplaceEditor->focusWidget())\n\t\tg_inplaceEditor->setFocus();\n\n\t// connect to editor destroyed signal\n\tQObject::connect(g_inplaceEditor, &QObject::destroyed,\n\t\tg_inplaceEditorHandler, &QtnInplaceEditorHandler::OnEditorDestroyed);\n\n\t// install application event filter\n\tQCoreApplication::instance()->installEventFilter(g_inplaceEditorHandler);\n\n\treturn true;\n}\n\nvoid qtnRetainInplaceEditor()\n{\n\t++g_inplaceEditorRetainCount;\n}\n\nvoid qtnReleaseInplaceEditor()\n{\n\tQ_ASSERT(g_inplaceEditorRetainCount > 0);\n\t--g_inplaceEditorRetainCount;\n}\n\nQWidget *qtnGetInplaceEdit()\n{\n\treturn g_inplaceEditor;\n}\n\nvoid onInplaceWidgetDestroyed(QObject *object)\n{\n\t// set focus to parent of inplace widget\n\tQWidget *parent = qobject_cast<QWidget *>(object->parent());\n\n\tif (parent)\n\t\tparent->setFocus();\n}\n\nbool qtnStopInplaceEdit(bool delete_later, bool restoreParentFocus)\n{\n\tif (!g_inplaceEditor)\n\t\treturn false;\n\n\tif (g_inplaceEditorRetainCount > 0)\n\t\treturn false;\n\n\tdelete g_inplaceEditorHandler;\n\tg_inplaceEditorHandler = nullptr;\n\n\tif (restoreParentFocus)\n\t{\n\t\tQObject::connect(\n\t\t\tg_inplaceEditor, &QObject::destroyed, &onInplaceWidgetDestroyed);\n\t}\n\n\tif (delete_later)\n\t\tg_inplaceEditor->deleteLater();\n\telse\n\t\tdelete g_inplaceEditor;\n\n\tg_inplaceEditor = nullptr;\n\n\treturn true;\n}\n\nbool hasParent(QObject *child, QObject *parent)\n{\n\tif (!child)\n\t\treturn false;\n\n\tif (child == parent)\n\t\treturn true;\n\n\treturn hasParent(child->parent(), parent);\n}\n\nbool QtnInplaceEditorHandler::eventFilter(QObject *watched, QEvent *event)\n{\n\tQ_ASSERT(g_inplaceEditor);\n\n\tif (!event)\n\t\treturn false;\n\n\t// try handle by base class\n\tif (QObject::eventFilter(watched, event))\n\t\treturn true;\n\n\tif (event->type() == QEvent::FocusIn)\n\t{\n\t\tif (!hasParent(QApplication::focusObject(), g_inplaceEditor))\n\t\t\tqtnStopInplaceEdit(true, false);\n\n\t\treturn false;\n\t}\n\n\treturn false;\n}\n\nvoid QtnInplaceEditorHandler::OnEditorDestroyed(QObject *obj)\n{\n\tQ_UNUSED(obj);\n\tQ_ASSERT(obj == g_inplaceEditor);\n\n\tdelete g_inplaceEditorHandler;\n\tg_inplaceEditorHandler = 0;\n\tg_inplaceEditor = 0;\n}\n"
  },
  {
    "path": "QtnProperty/Utils/InplaceEditing.h",
    "content": "/*******************************************************************************\nCopyright (c) 2012-2016 Alex Zhondin <lexxmark.dev@gmail.com>\nCopyright (C) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#ifndef INPLACE_EDITING_H\n#define INPLACE_EDITING_H\n\n#include \"QtnProperty/Config.h\"\n\n#include <QWidget>\n\nQTN_IMPORT_EXPORT void qtnRetainInplaceEditor();\nQTN_IMPORT_EXPORT void qtnReleaseInplaceEditor();\nQTN_IMPORT_EXPORT bool qtnStartInplaceEdit(QWidget *editor);\nQTN_IMPORT_EXPORT QWidget *qtnGetInplaceEdit();\nQTN_IMPORT_EXPORT bool qtnStopInplaceEdit(\n\tbool delete_later = true, bool restoreParentFocus = true);\n\n#endif // INPLACE_EDITING_H\n"
  },
  {
    "path": "QtnProperty/Utils/MultilineTextDialog.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"MultilineTextDialog.h\"\n#include \"ui_MultilineTextDialog.h\"\n\n#include <QAbstractButton>\n\nMultilineTextDialog::MultilineTextDialog(QWidget *parent)\n\t: QDialog(parent)\n\t, ui(new Ui::MultilineTextDialog)\n{\n\tui->setupUi(this);\n\n\tsetWindowFlags((windowFlags() & ~(Qt::WindowContextHelpButtonHint)) |\n\t\tQt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint);\n}\n\nMultilineTextDialog::~MultilineTextDialog()\n{\n\tdelete ui;\n}\n\nvoid MultilineTextDialog::setReadOnly(bool value)\n{\n\tui->plainTextEdit->setReadOnly(value);\n\n\tif (value)\n\t{\n\t\tui->buttonBox->setStandardButtons(QDialogButtonBox::Close);\n\t} else\n\t{\n\t\tui->buttonBox->setStandardButtons(\n\t\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel);\n\t}\n}\n\nvoid MultilineTextDialog::setText(const QString &text)\n{\n\tui->plainTextEdit->setPlainText(text);\n}\n\nQString MultilineTextDialog::getText() const\n{\n\treturn ui->plainTextEdit->toPlainText();\n}\n\nvoid MultilineTextDialog::on_buttonBox_clicked(QAbstractButton *button)\n{\n\tswitch (ui->buttonBox->buttonRole(button))\n\t{\n\t\tcase QDialogButtonBox::AcceptRole:\n\t\t\taccept();\n\t\t\tbreak;\n\n\t\tcase QDialogButtonBox::RejectRole:\n\t\t\treject();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Utils/MultilineTextDialog.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"QtnProperty/Config.h\"\n\n#include <QDialog>\n\nnamespace Ui\n{\nclass MultilineTextDialog;\n}\n\nclass QAbstractButton;\n\nclass QTN_IMPORT_EXPORT MultilineTextDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit MultilineTextDialog(QWidget *parent = nullptr);\n\tvirtual ~MultilineTextDialog();\n\n\tvoid setReadOnly(bool value);\n\n\tvoid setText(const QString &text);\n\tQString getText() const;\n\nprivate slots:\n\tvoid on_buttonBox_clicked(QAbstractButton *button);\n\nprivate:\n\tUi::MultilineTextDialog *ui;\n};\n"
  },
  {
    "path": "QtnProperty/Utils/MultilineTextDialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MultilineTextDialog</class>\n <widget class=\"QDialog\" name=\"MultilineTextDialog\">\n  <property name=\"geometry\">\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>400</width>\n    <height>300</height>\n   </rect>\n  </property>\n  <property name=\"windowTitle\">\n   <string/>\n  </property>\n  <property name=\"sizeGripEnabled\">\n   <bool>true</bool>\n  </property>\n  <property name=\"modal\">\n   <bool>true</bool>\n  </property>\n  <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\n   <property name=\"leftMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"topMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"rightMargin\">\n    <number>6</number>\n   </property>\n   <property name=\"bottomMargin\">\n    <number>6</number>\n   </property>\n   <item>\n    <widget class=\"QPlainTextEdit\" name=\"plainTextEdit\">\n     <property name=\"tabChangesFocus\">\n      <bool>true</bool>\n     </property>\n     <property name=\"lineWrapMode\">\n      <enum>QPlainTextEdit::WidgetWidth</enum>\n     </property>\n    </widget>\n   </item>\n   <item>\n    <widget class=\"QDialogButtonBox\" name=\"buttonBox\">\n     <property name=\"standardButtons\">\n      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>\n     </property>\n     <property name=\"centerButtons\">\n      <bool>false</bool>\n     </property>\n    </widget>\n   </item>\n  </layout>\n </widget>\n <resources/>\n <connections/>\n</ui>\n"
  },
  {
    "path": "QtnProperty/Utils/QtnCompleterItemDelegate.cpp",
    "content": "#include \"QtnCompleterItemDelegate.h\"\n\n#include \"QtnCompleterLineEdit.h\"\n\n#include <QPainter>\n#include <QCompleter>\n\nQtnCompleterItemDelegate::QtnCompleterItemDelegate(\n\tQtnCompleterLineEdit *lineEdit, QObject *parent)\n\t: QStyledItemDelegate(parent)\n\t, mLineEdit(lineEdit)\n{\n\tQ_ASSERT(mLineEdit);\n}\n\nvoid QtnCompleterItemDelegate::paint(QPainter *painter,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\tauto updatedOption = option;\n\tupdatedOption.text.clear();\n\tmLineEdit->style()->drawControl(\n\t\tQStyle::CE_ItemViewItem, &updatedOption, painter, nullptr);\n\tauto completer = mLineEdit->completer();\n\tQ_ASSERT(completer);\n\tswitch (completer->filterMode())\n\t{\n\t\tcase Qt::MatchStartsWith:\n\t\tcase Qt::MatchContains:\n\t\tcase Qt::MatchEndsWith:\n\t\t{\n\t\t\tauto subString = completer->completionPrefix();\n\t\t\tauto currentStr = index.data().toString();\n\t\t\tQFontMetrics fm(updatedOption.font);\n\t\t\tauto textRect = mLineEdit->style()->subElementRect(\n\t\t\t\tQStyle::SE_ItemViewItemText, &updatedOption);\n\t\t\tif (option.displayAlignment & Qt::AlignRight)\n\t\t\t{\n\t\t\t\ttextRect.setRight(textRect.right() -\n\t\t\t\t\tmLineEdit->style()->pixelMetric(\n\t\t\t\t\t\tQStyle::PM_FocusFrameHMargin));\n\t\t\t} else\n\t\t\t{\n\t\t\t\ttextRect.setLeft(textRect.left() +\n\t\t\t\t\tmLineEdit->style()->pixelMetric(\n\t\t\t\t\t\tQStyle::PM_FocusFrameHMargin));\n\t\t\t}\n\t\t\tint flags = Qt::TextSingleLine | int(option.displayAlignment);\n\t\t\tpainter->save();\n\n\t\t\tbool contains = false;\n\t\t\tauto highlightRect = textRect;\n\t\t\tswitch (completer->filterMode())\n\t\t\t{\n\t\t\t\tcase Qt::MatchStartsWith:\n\t\t\t\t\tif (currentStr.startsWith(\n\t\t\t\t\t\t\tsubString, completer->caseSensitivity()))\n\t\t\t\t\t{\n\t\t\t\t\t\thighlightRect.setWidth(fm.width(QString::fromRawData(\n\t\t\t\t\t\t\tcurrentStr.constData(), subString.length())));\n\t\t\t\t\t\tcontains = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Qt::MatchContains:\n\t\t\t\t{\n\t\t\t\t\tint i = currentStr.indexOf(\n\t\t\t\t\t\tsubString, 0, completer->caseSensitivity());\n\t\t\t\t\tif (i >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\thighlightRect.setLeft(highlightRect.left() +\n\t\t\t\t\t\t\tfm.width(QString::fromRawData(\n\t\t\t\t\t\t\t\tcurrentStr.constData(), i)));\n\t\t\t\t\t\thighlightRect.setWidth(fm.width(QString::fromRawData(\n\t\t\t\t\t\t\t&currentStr.constData()[i], subString.length())));\n\t\t\t\t\t\tcontains = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase Qt::MatchEndsWith:\n\t\t\t\t\tif (currentStr.endsWith(\n\t\t\t\t\t\t\tsubString, completer->caseSensitivity()))\n\t\t\t\t\t{\n\t\t\t\t\t\thighlightRect.setLeft(highlightRect.left() +\n\t\t\t\t\t\t\tfm.width(\n\t\t\t\t\t\t\t\tQString::fromRawData(currentStr.constData(),\n\t\t\t\t\t\t\t\t\tcurrentStr.length() - subString.length())));\n\t\t\t\t\t\tcontains = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpainter->setCompositionMode(QPainter::CompositionMode_Difference);\n\t\t\tif (contains)\n\t\t\t{\n\t\t\t\tpainter->setPen(Qt::transparent);\n\t\t\t\tpainter->setBrush(Qt::blue);\n\t\t\t\tpainter->drawRect(highlightRect);\n\t\t\t}\n\t\t\tpainter->setPen(Qt::white);\n\t\t\tpainter->setBrush(Qt::transparent);\n\t\t\tpainter->setFont(option.font);\n\t\t\tpainter->drawText(textRect, flags, currentStr);\n\t\t\tpainter->restore();\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tqWarning(\"Unsupported filter mode\");\n\t\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "QtnProperty/Utils/QtnCompleterItemDelegate.h",
    "content": "#pragma once\n\n#include <QStyledItemDelegate>\n\nclass QtnCompleterLineEdit;\nclass QtnCompleterItemDelegate : public QStyledItemDelegate\n{\n\tQ_OBJECT\n\n\tQtnCompleterLineEdit *mLineEdit;\n\npublic:\n\tQtnCompleterItemDelegate(\n\t\tQtnCompleterLineEdit *lineEdit, QObject *parent = nullptr);\n\n\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n};\n"
  },
  {
    "path": "QtnProperty/Utils/QtnCompleterLineEdit.cpp",
    "content": "#include \"QtnCompleterLineEdit.h\"\n#include \"QtnCompleterItemDelegate.h\"\n\n#include <QCompleter>\n#include <QFocusEvent>\n#include <QKeyEvent>\n#include <QListView>\n#include <QScrollBar>\n\nenum\n{\n\tPOPUP_MARGIN = 6\n};\n\nclass QtnCompleterLineEdit::ListView : public QListView\n{\n\tunsigned disableHide;\n\npublic:\n\tListView();\n\n\tvoid beginDisableHide();\n\tvoid endDisableHide();\n\tvirtual void setVisible(bool) override;\n};\n\nclass QtnCompleterLineEdit::Completer : public QCompleter\n{\n\tQtnCompleterLineEdit *mLineEdit;\n\tListView *mListView;\n\tbool mCompleting;\n\npublic:\n\texplicit Completer(QtnCompleterLineEdit *lineEdit);\n\tvirtual ~Completer() override;\n\n\tvirtual bool eventFilter(QObject *watched, QEvent *event) override;\n\n\tvoid complete();\n};\n\nQtnCompleterLineEdit::QtnCompleterLineEdit(QWidget *parent)\n\t: QLineEdit(parent)\n{\n\tmDefaultItemDelegate = new QtnCompleterItemDelegate(this);\n\tsetCompleter(new Completer(this));\n}\n\nQtnCompleterLineEdit::~QtnCompleterLineEdit()\n{\n\tsetCompleter(nullptr);\n\tdelete mDefaultItemDelegate;\n}\n\nQAbstractItemModel *QtnCompleterLineEdit::completerModel() const\n{\n\treturn completer()->model();\n}\n\nvoid QtnCompleterLineEdit::setCompleterModel(QAbstractItemModel *model)\n{\n\tauto oldModel = completerModel();\n\tif (oldModel == model)\n\t\treturn;\n\n\tif (oldModel)\n\t{\n\t\tQObject::disconnect(oldModel, &QAbstractItemModel::modelReset, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::disconnect(oldModel, &QAbstractItemModel::dataChanged, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::disconnect(oldModel, &QAbstractItemModel::rowsInserted, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::disconnect(oldModel, &QAbstractItemModel::rowsRemoved, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t}\n\n\tif (model)\n\t{\n\t\tQObject::connect(model, &QAbstractItemModel::modelReset, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::connect(model, &QAbstractItemModel::dataChanged, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::connect(model, &QAbstractItemModel::rowsInserted, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t\tQObject::connect(model, &QAbstractItemModel::rowsRemoved, this,\n\t\t\t&QtnCompleterLineEdit::complete);\n\t}\n\n\tcompleter()->setModel(model);\n\tcompleter()->popup()->setItemDelegate(mDefaultItemDelegate);\n}\n\nvoid QtnCompleterLineEdit::complete()\n{\n\tQ_ASSERT(dynamic_cast<Completer *>(this->completer()));\n\tauto completer = static_cast<Completer *>(this->completer());\n\tauto unselectedPrefix = text();\n\tif (selectionStart() >= 0)\n\t\tunselectedPrefix.resize(selectionStart());\n\tauto model = completer->model();\n\tbool hasMatch = false;\n\tfor (int i = 0, count = model->rowCount(); i < count; i++)\n\t{\n\t\tif (model->data(model->index(i, 0))\n\t\t\t\t.toString()\n\t\t\t\t.contains(unselectedPrefix, Qt::CaseInsensitive))\n\t\t{\n\t\t\thasMatch = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!hasMatch)\n\t\tunselectedPrefix.clear();\n\tif (unselectedPrefix != completer->completionPrefix())\n\t{\n\t\tcompleter->setCompletionPrefix(unselectedPrefix);\n\t}\n\tcompleter->complete();\n}\n\nbool QtnCompleterLineEdit::event(QEvent *e)\n{\n\treturn QLineEdit::event(e);\n}\n\nQtnCompleterLineEdit::ListView::ListView()\n\t: disableHide(0)\n{\n\tsetUniformItemSizes(true);\n\tsetLayoutMode(Batched);\n\tsetEditTriggers(NoEditTriggers);\n\tsetResizeMode(Adjust);\n\tsetTextElideMode(Qt::ElideNone);\n\tsetHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);\n\tsetSelectionBehavior(SelectRows);\n\tsetSelectionMode(SingleSelection);\n}\n\ninline void QtnCompleterLineEdit::ListView::beginDisableHide()\n{\n\tdisableHide++;\n}\n\ninline void QtnCompleterLineEdit::ListView::endDisableHide()\n{\n\tdisableHide--;\n}\n\nvoid QtnCompleterLineEdit::ListView::setVisible(bool yes)\n{\n\tif (yes || !disableHide)\n\t\tQListView::setVisible(yes);\n}\n\nQtnCompleterLineEdit::Completer::Completer(QtnCompleterLineEdit *lineEdit)\n\t: QCompleter(lineEdit)\n\t, mLineEdit(nullptr) //do not remove or eventFilter will crash\n\t, mListView(new ListView)\n\t, mCompleting(false)\n{\n\tsetCompletionMode(QCompleter::PopupCompletion);\n\tsetFilterMode(Qt::MatchContains);\n\tsetWrapAround(true);\n\tsetCaseSensitivity(Qt::CaseInsensitive);\n\tsetPopup(mListView);\n\n\tmListView->viewport()->installEventFilter(this);\n\n\tmLineEdit = lineEdit;\n}\n\nQtnCompleterLineEdit::Completer::~Completer()\n{\n\tmListView->viewport()->removeEventFilter(this);\n}\n\nbool QtnCompleterLineEdit::Completer::eventFilter(\n\tQObject *watched, QEvent *event)\n{\n\tif (!mLineEdit)\n\t\treturn QCompleter::eventFilter(watched, event);\n\n\tbool shouldComplete = false;\n\tbool disableHide = false;\n\tbool acceptEvent = false;\n\tbool escapePressed = false;\n\tbool finishEdit = false;\n\tif (!mLineEdit->isReadOnly())\n\t{\n\t\tswitch (event->type())\n\t\t{\n\t\t\tcase QEvent::FocusIn:\n\t\t\t\tshouldComplete = watched == mLineEdit;\n\t\t\t\tbreak;\n\n\t\t\tcase QEvent::MouseButtonPress:\n\t\t\tcase QEvent::MouseButtonRelease:\n\t\t\tcase QEvent::MouseButtonDblClick:\n\t\t\tcase QEvent::MouseMove:\n\t\t\t{\n\t\t\t\tauto me = static_cast<QMouseEvent *>(event);\n\t\t\t\tauto localPos = mLineEdit->mapFromGlobal(me->globalPos());\n\t\t\t\tif (mLineEdit->rect().contains(localPos))\n\t\t\t\t{\n\t\t\t\t\tshouldComplete = !mListView->isVisible();\n\t\t\t\t\tdisableHide = true;\n\t\t\t\t\tif (watched != mLineEdit)\n\t\t\t\t\t{\n\t\t\t\t\t\tme->setLocalPos(localPos);\n\t\t\t\t\t\tmLineEdit->event(event);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (watched != mLineEdit)\n\t\t\t\t{\n\t\t\t\t\tbool outside = !mListView->isVisible() ||\n\t\t\t\t\t\t!mListView->rect().contains(mListView->mapFromGlobal(\n\t\t\t\t\t\t\tstatic_cast<QMouseEvent *>(event)->globalPos()));\n\n\t\t\t\t\tif ((event->type() == QEvent::MouseButtonRelease &&\n\t\t\t\t\t\t\t!outside) ||\n\t\t\t\t\t\t(event->type() == QEvent::MouseButtonPress && outside))\n\t\t\t\t\t{\n\t\t\t\t\t\tacceptEvent = true;\n\t\t\t\t\t\tfinishEdit = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase QEvent::KeyPress:\n\t\t\t{\n\t\t\t\tauto ke = static_cast<QKeyEvent *>(event);\n\t\t\t\tswitch (ke->key())\n\t\t\t\t{\n\t\t\t\t\tcase Qt::Key_Up:\n\t\t\t\t\tcase Qt::Key_Down:\n\t\t\t\t\tcase Qt::Key_PageDown:\n\t\t\t\t\tcase Qt::Key_PageUp:\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase Qt::Key_Left:\n\t\t\t\t\tcase Qt::Key_Right:\n\t\t\t\t\tcase Qt::Key_Home:\n\t\t\t\t\tcase Qt::Key_End:\n\t\t\t\t\t\tacceptEvent = true;\n\t\t\t\t\t\tshouldComplete = true;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase Qt::Key_Tab:\n\t\t\t\t\tcase Qt::Key_Backtab:\n\t\t\t\t\t\tacceptEvent = true;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase Qt::Key_Enter:\n\t\t\t\t\tcase Qt::Key_Return:\n\t\t\t\t\t{\n\t\t\t\t\t\tsetCompletionPrefix(mLineEdit->text());\n\t\t\t\t\t\tacceptEvent = true;\n\t\t\t\t\t\tdisableHide = true;\n\t\t\t\t\t\tshouldComplete = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase Qt::Key_Escape:\n\t\t\t\t\t\tescapePressed = true;\n\t\t\t\t\t\tif (watched == mLineEdit ||\n\t\t\t\t\t\t\t!mListView->selectionModel()->hasSelection())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// fallthrough\n\t\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tacceptEvent = true;\n\t\t\t\t\t\tdisableHide = true;\n\t\t\t\t\t\tshouldComplete = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tif (disableHide)\n\t\tmListView->beginDisableHide();\n\n\tbool result = QCompleter::eventFilter(watched, event);\n\tif (acceptEvent && !result && watched != mLineEdit && event->isAccepted())\n\t{\n\t\twatched->event(event);\n\t\tresult = true;\n\t}\n\n\tif (disableHide)\n\t\tmListView->endDisableHide();\n\n\tif (finishEdit)\n\t{\n\t\tauto index = currentIndex();\n\t\tif (index.isValid())\n\t\t{\n\t\t\temit activated(index);\n\t\t} else\n\t\t{\n\t\t\tQMetaObject::invokeMethod(\n\t\t\t\tmLineEdit, \"editingFinished\", Qt::QueuedConnection);\n\t\t}\n\t} else if (escapePressed)\n\t{\n\t\tif (watched != mLineEdit && mListView->selectionModel()->hasSelection())\n\t\t{\n\t\t\tmListView->clearSelection();\n\t\t} else\n\t\t{\n\t\t\temit mLineEdit->escaped();\n\t\t}\n\t\tresult = true;\n\t} else if (shouldComplete)\n\t{\n\t\tmLineEdit->complete();\n\t}\n\n\treturn result;\n}\n\nvoid QtnCompleterLineEdit::Completer::complete()\n{\n\tif (mCompleting)\n\t\treturn;\n\n\tmCompleting = true;\n\n\tauto popup = this->popup();\n\tQRect rect(0, 0,\n\t\tqMin(popup->maximumWidth(),\n\t\t\tqMax(mLineEdit->width(),\n\t\t\t\tpopup->sizeHintForColumn(0) + POPUP_MARGIN)),\n\t\tmLineEdit->height());\n\n\tint h = popup->sizeHintForRow(0) *\n\t\t\tqMin(maxVisibleItems(), completionModel()->rowCount()) +\n\t\tPOPUP_MARGIN;\n\tpopup->setMinimumHeight(h);\n\tQCompleter::complete(rect);\n\n\tQScrollBar *hsb = popup->horizontalScrollBar();\n\tif (hsb && hsb->isVisible())\n\t\th += popup->horizontalScrollBar()->sizeHint().height();\n\tif (popup->height() < h)\n\t{\n\t\tpopup->setMinimumHeight(h);\n\n\t\tQCompleter::complete(rect);\n\t}\n\n\tmCompleting = false;\n}\n"
  },
  {
    "path": "QtnProperty/Utils/QtnCompleterLineEdit.h",
    "content": "#pragma once\n\n#include \"QtnProperty/Config.h\"\n\n#include <QLineEdit>\n\nclass QAbstractItemModel;\nclass QtnCompleterItemDelegate;\n\nclass QTN_IMPORT_EXPORT QtnCompleterLineEdit : public QLineEdit\n{\n\tQ_OBJECT\n\n\tclass ListView;\n\tclass Completer;\n\tQtnCompleterItemDelegate *mDefaultItemDelegate;\n\npublic:\n\texplicit QtnCompleterLineEdit(QWidget *parent = nullptr);\n\tvirtual ~QtnCompleterLineEdit() override;\n\n\tQAbstractItemModel *completerModel() const;\n\tvoid setCompleterModel(QAbstractItemModel *model);\n\npublic slots:\n\tvoid complete();\n\nsignals:\n\tvoid escaped();\n\nprotected:\n\tvirtual bool event(QEvent *e) override;\n\nprivate:\n\tusing QLineEdit::setCompleter;\n};\n"
  },
  {
    "path": "QtnProperty/Utils/QtnConnections.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"QtnConnections.h\"\n\n#include <QObject>\n\nvoid QtnConnections::disconnect()\n{\n\tfor (auto &connection : *this)\n\t{\n\t\tQObject::disconnect(connection);\n\t}\n\n\tclear();\n}\n\nQtnConnections::QtnConnections() {}\n\nQtnConnections::~QtnConnections()\n{\n\tif (!empty())\n\t\tdisconnect();\n}\n"
  },
  {
    "path": "QtnProperty/Utils/QtnConnections.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"QtnProperty/Config.h\"\n\n#include <QMetaObject>\n\n#include <vector>\n\nclass QTN_IMPORT_EXPORT QtnConnections\n\t: public std::vector<QMetaObject::Connection>\n{\n\tQ_DISABLE_COPY(QtnConnections)\n\npublic:\n\tvoid disconnect();\n\n\tQtnConnections();\n\t~QtnConnections();\n};\n"
  },
  {
    "path": "QtnProperty/Utils/QtnInt64SpinBox.cpp",
    "content": "/*******************************************************************************\nCopyright 2017 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"QtnInt64SpinBox.h\"\n\n#include <QLineEdit>\n#include <QStyleOptionSpinBox>\n#include <QApplication>\n#include <QKeyEvent>\n\nclass QtnInt64SpinBox::Validator : public QValidator\n{\npublic:\n\texplicit Validator(QtnInt64SpinBox *parent);\n\n\tvirtual State validate(QString &input, int &pos) const override;\n\tvirtual void fixup(QString &input) const override;\n\nprivate:\n\tQtnInt64SpinBox *mParent;\n};\n\nQtnInt64SpinBox::QtnInt64SpinBox(QWidget *parent)\n\t: QAbstractSpinBox(parent)\n\t, mValidator(new Validator(this))\n\t, mValue(0)\n\t, mSingleStep(1)\n\t, mMinimum(std::numeric_limits<qint64>::min())\n\t, mMaximum(std::numeric_limits<qint64>::max())\n\t, mDisplayIntegerBase(10)\n\t, mPendingEmit(false)\n\t, mCleared(false)\n\t, mIgnoreCursorPosition(false)\n{\n\tsetInputMethodHints(Qt::ImhDigitsOnly);\n\tauto edit = new QLineEdit(this);\n\tedit->setObjectName(QLatin1String(\"qt_spinbox_lineedit\"));\n\tsetLineEdit(edit);\n}\n\nvoid QtnInt64SpinBox::setPrefix(const QString &prefix)\n{\n\tif (mPrefix != prefix)\n\t{\n\t\tmPrefix = prefix;\n\n\t\tupdateEdit(true);\n\t}\n}\n\nvoid QtnInt64SpinBox::setSuffix(const QString &suffix)\n{\n\tif (mSuffix != suffix)\n\t{\n\t\tmSuffix = suffix;\n\n\t\tupdateEdit(true);\n\t}\n}\n\nQString QtnInt64SpinBox::cleanText() const\n{\n\treturn textFromValue(mValue);\n}\n\nvoid QtnInt64SpinBox::setSingleStep(qint64 val)\n{\n\tmSingleStep = val;\n}\n\nvoid QtnInt64SpinBox::setMinimum(qint64 min)\n{\n\tsetRange(min, mMaximum);\n}\n\nvoid QtnInt64SpinBox::setMaximum(qint64 max)\n{\n\tsetRange(mMinimum, max);\n}\n\nvoid QtnInt64SpinBox::setSpecialValueText(const QString &txt)\n{\n\tif (specialValueText() != txt)\n\t{\n\t\tQAbstractSpinBox::setSpecialValueText(txt);\n\t\tupdateEdit(true);\n\t}\n}\n\nvoid QtnInt64SpinBox::interpretText()\n{\n\tinterpret(EmitIfChanged);\n}\n\nvoid QtnInt64SpinBox::setRange(qint64 min, qint64 max)\n{\n\tif (min > max)\n\t{\n\t\tqSwap(min, max);\n\t}\n\n\tif (mMinimum == min && mMaximum == max)\n\t{\n\t\treturn;\n\t}\n\n\tmMinimum = min;\n\tmMaximum = max;\n\tupdateEdit(true, true);\n}\n\nvoid QtnInt64SpinBox::setDisplayIntegerBase(int base)\n{\n\t// Falls back to base 10 on invalid bases (like QString)\n\tif (Q_UNLIKELY(base < 2 || base > 36))\n\t{\n\t\tqWarning(\n\t\t\t\"QtnInt64SpinBox::setDisplayIntegerBase: Invalid base (%d)\", base);\n\t\tbase = 10;\n\t}\n\n\tif (mDisplayIntegerBase != base)\n\t{\n\t\tmDisplayIntegerBase = base;\n\n\t\tupdateEdit(true);\n\t}\n}\n\nQAbstractSpinBox::StepEnabled QtnInt64SpinBox::stepEnabled() const\n{\n\tif (isReadOnly())\n\t\treturn StepNone;\n\n\tif (wrapping())\n\t\treturn StepDownEnabled | StepUpEnabled;\n\n\tStepEnabled result;\n\n\tif (mValue > mMinimum)\n\t\tresult |= StepDownEnabled;\n\n\tif (mValue < mMaximum)\n\t\tresult |= StepUpEnabled;\n\n\treturn result;\n}\n\nvoid QtnInt64SpinBox::setLineEdit(QLineEdit *lineEdit)\n{\n\tQ_ASSERT(nullptr != lineEdit);\n\n\tif (lineEdit == this->lineEdit())\n\t{\n\t\treturn;\n\t}\n\n\tif (lineEdit)\n\t{\n\t\tconnect(lineEdit, &QLineEdit::textChanged, this,\n\t\t\t&QtnInt64SpinBox::onTextChanged);\n\t\tconnect(lineEdit, &QLineEdit::cursorPositionChanged, this,\n\t\t\t&QtnInt64SpinBox::onCursorPositionChanged);\n\t}\n\n\tQAbstractSpinBox::setLineEdit(lineEdit);\n\n\tlineEdit->setValidator(mValidator);\n\tupdateEdit();\n}\n\nbool QtnInt64SpinBox::isSpecialValue() const\n{\n\treturn mValue == mMinimum && !specialValueText().isEmpty();\n}\n\nvoid QtnInt64SpinBox::clear()\n{\n\tQAbstractSpinBox::clear();\n\n\tlineEdit()->setText(mPrefix + mSuffix);\n\tlineEdit()->setCursorPosition(mPrefix.size());\n\n\tmCleared = true;\n}\n\nQSize QtnInt64SpinBox::sizeHint() const\n{\n\tif (mCachedSizeHint.isEmpty())\n\t{\n\t\tmCachedSizeHint = calcSize(mPrefix + mSuffix + QLatin1Char(' '),\n\t\t\tlineEdit()->sizeHint().height());\n\t}\n\n\treturn mCachedSizeHint;\n}\n\nQSize QtnInt64SpinBox::minimumSizeHint() const\n{\n\tif (mCachedMinimumSizeHint.isEmpty())\n\t{\n\t\tmCachedMinimumSizeHint = calcSize(\n\t\t\tmPrefix + QLatin1Char(' '), lineEdit()->minimumSizeHint().height());\n\t}\n\n\treturn mCachedMinimumSizeHint;\n}\n\nqint64 QtnInt64SpinBox::validateAndInterpret(\n\tQString &input, int *pos, QValidator::State *statePtr) const\n{\n\tint inputSize = input.size();\n\n\tauto copy = input.trimmed();\n\n\tif (copy.startsWith(mPrefix))\n\t\tcopy.remove(0, mPrefix.size());\n\n\tif (copy.endsWith(mSuffix))\n\t\tcopy.resize(copy.size() - mSuffix.size());\n\n\tauto locale = this->locale();\n\n\tQValidator::State state = QValidator::Acceptable;\n\tqint64 num = mMinimum;\n\n\tif (mMinimum != mMaximum &&\n\t\t(copy.isEmpty() || (mMinimum < 0 && copy == QLatin1String(\"-\")) ||\n\t\t\t(mMaximum >= 0 && copy == QLatin1String(\"+\"))))\n\t{\n\t\tstate = QValidator::Intermediate;\n\t} else if (copy.startsWith(QLatin1Char('-')) && mMinimum >= 0)\n\t{\n\t\tstate = QValidator::Invalid;\n\t} else\n\t{\n\t\tbool ok = false;\n\n\t\tif (mDisplayIntegerBase != 10)\n\t\t{\n\t\t\tnum = copy.toLongLong(&ok, mDisplayIntegerBase);\n\t\t} else\n\t\t{\n\t\t\tnum = locale.toLongLong(copy, &ok);\n\n\t\t\tif (!ok && copy.contains(locale.groupSeparator()) &&\n\t\t\t\t(mMaximum >= 1000 || mMinimum <= -1000))\n\t\t\t{\n\t\t\t\tQString copy2 = copy;\n\t\t\t\tcopy2.remove(locale.groupSeparator());\n\t\t\t\tnum = locale.toLongLong(copy2, &ok);\n\t\t\t}\n\t\t}\n\n\t\tif (!ok)\n\t\t{\n\t\t\tstate = QValidator::Invalid;\n\t\t} else if (num >= mMinimum && num <= mMaximum)\n\t\t{\n\t\t\tstate = QValidator::Acceptable;\n\t\t} else if (mMinimum == mMaximum)\n\t\t{\n\t\t\tstate = QValidator::Invalid;\n\t\t} else\n\t\t{\n\t\t\tif ((num >= 0 && num > mMaximum) || (num < 0 && num < mMinimum))\n\t\t\t{\n\t\t\t\tstate = QValidator::Invalid;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tstate = QValidator::Intermediate;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (state != QValidator::Acceptable)\n\t\tnum = mMaximum > 0 ? mMinimum : mMaximum;\n\n\tinput = mPrefix + copy + mSuffix;\n\n\tif (pos)\n\t{\n\t\t(*pos) -= inputSize - input.size();\n\t}\n\n\tif (statePtr)\n\t{\n\t\t*statePtr = state;\n\t}\n\n\treturn num;\n}\n\nQSize QtnInt64SpinBox::calcSize(const QString &fixedContent, int h) const\n{\n\t//Use the prefix and range to calculate the minimumSizeHint\n\tensurePolished();\n\n\tconst QFontMetrics fm(fontMetrics());\n\tint w = 0;\n\n\tQString s;\n\ts = textFromValue(mMinimum);\n\ts.truncate(18);\n\ts += fixedContent;\n\tw = qMax(w, fm.width(s));\n\ts = textFromValue(mMaximum);\n\ts.truncate(18);\n\ts += fixedContent;\n\tw = qMax(w, fm.width(s));\n\n\ts = specialValueText();\n\n\tif (!s.isEmpty())\n\t{\n\t\tw = qMax(w, fm.width(s));\n\t}\n\n\tw += 2; // cursor blinking space\n\n\tQStyleOptionSpinBox opt;\n\tinitStyleOption(&opt);\n\tQSize hint(w, h);\n\n\treturn style()\n\t\t->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)\n\t\t.expandedTo(QApplication::globalStrut());\n}\n\nQValidator::State QtnInt64SpinBox::validate(QString &input, int &pos) const\n{\n\tQValidator::State state;\n\tvalidateAndInterpret(input, &pos, &state);\n\treturn state;\n}\n\nqint64 QtnInt64SpinBox::valueFromText(const QString &text) const\n{\n\tQString copy = text;\n\treturn validateAndInterpret(copy, nullptr, nullptr);\n}\n\nQString QtnInt64SpinBox::textFromValue(qint64 val) const\n{\n\tQString str;\n\n\tif (mDisplayIntegerBase != 10)\n\t{\n\t\tconst QLatin1String prefix =\n\t\t\tval < 0 ? QLatin1String(\"-\") : QLatin1String();\n\t\tstr = prefix + QString::number(qAbs(val), mDisplayIntegerBase);\n\t} else\n\t{\n\t\tstr = locale().toString(val);\n\n\t\tif (!isGroupSeparatorShown())\n\t\t\tstr.remove(locale().groupSeparator());\n\t}\n\n\treturn str;\n}\n\nvoid QtnInt64SpinBox::fixup(QString &str) const\n{\n\tif (!isGroupSeparatorShown())\n\t\tstr.remove(locale().groupSeparator());\n}\n\nvoid QtnInt64SpinBox::stepBy(int steps)\n{\n\tauto old = mValue;\n\n\tQString input = lineEdit()->text();\n\tint pos = lineEdit()->cursorPosition();\n\n\tbool dontStep = false;\n\tEmitPolicy ep = EmitIfChanged;\n\n\tif (mPendingEmit)\n\t{\n\t\tdontStep = validate(input, pos) != QValidator::Acceptable;\n\n\t\tmCleared = false;\n\t\tinterpret(NeverEmit);\n\n\t\tif (mValue != old)\n\t\t{\n\t\t\tep = AlwaysEmit;\n\t\t}\n\t}\n\n\tif (!dontStep)\n\t{\n\t\tqint64 step = mSingleStep * steps;\n\n\t\tqint64 newValue;\n\n\t\tif (step < 0 && quint64(-step) >= quint64(mValue - mMinimum))\n\t\t{\n\t\t\tnewValue = mMinimum;\n\t\t} else if (step > 0 && quint64(step) >= quint64(mMaximum - mValue))\n\t\t{\n\t\t\tnewValue = mMaximum;\n\t\t} else\n\t\t{\n\t\t\tnewValue = mValue + step;\n\t\t}\n\n\t\tsetValue(newValue, ep);\n\t} else if (ep == AlwaysEmit)\n\t{\n\t\temitSignals();\n\t}\n\n\tselectAll();\n}\n\nvoid QtnInt64SpinBox::keyPressEvent(QKeyEvent *event)\n{\n\tif (!event->text().isEmpty() &&\n\t\tlineEdit()->cursorPosition() < mPrefix.size())\n\t{\n\t\tlineEdit()->setCursorPosition(mPrefix.size());\n\t}\n\n\tQAbstractSpinBox::keyPressEvent(event);\n\n\tswitch (event->key())\n\t{\n\t\tcase Qt::Key_Enter:\n\t\tcase Qt::Key_Return:\n\t\t\tinterpret(keyboardTracking() ? AlwaysEmit : EmitIfChanged);\n\t\t\tselectAll();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tif (mCleared && !lineEdit()->text().isEmpty())\n\t{\n\t\tmCleared = false;\n\t}\n}\n\nvoid QtnInt64SpinBox::showEvent(QShowEvent *event)\n{\n\tQAbstractSpinBox::showEvent(event);\n\n\tupdateEdit();\n}\n\nvoid QtnInt64SpinBox::changeEvent(QEvent *event)\n{\n\tQAbstractSpinBox::changeEvent(event);\n\n\tif (event->type() == QEvent::ActivationChange)\n\t{\n\t\tif (!isActiveWindow())\n\t\t{\n\t\t\tif (mPendingEmit)\n\t\t\t\tinterpret(EmitIfChanged);\n\t\t}\n\t}\n}\n\nvoid QtnInt64SpinBox::focusOutEvent(QFocusEvent *event)\n{\n\tQAbstractSpinBox::focusOutEvent(event);\n\n\tif (mPendingEmit)\n\t\tinterpret(EmitIfChanged);\n\n\tupdateEdit();\n}\n\nvoid QtnInt64SpinBox::closeEvent(QCloseEvent *event)\n{\n\tQAbstractSpinBox::closeEvent(event);\n\n\tif (mPendingEmit)\n\t\tinterpret(EmitIfChanged);\n}\n\nvoid QtnInt64SpinBox::hideEvent(QHideEvent *event)\n{\n\tQAbstractSpinBox::hideEvent(event);\n\n\tif (mPendingEmit)\n\t\tinterpret(EmitIfChanged);\n}\n\nvoid QtnInt64SpinBox::updateEdit(bool withGeometry, bool withValue)\n{\n\tif (withValue && !isSpecialValue())\n\t{\n\t\tsetValue(mValue);\n\t} else if (!mCleared)\n\t{\n\t\tauto edit = lineEdit();\n\n\t\tbool isSpecialValue = this->isSpecialValue();\n\n\t\tconst QString newText = isSpecialValue\n\t\t\t? specialValueText()\n\t\t\t: mPrefix + textFromValue(mValue) + mSuffix;\n\n\t\tif (newText == edit->text())\n\t\t\treturn;\n\n\t\tconst bool empty = edit->text().isEmpty();\n\t\tint cursor = edit->cursorPosition();\n\t\tint selectedSize = edit->selectedText().size();\n\t\tconst QSignalBlocker blocker(edit);\n\t\tedit->setText(newText);\n\n\t\tif (!isSpecialValue)\n\t\t{\n\t\t\tcursor = qBound(\n\t\t\t\tmPrefix.size(), cursor, edit->text().size() - mSuffix.size());\n\n\t\t\tif (selectedSize > 0)\n\t\t\t{\n\t\t\t\tedit->setSelection(cursor, selectedSize);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tedit->setCursorPosition(empty ? mPrefix.size() : cursor);\n\t\t\t}\n\t\t}\n\n\t\tupdate();\n\t}\n\n\tif (withGeometry)\n\t{\n\t\tmCachedMinimumSizeHint = QSize();\n\t\tmCachedSizeHint = QSize();\n\t\tupdateGeometry();\n\t}\n}\n\nvoid QtnInt64SpinBox::onTextChanged(const QString &text)\n{\n\tmPendingEmit = true;\n\n\tif (keyboardTracking())\n\t{\n\t\tQString input = text;\n\t\tint pos = lineEdit()->cursorPosition();\n\t\tQValidator::State state = validate(input, pos);\n\n\t\tif (state == QValidator::Acceptable)\n\t\t{\n\t\t\tsetValue(valueFromText(input));\n\t\t\tmPendingEmit = false;\n\t\t}\n\t}\n}\n\nvoid QtnInt64SpinBox::onCursorPositionChanged(int oldPos, int newPos)\n{\n\tauto edit = lineEdit();\n\n\tif (!edit->hasSelectedText() && !mIgnoreCursorPosition && !isSpecialValue())\n\t{\n\t\tmIgnoreCursorPosition = true;\n\n\t\tbool allowSelection = true;\n\t\tint pos = -1;\n\n\t\tif (newPos < mPrefix.size() && newPos != 0)\n\t\t{\n\t\t\tif (oldPos == 0)\n\t\t\t{\n\t\t\t\tallowSelection = false;\n\t\t\t\tpos = mPrefix.size();\n\t\t\t} else\n\t\t\t{\n\t\t\t\tpos = oldPos;\n\t\t\t}\n\t\t} else if (newPos > edit->text().size() - mSuffix.size() &&\n\t\t\tnewPos != edit->text().size())\n\t\t{\n\t\t\tif (oldPos == edit->text().size())\n\t\t\t{\n\t\t\t\tpos = edit->text().size() - mSuffix.size();\n\t\t\t\tallowSelection = false;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tpos = edit->text().size();\n\t\t\t}\n\t\t}\n\n\t\tif (pos != -1)\n\t\t{\n\t\t\tconst int selSize = edit->selectionStart() >= 0 && allowSelection\n\t\t\t\t? (edit->selectedText().size() * (newPos < pos ? -1 : 1)) -\n\t\t\t\t\tnewPos + pos\n\t\t\t\t: 0;\n\n\t\t\tconst QSignalBlocker blocker(edit);\n\n\t\t\tif (selSize != 0)\n\t\t\t{\n\t\t\t\tedit->setSelection(pos - selSize, selSize);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tedit->setCursorPosition(pos);\n\t\t\t}\n\t\t}\n\n\t\tmIgnoreCursorPosition = false;\n\t}\n}\n\nvoid QtnInt64SpinBox::setValue(qint64 value, EmitPolicy ep, bool updateEdit)\n{\n\tQ_ASSERT(value >= mMinimum);\n\tQ_ASSERT(value <= mMaximum);\n\n\tauto old = mValue;\n\tmValue = value;\n\tmPendingEmit = false;\n\tmCleared = false;\n\n\tif (updateEdit)\n\t{\n\t\tthis->updateEdit();\n\t} else\n\t{\n\t\tupdate();\n\t}\n\n\tif (ep == AlwaysEmit || (ep == EmitIfChanged && old != mValue))\n\t{\n\t\temitSignals();\n\t}\n}\n\nvoid QtnInt64SpinBox::emitSignals()\n{\n\tmPendingEmit = false;\n\temit valueChanged(lineEdit()->text());\n\temit valueChanged(mValue);\n}\n\nvoid QtnInt64SpinBox::interpret(EmitPolicy ep)\n{\n\tif (mCleared)\n\t\treturn;\n\n\tqint64 v = 0;\n\tbool doInterpret = true;\n\tQString tmp = lineEdit()->text();\n\tint pos = lineEdit()->cursorPosition();\n\tconst int oldpos = pos;\n\n\tif (validate(tmp, pos) != QValidator::Acceptable)\n\t{\n\t\tconst QString copy = tmp;\n\t\tfixup(tmp);\n\n\t\tdoInterpret =\n\t\t\ttmp != copy && (validate(tmp, pos) == QValidator::Acceptable);\n\n\t\tif (!doInterpret)\n\t\t{\n\t\t\tif (correctionMode() == CorrectToNearestValue)\n\t\t\t{\n\t\t\t\tif (mMinimum < v)\n\t\t\t\t{\n\t\t\t\t\tv = std::min(v, mMaximum);\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tv = mMinimum;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t{\n\t\t\t\tv = mValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (doInterpret)\n\t{\n\t\tv = valueFromText(tmp);\n\t}\n\n\tsetValue(v, ep, true);\n\n\tif (oldpos != pos)\n\t\tlineEdit()->setCursorPosition(pos);\n}\n\nvoid QtnInt64SpinBox::setValue(qint64 val)\n{\n\tif (val < mMinimum)\n\t\tval = mMinimum;\n\n\tif (val > mMaximum)\n\t\tval = mMaximum;\n\n\tif (mValue != val)\n\t{\n\t\tsetValue(val, EmitIfChanged);\n\t}\n}\n\nQtnInt64SpinBox::Validator::Validator(QtnInt64SpinBox *parent)\n\t: QValidator(parent)\n\t, mParent(parent)\n{\n\tsetObjectName(QLatin1String(\"qt_int64_spinboxvalidator\"));\n}\n\nQValidator::State QtnInt64SpinBox::Validator::validate(\n\tQString &input, int &pos) const\n{\n\tauto specialText = mParent->specialValueText();\n\n\tif (!specialText.isEmpty() && input == specialText)\n\t\treturn QValidator::Acceptable;\n\n\tauto &prefix = mParent->mPrefix;\n\n\tif (!prefix.isEmpty() && !input.startsWith(prefix))\n\t{\n\t\tinput.prepend(prefix);\n\t\tpos += prefix.length();\n\t}\n\n\tauto &suffix = mParent->mSuffix;\n\n\tif (!suffix.isEmpty() && !input.endsWith(suffix))\n\t\tinput.append(suffix);\n\n\treturn mParent->validate(input, pos);\n}\n\nvoid QtnInt64SpinBox::Validator::fixup(QString &input) const\n{\n\tmParent->fixup(input);\n}\n"
  },
  {
    "path": "QtnProperty/Utils/QtnInt64SpinBox.h",
    "content": "/*******************************************************************************\nCopyright 2017 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"QtnProperty/Config.h\"\n\n#include <QAbstractSpinBox>\n\nclass QTN_IMPORT_EXPORT QtnInt64SpinBox : public QAbstractSpinBox\n{\n\tQ_OBJECT\n\tQ_DISABLE_COPY(QtnInt64SpinBox)\n\n\tQ_PROPERTY(QString suffix READ suffix WRITE setSuffix)\n\tQ_PROPERTY(QString prefix READ prefix WRITE setPrefix)\n\tQ_PROPERTY(QString cleanText READ cleanText)\n\tQ_PROPERTY(qint64 minimum READ minimum WRITE setMinimum)\n\tQ_PROPERTY(qint64 maximum READ maximum WRITE setMaximum)\n\tQ_PROPERTY(qint64 singleStep READ singleStep WRITE setSingleStep)\n\tQ_PROPERTY(\n\t\tqint64 value READ value WRITE setValue NOTIFY valueChanged USER true)\n\tQ_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE\n\t\t\tsetDisplayIntegerBase)\n\tQ_PROPERTY(bool isSpecialValue READ isSpecialValue)\n\tQ_PROPERTY(QString specialValueText READ specialValueText WRITE\n\t\t\tsetSpecialValueText)\n\npublic:\n\texplicit QtnInt64SpinBox(QWidget *parent = nullptr);\n\n\tinline qint64 value() const;\n\n\tinline const QString &prefix() const;\n\tvoid setPrefix(const QString &prefix);\n\n\tinline const QString &suffix() const;\n\tvoid setSuffix(const QString &suffix);\n\n\tQString cleanText() const;\n\n\tinline qint64 singleStep() const;\n\tvoid setSingleStep(qint64 val);\n\n\tinline qint64 minimum() const;\n\tvoid setMinimum(qint64 min);\n\n\tinline qint64 maximum() const;\n\tvoid setMaximum(qint64 max);\n\n\tvoid setSpecialValueText(const QString &txt);\n\n\tvoid interpretText();\n\n\tvoid setRange(qint64 min, qint64 max);\n\n\tinline int displayIntegerBase() const;\n\tvoid setDisplayIntegerBase(int base);\n\n\tvirtual StepEnabled stepEnabled() const override;\n\n\tvoid setLineEdit(QLineEdit *lineEdit);\n\n\tbool isSpecialValue() const;\n\n\tvirtual void clear() override;\n\tvirtual QSize sizeHint() const override;\n\tvirtual QSize minimumSizeHint() const override;\n\nprotected:\n\tvirtual QValidator::State validate(QString &input, int &pos) const override;\n\tvirtual qint64 valueFromText(const QString &text) const;\n\tvirtual QString textFromValue(qint64 val) const;\n\tvirtual void fixup(QString &str) const override;\n\tvirtual void stepBy(int steps) override;\n\tvirtual void keyPressEvent(QKeyEvent *event) override;\n\tvirtual void showEvent(QShowEvent *event) override;\n\tvirtual void changeEvent(QEvent *event) override;\n\tvirtual void focusOutEvent(QFocusEvent *event) override;\n\tvirtual void closeEvent(QCloseEvent *event) override;\n\tvirtual void hideEvent(QHideEvent *event) override;\n\n\tvoid updateEdit(bool withGeometry = false, bool withValue = false);\n\nprivate:\n\tenum EmitPolicy\n\t{\n\t\tEmitIfChanged,\n\t\tAlwaysEmit,\n\t\tNeverEmit\n\t};\n\n\tvoid onTextChanged(const QString &text);\n\tvoid onCursorPositionChanged(int oldPos, int newPos);\n\tvoid setValue(qint64 value, EmitPolicy ep, bool updateEdit = true);\n\tvoid emitSignals();\n\tvoid interpret(EmitPolicy ep);\n\n\tqint64 validateAndInterpret(\n\t\tQString &input, int *pos, QValidator::State *statePtr) const;\n\n\tQSize calcSize(const QString &fixedContent, int h) const;\n\npublic slots:\n\tvoid setValue(qint64 val);\n\nsignals:\n\tvoid valueChanged(qint64);\n\tvoid valueChanged(const QString &);\n\nprivate:\n\tclass Validator;\n\tfriend class Validator;\n\n\tValidator *mValidator;\n\tqint64 mValue;\n\tqint64 mSingleStep;\n\tqint64 mMinimum;\n\tqint64 mMaximum;\n\tint mDisplayIntegerBase;\n\tbool mPendingEmit;\n\tbool mCleared;\n\tbool mIgnoreCursorPosition;\n\tmutable QSize mCachedSizeHint;\n\tmutable QSize mCachedMinimumSizeHint;\n\tQString mPrefix;\n\tQString mSuffix;\n};\n\nqint64 QtnInt64SpinBox::value() const\n{\n\treturn mValue;\n}\n\nconst QString &QtnInt64SpinBox::prefix() const\n{\n\treturn mPrefix;\n}\n\nconst QString &QtnInt64SpinBox::suffix() const\n{\n\treturn mSuffix;\n}\n\nqint64 QtnInt64SpinBox::singleStep() const\n{\n\treturn mSingleStep;\n}\n\nqint64 QtnInt64SpinBox::minimum() const\n{\n\treturn mMinimum;\n}\n\nqint64 QtnInt64SpinBox::maximum() const\n{\n\treturn mMaximum;\n}\n\nint QtnInt64SpinBox::displayIntegerBase() const\n{\n\treturn mDisplayIntegerBase;\n}\n"
  },
  {
    "path": "QtnProperty/VarProperty.cpp",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#include \"VarProperty.h\"\n\n#include \"PropertyBase.h\"\n#include \"PropertySet.h\"\n#include \"Core/PropertyBool.h\"\n#include \"Core/PropertyInt.h\"\n#include \"Core/PropertyUInt.h\"\n#include \"Core/PropertyDouble.h\"\n#include \"Core/PropertyQString.h\"\n\nVarProperty::VarProperty(QObject *parent, VarProperty::Type type,\n\tconst QString &name, int index, const QVariant &value)\n\t: QObject(parent)\n\t, varParent(nullptr)\n\t, value(type == Value ? value : QVariant())\n\t, name(name)\n\t, index(index)\n\t, type(type)\n{\n}\n\nvoid VarProperty::ChangePropertyValue(const QVariant &value, QVariant *dest)\n{\n\tif (this->value != value)\n\t{\n\t\tthis->value = value;\n\n\t\tif (nullptr != dest)\n\t\t{\n\t\t\tauto top = TopParent();\n\n\t\t\tQ_ASSERT(nullptr != top);\n\n\t\t\t*dest = top->CreateVariant();\n\t\t}\n\t}\n}\n\nvoid VarProperty::RemoveFromParent()\n{\n\tif (nullptr != varParent)\n\t{\n\t\tauto &siblings = varParent->varChildren;\n\n\t\tauto it = std::find(siblings.begin(), siblings.end(), this);\n\n\t\tif (it != siblings.end())\n\t\t{\n\t\t\tsiblings.erase(it);\n\t\t}\n\t}\n}\n\nVarProperty *VarProperty::Duplicate(VarProperty *child, int newIndex)\n{\n\tQ_ASSERT(nullptr != child);\n\n\treturn AddChild(new VarProperty(nullptr, VarProperty::Value, \"\", newIndex,\n\t\t\t\t\t\tchild->CreateVariant()),\n\t\tnewIndex);\n}\n\nVarProperty *VarProperty::Duplicate(VarProperty *child, const QString &newName)\n{\n\tQ_ASSERT(nullptr != child);\n\n\treturn AddChild(new VarProperty(\n\t\tnullptr, VarProperty::Value, newName, -1, child->CreateVariant()));\n}\n\nVarProperty *VarProperty::Duplicate(int new_index)\n{\n\tQ_ASSERT(nullptr != varParent);\n\treturn varParent->Duplicate(this, new_index);\n}\n\nVarProperty *VarProperty::Duplicate(const QString &new_name)\n{\n\tQ_ASSERT(nullptr != varParent);\n\treturn varParent->Duplicate(this, new_name);\n}\n\nVarProperty *VarProperty::AddChild(VarProperty *child, int index)\n{\n\tif (index < 0)\n\t\tindex = static_cast<int>(varChildren.size());\n\n\tchild->varParent = this;\n\tvarChildren.insert(varChildren.begin() + index, child);\n\n\treturn child;\n}\n\nVarProperty *VarProperty::AddChild(int index, const QVariant &value)\n{\n\treturn AddChild(\n\t\tnew VarProperty(nullptr, GetTypeFromValue(value), \"\", index, value),\n\t\tindex);\n}\n\nVarProperty *VarProperty::AddChild(const QString &name, const QVariant &value)\n{\n\treturn AddChild(\n\t\tnew VarProperty(nullptr, GetTypeFromValue(value), name, -1, value));\n}\n\nVarProperty::Type VarProperty::GetTypeFromValue(const QVariant &value)\n{\n\tType type;\n\n\tswitch (value.type())\n\t{\n\t\tcase QVariant::Hash:\n\t\tcase QVariant::Map:\n\t\t\ttype = Map;\n\t\t\tbreak;\n\n\t\tcase QVariant::StringList:\n\t\tcase QVariant::List:\n\t\t\ttype = List;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\ttype = Value;\n\t\t\tbreak;\n\t}\n\n\treturn type;\n}\n\nVarProperty::Type VarProperty::GetType() const\n{\n\treturn type;\n}\n\nQVariant::Type VarProperty::GetVariantType() const\n{\n\tswitch (type)\n\t{\n\t\tcase Value:\n\t\t\treturn value.type();\n\n\t\tcase List:\n\t\t\treturn QVariant::List;\n\n\t\tcase Map:\n\t\t\treturn QVariant::Map;\n\t}\n\n\treturn QVariant::Invalid;\n}\n\nint VarProperty::GetIndex() const\n{\n\treturn index;\n}\n\nbool VarProperty::SetIndex(int newIndex)\n{\n\tif (index != newIndex)\n\t{\n\t\tindex = newIndex;\n\n\t\tif (newIndex >= 0)\n\t\t\tname = QStringLiteral(\"[%1]\").arg(QString::number(newIndex));\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nconst QString &VarProperty::GetName() const\n{\n\treturn name;\n}\n\nbool VarProperty::SetName(const QString &newName)\n{\n\tif (index < 0 && name != newName)\n\t{\n\t\tname = newName;\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nVarProperty *VarProperty::TopParent()\n{\n\tauto p = varParent;\n\n\tif (nullptr == p)\n\t\treturn this;\n\n\twhile (nullptr != p)\n\t{\n\t\tauto next_p = p->varParent;\n\n\t\tif (nullptr == next_p)\n\t\t\treturn p;\n\n\t\tp = next_p;\n\t}\n\n\treturn nullptr;\n}\n\nVarProperty *VarProperty::VarParent()\n{\n\treturn varParent;\n}\n\nVarProperty::VarChildren &VarProperty::GetChildren()\n{\n\treturn varChildren;\n}\n\nint VarProperty::GetChildrenCount() const\n{\n\treturn int(varChildren.size());\n}\n\nvoid VarProperty::SetValue(const QVariant &value)\n{\n\tthis->value = value;\n\n\tswitch (type)\n\t{\n\t\tcase Map:\n\t\tcase List:\n\n\t\t\tfor (auto child : varChildren)\n\t\t\t{\n\t\t\t\tchild->SetValue(QVariant());\n\t\t\t\tchild->setParent(nullptr);\n\t\t\t\tdelete child;\n\t\t\t}\n\n\t\t\tvarChildren.clear();\n\t\t\tbreak;\n\n\t\tcase Value:\n\t\t\tbreak;\n\t}\n\n\ttype = Value;\n}\n\nQVariant VarProperty::CreateVariant() const\n{\n\tswitch (type)\n\t{\n\t\tcase List:\n\t\t{\n\t\t\tQVariantList list;\n\n\t\t\tfor (auto child : varChildren)\n\t\t\t{\n\t\t\t\tlist.append(child->CreateVariant());\n\t\t\t}\n\n\t\t\treturn QVariant(list);\n\t\t}\n\n\t\tcase Map:\n\t\t{\n\t\t\tQVariantMap map;\n\n\t\t\tfor (auto child : varChildren)\n\t\t\t{\n\t\t\t\tmap.insert(child->name, child->CreateVariant());\n\t\t\t}\n\n\t\t\treturn QVariant(map);\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn value;\n}\n\nbool VarProperty::IsChildNameAvailable(\n\tconst QString &name, VarProperty *skip) const\n{\n\tfor (auto prop : varChildren)\n\t{\n\t\tif (skip == prop)\n\t\t\tcontinue;\n\n\t\tif (prop->name == name)\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nQtnPropertyBase *VarProperty::NewExtraProperty(QtnPropertySet *set,\n\tconst QVariant &value, const QString &key, int index,\n\tVarProperty *mapParent, const RegisterPropertyCallback &registerProperty)\n{\n\tQtnProperty *prop = nullptr;\n\n\tQString name(key);\n\n\tif (index >= 0)\n\t\tname = QString(\"[%1]\").arg(QString::number(index));\n\n\tauto type = value.type();\n\n\tswitch (type)\n\t{\n\t\tcase QVariant::Hash:\n\t\tcase QVariant::Map:\n\t\t{\n\t\t\treturn NewExtraPropertySet(\n\t\t\t\tset, value.toMap(), mapParent, name, index, registerProperty);\n\t\t}\n\n\t\tcase QVariant::StringList:\n\t\tcase QVariant::List:\n\t\t{\n\t\t\treturn NewExtraPropertyList(\n\t\t\t\tset, value.toList(), mapParent, name, index, registerProperty);\n\t\t}\n\n\t\tcase QVariant::Int:\n\t\t{\n\t\t\tauto p = new QtnPropertyInt(set);\n\n\t\t\tp->setId(PID_EXTRA_INT);\n\t\t\tp->setValue(value.toInt());\n\n\t\t\tprop = p;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QVariant::UInt:\n\t\t{\n\t\t\tauto p = new QtnPropertyUInt(set);\n\n\t\t\tp->setId(PID_EXTRA_UINT);\n\t\t\tp->setValue(value.toUInt());\n\n\t\t\tprop = p;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QVariant::LongLong:\n\t\tcase QVariant::ULongLong:\n\t\tcase QVariant::Double:\n\t\t{\n\t\t\tauto p = new QtnPropertyDouble(set);\n\n\t\t\tp->setId(PID_EXTRA_FLOAT);\n\t\t\tp->setValue(value.toDouble());\n\n\t\t\tprop = p;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase QVariant::Bool:\n\t\t{\n\t\t\tauto p = new QtnPropertyBool(set);\n\n\t\t\tp->setId(PID_EXTRA_BOOL);\n\t\t\tp->setValue(value.toBool());\n\n\t\t\tprop = p;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t{\n\t\t\tauto p = new QtnPropertyQString(set);\n\n\t\t\tp->setId(PID_EXTRA_STRING);\n\t\t\tp->setValue(value.toString());\n\n\t\t\tprop = p;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (nullptr != prop)\n\t{\n\t\tif (set)\n\t\t{\n\t\t\tset->addChildProperty(prop);\n\t\t}\n\t\tauto varprop =\n\t\t\tnew VarProperty(prop, VarProperty::Value, name, index, value);\n\n\t\tif (nullptr != mapParent)\n\t\t\tmapParent->AddChild(varprop, index);\n\n\t\tprop->setName(name);\n\n\t\tregisterProperty(prop);\n\t}\n\n\treturn prop;\n}\n\nbool VarProperty::PropertyValueAccept(\n\tconst QtnProperty *property, void *valueToAccept, QVariant *dest)\n{\n\tswitch (property->id())\n\t{\n\t\tcase VarProperty::PID_EXTRA:\n\t\tcase VarProperty::PID_EXTRA_STRING:\n\t\tcase VarProperty::PID_EXTRA_INT:\n\t\tcase VarProperty::PID_EXTRA_UINT:\n\t\tcase VarProperty::PID_EXTRA_FLOAT:\n\t\tcase VarProperty::PID_EXTRA_BOOL:\n\t\t{\n\t\t\tauto var_property = property->findChild<VarProperty *>(\n\t\t\t\tQString(), Qt::FindDirectChildrenOnly);\n\n\t\t\tQVariant value;\n\n\t\t\tif (nullptr != valueToAccept)\n\t\t\t{\n\t\t\t\tswitch (property->id())\n\t\t\t\t{\n\t\t\t\t\tcase PID_EXTRA_STRING:\n\t\t\t\t\t\tvalue = QVariant(*(QtnPropertyQString::ValueTypeStore *)\n\t\t\t\t\t\t\t\t\t\t\t valueToAccept);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PID_EXTRA_INT:\n\t\t\t\t\t\tvalue = QVariant(\n\t\t\t\t\t\t\t*(QtnPropertyInt::ValueTypeStore *) valueToAccept);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PID_EXTRA_UINT:\n\t\t\t\t\t\tvalue = QVariant(\n\t\t\t\t\t\t\t*(QtnPropertyUInt::ValueTypeStore *) valueToAccept);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PID_EXTRA_FLOAT:\n\t\t\t\t\t\tvalue = QVariant(*(\n\t\t\t\t\t\t\tQtnPropertyDouble::ValueTypeStore *) valueToAccept);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PID_EXTRA_BOOL:\n\t\t\t\t\t\tvalue = QVariant(\n\t\t\t\t\t\t\t*(QtnPropertyBool::ValueTypeStore *) valueToAccept);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue = *(QVariant *) valueToAccept;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar_property->ChangePropertyValue(value, dest);\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nQtnPropertySet *VarProperty::NewExtraPropertySet(QtnPropertySet *parent,\n\tconst QVariantMap &map, VarProperty *mapParent, const QString &name,\n\tint index, const RegisterPropertyCallback &registerProperty)\n{\n\tauto set = new QtnPropertySet(parent);\n\tif (parent)\n\t{\n\t\tparent->addChildProperty(set);\n\t}\n\n\tauto varprop =\n\t\tnew VarProperty(set, VarProperty::Map, name, index, QVariant());\n\n\tif (nullptr != mapParent)\n\t\tmapParent->AddChild(varprop, index);\n\n\tmapParent = varprop;\n\n\tset->setId(PID_EXTRA);\n\tset->setName(name);\n\n\tfor (auto it = map.begin(); it != map.end(); ++it)\n\t{\n\t\tauto &key = it.key();\n\t\tauto &value = it.value();\n\n\t\tNewExtraProperty(set, value, key, -1, mapParent, registerProperty);\n\t}\n\n\treturn set;\n}\n\nQtnPropertySet *VarProperty::NewExtraPropertyList(QtnPropertySet *parent,\n\tconst QVariantList &list, VarProperty *mapParent, const QString &name,\n\tint index, const RegisterPropertyCallback &registerProperty)\n{\n\tauto set = new QtnPropertySet(parent);\n\tif (parent)\n\t{\n\t\tparent->addChildProperty(set);\n\t}\n\n\tauto varprop =\n\t\tnew VarProperty(set, VarProperty::List, name, index, QVariant());\n\n\tif (nullptr != mapParent)\n\t\tmapParent->AddChild(varprop, index);\n\n\tmapParent = varprop;\n\n\tset->setId(PID_EXTRA);\n\tset->setName(name);\n\n\tint len = list.size();\n\n\tfor (int i = 0; i < len; i++)\n\t{\n\t\tauto &value = list.at(i);\n\n\t\tNewExtraProperty(set, value, QString(), i, mapParent, registerProperty);\n\t}\n\n\treturn set;\n}\n"
  },
  {
    "path": "QtnProperty/VarProperty.h",
    "content": "/*******************************************************************************\nCopyright (c) 2015-2019 Alexandra Cherdantseva <neluhus.vagus@gmail.com>\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*******************************************************************************/\n\n#pragma once\n\n#include \"Config.h\"\n\n#include <QObject>\n#include <QVariant>\n\n#include <functional>\n#include <vector>\n\nclass QtnPropertyBase;\nclass QtnProperty;\nclass QtnPropertySet;\n\nclass QTN_IMPORT_EXPORT VarProperty : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tenum Type\n\t{\n\t\tValue,\n\t\tList,\n\t\tMap\n\t};\n\n\ttypedef std::function<void(QtnProperty *)> RegisterPropertyCallback;\n\ttypedef std::vector<VarProperty *> VarChildren;\n\n\tVarProperty(QObject *parent, Type type, const QString &name, int index,\n\t\tconst QVariant &value);\n\n\tvoid ChangePropertyValue(const QVariant &value, QVariant *dest = nullptr);\n\tvoid RemoveFromParent();\n\tVarProperty *Duplicate(VarProperty *child, int newIndex);\n\tVarProperty *Duplicate(VarProperty *child, const QString &newName);\n\n\tVarProperty *Duplicate(int new_index);\n\tVarProperty *Duplicate(const QString &new_name);\n\n\tVarProperty *AddChild(VarProperty *child, int index = -1);\n\tVarProperty *AddChild(int index, const QVariant &value);\n\tVarProperty *AddChild(const QString &name, const QVariant &value);\n\n\tstatic Type GetTypeFromValue(const QVariant &value);\n\tType GetType() const;\n\tQVariant::Type GetVariantType() const;\n\n\tint GetIndex() const;\n\tbool SetIndex(int newIndex);\n\n\tconst QString &GetName() const;\n\tbool SetName(const QString &newName);\n\n\tVarProperty *TopParent();\n\tVarProperty *VarParent();\n\tVarChildren &GetChildren();\n\tint GetChildrenCount() const;\n\n\tvoid SetValue(const QVariant &value);\n\tQVariant CreateVariant() const;\n\tbool IsChildNameAvailable(const QString &name, VarProperty *skip) const;\n\n\tstatic QtnPropertyBase *NewExtraProperty(QtnPropertySet *set,\n\t\tconst QVariant &value, const QString &key, int index,\n\t\tVarProperty *mapParent,\n\t\tconst RegisterPropertyCallback &registerProperty);\n\n\tstatic bool PropertyValueAccept(const QtnProperty *property,\n\t\tvoid *valueToAccept, QVariant *dest = nullptr);\n\n\tenum\n\t{\n\t\tPID_EXTRA = 1,\n\n\t\tPID_EXTRA_STRING,\n\t\tPID_EXTRA_INT,\n\t\tPID_EXTRA_UINT,\n\t\tPID_EXTRA_FLOAT,\n\t\tPID_EXTRA_BOOL,\n\n\t\tPID_EXTRA_TOTAL\n\t};\n\nprivate:\n\tstatic QtnPropertySet *NewExtraPropertySet(QtnPropertySet *parent,\n\t\tconst QVariantMap &map, VarProperty *mapParent, const QString &name,\n\t\tint index, const RegisterPropertyCallback &registerProperty);\n\tstatic QtnPropertySet *NewExtraPropertyList(QtnPropertySet *parent,\n\t\tconst QVariantList &list, VarProperty *mapParent, const QString &name,\n\t\tint index, const RegisterPropertyCallback &registerProperty);\n\n\tVarProperty *varParent;\n\tVarChildren varChildren;\n\tQVariant value;\n\tQString name;\n\tint index;\n\tType type;\n};\n"
  },
  {
    "path": "QtnProperty.pro",
    "content": "TEMPLATE   = subdirs\nSUBDIRS   += \\\n    QtnProperty \\\n    PEG \\\n    Tests \\\n    Demo\n\nTests.depends = PEG QtnProperty\nDemo.depends = PEG QtnProperty\n\nOTHER_FILES += \\\n\tREADME.md \\\n\tCHANGELOG \\\n\tLICENSE \\\n\tAUTHORS \\\n\tTODO"
  },
  {
    "path": "QtnPropertyDepend.pri",
    "content": "isEmpty(QTNPROPERTY_BIN) {\n    include($$PWD/Internal/BaseConfig.pri)\n}\n\nQTNPROPERTY_PATH = $$PWD\n\nisEmpty(QTNPROPERTY_LIB) {\n    QTNPROPERTY_LIB = $$QTNPROPERTY_BIN\n}\n\nQTNPROPERTY_LIBNAME = QtnProperty\nqtnproperty_dynamic:QTNPROPERTY_LIBNAME = $$join(QTNPROPERTY_LIBNAME, , , 2)\n\nwin32 {\n    msvc:PRE_TARGETDEPS += $$QTNPROPERTY_LIB/$$join(QTNPROPERTY_LIBNAME, , , .lib)\n    else:PRE_TARGETDEPS += $$QTNPROPERTY_LIB/$$join(QTNPROPERTY_LIBNAME, , lib, .a)\n}\n\nqtnproperty_dynamic {\n    DEFINES += QTN_DYNAMIC_IMPORT\n    macx {\n        DYNAMIC_LIBS.files += $$QTNPROPERTY_LIB/$$join(QTNPROPERTY_LIBNAME, , lib, .dylib)\n    }\n} else {\n    unix {\n        PRE_TARGETDEPS += $$QTNPROPERTY_LIB/$$join(QTNPROPERTY_LIBNAME, , lib, .a)\n    }\n}\n\nLIBS += -L$$QTNPROPERTY_LIB\nLIBS += -l$$QTNPROPERTY_LIBNAME\n\nINCLUDEPATH += $$QTNPROPERTY_PATH\n"
  },
  {
    "path": "README.md",
    "content": "[![Build Status](https://travis-ci.org/qtinuum/QtnProperty.svg?branch=master)](https://travis-ci.org/qtinuum/QtnProperty)\n\n# QtnProperty\nThis is user and programmer friendly properties for Qt framework.\nSee [wiki](https://github.com/qtinuum/QtnProperty/wiki) for some details.\n\n# Overview\nThere are some limitations of standard Qt property system.\nThis project is an attempt to make better properties.\nThe key features are:\n\n* Properties hierarchy (properties can be organized in hierarchy at any depth)\n* Property widget to observe and edit properties in uniform way\n* Signals before and after property has changed\n* Property description - short text which help user to understand meaning and purpose of the property\n* Property state - property can be disabled or hidden at any moment\n* Serialization via QDataStream\n* Set/Get property value to/from QVariant and QString\n* Scripting support\n* Delegates to customize look and feel properties in property widget\n* PEG (property/enum generator) - it's optional tool like Qt moc which generates properties hierarchy from QML like files into C++ code.\n\nNew Features in v2.0.0\n* **Multi-properties with QtnMultipleProperty.** It is useful when you want to show properties of multiple objects at once. When values of objects's properties differ it shows grayed (**Multiple properties**). When you set a new property value, it will be changed in every dependent object. Multi-property set can be created with qtnCreateQObjectMultiPropertySet function defined in [QObjectPropertySet.h](https://github.com/qtinuum/QtnProperty/blob/master/QtnProperty/QObjectPropertySet.h) or from custom property sets in a loop with qtnPropertiesToMultiSet function where target argument is a multi-property set, and source argument is a source property set you want to join.\n* **QVariant properties with QtnCustomPropertyWidget.** You can edit QVariant as property set / add/remove subproperties in QVariantMap or QVariantList, copy/paste variant properties.\n* **Integer 64 properties** QtnPropertyInt64 QtnPropertyUInt64\n* **Floating point variants of QPoint, QSize, QRect properties**\n* **Overriding QtnPropertyDelegateFactory for QtnPropertySet**\n* **Improvements to sync objects values and property editors**\n* **Translations EN_RU**\n\n\nSome screenshots of the Demo application:\n![Demo_screenshot_linux](Docs/img/Demo1.png)\n![Demo_screenshot_win](Docs/img/DemoWin.png)\n\n# How to build\n**Requirements:**\n\n1. Qt 5.9 framework or later\n2. Optional: Flex 2.6.4 and Bison 3.1.1 (for Windows can be found [here](https://github.com/lexxmark/winflexbison)) if you build QtnPEG tool\n\n**To build:**\n  \n    mkdir path_to_build\n    cd path_to_build\n    qmake path_to_QtnProperty/QtnProperty.pro -r\n    make\n\nOr just open path\\_to\\_QtnProperty/QtnProperty.pro file in Qt Creator and build all.\nGenerated libraries and executables will be placed into the target specific folders.\nFor example:\n\n    bin-linux-gcc-x86_64\n    bin-osx-clang-x86_64\n    bin-win32-msvc-i386\n    bin-win32-msvc-clang-x86_64\n    bin-win32-gcc-i386\n    bin-win32-gcc-x86_64\n\n**To run tests and demo, go to one of the binary folders and run:**\n\n    ./QtnPropertyTests\n    ./QtnPropertyDemo\n\nQtnProperty project consists of four submodules:\n\n1. **QtnProperty** library - property classes. By default it is a static library. If you need a dynamic library, you should run **qmake** with **CONFIG+=qtnproperty_dynamic** argument\n3. **QtnPEG** tool - optional executable to generate C++ code for property sets from simple QML like files (*.pef files)\n4. **QtnPropertyTests** - tests for QtnPropertyCore library\n5. **QtnPropertyDemo** - demo application\n\n# How to use\n\n## Step 1.\nTo have QtnProperty in your project you should include QtnPropertyDepend.pri file into your pro file. Example:\n\nMyProject.pro\n-------------\n```\nTEMPLATE   = subdirs\nSUBDIRS   += \\\n        QtnProperty \\\n        Application\n\nQtnProperty.file = path_to/QtnProperty/QtnProperty.pro\n\nApplication.depends = \\\n    QtnProperty\n```\nApplication/Application.pro\n---------------------------\n```\nQT += core gui widgets script\n\nTEMPLATE = app\n\ninclude(path_to/QtnProperty/QtnPropertyDepend.pri)\n# this will add QtnProperty root to include path and will link the library to your app.\n```\n\n## Step 2.\nThen you can manually create property sets in your C++ code, create QtnPropertyWidget or QtnPropertyView widgets and assign property set to the widget:\n\n```C++\nclass Ui_MainWindow\n{\npublic:\n    QtnPropertyWidget *centralWidget;\n    ...\n};\n\nMainWindow::MainWindow(QWidget *parent) :\n    QMainWindow(parent),\n    ui(new Ui::MainWindow)\n{\n    ui->setupUi(this);\n\n    m_propertySet = new QtnPropertySet(this)\n\n    auto floatValue = qtnCreateProperty<QtnPropertyFloat>(m_propertySet);\n    floatValue->setName(\"value\");\n    floatValue->setDisplayName(tr(\"Value\"));\n    floatValue->setDescription(tr(\"Float value\"));\n    floatValue->setMaxValue(1.f);\n    floatValue->setMinValue(0.f);\n    floatValue->setStepValue(0.1f);\n    floatValue->setValue(0.3f);\n\n    auto textColor = qtnCreateProperty<QtnPropertyQColor>(m_propertySet);\n    textColor->setName(\"textColor\");\n    textColor->setDisplayName(tr(\"TextColor\"));\n    textColor->setDescription(tr(\"Foreground text color\"));\n    textColor->setValue(QColor(0, 0, 0));\n\n    ui->centralWidget->setPropertySet(m_propertySet);\n}\n```\nThis example will show you something like this:\n\n![Example_screenshot_windows](Docs/img/Example1.png)\n\n## Step 3.\nIf you want to use *.pef files to generate properties C++ code you need to build QtnPEG executable.\n\n## Step 4.\nTo use *.pef files in your project you should do the following in your pro file:\n\n* Define PEG_TOOL variable as full path to the QtnPEG executable\n* include PEG.pri file\n* list all *.pef files in PEG_SOURCES variable\n\n```C++\ninclude(path_to/QtnProperty/PEG/PEG.pri)\nPEG_SOURCES += TextEditor.pef\n```\n\n## Step 5.\nWrite *.pef file with propertyset declaration. See [wiki](https://github.com/qtinuum/QtnProperty/wiki/Property-Enum-file-format-(*.pef)) for more info. For example TextEditor.pef:\n  \n```C++\n#include \"QtnProperty/PropertyCore.h\"\n\nproperty_set TextEditor\n{\n    Bool enableWrapping\n    {\n        description = \"Enable/disable text wrapping\";\n        value = true;\n    }\n    \n    Bool replaceTabsWithSpaces\n    {\n        description = \"Automatically replace tabs with spaces\";\n        value = false;\n            \n        slot propertyDidChange\n        {\n            tabSize.switchState(QtnPropertyStateImmutable, !replaceTabsWithSpaces);\n        }\n    }\n    \n    UInt tabSize\n    {\n        description = \"Number of spaces to be placed.\";\n        state = QtnPropertyStateImmutable;\n        value = 4;\n    }\n}\n```\n    \n## Step 6.\nInclude generated TextEditor.peg.h and TextEditor.peg.cpp files into \nyour project.\n\n## Step 7.\nNow you can use QtnPropertySetTextEditor class (defined in generated files) in your C++ code like this:\n```C++\n    QtnPropertySetTextEditor params;\n    params.enableWrapping = false;\n    if (params.replaceTabsWithSpaces)\n        document.replaceTabsWithSpaces(params.tabSize);\n```\n\nVideo of GUI testing using Froglogic (c) Squish test framework is [here](https://www.youtube.com/watch?v=lCmM13vPWBU).\n\n\n\n"
  },
  {
    "path": "TODO",
    "content": "PropertyArray\n\nImplement PropertySetForm - property widgets on form\n\nMake wrapper propertyset for QObject derived classes (implement Enum and EnumFlags cases)\n\nSave/Load via XML\n\nPropertyTypes:\n1. Date/Time\n2. Bitmap ???\n4. Cursor\n5. Icon\n\nowner feature????\nHow to define default PropertySet?\n\ncommand line parameters for PEG\nrefactor PEG to support bison 3.0\nrefactor PEG to generate thread-safe property_set constructors (static variables)\nQtDesigner plugin\nHelp\npef files syntax highlight\nCMake support\n\nTests:\n2. Property equal (==)\n3. Property <, > for numerics\n4. make PropertySetAllPropertyTypes with subproperties\n5. add benchmarks\n\nimplement ReportError method\n"
  },
  {
    "path": "Tests/PEG/test.pef",
    "content": "#include \"QtnProperty/Enum.h\"\n#include_cpp <vector>\n#include_h \"QtnProperty/PropertyCore.h\"\n#include_h \"QtnProperty/PropertyGUI.h\"\n\nproperty_set Test1\n{\n    id = 1;\n    description = \"Test property_set description\";\n    state =0 ;\n    Int a\n    {\n        id = 2;\n        description = \"Descripion\";\n        value = 5;\n        stepValue = -1;\n        maxValue = 10;\n    }\n\nQString text{\n    id = 3;\n    value=QString(\"#^{};\");\n    description = \"defrf\\\"sde\\\"\"\"deerf3rf\"\n    \"derf r g\\r\\nreg r{}\"\"dfrgerg\"\n    \"fwrewre\";\n}\n\n}\n\nproperty_set Test2{\n    id = 4;\n}\n\n\ncode_h\n{\n    // declaration\n    void aaa();\n}\n\nproperty_set Test3 {\n    id = 5;\n    property_set YY yy\n    {\n        id = 6;\n        description = QString(\"ss\")+QString(\"ss\");\n        // rectangle property\n        QRect rect {value = QRect(10, 10, 10, 10);}\n\n        QString s;\n    }\n\n    property_set SS iis\n    {\n        id = 7;\n        Bool a{ value = true; id = 8; }\n\n        property_set AA aa\n        {\n            id = 9;\n           code_h\n           {\n               private:\n                   bool m_s;\n           }\n           code_cpp\n           {\n               // AA cpp code\n           }\n        }\n    }\n\n    Bool u\n    {\n        id = 10;\n        value = true;\n        slot propertyDidChange\n        {\n            // sub u propertyDidChange\n        }\n    }\n\n    slot propertyDidChange\n    {\n        // this propertyDidChange\n    }\n\n    slot u.propertyWillChange\n    {\n        // u.propertyWillChange code\n    }\n    \n    /*\n     * external property set\n     **/\n    extern property_set Test2 xx {}\n\n    extern property_set Test2 tt;\n\n    extern property_set SS s\n    {\n        a.value = false;\n\n        slot a.propertyWillChange\n        {\n            yy.rect = QRect(1, 1, 1, 1);\n            // ss propertyWillChange\n        }\n\n        slot a.propertyValueAccept\n        {\n            // s.a.propertyValueAccept\n        }\n\n    }\n\n    Bool ww {id = 11; }\n\n    BoolCallback bc\n    {\n        id = 12;\n        callbackValueGet = [this]()->bool {\n                return ww;\n        };\n\n        callbackValueAccepted = [](bool value)->bool {\n            if (value) {\n                return true;\n            } else {\n                return false;\n            }\n        };\n\n        callbackValueEqual = [](bool)->bool { return false; };\n\n        callbackValueSet = [this](bool value, QtnPropertyChangeReason /*reason*/) {\n            m_s = value;\n        };\n    }\n\n    code_h\n    {\n        public:\n            bool m_s;\n    }\n\n}\n\n    code_cpp{\n        void aaa()\n        {\n\n        }\n    }\n\nenum LANGUAGE\n{\n    ENG(3, \"English\")\n}\n\nenum TYPE{}\n\nenum COLOR {\n    RED (10, \"Red\"),\n    BLUE (22, \"Blue\") hidden obsolete,\n    YELLOW (1, \"Yellow\")\n}\n\nenum MASK {\n    ONE (1, \"One\"),\n    TWO (2, \"Two\"),\n    FOUR (4, \"Four\")\n}\n\nproperty_set AllPropertyTypes\n{\n    id = 13;\n    Bool bp { id = 14; }\n    BoolCallback bpc\n    {\n        callbackValueGet = [this]() { return _b; };\n        callbackValueSet = [this](bool v, QtnPropertyChangeReason /*reason*/) { _b = v; };\n        id = 15;\n    }\n\n    Int ip { id = 16; }\n    IntCallback ipc\n    {\n        callbackValueGet = [this]() { return _i; };\n        callbackValueSet = [this](qint32 v, QtnPropertyChangeReason /*reason*/) { _i =v; };\n        id = 17;\n    }\n\n    UInt up { id = 18; }\n    UIntCallback upc\n    {\n        callbackValueGet = [this]() { return _ui; };\n        callbackValueSet = [this](quint32 v, QtnPropertyChangeReason /*reason*/) { _ui = v; };\n        id = 19;\n    }\n\n    Float fp { id = 20; }\n    FloatCallback fpc\n    {\n        callbackValueGet = [this]() { return _f; };\n        callbackValueSet = [this](float v, QtnPropertyChangeReason /*reason*/) { _f = v; };\n        id = 21;\n    }\n\n    Double dp { id = 22; }\n    DoubleCallback dpc\n    {\n        callbackValueGet = [this]() { return _d; };\n        callbackValueSet = [this](double v, QtnPropertyChangeReason /*reason*/) { _d = v; };\n        id = 23;\n    }\n\n    QString sp { id = 24; }\n    QStringCallback spc\n    {\n        callbackValueGet = [this]() { return _s; };\n        callbackValueSet = [this](QString v, QtnPropertyChangeReason /*reason*/) { _s = v; };\n        id = 25;\n    }\n\n    QRect rp { id = 26; }\n    QRectCallback rpc\n    {\n        callbackValueGet = [this]() { return _r; };\n        callbackValueSet = [this](QRect v, QtnPropertyChangeReason /*reason*/) { _r = v; };\n        id = 27;\n    }\n\n    QPoint pp { id = 28; }\n    QPointCallback ppc\n    {\n        callbackValueGet = [this]() { return _p; };\n        callbackValueSet = [this](QPoint v, QtnPropertyChangeReason /*reason*/) { _p = v; };\n        id = 29;\n    }\n\n    QSize szp { id = 30; }\n    QSizeCallback szpc\n    {\n        callbackValueGet = [this]() { return _sz; };\n        callbackValueSet = [this](QSize v, QtnPropertyChangeReason /*reason*/) { _sz = v; };\n        id = 31;\n    }\n\n    Enum ep\n    {\n        enumInfo = &COLOR::info();\n        value = COLOR::BLUE;\n        id = 32;\n    }\n    EnumCallback epc\n    {\n        enumInfo = &COLOR::info();\n        callbackValueGet = [this]() { return _e; };\n        callbackValueSet = [this](QtnEnumValueType v, QtnPropertyChangeReason /*reason*/) { _e = v; };\n        id = 33;\n    }\n\n    EnumFlags efp\n    {\n        enumInfo = &MASK::info();\n        value = MASK::ONE|MASK::FOUR;\n        id = 34;\n    }\n    EnumFlagsCallback efpc\n    {\n        enumInfo = &MASK::info();\n        callbackValueGet = [this]() { return _ef; };\n        callbackValueSet = [this](QtnEnumFlagsValueType v, QtnPropertyChangeReason /*reason*/) { _ef = v; };\n        id = 35;\n    }\n\n    QColor cp\n    {\n        value = QColor(Qt::blue);\n        id = 36;\n    }\n    QColorCallback cpc\n    {\n        callbackValueGet = [this]() { return _cl; };\n        callbackValueSet = [this](QColor v, QtnPropertyChangeReason /*reason*/) { _cl = v; };\n        id = 37;\n    }\n\n    QFont fnp\n    {\n        value = QFont(\"Courier\", 10);\n        id = 38;\n    }\n    QFontCallback fnpc\n    {\n        callbackValueGet = [this]() { return _fn; };\n        callbackValueSet = [this](QFont v, QtnPropertyChangeReason /*reason*/) { _fn = v; };\n        id = 39;\n    }\n    \n    Button bttn\n    {\n        id = 40;\n    }\n\n    QPointF ppf { id = 41; }\n    QPointFCallback ppfc\n    {\n        callbackValueGet = [this]() { return _pf; };\n        callbackValueSet = [this](QPointF v, QtnPropertyChangeReason /*reason*/) { _pf = v; };\n        id = 42;\n    }\n\n    QRectF rpf { id = 43; }\n    QRectFCallback rpfc\n    {\n        callbackValueGet = [this]() { return _rf; };\n        callbackValueSet = [this](QRectF v, QtnPropertyChangeReason /*reason*/) { _rf = v; };\n        id = 44;\n    }\n    \n    QSizeF szpf { id = 45; }\n    QSizeFCallback szpfc\n    {\n        callbackValueGet = [this]() { return _szf; };\n        callbackValueSet = [this](QSizeF v, QtnPropertyChangeReason /*reason*/) { _szf = v; };\n        id = 46;\n    }\n\n    AllPropertyTypes()\n        : _b(true)\n    {\n        _i =12;\n        _ui = 9;\n        _f = 0.2f;\n        _d = 32.4;\n        _s = \"name\";\n        _r = QRect(10, 10, 10, 10);\n        _rf = QRectF(10.1, 10.2, 10.3, 10.4);\n        _p = QPoint(9, 2);\n        _pf = QPointF(9.9, 2.2);\n        _sz = QSize(33, 21);\n        _szf = QSizeF(33.0, 21.9);\n        _e = COLOR::RED;\n        _ef = MASK::ONE|MASK::FOUR;\n        _cl = QColor(Qt::red);\n        _fn = QFont(\"Arial\", 19);\n    }\n\n    ~AllPropertyTypes()\n    {\n        _b = false;\n    }\n\n    code_h\n    {\n    private:\n        bool _b;\n        qint32 _i;\n        quint32 _ui;\n        float _f;\n        double _d;\n        QString _s;\n        QRect _r;\n        QRectF _rf;\n        QPoint _p;\n        QPointF _pf;\n        QSize _sz;\n        QSizeF _szf;\n        QtnEnumValueType _e;\n        QtnEnumFlagsValueType _ef;\n        QColor _cl;\n        QFont _fn;\n    }\n}\n\n/*\n *    NONE(-1, \"None\") hidden,\n    ENG(0, \"English\"),\n    FR(1, \"French\"),\n    GM(2, \"German\")\n\nenum MY_TYPE\n{\n    MY_TYPE1(1, \"My type 1\"),\n    MY_TYPE2(2, \"My type 2\")\n}\n*/\n\nenum MY_TYPE\n{\n    MY_TYPE1(1, \"My type 1\"),\n    MY_TYPE2(2, \"My type 2\")\n}\n\nproperty_set Test12\n{\n    Enum p\n    {\n        value = MY_TYPE::MY_TYPE1;\n        enumInfo = &MY_TYPE::info();\n    }\n}"
  },
  {
    "path": "Tests/PEG/test.peg.cpp",
    "content": "#include \"test.peg.h\"\n\n#include <vector>\n\nQtnPropertySetTest1::QtnPropertySetTest1(QObject* parent)\n    : QtnPropertySet(parent)\n    , a(*qtnCreateProperty<QtnPropertyInt>(this))\n    , text(*qtnCreateProperty<QtnPropertyQString>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetTest1::~QtnPropertySetTest1()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetTest1& QtnPropertySetTest1::operator=(const QtnPropertySetTest1& other)\n{\n    Q_UNUSED(other);\n\n    a = other.a;\n    text = other.text;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetTest1::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetTest1(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetTest1::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetTest1* p = new QtnPropertySetTest1(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetTest1::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetTest1*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->a.state() & ignoreMask))\n    {\n        a = theCopyFrom->a;\n    }\n\n    if (!(theCopyFrom->text.state() & ignoreMask))\n    {\n        text = theCopyFrom->text;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetTest1::init()\n{\n    static QString Test1_name = QStringLiteral(\"Test1\");\n    setName(Test1_name);\n    static QString description = \"Test property_set description\";\n    setDescription(description);\n    setId(1);\n    setState(0);\n    \n    // start children initialization\n    static QString a_name = QStringLiteral(\"a\");\n    a.setName(a_name);\n    static QString a_description = \"Descripion\";\n    a.setDescription(a_description);\n    a.setId(2);\n    a.setMaxValue(10);\n    a.setStepValue(-1);\n    a.setValue(5);\n    static QString text_name = QStringLiteral(\"text\");\n    text.setName(text_name);\n    static QString text_description = \"defrf\\\"sde\\\"\"\"deerf3rf\"\n    \"derf r g\\r\\nreg r{}\"\"dfrgerg\"\n    \"fwrewre\";\n    text.setDescription(text_description);\n    text.setId(3);\n    text.setValue(QString(\"#^{};\"));\n    // end children initialization\n}\n\nvoid QtnPropertySetTest1::connectSlots()\n{\n}\n\nvoid QtnPropertySetTest1::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetTest1::connectDelegates()\n{\n}\n\nQtnPropertySetTest2::QtnPropertySetTest2(QObject* parent)\n    : QtnPropertySet(parent)\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetTest2::~QtnPropertySetTest2()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetTest2& QtnPropertySetTest2::operator=(const QtnPropertySetTest2& other)\n{\n    Q_UNUSED(other);\n\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetTest2::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetTest2(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetTest2::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetTest2* p = new QtnPropertySetTest2(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetTest2::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetTest2*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    return true;\n}\n\nvoid QtnPropertySetTest2::init()\n{\n    static QString Test2_name = QStringLiteral(\"Test2\");\n    setName(Test2_name);\n    setId(4);\n}\n\nvoid QtnPropertySetTest2::connectSlots()\n{\n}\n\nvoid QtnPropertySetTest2::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetTest2::connectDelegates()\n{\n}\n\nQtnPropertySetYY::QtnPropertySetYY(QObject* parent)\n    : QtnPropertySet(parent)\n    , rect(*qtnCreateProperty<QtnPropertyQRect>(this))\n    , s(*qtnCreateProperty<QtnPropertyQString>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetYY::~QtnPropertySetYY()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetYY& QtnPropertySetYY::operator=(const QtnPropertySetYY& other)\n{\n    Q_UNUSED(other);\n\n    rect = other.rect;\n    s = other.s;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetYY::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetYY(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetYY::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetYY* p = new QtnPropertySetYY(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetYY::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetYY*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->rect.state() & ignoreMask))\n    {\n        rect = theCopyFrom->rect;\n    }\n\n    if (!(theCopyFrom->s.state() & ignoreMask))\n    {\n        s = theCopyFrom->s;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetYY::init()\n{\n    static QString yy_name = QStringLiteral(\"yy\");\n    setName(yy_name);\n    static QString description = QString(\"ss\")+QString(\"ss\");\n    setDescription(description);\n    setId(6);\n    \n    // start children initialization\n    static QString rect_name = QStringLiteral(\"rect\");\n    rect.setName(rect_name);\n    rect.setValue(QRect(10, 10, 10, 10));\n    static QString s_name = QStringLiteral(\"s\");\n    s.setName(s_name);\n    // end children initialization\n}\n\nvoid QtnPropertySetYY::connectSlots()\n{\n}\n\nvoid QtnPropertySetYY::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetYY::connectDelegates()\n{\n}\n\nQtnPropertySetAA::QtnPropertySetAA(QObject* parent)\n    : QtnPropertySet(parent)\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetAA::~QtnPropertySetAA()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetAA& QtnPropertySetAA::operator=(const QtnPropertySetAA& other)\n{\n    Q_UNUSED(other);\n\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetAA::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetAA(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetAA::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetAA* p = new QtnPropertySetAA(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetAA::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetAA*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    return true;\n}\n\nvoid QtnPropertySetAA::init()\n{\n    static QString aa_name = QStringLiteral(\"aa\");\n    setName(aa_name);\n    setId(9);\n}\n\nvoid QtnPropertySetAA::connectSlots()\n{\n}\n\nvoid QtnPropertySetAA::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetAA::connectDelegates()\n{\n}\n\n               // AA cpp code\n           \n\nQtnPropertySetSS::QtnPropertySetSS(QObject* parent)\n    : QtnPropertySet(parent)\n    , a(*qtnCreateProperty<QtnPropertyBool>(this))\n    , aa(*qtnCreateProperty<QtnPropertySetAA>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetSS::~QtnPropertySetSS()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetSS& QtnPropertySetSS::operator=(const QtnPropertySetSS& other)\n{\n    Q_UNUSED(other);\n\n    a = other.a;\n    aa = other.aa;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetSS::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetSS(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetSS::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetSS* p = new QtnPropertySetSS(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetSS::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetSS*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->a.state() & ignoreMask))\n    {\n        a = theCopyFrom->a;\n    }\n\n    aa.copyValues(&theCopyFrom->aa, ignoreMask);\n\n    return true;\n}\n\nvoid QtnPropertySetSS::init()\n{\n    static QString iis_name = QStringLiteral(\"iis\");\n    setName(iis_name);\n    setId(7);\n    \n    // start children initialization\n    static QString a_name = QStringLiteral(\"a\");\n    a.setName(a_name);\n    a.setId(8);\n    a.setValue(true);\n    static QString aa_name = QStringLiteral(\"aa\");\n    aa.setName(aa_name);\n    aa.setId(9);\n    // end children initialization\n}\n\nvoid QtnPropertySetSS::connectSlots()\n{\n}\n\nvoid QtnPropertySetSS::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetSS::connectDelegates()\n{\n}\n\nQtnPropertySetTest3::QtnPropertySetTest3(QObject* parent)\n    : QtnPropertySet(parent)\n    , yy(*qtnCreateProperty<QtnPropertySetYY>(this))\n    , iis(*qtnCreateProperty<QtnPropertySetSS>(this))\n    , u(*qtnCreateProperty<QtnPropertyBool>(this))\n    , xx(*qtnCreateProperty<QtnPropertySetTest2>(this))\n    , tt(*qtnCreateProperty<QtnPropertySetTest2>(this))\n    , s(*qtnCreateProperty<QtnPropertySetSS>(this))\n    , ww(*qtnCreateProperty<QtnPropertyBool>(this))\n    , bc(*qtnCreateProperty<QtnPropertyBoolCallback>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetTest3::~QtnPropertySetTest3()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetTest3& QtnPropertySetTest3::operator=(const QtnPropertySetTest3& other)\n{\n    Q_UNUSED(other);\n\n    yy = other.yy;\n    iis = other.iis;\n    u = other.u;\n    xx = other.xx;\n    tt = other.tt;\n    s = other.s;\n    ww = other.ww;\n    bc = other.bc;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetTest3::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetTest3(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetTest3::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetTest3* p = new QtnPropertySetTest3(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetTest3::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetTest3*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    yy.copyValues(&theCopyFrom->yy, ignoreMask);\n\n    iis.copyValues(&theCopyFrom->iis, ignoreMask);\n\n    if (!(theCopyFrom->u.state() & ignoreMask))\n    {\n        u = theCopyFrom->u;\n    }\n\n    xx.copyValues(&theCopyFrom->xx, ignoreMask);\n\n    tt.copyValues(&theCopyFrom->tt, ignoreMask);\n\n    s.copyValues(&theCopyFrom->s, ignoreMask);\n\n    if (!(theCopyFrom->ww.state() & ignoreMask))\n    {\n        ww = theCopyFrom->ww;\n    }\n\n    if (!(theCopyFrom->bc.state() & ignoreMask))\n    {\n        bc = theCopyFrom->bc;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetTest3::init()\n{\n    static QString Test3_name = QStringLiteral(\"Test3\");\n    setName(Test3_name);\n    setId(5);\n    \n    // start children initialization\n    static QString yy_name = QStringLiteral(\"yy\");\n    yy.setName(yy_name);\n    static QString yy_description = QString(\"ss\")+QString(\"ss\");\n    yy.setDescription(yy_description);\n    yy.setId(6);\n    static QString iis_name = QStringLiteral(\"iis\");\n    iis.setName(iis_name);\n    iis.setId(7);\n    static QString u_name = QStringLiteral(\"u\");\n    u.setName(u_name);\n    u.setId(10);\n    u.setValue(true);\n    static QString xx_name = QStringLiteral(\"xx\");\n    xx.setName(xx_name);\n    static QString tt_name = QStringLiteral(\"tt\");\n    tt.setName(tt_name);\n    static QString s_name = QStringLiteral(\"s\");\n    s.setName(s_name);\n    s.a.setValue(false);\n    static QString ww_name = QStringLiteral(\"ww\");\n    ww.setName(ww_name);\n    ww.setId(11);\n    static QString bc_name = QStringLiteral(\"bc\");\n    bc.setName(bc_name);\n    bc.setCallbackValueAccepted([](bool value)->bool {\n            if (value) {\n                return true;\n            } else {\n                return false;\n            }\n        });\n    bc.setCallbackValueEqual([](bool)->bool { return false; });\n    bc.setCallbackValueGet([this]()->bool {\n                return ww;\n        });\n    bc.setCallbackValueSet([this](bool value, QtnPropertyChangeReason /*reason*/) {\n            m_s = value;\n        });\n    bc.setId(12);\n    // end children initialization\n}\n\nvoid QtnPropertySetTest3::connectSlots()\n{\n    QObject::connect(this, &QtnProperty::propertyDidChange, this, &QtnPropertySetTest3::on_propertyDidChange);\n    QObject::connect(&u, &QtnProperty::propertyWillChange, this, &QtnPropertySetTest3::on_u_propertyWillChange);\n    QObject::connect(&u, &QtnProperty::propertyDidChange, this, &QtnPropertySetTest3::on_u_propertyDidChange);\n    QObject::connect(&s.a, &QtnProperty::propertyValueAccept, this, &QtnPropertySetTest3::on_s_a_propertyValueAccept);\n    QObject::connect(&s.a, &QtnProperty::propertyWillChange, this, &QtnPropertySetTest3::on_s_a_propertyWillChange);\n}\n\nvoid QtnPropertySetTest3::disconnectSlots()\n{\n    QObject::disconnect(this, &QtnProperty::propertyDidChange, this, &QtnPropertySetTest3::on_propertyDidChange);\n    QObject::disconnect(&u, &QtnProperty::propertyWillChange, this, &QtnPropertySetTest3::on_u_propertyWillChange);\n    QObject::disconnect(&u, &QtnProperty::propertyDidChange, this, &QtnPropertySetTest3::on_u_propertyDidChange);\n    QObject::disconnect(&s.a, &QtnProperty::propertyValueAccept, this, &QtnPropertySetTest3::on_s_a_propertyValueAccept);\n    QObject::disconnect(&s.a, &QtnProperty::propertyWillChange, this, &QtnPropertySetTest3::on_s_a_propertyWillChange);\n}\n\nvoid QtnPropertySetTest3::on_propertyDidChange(QtnPropertyChangeReason reason)\n{\n    Q_UNUSED(reason);\n    \n        // this propertyDidChange\n    \n}\n\nvoid QtnPropertySetTest3::on_u_propertyWillChange(QtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId)\n{\n    Q_UNUSED(reason); Q_UNUSED(newValue);Q_UNUSED(typeId);\n    \n        // u.propertyWillChange code\n    \n}\n\nvoid QtnPropertySetTest3::on_u_propertyDidChange(QtnPropertyChangeReason reason)\n{\n    Q_UNUSED(reason);\n    \n            // sub u propertyDidChange\n        \n}\n\nvoid QtnPropertySetTest3::on_s_a_propertyValueAccept(QtnPropertyValuePtr valueToAccept, bool* accept)\n{\n    Q_UNUSED(valueToAccept); Q_UNUSED(accept);\n    \n            // s.a.propertyValueAccept\n        \n}\n\nvoid QtnPropertySetTest3::on_s_a_propertyWillChange(QtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId)\n{\n    Q_UNUSED(reason); Q_UNUSED(newValue);Q_UNUSED(typeId);\n    \n            yy.rect = QRect(1, 1, 1, 1);\n            // ss propertyWillChange\n        \n}\n\nvoid QtnPropertySetTest3::connectDelegates()\n{\n}\n\n        void aaa()\n        {\n\n        }\n    \nstatic QtnEnumInfo& create_LANGUAGE_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(LANGUAGE::ENG, \"ENG\", \"English\"));\n    \n    static QtnEnumInfo enumInfo(\"LANGUAGE\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& LANGUAGE::info()\n{\n    static QtnEnumInfo& enumInfo = create_LANGUAGE_info();\n    return enumInfo;\n}\nstatic QtnEnumInfo& create_TYPE_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    \n    static QtnEnumInfo enumInfo(\"TYPE\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& TYPE::info()\n{\n    static QtnEnumInfo& enumInfo = create_TYPE_info();\n    return enumInfo;\n}\nstatic QtnEnumInfo& create_COLOR_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(COLOR::RED, \"RED\", \"Red\"));\n    staticValues.append(QtnEnumValueInfo(COLOR::BLUE, \"BLUE\", \"Blue\", QtnEnumValueStateHidden | QtnEnumValueStateObsolete));\n    staticValues.append(QtnEnumValueInfo(COLOR::YELLOW, \"YELLOW\", \"Yellow\"));\n    \n    static QtnEnumInfo enumInfo(\"COLOR\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& COLOR::info()\n{\n    static QtnEnumInfo& enumInfo = create_COLOR_info();\n    return enumInfo;\n}\nstatic QtnEnumInfo& create_MASK_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(MASK::ONE, \"ONE\", \"One\"));\n    staticValues.append(QtnEnumValueInfo(MASK::TWO, \"TWO\", \"Two\"));\n    staticValues.append(QtnEnumValueInfo(MASK::FOUR, \"FOUR\", \"Four\"));\n    \n    static QtnEnumInfo enumInfo(\"MASK\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& MASK::info()\n{\n    static QtnEnumInfo& enumInfo = create_MASK_info();\n    return enumInfo;\n}\n\nQtnPropertySetAllPropertyTypes::QtnPropertySetAllPropertyTypes(QObject* parent)\n    : QtnPropertySet(parent)\n    , bp(*qtnCreateProperty<QtnPropertyBool>(this))\n    , bpc(*qtnCreateProperty<QtnPropertyBoolCallback>(this))\n    , ip(*qtnCreateProperty<QtnPropertyInt>(this))\n    , ipc(*qtnCreateProperty<QtnPropertyIntCallback>(this))\n    , up(*qtnCreateProperty<QtnPropertyUInt>(this))\n    , upc(*qtnCreateProperty<QtnPropertyUIntCallback>(this))\n    , fp(*qtnCreateProperty<QtnPropertyFloat>(this))\n    , fpc(*qtnCreateProperty<QtnPropertyFloatCallback>(this))\n    , dp(*qtnCreateProperty<QtnPropertyDouble>(this))\n    , dpc(*qtnCreateProperty<QtnPropertyDoubleCallback>(this))\n    , sp(*qtnCreateProperty<QtnPropertyQString>(this))\n    , spc(*qtnCreateProperty<QtnPropertyQStringCallback>(this))\n    , rp(*qtnCreateProperty<QtnPropertyQRect>(this))\n    , rpc(*qtnCreateProperty<QtnPropertyQRectCallback>(this))\n    , pp(*qtnCreateProperty<QtnPropertyQPoint>(this))\n    , ppc(*qtnCreateProperty<QtnPropertyQPointCallback>(this))\n    , szp(*qtnCreateProperty<QtnPropertyQSize>(this))\n    , szpc(*qtnCreateProperty<QtnPropertyQSizeCallback>(this))\n    , ep(*qtnCreateProperty<QtnPropertyEnum>(this))\n    , epc(*qtnCreateProperty<QtnPropertyEnumCallback>(this))\n    , efp(*qtnCreateProperty<QtnPropertyEnumFlags>(this))\n    , efpc(*qtnCreateProperty<QtnPropertyEnumFlagsCallback>(this))\n    , cp(*qtnCreateProperty<QtnPropertyQColor>(this))\n    , cpc(*qtnCreateProperty<QtnPropertyQColorCallback>(this))\n    , fnp(*qtnCreateProperty<QtnPropertyQFont>(this))\n    , fnpc(*qtnCreateProperty<QtnPropertyQFontCallback>(this))\n    , bttn(*qtnCreateProperty<QtnPropertyButton>(this))\n    , ppf(*qtnCreateProperty<QtnPropertyQPointF>(this))\n    , ppfc(*qtnCreateProperty<QtnPropertyQPointFCallback>(this))\n    , rpf(*qtnCreateProperty<QtnPropertyQRectF>(this))\n    , rpfc(*qtnCreateProperty<QtnPropertyQRectFCallback>(this))\n    , szpf(*qtnCreateProperty<QtnPropertyQSizeF>(this))\n    , szpfc(*qtnCreateProperty<QtnPropertyQSizeFCallback>(this))\n    , _b(true)\n{\n    \n        _i =12;\n        _ui = 9;\n        _f = 0.2f;\n        _d = 32.4;\n        _s = \"name\";\n        _r = QRect(10, 10, 10, 10);\n        _rf = QRectF(10.1, 10.2, 10.3, 10.4);\n        _p = QPoint(9, 2);\n        _pf = QPointF(9.9, 2.2);\n        _sz = QSize(33, 21);\n        _szf = QSizeF(33.0, 21.9);\n        _e = COLOR::RED;\n        _ef = MASK::ONE|MASK::FOUR;\n        _cl = QColor(Qt::red);\n        _fn = QFont(\"Arial\", 19);\n    \n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetAllPropertyTypes::~QtnPropertySetAllPropertyTypes()\n{\n    \n        _b = false;\n    \n    disconnectSlots();\n}\n\nQtnPropertySetAllPropertyTypes& QtnPropertySetAllPropertyTypes::operator=(const QtnPropertySetAllPropertyTypes& other)\n{\n    Q_UNUSED(other);\n\n    bp = other.bp;\n    bpc = other.bpc;\n    ip = other.ip;\n    ipc = other.ipc;\n    up = other.up;\n    upc = other.upc;\n    fp = other.fp;\n    fpc = other.fpc;\n    dp = other.dp;\n    dpc = other.dpc;\n    sp = other.sp;\n    spc = other.spc;\n    rp = other.rp;\n    rpc = other.rpc;\n    pp = other.pp;\n    ppc = other.ppc;\n    szp = other.szp;\n    szpc = other.szpc;\n    ep = other.ep;\n    epc = other.epc;\n    efp = other.efp;\n    efpc = other.efpc;\n    cp = other.cp;\n    cpc = other.cpc;\n    fnp = other.fnp;\n    fnpc = other.fnpc;\n    bttn = other.bttn;\n    ppf = other.ppf;\n    ppfc = other.ppfc;\n    rpf = other.rpf;\n    rpfc = other.rpfc;\n    szpf = other.szpf;\n    szpfc = other.szpfc;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetAllPropertyTypes::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetAllPropertyTypes(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetAllPropertyTypes::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetAllPropertyTypes* p = new QtnPropertySetAllPropertyTypes(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetAllPropertyTypes::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetAllPropertyTypes*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->bp.state() & ignoreMask))\n    {\n        bp = theCopyFrom->bp;\n    }\n\n    if (!(theCopyFrom->bpc.state() & ignoreMask))\n    {\n        bpc = theCopyFrom->bpc;\n    }\n\n    if (!(theCopyFrom->ip.state() & ignoreMask))\n    {\n        ip = theCopyFrom->ip;\n    }\n\n    if (!(theCopyFrom->ipc.state() & ignoreMask))\n    {\n        ipc = theCopyFrom->ipc;\n    }\n\n    if (!(theCopyFrom->up.state() & ignoreMask))\n    {\n        up = theCopyFrom->up;\n    }\n\n    if (!(theCopyFrom->upc.state() & ignoreMask))\n    {\n        upc = theCopyFrom->upc;\n    }\n\n    if (!(theCopyFrom->fp.state() & ignoreMask))\n    {\n        fp = theCopyFrom->fp;\n    }\n\n    if (!(theCopyFrom->fpc.state() & ignoreMask))\n    {\n        fpc = theCopyFrom->fpc;\n    }\n\n    if (!(theCopyFrom->dp.state() & ignoreMask))\n    {\n        dp = theCopyFrom->dp;\n    }\n\n    if (!(theCopyFrom->dpc.state() & ignoreMask))\n    {\n        dpc = theCopyFrom->dpc;\n    }\n\n    if (!(theCopyFrom->sp.state() & ignoreMask))\n    {\n        sp = theCopyFrom->sp;\n    }\n\n    if (!(theCopyFrom->spc.state() & ignoreMask))\n    {\n        spc = theCopyFrom->spc;\n    }\n\n    if (!(theCopyFrom->rp.state() & ignoreMask))\n    {\n        rp = theCopyFrom->rp;\n    }\n\n    if (!(theCopyFrom->rpc.state() & ignoreMask))\n    {\n        rpc = theCopyFrom->rpc;\n    }\n\n    if (!(theCopyFrom->pp.state() & ignoreMask))\n    {\n        pp = theCopyFrom->pp;\n    }\n\n    if (!(theCopyFrom->ppc.state() & ignoreMask))\n    {\n        ppc = theCopyFrom->ppc;\n    }\n\n    if (!(theCopyFrom->szp.state() & ignoreMask))\n    {\n        szp = theCopyFrom->szp;\n    }\n\n    if (!(theCopyFrom->szpc.state() & ignoreMask))\n    {\n        szpc = theCopyFrom->szpc;\n    }\n\n    if (!(theCopyFrom->ep.state() & ignoreMask))\n    {\n        ep = theCopyFrom->ep;\n    }\n\n    if (!(theCopyFrom->epc.state() & ignoreMask))\n    {\n        epc = theCopyFrom->epc;\n    }\n\n    if (!(theCopyFrom->efp.state() & ignoreMask))\n    {\n        efp = theCopyFrom->efp;\n    }\n\n    if (!(theCopyFrom->efpc.state() & ignoreMask))\n    {\n        efpc = theCopyFrom->efpc;\n    }\n\n    if (!(theCopyFrom->cp.state() & ignoreMask))\n    {\n        cp = theCopyFrom->cp;\n    }\n\n    if (!(theCopyFrom->cpc.state() & ignoreMask))\n    {\n        cpc = theCopyFrom->cpc;\n    }\n\n    if (!(theCopyFrom->fnp.state() & ignoreMask))\n    {\n        fnp = theCopyFrom->fnp;\n    }\n\n    if (!(theCopyFrom->fnpc.state() & ignoreMask))\n    {\n        fnpc = theCopyFrom->fnpc;\n    }\n\n    if (!(theCopyFrom->bttn.state() & ignoreMask))\n    {\n        bttn = theCopyFrom->bttn;\n    }\n\n    if (!(theCopyFrom->ppf.state() & ignoreMask))\n    {\n        ppf = theCopyFrom->ppf;\n    }\n\n    if (!(theCopyFrom->ppfc.state() & ignoreMask))\n    {\n        ppfc = theCopyFrom->ppfc;\n    }\n\n    if (!(theCopyFrom->rpf.state() & ignoreMask))\n    {\n        rpf = theCopyFrom->rpf;\n    }\n\n    if (!(theCopyFrom->rpfc.state() & ignoreMask))\n    {\n        rpfc = theCopyFrom->rpfc;\n    }\n\n    if (!(theCopyFrom->szpf.state() & ignoreMask))\n    {\n        szpf = theCopyFrom->szpf;\n    }\n\n    if (!(theCopyFrom->szpfc.state() & ignoreMask))\n    {\n        szpfc = theCopyFrom->szpfc;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetAllPropertyTypes::init()\n{\n    static QString AllPropertyTypes_name = QStringLiteral(\"AllPropertyTypes\");\n    setName(AllPropertyTypes_name);\n    setId(13);\n    \n    // start children initialization\n    static QString bp_name = QStringLiteral(\"bp\");\n    bp.setName(bp_name);\n    bp.setId(14);\n    static QString bpc_name = QStringLiteral(\"bpc\");\n    bpc.setName(bpc_name);\n    bpc.setCallbackValueGet([this]() { return _b; });\n    bpc.setCallbackValueSet([this](bool v, QtnPropertyChangeReason /*reason*/) { _b = v; });\n    bpc.setId(15);\n    static QString ip_name = QStringLiteral(\"ip\");\n    ip.setName(ip_name);\n    ip.setId(16);\n    static QString ipc_name = QStringLiteral(\"ipc\");\n    ipc.setName(ipc_name);\n    ipc.setCallbackValueGet([this]() { return _i; });\n    ipc.setCallbackValueSet([this](qint32 v, QtnPropertyChangeReason /*reason*/) { _i =v; });\n    ipc.setId(17);\n    static QString up_name = QStringLiteral(\"up\");\n    up.setName(up_name);\n    up.setId(18);\n    static QString upc_name = QStringLiteral(\"upc\");\n    upc.setName(upc_name);\n    upc.setCallbackValueGet([this]() { return _ui; });\n    upc.setCallbackValueSet([this](quint32 v, QtnPropertyChangeReason /*reason*/) { _ui = v; });\n    upc.setId(19);\n    static QString fp_name = QStringLiteral(\"fp\");\n    fp.setName(fp_name);\n    fp.setId(20);\n    static QString fpc_name = QStringLiteral(\"fpc\");\n    fpc.setName(fpc_name);\n    fpc.setCallbackValueGet([this]() { return _f; });\n    fpc.setCallbackValueSet([this](float v, QtnPropertyChangeReason /*reason*/) { _f = v; });\n    fpc.setId(21);\n    static QString dp_name = QStringLiteral(\"dp\");\n    dp.setName(dp_name);\n    dp.setId(22);\n    static QString dpc_name = QStringLiteral(\"dpc\");\n    dpc.setName(dpc_name);\n    dpc.setCallbackValueGet([this]() { return _d; });\n    dpc.setCallbackValueSet([this](double v, QtnPropertyChangeReason /*reason*/) { _d = v; });\n    dpc.setId(23);\n    static QString sp_name = QStringLiteral(\"sp\");\n    sp.setName(sp_name);\n    sp.setId(24);\n    static QString spc_name = QStringLiteral(\"spc\");\n    spc.setName(spc_name);\n    spc.setCallbackValueGet([this]() { return _s; });\n    spc.setCallbackValueSet([this](QString v, QtnPropertyChangeReason /*reason*/) { _s = v; });\n    spc.setId(25);\n    static QString rp_name = QStringLiteral(\"rp\");\n    rp.setName(rp_name);\n    rp.setId(26);\n    static QString rpc_name = QStringLiteral(\"rpc\");\n    rpc.setName(rpc_name);\n    rpc.setCallbackValueGet([this]() { return _r; });\n    rpc.setCallbackValueSet([this](QRect v, QtnPropertyChangeReason /*reason*/) { _r = v; });\n    rpc.setId(27);\n    static QString pp_name = QStringLiteral(\"pp\");\n    pp.setName(pp_name);\n    pp.setId(28);\n    static QString ppc_name = QStringLiteral(\"ppc\");\n    ppc.setName(ppc_name);\n    ppc.setCallbackValueGet([this]() { return _p; });\n    ppc.setCallbackValueSet([this](QPoint v, QtnPropertyChangeReason /*reason*/) { _p = v; });\n    ppc.setId(29);\n    static QString szp_name = QStringLiteral(\"szp\");\n    szp.setName(szp_name);\n    szp.setId(30);\n    static QString szpc_name = QStringLiteral(\"szpc\");\n    szpc.setName(szpc_name);\n    szpc.setCallbackValueGet([this]() { return _sz; });\n    szpc.setCallbackValueSet([this](QSize v, QtnPropertyChangeReason /*reason*/) { _sz = v; });\n    szpc.setId(31);\n    static QString ep_name = QStringLiteral(\"ep\");\n    ep.setName(ep_name);\n    ep.setEnumInfo(&COLOR::info());\n    ep.setId(32);\n    ep.setValue(COLOR::BLUE);\n    static QString epc_name = QStringLiteral(\"epc\");\n    epc.setName(epc_name);\n    epc.setCallbackValueGet([this]() { return _e; });\n    epc.setCallbackValueSet([this](QtnEnumValueType v, QtnPropertyChangeReason /*reason*/) { _e = v; });\n    epc.setEnumInfo(&COLOR::info());\n    epc.setId(33);\n    static QString efp_name = QStringLiteral(\"efp\");\n    efp.setName(efp_name);\n    efp.setEnumInfo(&MASK::info());\n    efp.setId(34);\n    efp.setValue(MASK::ONE|MASK::FOUR);\n    static QString efpc_name = QStringLiteral(\"efpc\");\n    efpc.setName(efpc_name);\n    efpc.setCallbackValueGet([this]() { return _ef; });\n    efpc.setCallbackValueSet([this](QtnEnumFlagsValueType v, QtnPropertyChangeReason /*reason*/) { _ef = v; });\n    efpc.setEnumInfo(&MASK::info());\n    efpc.setId(35);\n    static QString cp_name = QStringLiteral(\"cp\");\n    cp.setName(cp_name);\n    cp.setId(36);\n    cp.setValue(QColor(Qt::blue));\n    static QString cpc_name = QStringLiteral(\"cpc\");\n    cpc.setName(cpc_name);\n    cpc.setCallbackValueGet([this]() { return _cl; });\n    cpc.setCallbackValueSet([this](QColor v, QtnPropertyChangeReason /*reason*/) { _cl = v; });\n    cpc.setId(37);\n    static QString fnp_name = QStringLiteral(\"fnp\");\n    fnp.setName(fnp_name);\n    fnp.setId(38);\n    fnp.setValue(QFont(\"Courier\", 10));\n    static QString fnpc_name = QStringLiteral(\"fnpc\");\n    fnpc.setName(fnpc_name);\n    fnpc.setCallbackValueGet([this]() { return _fn; });\n    fnpc.setCallbackValueSet([this](QFont v, QtnPropertyChangeReason /*reason*/) { _fn = v; });\n    fnpc.setId(39);\n    static QString bttn_name = QStringLiteral(\"bttn\");\n    bttn.setName(bttn_name);\n    bttn.setId(40);\n    static QString ppf_name = QStringLiteral(\"ppf\");\n    ppf.setName(ppf_name);\n    ppf.setId(41);\n    static QString ppfc_name = QStringLiteral(\"ppfc\");\n    ppfc.setName(ppfc_name);\n    ppfc.setCallbackValueGet([this]() { return _pf; });\n    ppfc.setCallbackValueSet([this](QPointF v, QtnPropertyChangeReason /*reason*/) { _pf = v; });\n    ppfc.setId(42);\n    static QString rpf_name = QStringLiteral(\"rpf\");\n    rpf.setName(rpf_name);\n    rpf.setId(43);\n    static QString rpfc_name = QStringLiteral(\"rpfc\");\n    rpfc.setName(rpfc_name);\n    rpfc.setCallbackValueGet([this]() { return _rf; });\n    rpfc.setCallbackValueSet([this](QRectF v, QtnPropertyChangeReason /*reason*/) { _rf = v; });\n    rpfc.setId(44);\n    static QString szpf_name = QStringLiteral(\"szpf\");\n    szpf.setName(szpf_name);\n    szpf.setId(45);\n    static QString szpfc_name = QStringLiteral(\"szpfc\");\n    szpfc.setName(szpfc_name);\n    szpfc.setCallbackValueGet([this]() { return _szf; });\n    szpfc.setCallbackValueSet([this](QSizeF v, QtnPropertyChangeReason /*reason*/) { _szf = v; });\n    szpfc.setId(46);\n    // end children initialization\n}\n\nvoid QtnPropertySetAllPropertyTypes::connectSlots()\n{\n}\n\nvoid QtnPropertySetAllPropertyTypes::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetAllPropertyTypes::connectDelegates()\n{\n}\nstatic QtnEnumInfo& create_MY_TYPE_info()\n{\n    QVector<QtnEnumValueInfo> staticValues;\n    staticValues.append(QtnEnumValueInfo(MY_TYPE::MY_TYPE1, \"MY_TYPE1\", \"My type 1\"));\n    staticValues.append(QtnEnumValueInfo(MY_TYPE::MY_TYPE2, \"MY_TYPE2\", \"My type 2\"));\n    \n    static QtnEnumInfo enumInfo(\"MY_TYPE\", staticValues);\n    return enumInfo;\n}\n\nconst QtnEnumInfo& MY_TYPE::info()\n{\n    static QtnEnumInfo& enumInfo = create_MY_TYPE_info();\n    return enumInfo;\n}\n\nQtnPropertySetTest12::QtnPropertySetTest12(QObject* parent)\n    : QtnPropertySet(parent)\n    , p(*qtnCreateProperty<QtnPropertyEnum>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetTest12::~QtnPropertySetTest12()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetTest12& QtnPropertySetTest12::operator=(const QtnPropertySetTest12& other)\n{\n    Q_UNUSED(other);\n\n    p = other.p;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetTest12::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetTest12(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetTest12::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetTest12* p = new QtnPropertySetTest12(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetTest12::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetTest12*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->p.state() & ignoreMask))\n    {\n        p = theCopyFrom->p;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetTest12::init()\n{\n    static QString Test12_name = QStringLiteral(\"Test12\");\n    setName(Test12_name);\n    \n    // start children initialization\n    static QString p_name = QStringLiteral(\"p\");\n    p.setName(p_name);\n    p.setEnumInfo(&MY_TYPE::info());\n    p.setValue(MY_TYPE::MY_TYPE1);\n    // end children initialization\n}\n\nvoid QtnPropertySetTest12::connectSlots()\n{\n}\n\nvoid QtnPropertySetTest12::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetTest12::connectDelegates()\n{\n}\n"
  },
  {
    "path": "Tests/PEG/test.peg.h",
    "content": "#ifndef TEST_H\n#define TEST_H\n\n#include \"QtnProperty/Enum.h\"\n#include \"QtnProperty/PropertyCore.h\"\n#include \"QtnProperty/PropertyGUI.h\"\n\nclass QtnPropertySetTest1: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetTest1)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetTest1(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetTest1() override;\n    // assignment declaration\n    QtnPropertySetTest1& operator=(const QtnPropertySetTest1& other);\n    \n    // start children declarations\n    QtnPropertyInt& a;\n    QtnPropertyQString& text;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\nclass QtnPropertySetTest2: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetTest2)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetTest2(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetTest2() override;\n    // assignment declaration\n    QtnPropertySetTest2& operator=(const QtnPropertySetTest2& other);\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\n    // declaration\n    void aaa();\n\n\nclass QtnPropertySetYY: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetYY)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetYY(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetYY() override;\n    // assignment declaration\n    QtnPropertySetYY& operator=(const QtnPropertySetYY& other);\n    \n    // start children declarations\n    QtnPropertyQRect& rect;\n    QtnPropertyQString& s;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\nclass QtnPropertySetAA: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetAA)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetAA(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetAA() override;\n    // assignment declaration\n    QtnPropertySetAA& operator=(const QtnPropertySetAA& other);\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n\n               private:\n                   bool m_s;\n           \n};\n\nclass QtnPropertySetSS: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetSS)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetSS(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetSS() override;\n    // assignment declaration\n    QtnPropertySetSS& operator=(const QtnPropertySetSS& other);\n    \n    // start children declarations\n    QtnPropertyBool& a;\n    QtnPropertySetAA& aa;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\nclass QtnPropertySetTest3: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetTest3)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetTest3(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetTest3() override;\n    // assignment declaration\n    QtnPropertySetTest3& operator=(const QtnPropertySetTest3& other);\n    \n    // start children declarations\n    QtnPropertySetYY& yy;\n    QtnPropertySetSS& iis;\n    QtnPropertyBool& u;\n    QtnPropertySetTest2& xx;\n    QtnPropertySetTest2& tt;\n    QtnPropertySetSS& s;\n    QtnPropertyBool& ww;\n    QtnPropertyBoolCallback& bc;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n    \n    // start slot declarations\n    void on_propertyDidChange(QtnPropertyChangeReason reason);\n    void on_u_propertyWillChange(QtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId);\n    void on_u_propertyDidChange(QtnPropertyChangeReason reason);\n    void on_s_a_propertyValueAccept(QtnPropertyValuePtr valueToAccept, bool* accept);\n    void on_s_a_propertyWillChange(QtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId);\n    // end slot declarations\n\n        public:\n            bool m_s;\n    \n};\n\nclass LANGUAGE\n{\npublic:\n    enum Enum\n    {\n        ENG = 3\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 1;\n};\n\nclass TYPE\n{\npublic:\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 0;\n};\n\nclass COLOR\n{\npublic:\n    enum Enum\n    {\n        RED = 10,\n        BLUE = 22,\n        YELLOW = 1\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 3;\n};\n\nclass MASK\n{\npublic:\n    enum Enum\n    {\n        ONE = 1,\n        TWO = 2,\n        FOUR = 4\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 3;\n};\n\nclass QtnPropertySetAllPropertyTypes: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetAllPropertyTypes)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetAllPropertyTypes(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetAllPropertyTypes() override;\n    // assignment declaration\n    QtnPropertySetAllPropertyTypes& operator=(const QtnPropertySetAllPropertyTypes& other);\n    \n    // start children declarations\n    QtnPropertyBool& bp;\n    QtnPropertyBoolCallback& bpc;\n    QtnPropertyInt& ip;\n    QtnPropertyIntCallback& ipc;\n    QtnPropertyUInt& up;\n    QtnPropertyUIntCallback& upc;\n    QtnPropertyFloat& fp;\n    QtnPropertyFloatCallback& fpc;\n    QtnPropertyDouble& dp;\n    QtnPropertyDoubleCallback& dpc;\n    QtnPropertyQString& sp;\n    QtnPropertyQStringCallback& spc;\n    QtnPropertyQRect& rp;\n    QtnPropertyQRectCallback& rpc;\n    QtnPropertyQPoint& pp;\n    QtnPropertyQPointCallback& ppc;\n    QtnPropertyQSize& szp;\n    QtnPropertyQSizeCallback& szpc;\n    QtnPropertyEnum& ep;\n    QtnPropertyEnumCallback& epc;\n    QtnPropertyEnumFlags& efp;\n    QtnPropertyEnumFlagsCallback& efpc;\n    QtnPropertyQColor& cp;\n    QtnPropertyQColorCallback& cpc;\n    QtnPropertyQFont& fnp;\n    QtnPropertyQFontCallback& fnpc;\n    QtnPropertyButton& bttn;\n    QtnPropertyQPointF& ppf;\n    QtnPropertyQPointFCallback& ppfc;\n    QtnPropertyQRectF& rpf;\n    QtnPropertyQRectFCallback& rpfc;\n    QtnPropertyQSizeF& szpf;\n    QtnPropertyQSizeFCallback& szpfc;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n\n    private:\n        bool _b;\n        qint32 _i;\n        quint32 _ui;\n        float _f;\n        double _d;\n        QString _s;\n        QRect _r;\n        QRectF _rf;\n        QPoint _p;\n        QPointF _pf;\n        QSize _sz;\n        QSizeF _szf;\n        QtnEnumValueType _e;\n        QtnEnumFlagsValueType _ef;\n        QColor _cl;\n        QFont _fn;\n    \n};\n\nclass MY_TYPE\n{\npublic:\n    enum Enum\n    {\n        MY_TYPE1 = 1,\n        MY_TYPE2 = 2\n    };\n    \n    static const QtnEnumInfo& info();\n    static const unsigned int values_count = 2;\n};\n\nclass QtnPropertySetTest12: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetTest12)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetTest12(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetTest12() override;\n    // assignment declaration\n    QtnPropertySetTest12& operator=(const QtnPropertySetTest12& other);\n    \n    // start children declarations\n    QtnPropertyEnum& p;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n};\n\n#endif // TEST_H\n"
  },
  {
    "path": "Tests/PEG/test2.pef",
    "content": "#include_h \"QtnProperty/PropertyCore.h\"\n\nproperty_set A\n{\n    id = 50;\n    Bool b\n    {\n        id = 51;\n        value = true;\n        description = \"b property\";\n        delegate Combobox\n        {\n            labelTrue = \"On\";\n            labelFalse = \"Off\";\n        }\n    }\n\n    code_h\n    {\n        public:\n            void setOwner(int a);\n    }\n\n    code_cpp\n    {\n        void QtnPropertySetA::setOwner(int a)\n        {\n            b = (bool)a;\n        }\n    }\n};\n"
  },
  {
    "path": "Tests/PEG/test2.peg.cpp",
    "content": "#include \"test2.peg.h\"\n\n\nQtnPropertySetA::QtnPropertySetA(QObject* parent)\n    : QtnPropertySet(parent)\n    , b(*qtnCreateProperty<QtnPropertyBool>(this))\n{\n    init();\n    connectSlots();\n    connectDelegates();\n}\n\nQtnPropertySetA::~QtnPropertySetA()\n{\n    disconnectSlots();\n}\n\nQtnPropertySetA& QtnPropertySetA::operator=(const QtnPropertySetA& other)\n{\n    Q_UNUSED(other);\n\n    b = other.b;\n\n    return *this;\n}\n\nQtnPropertySet* QtnPropertySetA::createNewImpl(QObject* parentForNew) const\n{\n    return new QtnPropertySetA(parentForNew);\n}\n\nQtnPropertySet* QtnPropertySetA::createCopyImpl(QObject* parentForCopy) const\n{\n    QtnPropertySetA* p = new QtnPropertySetA(parentForCopy);\n    *p = *this;\n    return p;\n}\n\nbool QtnPropertySetA::copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask)\n{\n    Q_UNUSED(ignoreMask);\n\n    auto theCopyFrom = qobject_cast<QtnPropertySetA*>(propertySetCopyFrom);\n    if (!theCopyFrom)\n        return false;\n\n    if (!(theCopyFrom->b.state() & ignoreMask))\n    {\n        b = theCopyFrom->b;\n    }\n\n    return true;\n}\n\nvoid QtnPropertySetA::init()\n{\n    static QString A_name = QStringLiteral(\"A\");\n    setName(A_name);\n    setId(50);\n    \n    // start children initialization\n    static QString b_name = QStringLiteral(\"b\");\n    b.setName(b_name);\n    static QString b_description = \"b property\";\n    b.setDescription(b_description);\n    b.setId(51);\n    b.setValue(true);\n    // end children initialization\n}\n\nvoid QtnPropertySetA::connectSlots()\n{\n}\n\nvoid QtnPropertySetA::disconnectSlots()\n{\n}\n\nvoid QtnPropertySetA::connectDelegates()\n{\n    b.setDelegateInfoCallback([] () -> QtnPropertyDelegateInfo {\n        QtnPropertyDelegateInfo info;\n        info.name = \"Combobox\";\n        info.attributes[\"labelFalse\"] = \"Off\";\n        info.attributes[\"labelTrue\"] = \"On\";\n        return info;\n    });\n}\n\n        void QtnPropertySetA::setOwner(int a)\n        {\n            b = (bool)a;\n        }\n    \n"
  },
  {
    "path": "Tests/PEG/test2.peg.h",
    "content": "#ifndef TEST2_H\n#define TEST2_H\n\n#include \"QtnProperty/PropertyCore.h\"\n\nclass QtnPropertySetA: public QtnPropertySet\n{\n    Q_OBJECT\n    //Q_DISABLE_COPY(QtnPropertySetA)\n\npublic:\n    // constructor declaration\n    explicit QtnPropertySetA(QObject* parent = nullptr);\n    // destructor declaration\n    virtual ~QtnPropertySetA() override;\n    // assignment declaration\n    QtnPropertySetA& operator=(const QtnPropertySetA& other);\n    \n    // start children declarations\n    QtnPropertyBool& b;\n    // end children declarations\n\nprotected:\n    // cloning implementation\n    QtnPropertySet* createNewImpl(QObject* parentForNew) const override;\n    QtnPropertySet* createCopyImpl(QObject* parentForCopy) const override;\n    // copy values implementation\n    bool copyValuesImpl(QtnPropertySet* propertySetCopyFrom, QtnPropertyState ignoreMask) override;\n\nprivate:\n    void init();\n    void connectSlots();\n    void disconnectSlots();\n    void connectDelegates();\n\n        public:\n            void setOwner(int a);\n    \n};\n\n#endif // TEST2_H\n"
  },
  {
    "path": "Tests/TestEnum.cpp",
    "content": "#include \"TestEnum.h\"\n#include \"PEG/test.peg.h\"\n#include <QtTest/QtTest>\n\nvoid TestEnum::enumValue()\n{\n    COLOR::Enum color = COLOR::RED;\n    QVERIFY(color == COLOR::RED);\n}\n\nvoid TestEnum::forEachEnumValue()\n{\n    unsigned int count = 0;\n    COLOR::info().forEachEnumValue([&count](const QtnEnumValueInfo&)->bool {\n        ++count;\n        return true;\n    });\n    QVERIFY(count == COLOR::values_count);\n}\n\nvoid TestEnum::find()\n{\n    QVERIFY(COLOR::info().findByValue(COLOR::RED));\n    QVERIFY(!COLOR::info().findByValue(333));\n    QVERIFY(COLOR::info().findByDisplayName(\"Blue\"));\n    QVERIFY(COLOR::info().findByName(\"BLUE\"));\n    QVERIFY(!COLOR::info().findByName(\"Brown\"));\n    QVERIFY(!COLOR::info().findByDisplayName(\"Brown\"));\n}\n\nvoid TestEnum::state()\n{\n    QVERIFY(COLOR::info().findByValue(COLOR::RED)->state() == QtnEnumValueStateNone);\n    QVERIFY(COLOR::info().findByValue(COLOR::BLUE)->state() == (QtnEnumValueStateHidden | QtnEnumValueStateObsolete));\n}\n"
  },
  {
    "path": "Tests/TestEnum.h",
    "content": "#ifndef TEST_ENUM_H\n#define TEST_ENUM_H\n/*\n#include \"Property.h\"\n#include \"Enum.h\"\n#include \"PropertyCore.h\"\n#include \"PEG/test.peg.h\"\n#include <QtTest/QtTest>\n*/\n#include <QObject>\n\nclass TestEnum: public QObject\n{\n    Q_OBJECT\n\npublic:\n    Q_INVOKABLE TestEnum() {}\n\nprivate Q_SLOTS:\n\n    void enumValue();\n    void forEachEnumValue();\n    void find();\n    void state();\n};\n\n#endif // TEST_ENUM_H\n"
  },
  {
    "path": "Tests/TestGeneratedProperty.cpp",
    "content": "#include \"TestGeneratedProperty.h\"\n#include \"PEG/test.peg.h\"\n#include \"PEG/test2.peg.h\"\n#include <QtTest/QtTest>\n\nvoid TestGeneratedProperty::test1()\n{\n\tQtnPropertySetTest1 p;\n\tQVERIFY(p.name() == \"Test1\");\n\n\tp.a = 2;\n\tQVERIFY(p.a == 2);\n\tp.a = 15;\n\tQVERIFY(p.a.maxValue() == 10);\n\tQVERIFY(p.a == 2);\n\n\tp.a.incrementValue();\n\tQVERIFY(p.a == 1);\n\tQVERIFY(p.a > 0 && p.a >= 0 && p.a < 2 && p.a <= 1 && p.a != 3);\n\n\tQVERIFY(p.text == \"#^{};\");\n\tQVERIFY(p.text.description() ==\n\t\t\"defrf\\\"sde\\\"\"\n\t\t\"deerf3rfderf r g\\r\\nreg r{}dfrgergfwrewre\");\n\n\tp.text = QString(\"new value\");\n\tQVERIFY(p.text == \"new value\");\n}\n\nvoid TestGeneratedProperty::test2()\n{\n\tQtnPropertySetTest3 n(this);\n\tn.setName(\"SS\");\n\n\tQVERIFY(n.name() == \"SS\");\n\tQVERIFY(n.yy.rect == QRect(10, 10, 10, 10));\n\tQVERIFY(!n.s.a);\n\tn.s.a = true;\n\tQVERIFY(n.s.a);\n\tQVERIFY(n.yy.rect == QRect(1, 1, 1, 1));\n\n\tQVERIFY(n.ww == n.bc && n.bc == false);\n\tn.ww = true;\n\tQVERIFY(n.ww == n.bc && n.ww == true);\n\tn.bc = false;\n\tQVERIFY(n.bc);\n\tn.m_s = false;\n\tn.bc = true;\n\tQVERIFY(n.m_s);\n}\n\nvoid TestGeneratedProperty::testAllPropertyTypes()\n{\n\tQtnPropertySetAllPropertyTypes p;\n\n\tQVERIFY(p.ep == COLOR::BLUE);\n\tp.ep = COLOR::RED;\n\tswitch (p.ep)\n\t{\n\t\tcase COLOR::BLUE:\n\t\tcase COLOR::YELLOW:\n\t\t\tQFAIL(\"ep expected as COLOR::RED\");\n\t\t\tbreak;\n\n\t\tcase COLOR::RED:\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tQFAIL(\"ep expected as COLOR::RED\");\n\t}\n}\n\nvoid TestGeneratedProperty::testLoadSave()\n{\n\t{\n\t\tQtnPropertySetAllPropertyTypes p;\n\t\tQtnPropertySetA p2;\n\n\t\t{\n\t\t\tQtnPropertySet allProperties(nullptr);\n\t\t\tallProperties.addChildProperty(&p, false);\n\t\t\tallProperties.addChildProperty(&p2, false);\n\n\t\t\tQByteArray data;\n\n\t\t\t{\n\t\t\t\tQDataStream s(&data, QIODevice::WriteOnly);\n\t\t\t\ts.setVersion(QDataStream::Qt_4_2);\n\t\t\t\tQVERIFY(allProperties.save(s));\n\t\t\t}\n\n\t\t\tQCOMPARE(data.toBase64(),\n\t\t\t\tQByteArray(\n\t\t\t\t\t\"GYQCAAAEWwACAAAAAAAAAAACAAAADRmEAgAABBEAAgAAAAAAAAAAAgAAAA\"\n\t\t\t\t\t\"4ZhAIAAAALAAIAAAAAAAAAAAAAAAAPGYQCAAAACwACAAAAAAAAAAABAAAA\"\n\t\t\t\t\t\"EBmEAgAAAA4AAgAAAQAAAAAAAAAAAAAAABEZhAIAAAAOAAIAAAAAAAAAAA\"\n\t\t\t\t\t\"AAAAwAAAASGYQCAAAADgACAAABAAAAAAAAAAAAAAAAExmEAgAAAA4AAgAA\"\n\t\t\t\t\t\"AAAAAAAAAAAACQAAABQZhAIAAAAOAAIAAAEAAAAAAAAAAAAAAAAVGYQCAA\"\n\t\t\t\t\t\"AADgACAAAAAAAAAAA+\"\n\t\t\t\t\t\"TMzNAAAAFhmEAgAAABIAAgAAAQAAAAAAAAAAAAAAAAAAAAAXGYQCAAAAEg\"\n\t\t\t\t\t\"ACAAAAAAAAAABAQDMzMzMzMwAAABgZhAIAAAAOAAIAAAAAAAAAAP////\"\n\t\t\t\t\t\"8AAAAZGYQCAAAAFgACAAAAAAAAAAAAAAAIAG4AYQBtAGUAAAAaGYQCAAAA\"\n\t\t\t\t\t\"GgACAAAAAAAAAAAAAAAAAAAAAP//////////\"\n\t\t\t\t\t\"AAAAGxmEAgAAABoAAgAAAAAAAAAAAAAACgAAAAoAAAATAAAAEwAAABwZhA\"\n\t\t\t\t\t\"IAAAASAAIAAAAAAAAAAAAAAAAAAAAAAAAAHRmEAgAAABIAAgAAAAAAAAAA\"\n\t\t\t\t\t\"AAAACQAAAAIAAAAeGYQCAAAAEgACAAAAAAAAAAD//////////\"\n\t\t\t\t\t\"wAAAB8ZhAIAAAASAAIAAAAAAAAAAAAAACEAAAAVAAAAIBmEAgAAAA4AAgA\"\n\t\t\t\t\t\"AAAAAAAAAAAAAFgAAACEZhAIAAAAOAAIAAAAAAAAAAAAAAAoAAAAiGYQCA\"\n\t\t\t\t\t\"AAADgACAAAAAAAAAAAAAAAFAAAAIxmEAgAAAA4AAgAAAAAAAAAAAAAABQA\"\n\t\t\t\t\t\"AACQZhAIAAAAVAAIAAAAAAAAAAAH//wAAAAD//\"\n\t\t\t\t\t\"wAAAAAAJRmEAgAAABUAAgAAAAAAAAAAAf////\"\n\t\t\t\t\t\"8AAAAAAAAAAAAmGYQCAAAALQACAAAAAAAAAAAAAAAOAEMAbwB1AHIAaQBl\"\n\t\t\t\t\t\"AHJAJAAAAAAAAP////\"\n\t\t\t\t\t\"8FAQAyEAAAACcZhAIAAAApAAIAAAAAAAAAAAAAAAoAQQByAGkAYQBsQDMA\"\n\t\t\t\t\t\"AAAAAAD/////\"\n\t\t\t\t\t\"BQEAMhAAAAApGYQCAAAAGgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n\t\t\t\t\t\"AAKhmEAgAAABoAAgAAAAAAAAAAQCPMzMzMzM1AAZmZmZmZmgAAACsZhAIA\"\n\t\t\t\t\t\"AAAqAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n\t\t\t\t\t\"AAAAAALBmEAgAAACoAAgAAAAAAAAAAQCQzMzMzMzNAJGZmZmZmZkAkmZmZ\"\n\t\t\t\t\t\"mZmaQCTMzMzMzM0AAAAtGYQCAAAAGgACAAAAAAAAAAC/8AAAAAAAAL/\"\n\t\t\t\t\t\"wAAAAAAAAAAAALhmEAgAAABoAAgAAAAAAAAAAQECAAAAAAABANeZmZmZmZ\"\n\t\t\t\t\t\"v////\"\n\t\t\t\t\t\"8AAAAyGYQCAAAAJQACAAAAAAAAAAACAAAAMxmEAgAAAAsAAgAAAAAAAAAA\"\n\t\t\t\t\t\"Af//////////\"));\n\t\t\tQCOMPARE(data.size(), 1122);\n\n\t\t\t{\n\t\t\t\tQDataStream s(&data, QIODevice::ReadOnly);\n\t\t\t\ts.setVersion(QDataStream::Qt_4_2);\n\t\t\t\tQVERIFY(allProperties.load(s));\n\t\t\t}\n\n\t\t\tQString result;\n\t\t\tQVERIFY(allProperties.toStr(result));\n\n\t\t\tQCOMPARE(result.size(), 1091);\n\t\t}\n\t}\n}\n\nvoid TestGeneratedProperty::testJson()\n{\n\tQtnPropertySetAllPropertyTypes p;\n\n\tQJsonObject o;\n\tQVERIFY(p.toJson(o));\n\n\tQJsonDocument d(o);\n\tauto res = d.toJson();\n\tQCOMPARE(res.size(), 1595);\n\tres = d.toJson(QJsonDocument::Compact);\n\tQCOMPARE(res.size(), 921);\n\n\tQVERIFY(p.fromJson(o));\n}\n"
  },
  {
    "path": "Tests/TestGeneratedProperty.h",
    "content": "#ifndef TEST_GENERATED_PROPERTY_H\n#define TEST_GENERATED_PROPERTY_H\n\n#include <QObject>\n\nclass TestGeneratedProperty: public QObject\n{\n    Q_OBJECT\n\npublic:\n    Q_INVOKABLE TestGeneratedProperty() {}\n\nprivate Q_SLOTS:\n\n    void test1();\n    void test2();\n    void testAllPropertyTypes();\n    void testLoadSave();\n    void testJson();\n};\n\n#endif // TEST_GENERATED_PROPERTY_H\n"
  },
  {
    "path": "Tests/TestProperty.cpp",
    "content": "#include \"TestProperty.h\"\n#include \"QtnProperty/QObjectPropertySet.h\"\n#include \"PEG/test.peg.h\"\n#include <QtTest/QtTest>\n#include <QtScript/QScriptEngine>\n\nstatic bool ret_true()\n{\n\treturn true;\n}\n\nstatic void verifyInitialValues(QtnPropertySetAllPropertyTypes &pp)\n{\n\tQVERIFY(pp.bp == false);\n\tQVERIFY(pp.bpc == true);\n\tQVERIFY(pp.ip == 0);\n\tQVERIFY(pp.ipc == 12);\n\tQVERIFY(pp.up == 0u);\n\tQVERIFY(pp.upc == 9u);\n\tQVERIFY(pp.fp == 0.f);\n\tQVERIFY(pp.fpc == 0.2f);\n\tQVERIFY(pp.dp == 0.);\n\tQVERIFY(pp.dpc == 32.4);\n\tQVERIFY(pp.sp == \"\");\n\tQVERIFY(pp.spc == \"name\");\n\tQVERIFY(pp.rp == QRect());\n\tQVERIFY(pp.rpc == QRect(10, 10, 10, 10));\n\tQVERIFY(pp.rpf == QRectF());\n\tQVERIFY(pp.rpfc == QRectF(10.1, 10.2, 10.3, 10.4));\n\tQVERIFY(pp.pp == QPoint());\n\tQVERIFY(pp.ppc == QPoint(9, 2));\n\tQVERIFY(pp.ppf == QPointF());\n\tQVERIFY(pp.ppfc == QPointF(9.9, 2.2));\n\tQVERIFY(pp.szp == QSize());\n\tQVERIFY(pp.szpc == QSize(33, 21));\n\tQVERIFY(pp.szpf == QSizeF());\n\tQVERIFY(pp.szpfc == QSizeF(33.0, 21.9));\n\tQVERIFY(pp.ep == COLOR::BLUE);\n\tQVERIFY(pp.epc == COLOR::RED);\n\tQVERIFY(pp.efp == (MASK::ONE | MASK::FOUR));\n\tQVERIFY(pp.efpc == (MASK::ONE | MASK::FOUR));\n\tQVERIFY(pp.cp == QColor(Qt::blue));\n\tQVERIFY(pp.cpc == QColor(Qt::red));\n\tQVERIFY(pp.fnp == QFont(\"Courier\", 10));\n\tQVERIFY(pp.fnpc == QFont(\"Arial\", 19));\n}\n\nstatic void modify(QtnPropertySetAllPropertyTypes &pp)\n{\n\tpp.bp = true;\n\tpp.bpc = false;\n\tpp.ip = 12;\n\tpp.ipc = 2;\n\tpp.up = 3u;\n\tpp.upc = 32u;\n\tpp.fp = 0.32f;\n\tpp.fpc = 32.2f;\n\tpp.dp = 12.;\n\tpp.dpc = 2.4;\n\tpp.sp = \"test\";\n\tpp.spc = \"name#1\";\n\tpp.rp = QRect(12, 10, 16, 17);\n\tpp.rpc = QRect(4, 3, 1, 0);\n\tpp.rpf = QRectF(12.3, 10.4, 16.5, 17.6);\n\tpp.rpfc = QRectF(4.1, 3.2, 1.3, 0.0);\n\tpp.pp = QPoint(21, 9);\n\tpp.ppc = QPoint(15, 0);\n\tpp.ppf = QPointF(21.21, 9.9);\n\tpp.ppfc = QPointF(15.15, 0.0);\n\tpp.szp = QSize(90, 87);\n\tpp.szpc = QSize(0, 1);\n\tpp.szpf = QSizeF(90.9, 87.7);\n\tpp.szpfc = QSizeF(0.1, 1.0);\n\tpp.ep = COLOR::RED;\n\tpp.epc = COLOR::BLUE;\n\tpp.efp = (MASK::FOUR);\n\tpp.efpc = (MASK::ONE);\n\tpp.cp = QColor(Qt::red);\n\tpp.cpc = QColor(Qt::blue);\n\tpp.fnp = QFont(\"Courier New\", 11);\n\tpp.fnpc = QFont(\"Myfont\", 0);\n}\n\nstatic void verifyModified(QtnPropertySetAllPropertyTypes &pp)\n{\n\tQCOMPARE(pp.bp.value(), true);\n\tQCOMPARE(pp.bpc.value(), false);\n\tQCOMPARE(pp.ip.value(), 12);\n\tQCOMPARE(pp.ipc.value(), 2);\n\tQCOMPARE(pp.up.value(), 3u);\n\tQCOMPARE(pp.upc.value(), 32u);\n\tQCOMPARE(pp.fp.value(), 0.32f);\n\tQCOMPARE(pp.fpc.value(), 32.2f);\n\tQCOMPARE(pp.dp.value(), 12.);\n\tQCOMPARE(pp.dpc.value(), 2.4);\n\tQCOMPARE(pp.sp.value(), QString(\"test\"));\n\tQCOMPARE(pp.spc.value(), QString(\"name#1\"));\n\tQCOMPARE(pp.rp.value(), QRect(12, 10, 16, 17));\n\tQCOMPARE(pp.rpc.value(), QRect(4, 3, 1, 0));\n\tQCOMPARE(pp.rpf.value(), QRectF(12.3, 10.4, 16.5, 17.6));\n\tQCOMPARE(pp.rpfc.value(), QRectF(4.1, 3.2, 1.3, 0.0));\n\tQCOMPARE(pp.pp.value(), QPoint(21, 9));\n\tQCOMPARE(pp.ppc.value(), QPoint(15, 0));\n\tQCOMPARE(pp.ppf.value(), QPointF(21.21, 9.9));\n\tQCOMPARE(pp.ppfc.value(), QPointF(15.15, 0.0));\n\tQCOMPARE(pp.szp.value(), QSize(90, 87));\n\tQCOMPARE(pp.szpc.value(), QSize(0, 1));\n\tQCOMPARE(pp.szpf.value(), QSizeF(90.9, 87.7));\n\tQCOMPARE(pp.szpfc.value(), QSizeF(0.1, 1.0));\n\tQCOMPARE(pp.ep.value(), (QtnEnumValueType) COLOR::RED);\n\tQCOMPARE(pp.epc.value(), (QtnEnumValueType) COLOR::BLUE);\n\tQCOMPARE(pp.efp.value(), (QtnEnumFlagsValueType) MASK::FOUR);\n\tQCOMPARE(pp.efpc.value(), (QtnEnumFlagsValueType) MASK::ONE);\n\tQCOMPARE(pp.cp.value(), QColor(Qt::red));\n\tQCOMPARE(pp.cpc.value(), QColor(Qt::blue));\n\tQCOMPARE(pp.fnp.value(), QFont(\"Courier New\", 11));\n\tQCOMPARE(pp.fnpc.value(), QFont(\"Myfont\", 0));\n}\n\nvoid TestProperty::name()\n{\n\tQtnPropertyInt p(this);\n\tp.setName(QString(\"PropertyName\"));\n\tQCOMPARE(p.name(), QString(\"PropertyName\"));\n\n\tQtnPropertySet p1(nullptr);\n\tp1.setName(\"AnotherName\");\n\tQCOMPARE(p1.name(), QString(\"AnotherName\"));\n}\n\nvoid TestProperty::description()\n{\n\tQtnPropertyBool p(this);\n\tp.setDescription(QString(\"PropertyDescription\"));\n\tQCOMPARE(p.description(), QString(\"PropertyDescription\"));\n\n\tQtnPropertySet p1(nullptr);\n\tp1.setDescription(\"Another description\\nwith multiline.\");\n\tQCOMPARE(p1.description(), QString(\"Another description\\nwith multiline.\"));\n}\n\nvoid TestProperty::id()\n{\n\tQtnPropertySet p(nullptr);\n\tQCOMPARE(p.id(), QtnPropertyIDInvalid);\n\tp.setId(12);\n\tQCOMPARE(p.id(), 12);\n\n\tQtnPropertyUInt p1(&p);\n\tQCOMPARE(p1.id(), QtnPropertyIDInvalid);\n\tp1.setId(5);\n\tQCOMPARE(p1.id(), 5);\n}\n\nvoid TestProperty::state()\n{\n\tQtnPropertySet ps(0);\n\tQtnPropertyInt p(&ps);\n\tps.addChildProperty(&p);\n\n\tQCOMPARE(ps.state(), QtnPropertyStateNone);\n\tQCOMPARE(p.state(), QtnPropertyStateResettable);\n\n\tQtnPropertyState master_state =\n\t\tQtnPropertyStateInvisible | QtnPropertyStateNonSimple;\n\n\tps.setState(master_state);\n\tQCOMPARE(ps.state(), master_state);\n\tQCOMPARE(ps.stateLocal(), master_state);\n\tQCOMPARE(ps.stateInherited(), QtnPropertyStateNone);\n\tQCOMPARE(p.state(), master_state | QtnPropertyStateResettable);\n\tQCOMPARE(p.stateLocal(), QtnPropertyStateResettable);\n\tQCOMPARE(p.stateInherited(), master_state);\n\n\tp.addState(QtnPropertyStateImmutable);\n\tQCOMPARE(ps.state(), master_state);\n\tQCOMPARE(ps.stateLocal(), master_state);\n\tQCOMPARE(ps.stateInherited(), QtnPropertyStateNone);\n\tQCOMPARE(p.state(),\n\t\tmaster_state | QtnPropertyStateResettable | QtnPropertyStateImmutable);\n\tQCOMPARE(\n\t\tp.stateLocal(), QtnPropertyStateResettable | QtnPropertyStateImmutable);\n\tQCOMPARE(p.stateInherited(), master_state);\n\n\tps.removeState(QtnPropertyStateInvisible);\n\tQCOMPARE(ps.state(), QtnPropertyStateNonSimple);\n\tQCOMPARE(ps.stateLocal(), QtnPropertyStateNonSimple);\n\tQCOMPARE(ps.stateInherited(), QtnPropertyStateNone);\n\tQCOMPARE(p.state(),\n\t\tQtnPropertyStateNonSimple | QtnPropertyStateResettable |\n\t\t\tQtnPropertyStateImmutable);\n\tQCOMPARE(\n\t\tp.stateLocal(), QtnPropertyStateResettable | QtnPropertyStateImmutable);\n\tQCOMPARE(p.stateInherited(), QtnPropertyStateNonSimple);\n\n\tp.switchState(QtnPropertyStateResettable, false);\n\tps.switchState(QtnPropertyStateInvisible, true);\n\tQCOMPARE(ps.state(), master_state);\n\tQCOMPARE(ps.stateLocal(), master_state);\n\tQCOMPARE(ps.stateInherited(), QtnPropertyStateNone);\n\tQCOMPARE(p.state(), master_state | QtnPropertyStateImmutable);\n\tQCOMPARE(p.stateLocal(), QtnPropertyStateImmutable);\n\tQCOMPARE(p.stateInherited(), master_state);\n\n\tQVERIFY(!ps.isEditableByUser());\n\n\tps.removeState(master_state | QtnPropertyStateCollapsed);\n\tQVERIFY(ps.isEditableByUser());\n\tQCOMPARE(ps.state(), QtnPropertyStateNone);\n\n\tint call_count = 0;\n\tauto connection1 =\n\t\tQObject::connect(&ps, &QtnPropertyBase::propertyWillChange,\n\t\t\t[&call_count](QtnPropertyChangeReason, QtnPropertyValuePtr, int) {\n\t\t\t\t++call_count;\n\t\t\t});\n\n\tauto connection2 =\n\t\tQObject::connect(&ps, &QtnPropertyBase::propertyDidChange,\n\t\t\t[&call_count](QtnPropertyChangeReason) { ++call_count; });\n\n\tps.addState(QtnPropertyStateNone, true);\n\tQCOMPARE(call_count, 2);\n\n\tps.removeState(QtnPropertyStateCollapsed);\n\tQCOMPARE(call_count, 2);\n\n\tps.removeState(QtnPropertyStateCollapsed, true);\n\tQCOMPARE(call_count, 4);\n\n\tQObject::disconnect(connection1);\n\tQObject::disconnect(connection2);\n}\n\nvoid TestProperty::stateChange()\n{\n\tQtnPropertyFloat p(this);\n\tQObject::connect(&p, &QtnPropertyBase::propertyWillChange, this,\n\t\t&TestProperty::checkPropertyStateIsNonSimple);\n\n\tp.addState(QtnPropertyStateNonSimple);\n}\n\nvoid TestProperty::propertyDelegate()\n{\n\tQtnPropertyBool p(this);\n\tQVERIFY(!p.delegateInfo());\n\n\tQtnPropertyDelegateInfo info;\n\tinfo.name = \"delegateName\";\n\tp.setDelegateInfo(info);\n\tQVERIFY(p.delegateInfo());\n\tQVERIFY(p.delegateInfo()->name == \"delegateName\");\n\tQVERIFY(p.delegateInfo()->attributes.isEmpty());\n\n\tinfo.attributes[\"int\"] = 4;\n\tp.setDelegateInfo(info);\n\tQVERIFY(p.delegateInfo()->attributes.size() == 1);\n\tQVERIFY(p.delegateInfo()->attributes[\"int\"] == 4);\n\n\tinfo.attributes[\"str\"] = QString(\"Text\");\n\tp.setDelegateInfo(info);\n\tQVERIFY(p.delegateInfo()->attributes.size() == 2);\n\tQVERIFY(p.delegateInfo()->attributes[\"str\"] == \"Text\");\n\n\tinfo.attributes[\"int\"] = 12;\n\tp.setDelegateInfo(info);\n\tQVERIFY(p.delegateInfo()->attributes.size() == 2);\n\tQVERIFY(p.delegateInfo()->attributes[\"int\"] == 12);\n}\n\nvoid TestProperty::propertyDelegateCallback()\n{\n\tQtnPropertyBool p(this);\n\tQVERIFY(!p.delegateInfo());\n\n\tp.setDelegateInfoCallback([]() -> QtnPropertyDelegateInfo {\n\t\tQtnPropertyDelegateInfo info;\n\t\tinfo.name = \"delegate\";\n\t\tinfo.attributes[\"one\"] = 1;\n\t\tinfo.attributes[\"color\"] = QColor(Qt::black);\n\t\treturn info;\n\t});\n\n\tQVERIFY(p.delegateInfo());\n\tQVERIFY(p.delegateInfo()->name == \"delegate\");\n\tQVERIFY(p.delegateInfo()->attributes.size() == 2);\n\tQVERIFY(p.delegateInfo()->attributes[\"one\"] == 1);\n\tQVERIFY(p.delegateInfo()->attributes[\"color\"] == QColor(Qt::black));\n}\n\nvoid TestProperty::propertyBool()\n{\n\t{\n\t\tQtnPropertyBoolCallback p(this);\n\n\t\tp.setCallbackValueGet([]() -> bool { return false; });\n\t\tQVERIFY(p.value() == false);\n\n\t\tp.setCallbackValueSet(\n\t\t\t[](bool newValue, QtnPropertyChangeReason /*reason*/) {\n\t\t\t\tQVERIFY(newValue == true);\n\t\t\t});\n\n\t\tp = true;\n\n\t\tp.setCallbackValueSet(\n\t\t\t[](bool newValue, QtnPropertyChangeReason /*reason*/) {\n\t\t\t\tQVERIFY(newValue == false);\n\t\t\t});\n\t\tp.setValue(false);\n\n\t\tQVERIFY2(!p, \"p expected as false\");\n\n\t\tp.setCallbackValueGet(&ret_true);\n\t\tQVERIFY2(p, \"p expected as true\");\n\n\t\tQtnPropertyBoolBase &p1 = p;\n\t\tQVERIFY2(p1, \"p1 expected as true\");\n\n\t\tQtnPropertyBoolCallback p2(this);\n\t\tbool val = true;\n\n\t\tp2.setCallbackValueGet([&val]() -> bool { return val; });\n\n\t\tp2.setCallbackValueSet(\n\t\t\t[&val](bool newValue, QtnPropertyChangeReason /*reason*/) {\n\t\t\t\tval = newValue;\n\t\t\t});\n\n\t\tQVERIFY(p2);\n\n\t\tp2 = false;\n\t\tQVERIFY(!val);\n\n\t\tp2 = p;\n\t\tQVERIFY(p);\n\n\t\tp2 = !p;\n\t\tQVERIFY(!p2);\n\n\t\tp1 = p2;\n\t\tQVERIFY(p1 && p && !p2);\n\n\t\tQtnPropertyBool p3(this);\n\t\tp2 = p3 = true;\n\t\tQVERIFY(p2);\n\t}\n\n\t{\n\t\tQtnPropertyBool p(this);\n\t\tQVERIFY2(!p, \"p expected as false\");\n\n\t\tp = true;\n\t\tQVERIFY(p == true);\n\n\t\tp = (p != true);\n\t\tQVERIFY(!p);\n\n\t\tswitch (int(p) + 4)\n\t\t{\n\t\t\tcase 4:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tQFAIL(\"p expected as false\");\n\t\t}\n\n\t\tp = bool(5);\n\t\tQVERIFY(p);\n\n\t\tQVERIFY(p != false);\n\t\tQVERIFY(p == true);\n\t\tQVERIFY(p && (p > false));\n\t\tQVERIFY(p >= true);\n\t\tQVERIFY(!(p <= false));\n\n\t\tQtnPropertyBoolCallback p2(this);\n\t\tp2.setCallbackValueGet([]() -> bool { return false; });\n\t\tp = p2;\n\t\tQVERIFY(!p);\n\t}\n}\n\nvoid TestProperty::propertyInt()\n{\n\tQtnPropertyInt p(this);\n\tp.setMaxValue(10);\n\tp.setMinValue(1);\n\tp.setValue(5);\n\tQVERIFY(p.value() == 5);\n\n\tp.setMaxValue(3);\n\tQVERIFY(p.value() == 3);\n\n\tp = 1;\n\tQVERIFY(p == 1);\n\tQVERIFY(p > 0);\n\tQVERIFY(p >= 0);\n\tQVERIFY(p < 2);\n\tQVERIFY(p <= 2);\n}\n\nvoid TestProperty::propertyString()\n{\n\tQtnPropertyQString p(this);\n\tQVERIFY(p == QString(\"\"));\n\tp = QString(\"hello\");\n\tQVERIFY(p == QString(\"hello\"));\n\tp = \"latin string\";\n\tQVERIFY(p == \"latin string\");\n\n\tconst QString &val = p;\n\tQVERIFY(val == \"latin string\");\n}\n\nvoid TestProperty::propertyRect()\n{\n\tQtnPropertyQRect p(this);\n\tQVERIFY(p == QRect());\n\tQRect rect(1, 2, 3, 4);\n\tp = rect;\n\tQVERIFY(p == rect);\n\n\tQtnPropertyQRectCallback pc(this);\n\tQRect pc_value;\n\tpc.setCallbackValueGet([&pc_value]() -> const QRect & { return pc_value; });\n\tpc.setCallbackValueSet(\n\t\t[&pc_value](const QRect &value, QtnPropertyChangeReason /*reason*/) {\n\t\t\tpc_value = value;\n\t\t});\n\n\tpc = QRect(10, 10, 10, 10);\n\tQCOMPARE(pc.value(), QRect(10, 10, 10, 10));\n\n\tpc = p;\n\tQVERIFY(pc.value() == p.value());\n\tQVERIFY(pc == p);\n\n\tQtnPropertyQRectBase *pb = &pc;\n\t*pb = QRect(3, 4, 5, 6);\n\tQVERIFY(pc.value() == pb->value() && (*pb) == QRect(3, 4, 5, 6));\n}\n\nvoid TestProperty::propertyEnum()\n{\n\tQtnPropertyEnum p(this);\n\tp = COLOR::BLUE;\n\tQVERIFY(p != COLOR::BLUE);\n\tQVERIFY(!p.setValue(COLOR::RED));\n\n\tp.setEnumInfo(&COLOR::info());\n\tQVERIFY(p.setValue(COLOR::RED));\n\tQVERIFY(p == COLOR::RED);\n\n\tQtnPropertyEnumCallback pc(this);\n\tpc.setCallbackValueGet([]() -> QtnEnumValueType { return COLOR::YELLOW; });\n\tQVERIFY(pc == COLOR::YELLOW);\n}\n\nvoid TestProperty::propertyEnumFlags()\n{\n\tQtnPropertyEnumFlags p(this);\n\tp.setEnumInfo(&MASK::info());\n\tp = MASK::ONE;\n\t//QVERIFY(p == MASK::ONE);\n\tp = MASK::TWO | MASK::FOUR;\n\tQVERIFY(p & MASK::FOUR);\n\tQVERIFY(!(p & MASK::ONE));\n}\n\nvoid TestProperty::propertyPen()\n{\n\t{\n\t\tQtnPropertyQPenStyle p(this);\n\t\tp = Qt::SolidLine;\n\t\tQCOMPARE(p.value(), Qt::SolidLine);\n\n\t\tp = Qt::DashDotDotLine;\n\t\tQCOMPARE(p.value(), Qt::DashDotDotLine);\n\t}\n\n\t{\n\t\tQtnPropertyQPen p(this);\n\n\t\t{\n\t\t\tQPen pen(QBrush(QColor(10, 100, 200)), 10, Qt::DashDotLine,\n\t\t\t\tQt::RoundCap, Qt::SvgMiterJoin);\n\t\t\tp = pen;\n\t\t\tQCOMPARE(p.value(), pen);\n\t\t}\n\n\t\t{\n\t\t\tQString str;\n\t\t\tQVERIFY(p.toStr(str));\n\t\t\tQCOMPARE(str,\n\t\t\t\tQString(\"#0a64c8, DashDotLine, 10, RoundCap, \"\n\t\t\t\t\t\t\"SvgMiterJoin\"));\n\t\t}\n\n\t\t{\n\t\t\tQString str = \"#0000ff, DashLine, 3, SquareCap, BevelJoin\";\n\t\t\tQVERIFY(p.fromStr(str));\n\n\t\t\tQCOMPARE(p.value().color(), QColor(Qt::blue));\n\t\t\tQCOMPARE(p.value().width(), 3);\n\t\t\tQCOMPARE(p.value().style(), Qt::DashLine);\n\t\t\tQCOMPARE(p.value().capStyle(), Qt::SquareCap);\n\t\t\tQCOMPARE(p.value().joinStyle(), Qt::BevelJoin);\n\t\t}\n\t}\n}\n\nvoid TestProperty::propertyVector3D()\n{\n\tQVector3D testValue(12.f, 22.f, 33.f);\n\tQtnPropertyQVector3D p;\n\tp.setValue(testValue);\n\n\tQCOMPARE(p.value(), testValue);\n\n\tQString str;\n\tQVERIFY(p.toStr(str));\n\tp.setValue(QVector3D(1.f, 1.f, 1.f));\n\tQVERIFY(p.value() != testValue);\n\tQVERIFY(p.fromStr(str));\n\tQCOMPARE(p.value(), testValue);\n}\n\nvoid TestProperty::propertySet()\n{\n\tQtnPropertySet p(this);\n\n\tQtnPropertySet pp(&p);\n\tpp.setName(\"pp\");\n\tp.addChildProperty(&pp);\n\n\tQtnPropertyBool b(&pp);\n\tb.setName(\"b\");\n\tpp.addChildProperty(&b);\n\n\tQtnPropertyFloat f(nullptr);\n\tf.setName(\"f\");\n\tp.addChildProperty(&f);\n\n\tQtnPropertyBool bb(&p);\n\tbb.setName(\"b\");\n\tp.addChildProperty(&bb);\n\n\tQList<QtnPropertyBase *> res = p.findChildProperties(\"pp\");\n\tQCOMPARE(res.size(), 1);\n\tQCOMPARE(res[0], &pp);\n\n\tres = p.findChildProperties(\"b\");\n\tQCOMPARE(res.size(), 2);\n\n\tres = p.findChildProperties(\"b\", Qt::FindDirectChildrenOnly);\n\tQCOMPARE(res.size(), 1);\n\tQCOMPARE(res[0], &bb);\n\n\tres = pp.findChildProperties(\"b\");\n\tQCOMPARE(res.size(), 1);\n\tQCOMPARE(res[0], &b);\n\n\tres = p.findChildProperties(\"pp.b\");\n\tQCOMPARE(res.size(), 1);\n\tQCOMPARE(res[0], &b);\n}\n\nstatic void testSerializationState(QtnPropertyBase &p)\n{\n\tp.setState(QtnPropertyStateCollapsed);\n\n\tQByteArray data;\n\n\t{\n\t\tQDataStream s(&data, QIODevice::WriteOnly);\n\t\tQVERIFY(p.save(s));\n\t}\n\n\tp.setState(QtnPropertyStateImmutable);\n\tQCOMPARE(p.state(), QtnPropertyStateImmutable);\n\n\t{\n\t\tQDataStream s(&data, QIODevice::ReadOnly);\n\t\tQVERIFY(p.load(s));\n\t}\n\n\tQCOMPARE(p.state(), QtnPropertyStateCollapsed);\n}\n\nvoid TestProperty::serializationState()\n{\n\t{\n\t\tQtnPropertyInt p(this);\n\t\ttestSerializationState(p);\n\t}\n\n\t{\n\t\tQtnPropertySet p(nullptr);\n\t\ttestSerializationState(p);\n\t}\n}\n\nvoid TestProperty::serializationChildren()\n{\n\tQtnPropertySet ps(this);\n\tps.setState(QtnPropertyStateCollapsed);\n\n\tQByteArray data;\n\n\tQtnProperty *p2(qtnCreateProperty<QtnPropertyInt>(&ps));\n\tp2->setId(1);\n\tp2->setState(QtnPropertyStateImmutable);\n\n\tQtnPropertyBool p3(&ps);\n\tp3.setId(2);\n\tp3.setState(QtnPropertyStateNonSerialized);\n\tps.addChildProperty(&p3);\n\n\t{\n\t\tQDataStream s(&data, QIODevice::WriteOnly);\n\t\ts << ps;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tQCOMPARE(\n\t\tp2->state(), (QtnPropertyStateImmutable | QtnPropertyStateCollapsed));\n\tQCOMPARE(p3.state(),\n\t\t(QtnPropertyStateNonSerialized | QtnPropertyStateCollapsed));\n\n\tp2->removeState(QtnPropertyStateImmutable);\n\tp3.addState(QtnPropertyStateImmutable);\n\n\tQCOMPARE(p2->state(), QtnPropertyStateCollapsed);\n\tQCOMPARE(p3.state(),\n\t\t(QtnPropertyStateNonSerialized | QtnPropertyStateImmutable |\n\t\t\tQtnPropertyStateCollapsed));\n\n\t{\n\t\tQDataStream s(&data, QIODevice::ReadOnly);\n\t\ts >> ps;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tQCOMPARE(\n\t\tp2->state(), (QtnPropertyStateImmutable | QtnPropertyStateCollapsed));\n\tQCOMPARE(p3.state(),\n\t\t(QtnPropertyStateNonSerialized | QtnPropertyStateImmutable |\n\t\t\tQtnPropertyStateCollapsed));\n\n\tdelete p2;\n\tp2 = 0;\n\n\t{\n\t\tQDataStream s(&data, QIODevice::ReadOnly);\n\t\ts >> ps;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n}\n\nvoid TestProperty::serializationValue()\n{\n\tQtnPropertyBool p(this);\n\tp = true;\n\tQVERIFY(p);\n\n\tQByteArray data;\n\n\t{\n\t\tQDataStream s(&data, QIODevice::WriteOnly);\n\t\ts << p;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tp = false;\n\tQVERIFY(!p);\n\n\t{\n\t\tQDataStream s(&data, QIODevice::ReadOnly);\n\t\ts >> p;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tQVERIFY(p);\n\n\tQtnPropertySetAllPropertyTypes pp(this);\n\n\tverifyInitialValues(pp);\n\n\t{\n\t\tQDataStream s(&data, QIODevice::WriteOnly);\n\t\ts << pp;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tmodify(pp);\n\tverifyModified(pp);\n\n\t{\n\t\tQDataStream s(&data, QIODevice::ReadWrite);\n\t\ts >> pp;\n\t\tQCOMPARE(s.status(), QDataStream::Ok);\n\t}\n\n\tverifyInitialValues(pp);\n}\n\nvoid TestProperty::createNew()\n{\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\n\t\tverifyInitialValues(pp);\n\n\t\tmodify(pp);\n\n\t\tQScopedPointer<QtnPropertySetAllPropertyTypes> pn;\n\t\tpn.reset(\n\t\t\tqobject_cast<QtnPropertySetAllPropertyTypes *>(pp.createNew(this)));\n\t\tQVERIFY(pn);\n\t\tQVERIFY(pn.data() != &pp);\n\t\tQCOMPARE(pn->parent(), this);\n\n\t\tverifyInitialValues(*pn);\n\t}\n}\n\nvoid TestProperty::createCopy()\n{\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\n\t\tverifyInitialValues(pp);\n\n\t\tmodify(pp);\n\n\t\tQScopedPointer<QtnPropertySetAllPropertyTypes> pn;\n\t\tpn.reset(qobject_cast<QtnPropertySetAllPropertyTypes *>(\n\t\t\tpp.createCopy(this)));\n\t\tQVERIFY(pn);\n\t\tQVERIFY(pn.data() != &pp);\n\t\tQCOMPARE(pn->parent(), this);\n\n\t\tverifyModified(*pn);\n\t}\n}\n\nvoid TestProperty::copyValues()\n{\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\t\tverifyInitialValues(pp);\n\t\tmodify(pp);\n\n\t\tQtnPropertySetAllPropertyTypes pp1(this);\n\t\tverifyInitialValues(pp1);\n\t\tpp1.copyValues(&pp, QtnPropertyStateNone);\n\t\tverifyModified(pp1);\n\t}\n\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\t\tverifyInitialValues(pp);\n\t\tmodify(pp);\n\n\t\tQtnPropertySetAllPropertyTypes pp1(this);\n\t\tverifyInitialValues(pp1);\n\t\tQCOMPARE(pp1.bp.value(), false);\n\t\tpp.bp.addState(QtnPropertyStateImmutable);\n\t\tQCOMPARE(pp.bp.state(), QtnPropertyStateImmutable);\n\n\t\tpp1.copyValues(&pp, QtnPropertyStateImmutable);\n\t\tQCOMPARE(pp1.bp.value(), false);\n\n\t\tpp1.copyValues(&pp);\n\t\tverifyModified(pp1);\n\t}\n}\n\nvoid TestProperty::propertyAssignment()\n{\n\t{\n\t\tQtnPropertyDouble p1(this);\n\t\tQtnPropertyDouble p2(this);\n\t\tQtnPropertyDoubleCallback p3(this);\n\t\tdouble d = 54.32;\n\n\t\tp1 = 0.5;\n\t\tp2 = 1.3;\n\t\tp3.setCallbackValueGet([]() -> double { return 23.4; });\n\t\tp3.setCallbackValueSet(\n\t\t\t[&d](double v, QtnPropertyChangeReason /*reason*/) { d = v; });\n\n\t\tQCOMPARE(p1.value(), 0.5);\n\t\tQCOMPARE(p2.value(), 1.3);\n\t\tQCOMPARE(p3.value(), 23.4);\n\n\t\tp2 = p1;\n\t\tQCOMPARE(p1.value(), 0.5);\n\t\tQCOMPARE(p2.value(), 0.5);\n\n\t\tp1 = p3;\n\t\tQCOMPARE(p3.value(), 23.4);\n\t\tQCOMPARE(p1.value(), 23.4);\n\n\t\tp3 = p2;\n\t\tQCOMPARE(p2.value(), 0.5);\n\t\tQCOMPARE(p3.value(), 23.4);\n\t\tQCOMPARE(d, 0.5);\n\t}\n\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\n\t\tverifyInitialValues(pp);\n\n\t\tQtnPropertySetAllPropertyTypes pp1(this);\n\n\t\tverifyInitialValues(pp1);\n\n\t\tmodify(pp);\n\n\t\tverifyModified(pp);\n\n\t\tpp1 = pp;\n\n\t\tverifyModified(pp1);\n\t}\n}\n\nvoid TestProperty::propertyScripting()\n{\n\t{\n\t\tQtnPropertyBool b(this);\n\t\tb.setName(\"isValid\");\n\t\tb.setDescription(\"isValid property.\");\n\t\tb.setId(15);\n\n\t\tQScriptEngine eng;\n\t\tqtnScriptRegisterPropertyTypes(&eng);\n\t\teng.globalObject().setProperty(\"b\", eng.newQObject(&b));\n\n\t\tQScriptValue val = eng.evaluate(\"b.name\");\n\t\tQCOMPARE(val.toString(), b.name());\n\n\t\tval = eng.evaluate(\"b.name = \\\"a\\\"\");\n\t\tQCOMPARE(b.name(), QString(\"isValid\"));\n\n\t\tval = eng.evaluate(\"b.description\");\n\t\tQCOMPARE(val.toString(), QString(\"isValid property.\"));\n\n\t\tval = eng.evaluate(\"b.description = 'new description'\");\n\t\tQCOMPARE(b.description(), QString(\"isValid property.\"));\n\n\t\tval = eng.evaluate(\"var id = b.id\");\n\t\tval = eng.evaluate(\"id\");\n\t\tQVERIFY(val.isNumber());\n\t\tQCOMPARE(val.toNumber(), 15.);\n\n\t\tval = eng.evaluate(\"b.id = 92\");\n\t\tQCOMPARE(b.id(), 15);\n\n\t\tval = eng.evaluate(\"b.isEditable\");\n\t\tQCOMPARE(val.toBool(), true);\n\n\t\tval = eng.evaluate(\"b.isEditable = false\");\n\t\tQCOMPARE(b.isEditableByUser(), true);\n\n\t\tb.addState(QtnPropertyStateImmutable);\n\t\tval = eng.evaluate(\"b.isEditable\");\n\t\tQCOMPARE(val.toBool(), false);\n\n\t\tb.setState(QtnPropertyStateInvisible);\n\t\tval = eng.evaluate(\"b.isEditable\");\n\t\tQCOMPARE(val.toBool(), true);\n\t\tval = eng.evaluate(\"b.isEditableByUser\");\n\t\tQCOMPARE(val.toBool(), false);\n\n\t\tval = eng.evaluate(\"b.state\");\n\t\tQCOMPARE(val.toUInt32(), 2u);\n\n\t\tval = eng.evaluate(\"b.state == QtnPropertyStateInvisible\");\n\t\tQCOMPARE(val.toBool(), true);\n\n\t\tval = eng.evaluate(\"b.state == QtnPropertyStateNonSerialized\");\n\t\tQCOMPARE(val.toBool(), false);\n\n\t\tval = eng.evaluate(\"b.value\");\n\t\tQCOMPARE(val.toBool(), false);\n\n\t\tb = true;\n\t\tval = eng.evaluate(\"b.value\");\n\t\tQCOMPARE(val.toBool(), true);\n\n\t\tval = eng.evaluate(\"b.value = false\");\n\t\tQCOMPARE(b.value(), false);\n\n\t\teng.evaluate(\"b.state = 0\");\n\t\tQCOMPARE(b.state(), QtnPropertyStateInvisible);\n\n\t\tb.setState(QtnPropertyStateNone);\n\t\tval = eng.evaluate(\"b.value = false\");\n\t\tQCOMPARE(b.value(), false);\n\n\t\teng.evaluate(\"var b_changed = false;\"\n\t\t\t\t\t \"function on_b_changed() {\"\n\t\t\t\t\t \"  b_changed = true;\"\n\t\t\t\t\t \"}\");\n\n\t\tval = eng.evaluate(\"b_changed\");\n\t\tQCOMPARE(val.toBool(), false);\n\n\t\tval = eng.evaluate(\"on_b_changed()\");\n\t\tval = eng.evaluate(\"b_changed\");\n\t\tQCOMPARE(val.toBool(), true);\n\n\t\teng.evaluate(\"var success = true;\");\n\t\teng.evaluate(\n\t\t\t\"var f1 = function(reason) {\"\n\t\t\t\"  if (this.name != 'isValid') success = false;\"\n\t\t\t\"  if (this.state != QtnPropertyStateNone) success = false;\"\n\t\t\t\"  if (this.id != 15) success = false;\"\n\t\t\t\"  if (reason != QtnPropertyChangeReasonNewValue) success = false;\"\n\t\t\t\"  if (this.value != true) success = false;\"\n\t\t\t\"}\");\n\t\teng.evaluate(\"b.propertyDidChange.connect(b, f1);\");\n\t\teng.evaluate(\"b.value = true;\");\n\t\tval = eng.evaluate(\"success\");\n\t\tQCOMPARE(val.toBool(), true);\n\n\t\teng.evaluate(\"b.propertyDidChange.disconnect(b, f1);\");\n\t\teng.evaluate(\"b.value = true;\");\n\t\tval = eng.evaluate(\"success\");\n\t\tQCOMPARE(val.toBool(), true);\n\t}\n}\n\nvoid TestProperty::variantConversions()\n{\n\t{\n\t\tQtnPropertyBool b(this);\n\t\tQVariant value = true;\n\n\t\tQCOMPARE(b.value(), false);\n\t\tQVERIFY(b.fromVariant(value));\n\t\tQCOMPARE(b.value(), true);\n\n\t\tvalue = QRect();\n\t\tQVERIFY(!b.fromVariant(value));\n\t\tQCOMPARE(b.value(), true);\n\n\t\tQVERIFY(b.toVariant(value));\n\t\tQCOMPARE(value.toBool(), true);\n\n\t\tb = false;\n\t\tQVERIFY(b.toVariant(value));\n\t\tQCOMPARE(value.toBool(), false);\n\t}\n\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\t\tQVariant value;\n\t\tbool ok = false;\n\n\t\tQVERIFY(pp.bp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Bool);\n\t\tQCOMPARE(value.toBool(), false);\n\t\tvalue = true;\n\t\tQVERIFY(pp.bp.fromVariant(value));\n\t\tQCOMPARE(pp.bp.value(), true);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.bp.fromVariant(value));\n\t\tQCOMPARE(pp.bp.value(), true);\n\n\t\tQVERIFY(pp.bpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Bool);\n\t\tQCOMPARE(value.toBool(), true);\n\t\tvalue = false;\n\t\tQVERIFY(pp.bpc.fromVariant(value));\n\t\tQCOMPARE(pp.bpc.value(), false);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.bpc.fromVariant(value));\n\t\tQCOMPARE(pp.bpc.value(), false);\n\n\t\tQVERIFY(pp.ip.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(&ok), 0);\n\t\tQVERIFY(ok);\n\t\tvalue = 13;\n\t\tQVERIFY(pp.ip.fromVariant(value));\n\t\tQCOMPARE(pp.ip.value(), 13);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.ip.fromVariant(value));\n\t\tQCOMPARE(pp.ip.value(), 13);\n\n\t\tQVERIFY(pp.ipc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(&ok), 12);\n\t\tQVERIFY(ok);\n\t\tvalue = -83;\n\t\tQVERIFY(pp.ipc.fromVariant(value));\n\t\tQCOMPARE(pp.ipc.value(), -83);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.ipc.fromVariant(value));\n\t\tQCOMPARE(pp.ipc.value(), -83);\n\n\t\tQVERIFY(pp.up.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::UInt);\n\t\tQCOMPARE(value.toUInt(&ok), 0u);\n\t\tQVERIFY(ok);\n\t\tvalue = 98234;\n\t\tQVERIFY(pp.up.fromVariant(value));\n\t\tQCOMPARE(pp.up.value(), 98234u);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.up.fromVariant(value));\n\t\tQCOMPARE(pp.up.value(), 98234u);\n\n\t\tQVERIFY(pp.upc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::UInt);\n\t\tQCOMPARE(value.toUInt(&ok), 9u);\n\t\tQVERIFY(ok);\n\t\tvalue = 76u;\n\t\tQVERIFY(pp.upc.fromVariant(value));\n\t\tQCOMPARE(pp.upc.value(), 76u);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.upc.fromVariant(value));\n\t\tQCOMPARE(pp.upc.value(), 76u);\n\n\t\tQVERIFY(pp.fp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Float);\n\t\tQCOMPARE(value.toFloat(&ok), 0.f);\n\t\tQVERIFY(ok);\n\t\tvalue = 0.32f;\n\t\tQVERIFY(pp.fp.fromVariant(value));\n\t\tQCOMPARE(pp.fp.value(), 0.32f);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.fp.fromVariant(value));\n\t\tQCOMPARE(pp.fp.value(), 0.32f);\n\n\t\tQVERIFY(pp.fpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Float);\n\t\tQCOMPARE(value.toFloat(&ok), 0.2f);\n\t\tQVERIFY(ok);\n\t\tvalue = -0.32f;\n\t\tQVERIFY(pp.fpc.fromVariant(value));\n\t\tQCOMPARE(pp.fpc.value(), -0.32f);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.fpc.fromVariant(value));\n\t\tQCOMPARE(pp.fpc.value(), -0.32f);\n\n\t\tQVERIFY(pp.dp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Double);\n\t\tQCOMPARE(value.toDouble(&ok), 0.);\n\t\tQVERIFY(ok);\n\t\tvalue = -23.4;\n\t\tQVERIFY(pp.dp.fromVariant(value));\n\t\tQCOMPARE(pp.dp.value(), -23.4);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.dp.fromVariant(value));\n\t\tQCOMPARE(pp.dp.value(), -23.4);\n\n\t\tQVERIFY(pp.dpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Double);\n\t\tQCOMPARE(value.toDouble(&ok), 32.4);\n\t\tQVERIFY(ok);\n\t\tvalue = 543.22;\n\t\tQVERIFY(pp.dpc.fromVariant(value));\n\t\tQCOMPARE(pp.dpc.value(), 543.22);\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.dpc.fromVariant(value));\n\t\tQCOMPARE(pp.dpc.value(), 543.22);\n\n\t\tpp.sp = QString(\"hello\");\n\t\tQVERIFY(pp.sp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QString);\n\t\tQCOMPARE(value.toString(), QString(\"hello\"));\n\t\tvalue = QString(\"world\");\n\t\tQVERIFY(pp.sp.fromVariant(value));\n\t\tQCOMPARE(pp.sp.value(), QString(\"world\"));\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.sp.fromVariant(value));\n\t\tQCOMPARE(pp.sp.value(), QString(\"world\"));\n\n\t\tQVERIFY(pp.spc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QString);\n\t\tQCOMPARE(value.toString(), QString(\"name\"));\n\t\tvalue = QString(\"another\");\n\t\tQVERIFY(pp.spc.fromVariant(value));\n\t\tQCOMPARE(pp.spc.value(), QString(\"another\"));\n\t\tvalue = QPoint(3, 5);\n\t\tQVERIFY(!pp.spc.fromVariant(value));\n\t\tQCOMPARE(pp.spc.value(), QString(\"another\"));\n\n\t\tQVERIFY(pp.rp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QRect);\n\t\tQCOMPARE(value.toRect(), QRect());\n\t\tvalue = QRect(23, 4, 56, 76);\n\t\tQVERIFY(pp.rp.fromVariant(value));\n\t\tQCOMPARE(pp.rp.value(), QRect(23, 4, 56, 76));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.rp.fromVariant(value));\n\t\tQCOMPARE(pp.rp.value(), QRect(23, 4, 56, 76));\n\n\t\tQVERIFY(pp.rpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QRect);\n\t\tQCOMPARE(value.toRect(), QRect(10, 10, 10, 10));\n\t\tvalue = QRect(-2, 3, 23, 3);\n\t\tQVERIFY(pp.rpc.fromVariant(value));\n\t\tQCOMPARE(pp.rpc.value(), QRect(-2, 3, 23, 3));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.rpc.fromVariant(value));\n\t\tQCOMPARE(pp.rpc.value(), QRect(-2, 3, 23, 3));\n\n\t\tQVERIFY(pp.rpf.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QRectF);\n\t\tQCOMPARE(value.toRectF(), QRectF());\n\t\tvalue = QRectF(23.1, 4.2, 56.3, 76.4);\n\t\tQVERIFY(pp.rpf.fromVariant(value));\n\t\tQCOMPARE(pp.rpf.value(), QRectF(23.1, 4.2, 56.3, 76.4));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.rpf.fromVariant(value));\n\t\tQCOMPARE(pp.rpf.value(), QRectF(23.1, 4.2, 56.3, 76.4));\n\n\t\tQVERIFY(pp.rpfc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QRectF);\n\t\tQCOMPARE(value.toRectF(), QRectF(10.1, 10.2, 10.3, 10.4));\n\t\tvalue = QRectF(-2.7, 3.6, 23.5, 3.4);\n\t\tQVERIFY(pp.rpfc.fromVariant(value));\n\t\tQCOMPARE(pp.rpfc.value(), QRectF(-2.7, 3.6, 23.5, 3.4));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.rpfc.fromVariant(value));\n\t\tQCOMPARE(pp.rpfc.value(), QRectF(-2.7, 3.6, 23.5, 3.4));\n\n\t\tQVERIFY(pp.pp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QPoint);\n\t\tQCOMPARE(value.toPoint(), QPoint());\n\t\tvalue = QPoint(-2, 3);\n\t\tQVERIFY(pp.pp.fromVariant(value));\n\t\tQCOMPARE(pp.pp.value(), QPoint(-2, 3));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.pp.fromVariant(value));\n\t\tQCOMPARE(pp.pp.value(), QPoint(-2, 3));\n\n\t\tQVERIFY(pp.ppc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QPoint);\n\t\tQCOMPARE(value.toPoint(), QPoint(9, 2));\n\t\tvalue = QPoint(100, 100);\n\t\tQVERIFY(pp.ppc.fromVariant(value));\n\t\tQCOMPARE(pp.ppc.value(), QPoint(100, 100));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.ppc.fromVariant(value));\n\t\tQCOMPARE(pp.ppc.value(), QPoint(100, 100));\n\n\t\tQVERIFY(pp.ppf.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QPointF);\n\t\tQCOMPARE(value.toPointF(), QPointF());\n\t\tvalue = QPointF(-2.2, 3.3);\n\t\tQVERIFY(pp.ppf.fromVariant(value));\n\t\tQCOMPARE(pp.ppf.value(), QPointF(-2.2, 3.3));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.ppf.fromVariant(value));\n\t\tQCOMPARE(pp.ppf.value(), QPointF(-2.2, 3.3));\n\n\t\tQVERIFY(pp.ppfc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QPointF);\n\t\tQCOMPARE(value.toPointF(), QPointF(9.9, 2.2));\n\t\tvalue = QPointF(100.100, 100.100);\n\t\tQVERIFY(pp.ppfc.fromVariant(value));\n\t\tQCOMPARE(pp.ppfc.value(), QPointF(100.100, 100.100));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.ppfc.fromVariant(value));\n\t\tQCOMPARE(pp.ppfc.value(), QPointF(100.100, 100.100));\n\n\t\tQVERIFY(pp.szp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QSize);\n\t\tQCOMPARE(value.toSize(), QSize());\n\t\tvalue = QSize(72, 3);\n\t\tQVERIFY(pp.szp.fromVariant(value));\n\t\tQCOMPARE(pp.szp.value(), QSize(72, 3));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.szp.fromVariant(value));\n\t\tQCOMPARE(pp.szp.value(), QSize(72, 3));\n\n\t\tQVERIFY(pp.szpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QSize);\n\t\tQCOMPARE(value.toSize(), QSize(33, 21));\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(pp.szpc.fromVariant(value));\n\t\tQCOMPARE(pp.szpc.value(), QSize(6, 4));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.szpc.fromVariant(value));\n\t\tQCOMPARE(pp.szpc.value(), QSize(6, 4));\n\n\t\tQVERIFY(pp.szpf.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QSizeF);\n\t\tQCOMPARE(value.toSizeF(), QSizeF());\n\t\tvalue = QSizeF(72.3, 3.2);\n\t\tQVERIFY(pp.szpf.fromVariant(value));\n\t\tQCOMPARE(pp.szpf.value(), QSizeF(72.3, 3.2));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.szpf.fromVariant(value));\n\t\tQCOMPARE(pp.szpf.value(), QSizeF(72.3, 3.2));\n\n\t\tQVERIFY(pp.szpfc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QSizeF);\n\t\tQCOMPARE(value.toSizeF(), QSizeF(33.0, 21.9));\n\t\tvalue = QSizeF(6.3, 4.5);\n\t\tQVERIFY(pp.szpfc.fromVariant(value));\n\t\tQCOMPARE(pp.szpfc.value(), QSizeF(6.3, 4.5));\n\t\tvalue = \"sss\";\n\t\tQVERIFY(!pp.szpfc.fromVariant(value));\n\t\tQCOMPARE(pp.szpfc.value(), QSizeF(6.3, 4.5));\n\n\t\tQVERIFY(pp.ep.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(), (int) COLOR::BLUE);\n\t\tvalue = (int) COLOR::RED;\n\t\tQVERIFY(pp.ep.fromVariant(value));\n\t\tQCOMPARE(pp.ep.value(), (int) COLOR::RED);\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.ep.fromVariant(value));\n\t\tQCOMPARE(pp.ep.value(), (int) COLOR::RED);\n\n\t\tQVERIFY(pp.epc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(), (int) COLOR::RED);\n\t\tvalue = (int) COLOR::YELLOW;\n\t\tQVERIFY(pp.epc.fromVariant(value));\n\t\tQCOMPARE(pp.epc.value(), (int) COLOR::YELLOW);\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.epc.fromVariant(value));\n\t\tQCOMPARE(pp.epc.value(), (int) COLOR::YELLOW);\n\n\t\tQVERIFY(pp.efp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(), (int) (MASK::ONE | MASK::FOUR));\n\t\tvalue = (int) MASK::TWO;\n\t\tQVERIFY(pp.efp.fromVariant(value));\n\t\tQCOMPARE(pp.efp.value(), (int) MASK::TWO);\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.efp.fromVariant(value));\n\t\tQCOMPARE(pp.efp.value(), (int) MASK::TWO);\n\n\t\tQVERIFY(pp.efpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::Int);\n\t\tQCOMPARE(value.toInt(), (int) (MASK::ONE | MASK::FOUR));\n\t\tvalue = (int) MASK::TWO;\n\t\tQVERIFY(pp.efpc.fromVariant(value));\n\t\tQCOMPARE(pp.efpc.value(), (int) MASK::TWO);\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.efpc.fromVariant(value));\n\t\tQCOMPARE(pp.efpc.value(), (int) MASK::TWO);\n\n\t\tQVERIFY(pp.cp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QColor);\n\t\tQCOMPARE(value.value<QColor>(), QColor(Qt::blue));\n\t\tvalue = QColor(200, 23, 44);\n\t\tQVERIFY(pp.cp.fromVariant(value));\n\t\tQCOMPARE(pp.cp.value(), QColor(200, 23, 44));\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.cp.fromVariant(value));\n\t\tQCOMPARE(pp.cp.value(), QColor(200, 23, 44));\n\n\t\tQVERIFY(pp.cpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QColor);\n\t\tQCOMPARE(value.value<QColor>(), QColor(Qt::red));\n\t\tvalue = QColor(0, 3, 3);\n\t\tQVERIFY(pp.cpc.fromVariant(value));\n\t\tQCOMPARE(pp.cpc.value(), QColor(0, 3, 3));\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.cpc.fromVariant(value));\n\t\tQCOMPARE(pp.cpc.value(), QColor(0, 3, 3));\n\n\t\tQVERIFY(pp.fnp.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QFont);\n\t\tQCOMPARE(value.value<QFont>(), QFont(\"Courier\", 10));\n\t\tvalue = QFont(\"Arial\", 14);\n\t\tQVERIFY(pp.fnp.fromVariant(value));\n\t\tQCOMPARE(pp.fnp.value(), QFont(\"Arial\", 14));\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.fnp.fromVariant(value));\n\t\tQCOMPARE(pp.fnp.value(), QFont(\"Arial\", 14));\n\n\t\tQVERIFY(pp.fnpc.toVariant(value));\n\t\tQCOMPARE(value.userType(), (int) QMetaType::QFont);\n\t\tQCOMPARE(value.value<QFont>(), QFont(\"Arial\", 19));\n\t\tvalue = QFont(\"Courier\", 9);\n\t\tQVERIFY(pp.fnpc.fromVariant(value));\n\t\tQCOMPARE(pp.fnpc.value(), QFont(\"Courier\", 9));\n\t\tvalue = QSize(6, 4);\n\t\tQVERIFY(!pp.fnpc.fromVariant(value));\n\t\tQCOMPARE(pp.fnpc.value(), QFont(\"Courier\", 9));\n\t}\n}\n\nvoid TestProperty::stringConversions()\n{\n\t{\n\t\tQtnPropertyBool p(this);\n\t\tQString text;\n\t\tQVERIFY(p.toStr(text));\n\t\tQCOMPARE(text, QString(\"False\"));\n\n\t\tQVERIFY(p.fromStr(\"true\"));\n\t\tQCOMPARE(p.value(), true);\n\n\t\tQVERIFY(p.toStr(text));\n\t\tQCOMPARE(text, QString(\"True\"));\n\n\t\tQVERIFY(!p.fromStr(\"Hello\"));\n\t\tQCOMPARE(p.value(), true);\n\t}\n\n\t{\n\t\tQtnPropertySetAllPropertyTypes pp(this);\n\t\tQString str;\n\t\t//        bool ok = false;\n\n\t\tQVERIFY(pp.bp.toStr(str));\n\t\tQCOMPARE(str, QString(\"False\"));\n\t\tQVERIFY(pp.bp.fromStr(QString(\"tRue\")));\n\t\tQCOMPARE(pp.bp.value(), true);\n\t\tQVERIFY(pp.bp.toStr(str));\n\t\tQCOMPARE(str, QString(\"True\"));\n\t\tQVERIFY(!pp.bp.fromStr(\"aaa\"));\n\t\tQCOMPARE(pp.bp.value(), true);\n\n\t\tQVERIFY(pp.bpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"True\"));\n\t\tQVERIFY(pp.bpc.fromStr(QString(\"falSe\")));\n\t\tQCOMPARE(pp.bpc.value(), false);\n\t\tQVERIFY(pp.bpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"False\"));\n\t\tQVERIFY(!pp.bpc.fromStr(\"bbb\"));\n\t\tQCOMPARE(pp.bpc.value(), false);\n\n\t\tQVERIFY(pp.ip.toStr(str));\n\t\tQCOMPARE(str, QString(\"0\"));\n\t\tQVERIFY(pp.ip.fromStr(QString(\"-23\")));\n\t\tQCOMPARE(pp.ip.value(), -23);\n\t\tQVERIFY(pp.ip.toStr(str));\n\t\tQCOMPARE(str, QString(\"-23\"));\n\t\tQVERIFY(!pp.ip.fromStr(\"93jms\"));\n\t\tQCOMPARE(pp.ip.value(), -23);\n\t\tpp.ip.setMinValue(-2);\n\t\tQCOMPARE(pp.ip.value(), -2);\n\t\tQVERIFY(!pp.ip.fromStr(\"-32\"));\n\t\tQCOMPARE(pp.ip.value(), -2);\n\n\t\tQVERIFY(pp.ipc.toStr(str));\n\t\tQCOMPARE(str, QString(\"12\"));\n\t\tQVERIFY(pp.ipc.fromStr(QString(\"45\")));\n\t\tQCOMPARE(pp.ipc.value(), 45);\n\t\tQVERIFY(pp.ipc.toStr(str));\n\t\tQCOMPARE(str, QString(\"45\"));\n\t\tQVERIFY(!pp.ipc.fromStr(\"23.22\"));\n\t\tQCOMPARE(pp.ipc.value(), 45);\n\n\t\tQVERIFY(pp.up.toStr(str));\n\t\tQCOMPARE(str, QString(\"0\"));\n\t\tQVERIFY(pp.up.fromStr(QString(\"7829\")));\n\t\tQCOMPARE(pp.up.value(), 7829u);\n\t\tQVERIFY(pp.up.toStr(str));\n\t\tQCOMPARE(str, QString(\"7829\"));\n\t\tQVERIFY(!pp.up.fromStr(\"92ms\"));\n\t\tQCOMPARE(pp.up.value(), 7829u);\n\n\t\tQVERIFY(pp.upc.toStr(str));\n\t\tQCOMPARE(str, QString(\"9\"));\n\t\tQVERIFY(pp.upc.fromStr(QString(\"11\")));\n\t\tQCOMPARE(pp.upc.value(), 11u);\n\t\tQVERIFY(pp.upc.toStr(str));\n\t\tQCOMPARE(str, QString(\"11\"));\n\t\tQVERIFY(!pp.upc.fromStr(\"-233\"));\n\t\tQCOMPARE(pp.upc.value(), 11u);\n\t\tpp.upc.setMaxValue(100);\n\t\tQCOMPARE(pp.upc.value(), 11u);\n\t\tQVERIFY(!pp.upc.fromStr(\"110\"));\n\t\tQCOMPARE(pp.upc.value(), 11u);\n\n\t\tQVERIFY(pp.fp.toStr(str));\n\t\tQCOMPARE(str, QString(\"0\"));\n\t\tQVERIFY(pp.fp.fromStr(QString(\"-23.2\")));\n\t\tQCOMPARE(pp.fp.value(), -23.2f);\n\t\tQVERIFY(pp.fp.toStr(str));\n\t\tQCOMPARE(str, QString(\"-23.2\"));\n\t\tQVERIFY(!pp.fp.fromStr(\"32.ws\"));\n\t\tQCOMPARE(pp.fp.value(), -23.2f);\n\n\t\tQVERIFY(pp.fpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"0.2\"));\n\t\tQVERIFY(pp.fpc.fromStr(QString(\"0.002\")));\n\t\tQCOMPARE(pp.fpc.value(), 0.002f);\n\t\tQVERIFY(pp.fpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"0.002\"));\n\t\tQVERIFY(!pp.fpc.fromStr(\"-s233\"));\n\t\tQCOMPARE(pp.fpc.value(), 0.002f);\n\n\t\tQVERIFY(pp.dp.toStr(str));\n\t\tQCOMPARE(str, QString(\"0\"));\n\t\tQVERIFY(pp.dp.fromStr(QString(\"9403.234\")));\n\t\tQCOMPARE(pp.dp.value(), 9403.234);\n\t\tQVERIFY(pp.dp.toStr(str));\n\t\tQCOMPARE(str, QString(\"9403.234\"));\n\t\tQVERIFY(!pp.dp.fromStr(\"94d03.234s\"));\n\t\tQCOMPARE(pp.dp.value(), 9403.234);\n\n\t\tQVERIFY(pp.dpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"32.4\"));\n\t\tQVERIFY(pp.dpc.fromStr(QString(\"-92.34\")));\n\t\tQCOMPARE(pp.dpc.value(), -92.34);\n\t\tQVERIFY(pp.dpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"-92.34\"));\n\t\tQVERIFY(!pp.dpc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.dpc.value(), -92.34);\n\n\t\tQVERIFY(pp.sp.toStr(str));\n\t\tQCOMPARE(str, QString(\"\"));\n\t\tQVERIFY(pp.sp.fromStr(\"Hello\"));\n\t\tQCOMPARE(pp.sp.value(), QString(\"Hello\"));\n\t\tQVERIFY(pp.sp.toStr(str));\n\t\tQCOMPARE(str, QString(\"Hello\"));\n\t\tQVERIFY(pp.sp.fromStr(\"  \\\"Hello world \\\"  \"));\n\t\tQCOMPARE(pp.sp.value(), QString(\"\\\"Hello world \\\"\"));\n\n\t\tQVERIFY(pp.spc.toStr(str));\n\t\tQCOMPARE(str, QString(\"name\"));\n\t\tQVERIFY(pp.spc.fromStr(QString(\"Name\")));\n\t\tQCOMPARE(pp.spc.value(), QString(\"Name\"));\n\t\tQVERIFY(pp.spc.toStr(str));\n\t\tQCOMPARE(str, QString(\"Name\"));\n\n\t\tQVERIFY(pp.rp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRect(0, 0, 0, 0)\"));\n\t\tQVERIFY(pp.rp.fromStr(QString(\"QRect (-2, 3, 43, 45 )   \")));\n\t\tQCOMPARE(pp.rp.value(), QRect(-2, 3, 43, 45));\n\t\tQVERIFY(pp.rp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRect(-2, 3, 43, 45)\"));\n\t\tQVERIFY(!pp.rp.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.rp.value(), QRect(-2, 3, 43, 45));\n\n\t\tQVERIFY(pp.rpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRect(10, 10, 10, 10)\"));\n\t\tQVERIFY(pp.rpc.fromStr(QString(\"QRect(0, 0, 10, 10)\")));\n\t\tQCOMPARE(pp.rpc.value(), QRect(0, 0, 10, 10));\n\t\tQVERIFY(pp.rpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRect(0, 0, 10, 10)\"));\n\t\tQVERIFY(!pp.rpc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.rpc.value(), QRect(0, 0, 10, 10));\n\n\t\tQVERIFY(pp.rpf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRectF(0, 0, 0, 0)\"));\n\t\tQVERIFY(pp.rpf.fromStr(QString(\"QRectF (-2.3, 3.2, 43.5, 45.6 )   \")));\n\t\tQCOMPARE(pp.rpf.value(), QRectF(-2.3, 3.2, 43.5, 45.6));\n\t\tQVERIFY(pp.rpf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRectF(-2.3, 3.2, 43.5, 45.6)\"));\n\t\tQVERIFY(!pp.rpf.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.rpf.value(), QRectF(-2.3, 3.2, 43.5, 45.6));\n\n\t\tQVERIFY(pp.rpfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRectF(10.1, 10.2, 10.3, 10.4)\"));\n\t\tQVERIFY(pp.rpfc.fromStr(QString(\"QRectF(0.3, 0.0, 10.1, 10.1)\")));\n\t\tQCOMPARE(pp.rpfc.value(), QRectF(0.3, 0.0, 10.1, 10.10));\n\t\tQVERIFY(pp.rpfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QRectF(0.3, 0, 10.1, 10.1)\"));\n\t\tQVERIFY(!pp.rpfc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.rpfc.value(), QRectF(0.3, 0.0, 10.1, 10.1));\n\n\t\tQVERIFY(pp.pp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPoint(0, 0)\"));\n\t\tQVERIFY(pp.pp.fromStr(QString(\"QPoint (-2, 3 )   \")));\n\t\tQCOMPARE(pp.pp.value(), QPoint(-2, 3));\n\t\tQVERIFY(pp.pp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPoint(-2, 3)\"));\n\t\tQVERIFY(!pp.pp.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.pp.value(), QPoint(-2, 3));\n\n\t\tQVERIFY(pp.ppc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPoint(9, 2)\"));\n\t\tQVERIFY(pp.ppc.fromStr(QString(\"QPoint(-3, 20)\")));\n\t\tQCOMPARE(pp.ppc.value(), QPoint(-3, 20));\n\t\tQVERIFY(pp.ppc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPoint(-3, 20)\"));\n\t\tQVERIFY(!pp.ppc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.ppc.value(), QPoint(-3, 20));\n\n\t\tQVERIFY(pp.ppf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPointF(0, 0)\"));\n\t\tQVERIFY(pp.ppf.fromStr(QString(\"QPointF (-2.2, 3.3 )   \")));\n\t\tQCOMPARE(pp.ppf.value(), QPointF(-2.2, 3.3));\n\t\tQVERIFY(pp.ppf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPointF(-2.2, 3.3)\"));\n\t\tQVERIFY(!pp.ppf.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.ppf.value(), QPointF(-2.2, 3.3));\n\n\t\tQVERIFY(pp.ppfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPointF(9.9, 2.2)\"));\n\t\tQVERIFY(pp.ppfc.fromStr(QString(\"QPointF(-3.3, 20.20)\")));\n\t\tQCOMPARE(pp.ppfc.value(), QPointF(-3.3, 20.20));\n\t\tQVERIFY(pp.ppfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QPointF(-3.3, 20.2)\"));\n\t\tQVERIFY(!pp.ppfc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.ppfc.value(), QPointF(-3.3, 20.20));\n\n\t\tQVERIFY(pp.szp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSize(-1, -1)\"));\n\t\tQVERIFY(pp.szp.fromStr(QString(\"QSize (-2, 3 )   \")));\n\t\tQCOMPARE(pp.szp.value(), QSize(-2, 3));\n\t\tQVERIFY(pp.szp.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSize(-2, 3)\"));\n\t\tQVERIFY(!pp.szp.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.szp.value(), QSize(-2, 3));\n\n\t\tQVERIFY(pp.szpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSize(33, 21)\"));\n\t\tQVERIFY(pp.szpc.fromStr(QString(\"QSize(-3, 20)\")));\n\t\tQCOMPARE(pp.szpc.value(), QSize(-3, 20));\n\t\tQVERIFY(pp.szpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSize(-3, 20)\"));\n\t\tQVERIFY(!pp.szpc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.szpc.value(), QSize(-3, 20));\n\n\t\tQVERIFY(pp.szpf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSizeF(-1, -1)\"));\n\t\tQVERIFY(pp.szpf.fromStr(QString(\"QSizeF (-2.3, 3.4 )   \")));\n\t\tQCOMPARE(pp.szpf.value(), QSizeF(-2.3, 3.4));\n\t\tQVERIFY(pp.szpf.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSizeF(-2.3, 3.4)\"));\n\t\tQVERIFY(!pp.szpf.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.szpf.value(), QSizeF(-2.3, 3.4));\n\n\t\tQVERIFY(pp.szpfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSizeF(33, 21.9)\"));\n\t\tQVERIFY(pp.szpfc.fromStr(QString(\"QSizeF(-3.1, 20.8)\")));\n\t\tQCOMPARE(pp.szpfc.value(), QSizeF(-3.1, 20.8));\n\t\tQVERIFY(pp.szpfc.toStr(str));\n\t\tQCOMPARE(str, QString(\"QSizeF(-3.1, 20.8)\"));\n\t\tQVERIFY(!pp.szpfc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.szpfc.value(), QSizeF(-3.1, 20.8));\n\n\t\tQVERIFY(pp.ep.toStr(str));\n\t\tQCOMPARE(str, QString(\"BLUE\"));\n\t\tQVERIFY(pp.ep.fromStr(QString(\" Yellow   \\t\")));\n\t\tQCOMPARE(pp.ep.value(), (QtnEnumValueType) COLOR::YELLOW);\n\t\tQVERIFY(pp.ep.toStr(str));\n\t\tQCOMPARE(str, QString(\"YELLOW\"));\n\t\tQVERIFY(!pp.ep.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.ep.value(), (QtnEnumValueType) COLOR::YELLOW);\n\n\t\tQVERIFY(pp.epc.toStr(str));\n\t\tQCOMPARE(str, QString(\"RED\"));\n\t\tQVERIFY(pp.epc.fromStr(QString(\"BlUe\")));\n\t\tQCOMPARE(pp.epc.value(), (QtnEnumValueType) COLOR::BLUE);\n\t\tQVERIFY(pp.epc.toStr(str));\n\t\tQCOMPARE(str, QString(\"BLUE\"));\n\t\tQVERIFY(!pp.epc.fromStr(\"COLOUR::Red\"));\n\t\tQCOMPARE(pp.epc.value(), (QtnEnumValueType) COLOR::BLUE);\n\n\t\tQVERIFY(pp.efp.toStr(str));\n\t\tQCOMPARE(str, QString(\"ONE|FOUR\"));\n\t\tQVERIFY(pp.efp.fromStr(QString(\" 0   \\t\")));\n\t\tQCOMPARE(pp.efp.value(), 0);\n\t\tQVERIFY(pp.efp.toStr(str));\n\t\tQCOMPARE(str, QString(\"0\"));\n\t\tQVERIFY(pp.efp.fromStr(\"Two\"));\n\t\tQCOMPARE(pp.efp.value(), (QtnEnumFlagsValueType) MASK::TWO);\n\t\tQVERIFY(pp.efp.fromStr(\"Two | Four\"));\n\t\tQCOMPARE(\n\t\t\tpp.efp.value(), (QtnEnumFlagsValueType)(MASK::TWO | MASK::FOUR));\n\t\tQVERIFY(!pp.efp.fromStr(\"Two&Four\"));\n\t\tQCOMPARE(\n\t\t\tpp.efp.value(), (QtnEnumFlagsValueType)(MASK::TWO | MASK::FOUR));\n\n\t\tQVERIFY(pp.efpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"ONE|FOUR\"));\n\t\tQVERIFY(pp.efpc.fromStr(QString(\"Two\")));\n\t\tQCOMPARE(pp.efpc.value(), (QtnEnumFlagsValueType) MASK::TWO);\n\t\tQVERIFY(pp.efpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"TWO\"));\n\t\tQVERIFY(!pp.efpc.fromStr(\"weee\"));\n\t\tQCOMPARE(pp.efpc.value(), (QtnEnumFlagsValueType) MASK::TWO);\n\n\t\tQVERIFY(pp.cp.toStr(str));\n\t\tQCOMPARE(str, QString(\"#0000ff\"));\n\t\tQVERIFY(pp.cp.fromStr(QString(\" Red   \\t\")));\n\t\tQCOMPARE(pp.cp.value(), QColor(Qt::red));\n\t\tQVERIFY(pp.cp.toStr(str));\n\t\tQCOMPARE(str, QString(\"#ff0000\"));\n\t\tQVERIFY(!pp.cp.fromStr(\"ddlwk,s\"));\n\t\tQCOMPARE(pp.cp.value(), QColor(Qt::red));\n\n\t\tQVERIFY(pp.cpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"#ff0000\"));\n\t\tQVERIFY(pp.cpc.fromStr(QString(\"transparent\")));\n\t\tQCOMPARE(pp.cpc.value(), QColor(Qt::transparent));\n\t\tQVERIFY(pp.cpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"#00000000\"));\n\t\tQVERIFY(!pp.cpc.fromStr(\"COLOUR::Red\"));\n\t\tQCOMPARE(pp.cpc.value(), QColor(Qt::transparent));\n\n\t\tQVERIFY(pp.fnp.toStr(str));\n\t\tQCOMPARE(str, QString(\"Courier,10,-1,5,50,0,0,0,0,0\"));\n\t\tQVERIFY(pp.fnp.fromStr(QString(\" Arial,18,-1,5,50,0,0,0,0,0   \\t\")));\n\t\tQCOMPARE(pp.fnp.value(), QFont(\"Arial\", 18));\n\t\tQVERIFY(pp.fnp.toStr(str));\n\t\tQCOMPARE(str, QString(\"Arial,18,-1,5,50,0,0,0,0,0\"));\n\n\t\tQVERIFY(pp.fnpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"Arial,19,-1,5,50,0,0,0,0,0\"));\n\t\tQVERIFY(pp.fnpc.fromStr(QString(\"Mono,23\")));\n\t\tQFont font;\n\t\tfont.setFamily(\"Mono\");\n\t\tfont.setPointSize(23);\n\t\tQCOMPARE(pp.fnpc.value(), font);\n\t\tQVERIFY(pp.fnpc.toStr(str));\n\t\tQCOMPARE(str, QString(\"Mono,23,-1,5,50,0,0,0,0,0\"));\n\t}\n\n\t{\n\t\tQtnPropertySetTest3 p(this);\n\t\tQCOMPARE(p.iis.a.value(), true);\n\t\tQVERIFY(p.fromStr(\"iis.a = false\"));\n\t\tQCOMPARE(p.iis.a.value(), false);\n\n\t\tQCOMPARE(p.u.value(), true);\n\t\tQCOMPARE(p.yy.s.value(), QString(\"\"));\n\t\tQCOMPARE(p.s.a.value(), false);\n\t\tQVERIFY(p.fromStr(\"u = False\\r\\nyy.s = \\\"new value\\\"\\n  s.a=true\"));\n\t\tQCOMPARE(p.u.value(), false);\n\t\tQCOMPARE(p.yy.s.value(), QString(\"new value\"));\n\t\tQCOMPARE(p.s.a.value(), true);\n\t}\n\n\t{\n\t\tQtnPropertySet ps(this);\n\n\t\tQtnPropertyBool pb(&ps);\n\t\tpb.setName(\"AAAA\");\n\t\tpb.setDisplayName(\"AA AA\");\n\t\tpb.setValue(false);\n\n\t\tQtnPropertyInt pi(&ps);\n\t\tpi.setName(\"BBBB\");\n\t\tpi.setDisplayName(\"BB BB\");\n\t\tpi.setValue(12);\n\n\t\t{\n\t\t\tQString res;\n\t\t\tQVERIFY(ps.toStr(res));\n\t\t\tQVERIFY(ps.fromStr(res));\n\t\t}\n\n\t\tpb.addState(QtnPropertyStateInvisible);\n\n\t\t{\n\t\t\tQString res;\n\t\t\tQVERIFY(ps.toStr(res));\n\t\t\tQVERIFY(ps.fromStr(res));\n\t\t}\n\t}\n\n\t{\n\t\tQtnPropertySetTest12 ps(this);\n\n\t\tQString res;\n\t\tQVERIFY(ps.toStr(res));\n\t\tQVERIFY(ps.fromStr(res));\n\t}\n}\n\nvoid TestProperty::qObjectProperty()\n{\n\t{\n\t\tQObject obj;\n\t\tobj.setObjectName(\"Item1\");\n\n\t\tQtnProperty *p = qtnCreateQObjectProperty(&obj, \"objectName\");\n\t\tQVERIFY(p);\n\t\tQtnPropertyQStringBase *ps = qobject_cast<QtnPropertyQStringBase *>(p);\n\t\tQVERIFY(ps);\n\t\tQCOMPARE(ps->value(), QString(\"Item1\"));\n\t\tQCOMPARE(ps->state(), QtnPropertyStateNone);\n\t\tps->setValue(\"NewItemName\");\n\t\tQCOMPARE(obj.objectName(), QString(\"NewItemName\"));\n\t\tQCOMPARE(ps->value(), QString(\"NewItemName\"));\n\t}\n}\n\nvoid TestProperty::qObjectPropertySet()\n{\n\t{\n\t\tQObject obj;\n\t\tobj.setObjectName(\"name\");\n\n\t\tQtnPropertySet *p = qtnCreateQObjectPropertySet(&obj);\n\t\tQVERIFY(p);\n\t\tQCOMPARE(p->name(), QString(\"name\"));\n\t\tconst QList<QtnPropertyBase *> &subPropertySets = p->childProperties();\n\t\tQCOMPARE(subPropertySets.size(), 1);\n\n\t\tQtnPropertySet *p1 = subPropertySets[0]->asPropertySet();\n\t\tQVERIFY(p1);\n\t\tQCOMPARE(p1->name(), QString(\"QObject\"));\n\t\tQCOMPARE(p1->childProperties().size(), 1);\n\t}\n\n\t{\n\t\tQCoreApplication *app = QCoreApplication::instance();\n\t\tQVERIFY(app);\n\n\t\tQtnPropertySet *p = qtnCreateQObjectPropertySet(app);\n\t\tQVERIFY(p);\n\t}\n}\n\nvoid TestProperty::checkPropertyStateIsNonSimple(\n\tQtnPropertyChangeReason reason, QtnPropertyValuePtr newValue, int typeId)\n{\n\tQCOMPARE(typeId, qMetaTypeId<QtnPropertyState>());\n\tQCOMPARE(reason, QtnPropertyChangeReasonStateLocal);\n\tauto state = qtnCastPropertyValue<QtnPropertyState>(newValue);\n\tQVERIFY(state);\n\tQCOMPARE(*state, QtnPropertyStateNonSimple | QtnPropertyStateResettable);\n}\n"
  },
  {
    "path": "Tests/TestProperty.h",
    "content": "#ifndef TEST_PROPERTY_H\n#define TEST_PROPERTY_H\n\n#include \"QtnProperty/Property.h\"\n#include <QObject>\n\nclass TestProperty : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tQ_INVOKABLE TestProperty() {}\n\nprivate Q_SLOTS:\n\n\tvoid name();\n\tvoid description();\n\tvoid id();\n\tvoid state();\n\tvoid stateChange();\n\tvoid propertyDelegate();\n\tvoid propertyDelegateCallback();\n\tvoid propertyBool();\n\tvoid propertyInt();\n\tvoid propertyString();\n\tvoid propertyRect();\n\tvoid propertyEnum();\n\tvoid propertyEnumFlags();\n\tvoid propertyPen();\n\tvoid propertyVector3D();\n\tvoid propertySet();\n\tvoid serializationState();\n\tvoid serializationChildren();\n\tvoid serializationValue();\n\tvoid createNew();\n\tvoid createCopy();\n\tvoid copyValues();\n\tvoid propertyAssignment();\n\tvoid propertyScripting();\n\tvoid variantConversions();\n\tvoid stringConversions();\n\tvoid qObjectProperty();\n\tvoid qObjectPropertySet();\n\npublic Q_SLOTS:\n\n\tvoid checkPropertyStateIsNonSimple(QtnPropertyChangeReason reason,\n\t\tQtnPropertyValuePtr newValue, int typeId);\n};\n\n#endif // TEST_PROPERTY_H\n"
  },
  {
    "path": "Tests/Tests.pro",
    "content": "include(../QtnPropertyDepend.pri)\ninclude(../Internal/TargetConfig.pri)\ninclude(../PEG/PEG.pri)\n\nQT += core gui widgets script testlib\n\nTARGET = QtnPropertyTests\n\nCONFIG   += cmdline\nCONFIG -= app_bundle\n\nTEMPLATE = app\n\nHEADERS += \\\n    TestProperty.h \\\n    TestGeneratedProperty.h \\\n    TestEnum.h\n\nSOURCES += main.cpp \\\n    TestProperty.cpp \\\n    TestGeneratedProperty.cpp \\\n    TestEnum.cpp\n\nPEG_SOURCES += PEG/test.pef \\\n               PEG/test2.pef\n\nOTHER_FILES += $$PEG_SOURCES\n\n\n"
  },
  {
    "path": "Tests/main.cpp",
    "content": "#include \"TestProperty.h\"\n#include \"TestGeneratedProperty.h\"\n#include \"TestEnum.h\"\n#include <QtTest/QtTest>\n#include <QDebug>\n\nint main(int argc, char *argv[])\n{\n\tqInfo(\"Init tests...\");\n\tQCoreApplication app(argc, argv);\n\n\tint result = 0;\n\n\tQList<const QMetaObject *> tests;\n\n\t// register tests\n\ttests.append(&TestProperty::staticMetaObject);\n\ttests.append(&TestGeneratedProperty::staticMetaObject);\n\ttests.append(&TestEnum::staticMetaObject);\n\n\t// run tests\n\tforeach (const QMetaObject *testMetaObject, tests)\n\t{\n\t\tQScopedPointer<QObject> test(testMetaObject->newInstance());\n\t\tQ_ASSERT(test);\n\n\t\tif (test)\n\t\t{\n\t\t\tresult |= QTest::qExec(test.data(), argc, argv);\n\t\t}\n\t}\n\n\treturn result;\n}\n"
  },
  {
    "path": "Tests/suite_squish_test_suit/envvars",
    "content": ""
  },
  {
    "path": "Tests/suite_squish_test_suit/suite.conf",
    "content": "AUT=QtnPropertyDemo\nCWD=<AUT_path>\nENVVARS=envvars\nHOOK_SUB_PROCESSES=false\nIMPLICITAUTSTART=1\nLANGUAGE=JavaScript\nTEST_CASES=tst_gui_test\nVERSION=3\nWRAPPERS=Qt\n"
  },
  {
    "path": "Tests/suite_squish_test_suit/tst_gui_test/test.js",
    "content": "function waitForChild() {\n    if (arguments.length < 2)\n        return null\n    var obj = arguments[0]\n    objectMap.add(obj)\n    obj = waitForObject(\"{type='\"+arguments[1]+\"' parent='\"+objectMap.symbolicName(obj)+\"'}\")\n    for (var i = 2; i < arguments.length; i++) {\n        objectMap.add(obj)\n        obj = waitForObject(\"{type='\"+arguments[i]+\"' parent='\"+objectMap.symbolicName(obj)+\"'}\")\n    }\n    return obj\n}\n\nfunction main() {\n    var w = waitForObject(\"{type='QtnPropertyView' visible='1' window=':PropertyWidget Demo_MainWindow'}\")\n    var ap = w.accessibilityProxy()\n    \n    // test BoolProperty\n    var p = ap.findProperty(\"BoolProperty\")\n    test.verify(!isNull(p), \"BoolProperty should exists\")\n    // check property value\n    test.compare(object.convertTo(p.value,\"bool\"), false)\n    // check property delegate name\n    test.compare(ap.propertyDelegateName(p), \"default\")\n    // check property description\n    test.compare(p.description, \"Property to hold boolean values.\")\n    // get center of property edit rect\n    var pt = ap.propertyActionRect(p, 0).center()\n    mouseClick(w, pt.x, pt.y, Qt.NoModifier, Qt.LeftButton)\n    snooze(1)\n    // wait for popup checkbox widget\n    var e = waitForChild(w, \"QCheckBox\")\n    test.compare(e.checked, false)\n    // modify property\n    pt = e.rect.center()\n    mouseClick(e, pt.x, pt.y, Qt.NoModifier, Qt.LeftButton)\n    type(e, \"<Return>\")\n    test.compare(object.convertTo(p.value,\"bool\"), true)\n    snooze(1)\n    \n    // enable subproperty set\n    p = ap.findProperty(\"EnableSubPropertySet\")\n    test.verify(!isNull(p))\n    // get center of property name rect\n    pt = ap.propertyNameRect(p).center()\n    // activate property\n    mouseClick(w, pt.x, pt.y, Qt.NoModifier, Qt.LeftButton)\n    snooze(1)\n    var p2 = ap.activeProperty()\n    test.compare(p, p2, \"EnableSubPropertySet should become active\")\n\n    // verify SubPropertySet is disabled\n    p2 = ap.findProperty(\"SubPropertySet\")\n    test.verify(!isNull(p2))\n    test.compare(p2.isEditable, false)\n    test.compare(p2.state, 4) // QtnPropertyStateImmutable\n    // start edit\n    type(w, \"<Return>\")\n    snooze(1)\n    // wait for popup checkbox widget\n    e = waitForChild(w, \"QCheckBox\")\n    type(e, \" \")\n    type(e, \"<Return>\")\n    // now SubPropertySet should be enabled\n    test.compare(p2.isEditable, true)\n    test.compare(p2.state, 0)\n    \n    // navigation by keyboard\n    snooze(1)\n    type(w, \"<Down>\")\n    test.compare(ap.activeProperty().name, \"SubPropertySet\")\n    snooze(1)\n    // collapse property set by keyboard\n    type(w, \"<Left>\")\n    p = ap.findProperty(\"SubPropertySet.ReadOnlyString\")\n    test.verify(!isNull(p))\n    test.compare(p.isEditable, false)\n    test.compare(p.state, 12) // QtnPropertyStateImmutable | QtnPropertyStateCollapsed\n    snooze(1)\n\n    // expand property set by mouse\n    pt = ap.propertyActionRect(ap.findProperty(\"SubPropertySet\"), 0).center()\n    mouseClick(w, pt.x, pt.y, Qt.NoModifier, Qt.LeftButton)\n    test.compare(p.state, 4) // QtnPropertyStateImmutable\n    snooze(1)\n    \n    //test string list delegate\n    p = ap.findProperty(\"SubPropertySet.StringFromList\")\n    pt = ap.propertyActionRect(p, 0).center()\n    mouseClick(w, pt.x, pt.y, Qt.NoModifier, Qt.LeftButton)\n    e = waitForChild(w, \"QComboBox\")\n    // get popup listbox\n    e = e.view()\n    snooze(1)\n    clickItem(e, \"four\", 0, 0, Qt.NoModifier, Qt.LeftButton)\n    // check property value\n    test.compare(object.convertTo(p.value,\"QString\"), \"four\")\n    snooze(1)\n\n    p = ap.findProperty(\"SubPropertySet2.FileNameProperty\")\n    ap.ensureVisibleProperty(p)\n    p = ap.propertyActionRect(p, 0).center()\n    mouseClick(w, p.x, p.y, Qt.NoModifier, Qt.LeftButton)\n    snooze(1)\n\n    e = waitForChild(w, \"QLineEdit\")\n    type(e, \"hello from squish\")\n    type(e, \"<Return>\")\n    snooze(3)\n\n    return\n}"
  }
]