From a82a2ccffeaf0253af584d8ba050c4d78bb7e09b Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Wed, 22 Feb 2023 15:03:16 +0100 Subject: [PATCH] Add option to find and replace strings in current value --- data/locale/en-US.ini | 4 ++ src/macro-core/macro-action-variable.cpp | 62 +++++++++++++++++++++++- src/macro-core/macro-action-variable.hpp | 11 +++++ src/utils/utility.hpp | 3 +- 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9856a309..8eb68583 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -606,6 +606,9 @@ AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value" AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value" AdvSceneSwitcher.action.variable.type.roundToInt="Round to nearest integer" AdvSceneSwitcher.action.variable.type.subString="Set to substring of current value" +AdvSceneSwitcher.action.variable.type.findAndReplace="Find and replace in current value" +AdvSceneSwitcher.action.variable.findAndReplace.find="Text to find" +AdvSceneSwitcher.action.variable.findAndReplace.replace="Text to replace with" AdvSceneSwitcher.action.variable.subString.begin="Beginning" AdvSceneSwitcher.action.variable.subString.all="All" AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!" @@ -615,6 +618,7 @@ AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:" AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}" AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}} Substring size:{{subStringSize}}" AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:" +AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}" AdvSceneSwitcher.action.projector="Projector" AdvSceneSwitcher.action.projector.type.source="Source" AdvSceneSwitcher.action.projector.type.scene="Scene" diff --git a/src/macro-core/macro-action-variable.cpp b/src/macro-core/macro-action-variable.cpp index 5d7202bb..7b6a9f8f 100644 --- a/src/macro-core/macro-action-variable.cpp +++ b/src/macro-core/macro-action-variable.cpp @@ -29,6 +29,8 @@ static std::map actionTypes = { "AdvSceneSwitcher.action.variable.type.roundToInt"}, {MacroActionVariable::Type::SUBSTRING, "AdvSceneSwitcher.action.variable.type.subString"}, + {MacroActionVariable::Type::FIND_AND_REPLACE, + "AdvSceneSwitcher.action.variable.type.findAndReplace"}, }; static void apppend(Variable &var, const std::string &value) @@ -95,6 +97,13 @@ void MacroActionVariable::HandleRegexSubString(Variable *var) var->SetValue(match.captured(0).toStdString()); } +void MacroActionVariable::HandleFindAndReplace(Variable *var) +{ + auto value = var->Value(); + replaceAll(value, _findStr, _replaceStr); + var->SetValue(value); +} + bool MacroActionVariable::PerformAction() { auto var = GetVariableByName(_variableName); @@ -155,6 +164,10 @@ bool MacroActionVariable::PerformAction() HandleIndexSubString(var); return true; } + case Type::FIND_AND_REPLACE: { + HandleFindAndReplace(var); + return true; + } } return true; @@ -173,6 +186,8 @@ bool MacroActionVariable::Save(obs_data_t *obj) const obs_data_set_int(obj, "subStringSize", _subStringSize); obs_data_set_string(obj, "regexPattern", _regexPattern.c_str()); obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx); + obs_data_set_string(obj, "findStr", _findStr.c_str()); + obs_data_set_string(obj, "replaceStr", _replaceStr.c_str()); _regex.Save(obj); return true; } @@ -191,6 +206,8 @@ bool MacroActionVariable::Load(obs_data_t *obj) _regex.Load(obj); _regexPattern = obs_data_get_string(obj, "regexPattern"); _regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx"); + _findStr = obs_data_get_string(obj, "findStr"); + _replaceStr = obs_data_get_string(obj, "replaceStr"); return true; } @@ -303,7 +320,10 @@ MacroActionVariableEdit::MacroActionVariableEdit( _subStringSize(new QSpinBox()), _regex(new RegexConfigWidget(parent)), _regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)), - _regexMatchIdx(new QSpinBox()) + _regexMatchIdx(new QSpinBox()), + _findReplaceLayout(new QHBoxLayout()), + _findStr(new ResizingPlainTextEdit(this, 10, 1, 1)), + _replaceStr(new ResizingPlainTextEdit(this, 10, 1, 1)) { _numValue->setMinimum(-9999999999); _numValue->setMaximum(9999999999); @@ -348,6 +368,10 @@ MacroActionVariableEdit::MacroActionVariableEdit( SLOT(RegexPatternChanged())); QWidget::connect(_regexMatchIdx, SIGNAL(valueChanged(int)), this, SLOT(RegexMatchIdxChanged(int))); + QWidget::connect(_findStr, SIGNAL(textChanged()), this, + SLOT(FindStrValueChanged())); + QWidget::connect(_replaceStr, SIGNAL(textChanged()), this, + SLOT(ReplaceStrValueChanged())); std::unordered_map widgetPlaceholders = { {"{{variables}}", _variables}, @@ -359,6 +383,8 @@ MacroActionVariableEdit::MacroActionVariableEdit( {"{{subStringStart}}", _subStringStart}, {"{{subStringSize}}", _subStringSize}, {"{{regexMatchIdx}}", _regexMatchIdx}, + {"{{findStr}}", _findStr}, + {"{{replaceStr}}", _replaceStr}, }; auto entryLayout = new QHBoxLayout; placeWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"), @@ -374,6 +400,11 @@ MacroActionVariableEdit::MacroActionVariableEdit( "AdvSceneSwitcher.action.variable.entry.substringRegex"), _subStringRegexEntryLayout, widgetPlaceholders); + placeWidgets( + obs_module_text( + "AdvSceneSwitcher.action.variable.entry.findAndReplace"), + _findReplaceLayout, widgetPlaceholders, false); + auto regexConfigLayout = new QHBoxLayout; regexConfigLayout->addWidget(_regex); regexConfigLayout->addStretch(); @@ -388,6 +419,7 @@ MacroActionVariableEdit::MacroActionVariableEdit( layout->addLayout(_substringLayout); layout->addWidget(_segmentValueStatus); layout->addWidget(_segmentValue); + layout->addLayout(_findReplaceLayout); setLayout(layout); _entryData = entryData; @@ -418,6 +450,9 @@ void MacroActionVariableEdit::UpdateEntryData() _regexPattern->setPlainText( QString::fromStdString(_entryData->_regexPattern)); _regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1); + _findStr->setPlainText(QString::fromStdString(_entryData->_findStr)); + _replaceStr->setPlainText( + QString::fromStdString(_entryData->_replaceStr)); SetWidgetVisibility(); } @@ -635,6 +670,28 @@ void MacroActionVariableEdit::RegexMatchIdxChanged(int val) _entryData->_regexMatchIdx = val - 1; } +void MacroActionVariableEdit::FindStrValueChanged() +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_findStr = _findStr->toPlainText().toStdString(); + adjustSize(); +} + +void MacroActionVariableEdit::ReplaceStrValueChanged() +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_replaceStr = _replaceStr->toPlainText().toStdString(); + adjustSize(); +} + void MacroActionVariableEdit::MarkSelectedSegment() { if (switcher->disableHints) { @@ -710,6 +767,9 @@ void MacroActionVariableEdit::SetWidgetVisibility() setLayoutVisible(_subStringRegexEntryLayout, showRegex); _regexPattern->setVisible(showRegex); } + setLayoutVisible(_findReplaceLayout, + _entryData->_type == + MacroActionVariable::Type::FIND_AND_REPLACE); adjustSize(); updateGeometry(); diff --git a/src/macro-core/macro-action-variable.hpp b/src/macro-core/macro-action-variable.hpp index 9e11bc54..3a919991 100644 --- a/src/macro-core/macro-action-variable.hpp +++ b/src/macro-core/macro-action-variable.hpp @@ -31,6 +31,7 @@ public: SET_ACTION_VALUE, ROUND_TO_INT, SUBSTRING, + FIND_AND_REPLACE, }; Type _type = Type::SET_FIXED_VALUE; @@ -43,11 +44,16 @@ public: RegexConfig _regex = RegexConfig::PartialMatchRegexConfig(); std::string _regexPattern = ".*"; int _regexMatchIdx = 0; + std::string _findStr = obs_module_text( + "AdvSceneSwitcher.action.variable.findAndReplace.find"); + std::string _replaceStr = obs_module_text( + "AdvSceneSwitcher.action.variable.findAndReplace.replace"); private: void DecrementCurrentSegmentVariableRef(); void HandleIndexSubString(Variable *); void HandleRegexSubString(Variable *); + void HandleFindAndReplace(Variable *); std::weak_ptr _macroSegment; int _segmentIdxLoadValue = -1; @@ -85,6 +91,8 @@ private slots: void RegexChanged(RegexConfig conf); void RegexPatternChanged(); void RegexMatchIdxChanged(int val); + void FindStrValueChanged(); + void ReplaceStrValueChanged(); signals: void HeaderInfoChanged(const QString &); @@ -106,6 +114,9 @@ protected: RegexConfigWidget *_regex; ResizingPlainTextEdit *_regexPattern; QSpinBox *_regexMatchIdx; + QHBoxLayout *_findReplaceLayout; + ResizingPlainTextEdit *_findStr; + ResizingPlainTextEdit *_replaceStr; std::shared_ptr _entryData; private: diff --git a/src/utils/utility.hpp b/src/utils/utility.hpp index 688a7ce7..f12031a6 100644 --- a/src/utils/utility.hpp +++ b/src/utils/utility.hpp @@ -118,4 +118,5 @@ QString formatJsonString(QString); QString escapeForRegex(QString &s); bool doubleEquals(double left, double right, double epsilon); std::pair getCursorPos(); -void replaceAll(std::string &str, const std::string &from, const std::string &to); +void replaceAll(std::string &str, const std::string &from, + const std::string &to);