diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui
index 6f22df7f..959cd287 100644
--- a/forms/advanced-scene-switcher.ui
+++ b/forms/advanced-scene-switcher.ui
@@ -2186,6 +2186,13 @@
+ -
+
+
+ Only match if content changed
+
+
+
-
diff --git a/src/headers/switch-file.hpp b/src/headers/switch-file.hpp
index b042ae24..aa08e58a 100644
--- a/src/headers/switch-file.hpp
+++ b/src/headers/switch-file.hpp
@@ -10,19 +10,23 @@ struct FileSwitch : SceneSwitcherEntry {
bool remote = false;
bool useRegex = false;
bool useTime = false;
+ bool onlyMatchIfChanged = false;
QDateTime lastMod;
+ size_t lastHash = 0;
const char *getType() { return "file"; }
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
const char *file_, const char *text_, bool remote_,
- bool useRegex_, bool useTime_)
+ bool useRegex_, bool useTime_,
+ bool onlyMatchIfChanged_)
: SceneSwitcherEntry(scene_, transition_),
file(file_),
text(text_),
remote(remote_),
useRegex(useRegex_),
useTime(useTime_),
+ onlyMatchIfChanged(onlyMatchIfChanged_),
lastMod()
{
}
@@ -39,4 +43,4 @@ static inline QString MakeFileSwitchName(const QString &scene,
const QString &transition,
const QString &fileName,
const QString &text, bool useRegex,
- bool useTime);
+ bool useTime, bool onlyMatchIfChanged);
diff --git a/src/switch-file.cpp b/src/switch-file.cpp
index 5d5b832e..3f5dffac 100644
--- a/src/switch-file.cpp
+++ b/src/switch-file.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include
#include "headers/advanced-scene-switcher.hpp"
@@ -10,6 +11,8 @@
#define LOCAL_FILE_IDX 0
#define REMOTE_FILE_IDX 1
+std::hash strHash;
+
void AdvSceneSwitcher::on_browseButton_clicked()
{
QString path = QFileDialog::getOpenFileName(
@@ -158,24 +161,33 @@ bool compareIgnoringLineEnding(QString &s1, QString &s2)
return true;
}
+bool matchFileContent(QString &filedata, FileSwitch &s)
+{
+ if (s.onlyMatchIfChanged) {
+ size_t newHash = strHash(filedata.toUtf8().constData());
+ if (newHash == s.lastHash)
+ return false;
+ s.lastHash = newHash;
+ }
+
+ if (s.useRegex) {
+ return filedata.contains(
+ QRegularExpression(QString::fromStdString(s.text)));
+ }
+
+ QString text = QString::fromStdString(s.text);
+ return compareIgnoringLineEnding(text, filedata);
+}
+
bool checkRemoteFileContent(FileSwitch &s)
{
std::string data = getRemoteData(s.file);
- bool ret = false;
- if (s.useRegex) {
- ret = QString::fromStdString(data).contains(
- QRegularExpression(QString::fromStdString(s.text)));
- return ret;
- }
- QString t = QString::fromStdString(s.text);
- QString d = QString::fromStdString(data);
-
- return compareIgnoringLineEnding(t, d);
+ QString text = QString::fromStdString(s.text);
+ return matchFileContent(text, s);
}
bool checkLocalFileContent(FileSwitch &s)
{
- bool equal = false;
QString t = QString::fromStdString(s.text);
QFile file(QString::fromStdString(s.file));
if (!file.open(QIODevice::ReadOnly))
@@ -188,17 +200,11 @@ bool checkLocalFileContent(FileSwitch &s)
s.lastMod = newLastMod;
}
- if (s.useRegex) {
- QTextStream in(&file);
- QRegExp rx(t);
- equal = rx.exactMatch(in.readAll());
- } else {
- QTextStream in(&file);
- QString filedata = in.readAll();
- equal = compareIgnoringLineEnding(filedata, t);
- }
+ QString filedata = QTextStream(&file).readAll();
+ bool match = matchFileContent(filedata, s);
+
file.close();
- return equal;
+ return match;
}
void SwitcherData::checkFileContent(bool &match, OBSWeakSource &scene,
@@ -258,6 +264,7 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
bool remote = (ui->fileType->currentIndex() == REMOTE_FILE_IDX);
bool useRegex = ui->fileContentRegExCheckBox->isChecked();
bool useTime = ui->fileContentTimeCheckBox->isChecked();
+ bool onlyMatchIfChanged = ui->onlyMatchIfChanged->isChecked();
if (sceneName.isEmpty() || transitionName.isEmpty() ||
fileName.isEmpty() || text.isEmpty())
@@ -266,8 +273,9 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
OBSWeakSource source = GetWeakSourceByQString(sceneName);
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
- QString switchText = MakeFileSwitchName(
- sceneName, transitionName, fileName, text, useRegex, useTime);
+ QString switchText = MakeFileSwitchName(sceneName, transitionName,
+ fileName, text, useRegex,
+ useTime, onlyMatchIfChanged);
QVariant v = QVariant::fromValue(switchText);
QListWidgetItem *item =
@@ -278,7 +286,8 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
switcher->fileSwitches.emplace_back(source, transition,
fileName.toUtf8().constData(),
text.toUtf8().constData(), remote,
- useRegex, useTime);
+ useRegex, useTime,
+ onlyMatchIfChanged);
}
void AdvSceneSwitcher::on_fileRemove_clicked()
@@ -326,6 +335,7 @@ void AdvSceneSwitcher::on_fileScenesList_currentRowChanged(int idx)
ui->fileType->setCurrentIndex(LOCAL_FILE_IDX);
ui->fileContentRegExCheckBox->setChecked(s.useRegex);
ui->fileContentTimeCheckBox->setChecked(s.useTime);
+ ui->onlyMatchIfChanged->setChecked(s.onlyMatchIfChanged);
}
void AdvSceneSwitcher::on_fileUp_clicked()
@@ -380,6 +390,8 @@ void SwitcherData::saveFileSwitches(obs_data_t *obj)
obs_data_set_bool(array_obj, "remote", s.remote);
obs_data_set_bool(array_obj, "useRegex", s.useRegex);
obs_data_set_bool(array_obj, "useTime", s.useTime);
+ obs_data_set_bool(array_obj, "onlyMatchIfChanged",
+ s.onlyMatchIfChanged);
obs_data_array_push_back(fileArray, array_obj);
}
obs_source_release(source);
@@ -413,11 +425,13 @@ void SwitcherData::loadFileSwitches(obs_data_t *obj)
bool remote = obs_data_get_bool(array_obj, "remote");
bool useRegex = obs_data_get_bool(array_obj, "useRegex");
bool useTime = obs_data_get_bool(array_obj, "useTime");
+ bool onlyMatchIfChanged =
+ obs_data_get_bool(array_obj, "onlyMatchIfChanged");
switcher->fileSwitches.emplace_back(
GetWeakSourceByName(scene),
GetWeakTransitionByName(transition), file, text, remote,
- useRegex, useTime);
+ useRegex, useTime, onlyMatchIfChanged);
obs_data_release(array_obj);
}
@@ -450,7 +464,8 @@ void AdvSceneSwitcher::setupFileTab()
std::string transitionName = GetWeakSourceName(s.transition);
QString listText = MakeFileSwitchName(
sceneName.c_str(), transitionName.c_str(),
- s.file.c_str(), s.text.c_str(), s.useRegex, s.useTime);
+ s.file.c_str(), s.text.c_str(), s.useRegex, s.useTime,
+ s.onlyMatchIfChanged);
QListWidgetItem *item =
new QListWidgetItem(listText, ui->fileScenesList);
@@ -476,13 +491,15 @@ static inline QString MakeFileSwitchName(const QString &scene,
const QString &transition,
const QString &fileName,
const QString &text, bool useRegex,
- bool useTime)
+ bool useTime, bool onlyMatchIfChanged)
{
QString switchName = QStringLiteral("Switch to ") + scene +
QStringLiteral(" using ") + transition +
QStringLiteral(" if ") + fileName;
if (useTime)
switchName += QStringLiteral(" was modified and");
+ if (onlyMatchIfChanged)
+ switchName += QStringLiteral(" if the contents changed and");
switchName += QStringLiteral(" contains");
if (useRegex)
switchName += QStringLiteral(" (RegEx): \n\"");