From 57d78a996a838a2d9cf54d597ae8e5406be5841d Mon Sep 17 00:00:00 2001 From: Przemek Pawlas <3606072+Destroy666x@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:34:10 +0200 Subject: [PATCH] Add variable trim and case change actions --- data/locale/en-US.ini | 8 ++- data/locale/pt-BR.ini | 1 - lib/macro/macro-action-variable.cpp | 96 +++++++++++++++++++++++++++++ lib/macro/macro-action-variable.hpp | 14 +++++ 4 files changed, 117 insertions(+), 2 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index b8c8e995..25f75aa0 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -1040,6 +1040,12 @@ AdvSceneSwitcher.action.variable.type.sceneItemName="Set to scene item name at i AdvSceneSwitcher.action.variable.type.padValue="Pad current value" AdvSceneSwitcher.action.variable.type.truncateValue="Truncate current value" AdvSceneSwitcher.action.variable.type.swapValues="Swap variable values" +AdvSceneSwitcher.action.variable.type.trim="Trim whitespace" +AdvSceneSwitcher.action.variable.type.changeCase="Change case" +AdvSceneSwitcher.action.variable.case.type.lowerCase="lowercase" +AdvSceneSwitcher.action.variable.case.type.upperCase="UPPERCASE" +AdvSceneSwitcher.action.variable.case.type.capitalized="Capitalized" +AdvSceneSwitcher.action.variable.case.type.startCase="Start Case" AdvSceneSwitcher.action.variable.truncateOrPadDirection.left="Left" AdvSceneSwitcher.action.variable.truncateOrPadDirection.right="Right" AdvSceneSwitcher.action.variable.askForValuePromptDefault="Assign value to variable \"%1\":" @@ -1053,7 +1059,7 @@ AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!" AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!" AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!" AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:" -AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{tempVarsHelp}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}" +AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{tempVarsHelp}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}{{caseType}}" AdvSceneSwitcher.action.variable.entry.pad="{{actions}}of{{variables}}to length{{stringLength}}by adding{{paddingCharSelection}}to the{{direction}}" AdvSceneSwitcher.action.variable.entry.truncate="{{actions}}of{{variables}}to length{{stringLength}}by removing characters from the{{direction}}" AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}}Substring size:{{subStringSize}}" diff --git a/data/locale/pt-BR.ini b/data/locale/pt-BR.ini index affc5b48..b011a05d 100644 --- a/data/locale/pt-BR.ini +++ b/data/locale/pt-BR.ini @@ -1038,7 +1038,6 @@ AdvSceneSwitcher.action.variable.invalidSelection="Seleção inválida!" AdvSceneSwitcher.action.variable.actionNoVariableSupport="Obter valores de variáveis das ações %1 não é suportado!" AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Obter valores de variáveis das condições %1 não é suportado!" AdvSceneSwitcher.action.variable.currentSegmentValue="Valor atual:" -AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{tempVarsHelp}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}" AdvSceneSwitcher.action.variable.entry.pad="{{actions}}de{{variables}}para comprimento{{stringLength}}adicionando{{paddingCharSelection}}ao{{direction}}" AdvSceneSwitcher.action.variable.entry.truncate="{{actions}}de{{variables}}para comprimento{{stringLength}}removendo caracteres da{{direction}}" AdvSceneSwitcher.action.variable.entry.substringIndex="Início da substring:{{subStringStart}}Tamanho da substring:{{subStringSize}}" diff --git a/lib/macro/macro-action-variable.cpp b/lib/macro/macro-action-variable.cpp index 809e0bbc..9040d46c 100644 --- a/lib/macro/macro-action-variable.cpp +++ b/lib/macro/macro-action-variable.cpp @@ -60,6 +60,21 @@ const static std::map actionTypes = { "AdvSceneSwitcher.action.variable.type.truncateValue"}, {MacroActionVariable::Type::SWAP_VALUES, "AdvSceneSwitcher.action.variable.type.swapValues"}, + {MacroActionVariable::Type::TRIM, + "AdvSceneSwitcher.action.variable.type.trim"}, + {MacroActionVariable::Type::CHANGE_CASE, + "AdvSceneSwitcher.action.variable.type.changeCase"}, +}; + +const static std::map caseTypes = { + {MacroActionVariable::CaseType::LOWER_CASE, + "AdvSceneSwitcher.action.variable.case.type.lowerCase"}, + {MacroActionVariable::CaseType::UPPER_CASE, + "AdvSceneSwitcher.action.variable.case.type.upperCase"}, + {MacroActionVariable::CaseType::CAPITALIZED, + "AdvSceneSwitcher.action.variable.case.type.capitalized"}, + {MacroActionVariable::CaseType::START_CASE, + "AdvSceneSwitcher.action.variable.case.type.startCase"}, }; static void apppend(Variable &var, const std::string &value) @@ -159,6 +174,43 @@ void MacroActionVariable::HandleMathExpression(Variable *var) var->SetValue(std::get(result)); } +void MacroActionVariable::HandleCaseChange(Variable *var) +{ + auto value = QString::fromStdString(var->Value()); + + switch (_caseType) { + case CaseType::LOWER_CASE: + var->SetValue(value.toLower().toStdString()); + break; + case CaseType::UPPER_CASE: + var->SetValue(value.toUpper().toStdString()); + break; + case CaseType::CAPITALIZED: { + if (value.isEmpty()) { + return; + } + + value[0] = value[0].toUpper(); + var->SetValue(value.toStdString()); + break; + } + case CaseType::START_CASE: { + auto partList = value.split(QRegularExpression("\\b")); + + for (auto &part : partList) { + if (part.isEmpty()) { + continue; + } + + part[0] = part[0].toUpper(); + } + + var->SetValue(partList.join("").toStdString()); + + break; + } + } +} struct GetSceneItemNameHelper { int curIdx = 0; int targetIdx = 0; @@ -405,6 +457,15 @@ bool MacroActionVariable::PerformAction() var2->SetValue(tempValue); return true; } + case Type::TRIM: { + var->SetValue(QString::fromStdString(var->Value()) + .trimmed() + .toStdString()); + return true; + } + case Type::CHANGE_CASE: + HandleCaseChange(var.get()); + return true; } return true; @@ -441,6 +502,8 @@ bool MacroActionVariable::Save(obs_data_t *obj) const obs_data_set_int(obj, "direction", static_cast(_direction)); _stringLength.Save(obj, "stringLength"); obs_data_set_int(obj, "paddingChar", _paddingChar); + obs_data_set_int(obj, "caseType", static_cast(_caseType)); + return true; } @@ -479,6 +542,8 @@ bool MacroActionVariable::Load(obs_data_t *obj) } else { _paddingChar = ' '; } + _caseType = static_cast(obs_data_get_int(obj, "caseType")); + return true; } @@ -597,6 +662,14 @@ static inline void populateTypeSelection(QComboBox *list) } } +static inline void populateCaseTypeSelection(QComboBox *list) +{ + for (const auto &[type, name] : caseTypes) { + list->addItem(obs_module_text(name.c_str()), + static_cast(type)); + } +} + static inline void populateDirectionSelection(QComboBox *list) { list->addItems( @@ -649,6 +722,7 @@ MacroActionVariableEdit::MacroActionVariableEdit( _direction(new QComboBox()), _stringLength(new VariableSpinBox()), _paddingCharSelection(new SingleCharSelection()), + _caseType(new FilterComboBox(this)), _entryLayout(new QHBoxLayout()) { _numValue->setMinimum(-9999999999); @@ -671,6 +745,7 @@ MacroActionVariableEdit::MacroActionVariableEdit( _stringLength->setMaximum(999); populateTypeSelection(_actions); populateDirectionSelection(_direction); + populateCaseTypeSelection(_caseType); QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)), this, SLOT(VariableChanged(const QString &))); @@ -735,6 +810,8 @@ MacroActionVariableEdit::MacroActionVariableEdit( QWidget::connect(_paddingCharSelection, SIGNAL(CharChanged(const QString &)), this, SLOT(CharSelectionChanged(const QString &))); + QWidget::connect(_caseType, SIGNAL(currentIndexChanged(int)), this, + SLOT(CaseTypeChanged(int))); const std::unordered_map widgetPlaceholders = { {"{{variables}}", _variables}, @@ -762,6 +839,7 @@ MacroActionVariableEdit::MacroActionVariableEdit( {"{{direction}}", _direction}, {"{{stringLength}}", _stringLength}, {"{{paddingCharSelection}}", _paddingCharSelection}, + {"{{caseType}}", _caseType}, }; PlaceWidgets( obs_module_text("AdvSceneSwitcher.action.variable.entry.other"), @@ -862,6 +940,9 @@ void MacroActionVariableEdit::UpdateEntryData() _stringLength->SetValue(_entryData->_stringLength); _paddingCharSelection->setText( QChar::fromLatin1(_entryData->_paddingChar)); + _caseType->setCurrentIndex( + _caseType->findData(static_cast(_entryData->_caseType))); + SetWidgetVisibility(); } @@ -1268,6 +1349,17 @@ void MacroActionVariableEdit::CharSelectionChanged(const QString &character) } } +void MacroActionVariableEdit::CaseTypeChanged(int index) +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_caseType = static_cast( + _caseType->itemData(index).toInt()); +} + void MacroActionVariableEdit::SetWidgetVisibility() { if (!_entryData) { @@ -1290,6 +1382,7 @@ void MacroActionVariableEdit::SetWidgetVisibility() {"{{direction}}", _direction}, {"{{stringLength}}", _stringLength}, {"{{paddingCharSelection}}", _paddingCharSelection}, + {"{{caseType}}", _caseType}, }; const char *layoutString = ""; @@ -1414,6 +1507,9 @@ void MacroActionVariableEdit::SetWidgetVisibility() _entryData->_type == MacroActionVariable::Type::TRUNCATE); _paddingCharSelection->setVisible(_entryData->_type == MacroActionVariable::Type::PAD); + _caseType->setVisible(_entryData->_type == + MacroActionVariable::Type::CHANGE_CASE); + adjustSize(); updateGeometry(); } diff --git a/lib/macro/macro-action-variable.hpp b/lib/macro/macro-action-variable.hpp index 62b2ea60..fe60dae6 100644 --- a/lib/macro/macro-action-variable.hpp +++ b/lib/macro/macro-action-variable.hpp @@ -50,6 +50,8 @@ public: PAD, TRUNCATE, SWAP_VALUES, + TRIM, + CHANGE_CASE, }; Type _type = Type::SET_FIXED_VALUE; @@ -89,12 +91,22 @@ public: IntVariable _stringLength = 1; char _paddingChar = '0'; + enum class CaseType { + LOWER_CASE, + UPPER_CASE, + CAPITALIZED, + START_CASE, + }; + + CaseType _caseType = CaseType::LOWER_CASE; + private: void DecrementCurrentSegmentVariableRef(); void HandleIndexSubString(Variable *); void HandleRegexSubString(Variable *); void HandleFindAndReplace(Variable *); void HandleMathExpression(Variable *); + void HandleCaseChange(Variable *); void SetToSceneItemName(Variable *); std::weak_ptr _macroSegment; @@ -148,6 +160,7 @@ private slots: void DirectionChanged(int); void StringLengthChanged(const NumberVariable &); void CharSelectionChanged(const QString &); + void CaseTypeChanged(int index); signals: void HeaderInfoChanged(const QString &); @@ -192,6 +205,7 @@ private: QComboBox *_direction; VariableSpinBox *_stringLength; SingleCharSelection *_paddingCharSelection; + FilterComboBox *_caseType; QHBoxLayout *_entryLayout; std::shared_ptr _entryData;