SceneSwitcher/lib/legacy/switch-executable.cpp
2024-03-02 15:27:02 +01:00

284 lines
6.9 KiB
C++

#include "advanced-scene-switcher.hpp"
#include "layout-helpers.hpp"
#include "platform-funcs.hpp"
#include "selection-helpers.hpp"
#include "switcher-data.hpp"
#include "ui-helpers.hpp"
#include "utility.hpp"
namespace advss {
bool ExecutableSwitch::pause = false;
static QMetaObject::Connection addPulse;
void AdvSceneSwitcher::on_executableAdd_clicked()
{
std::lock_guard<std::mutex> lock(switcher->m);
switcher->executableSwitches.emplace_back();
listAddClicked(ui->executables,
new ExecutableSwitchWidget(
this, &switcher->executableSwitches.back()),
ui->executableAdd, &addPulse);
ui->exeHelp->setVisible(false);
}
void AdvSceneSwitcher::on_executableRemove_clicked()
{
QListWidgetItem *item = ui->executables->currentItem();
if (!item) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
int idx = ui->executables->currentRow();
auto &switches = switcher->executableSwitches;
switches.erase(switches.begin() + idx);
}
delete item;
}
void AdvSceneSwitcher::on_executableUp_clicked()
{
int index = ui->executables->currentRow();
if (!listMoveUp(ui->executables)) {
return;
}
ExecutableSwitchWidget *s1 =
(ExecutableSwitchWidget *)ui->executables->itemWidget(
ui->executables->item(index));
ExecutableSwitchWidget *s2 =
(ExecutableSwitchWidget *)ui->executables->itemWidget(
ui->executables->item(index - 1));
ExecutableSwitchWidget::swapSwitchData(s1, s2);
std::lock_guard<std::mutex> lock(switcher->m);
std::swap(switcher->executableSwitches[index],
switcher->executableSwitches[index - 1]);
}
void AdvSceneSwitcher::on_executableDown_clicked()
{
int index = ui->executables->currentRow();
if (!listMoveDown(ui->executables)) {
return;
}
ExecutableSwitchWidget *s1 =
(ExecutableSwitchWidget *)ui->executables->itemWidget(
ui->executables->item(index));
ExecutableSwitchWidget *s2 =
(ExecutableSwitchWidget *)ui->executables->itemWidget(
ui->executables->item(index + 1));
ExecutableSwitchWidget::swapSwitchData(s1, s2);
std::lock_guard<std::mutex> lock(switcher->m);
std::swap(switcher->executableSwitches[index],
switcher->executableSwitches[index + 1]);
}
bool SwitcherData::checkExeSwitch(OBSWeakSource &scene,
OBSWeakSource &transition)
{
if (executableSwitches.size() == 0 || ExecutableSwitch::pause) {
return false;
}
std::string title = switcher->currentTitle;
QStringList runningProcesses;
bool ignored = false;
bool match = false;
// Check for match
GetProcessList(runningProcesses);
for (ExecutableSwitch &s : executableSwitches) {
if (!s.initialized()) {
continue;
}
bool equals = runningProcesses.contains(s.exe);
bool matches = (runningProcesses.indexOf(
QRegularExpression(s.exe)) != -1);
bool focus = (!s.inFocus || IsInFocus(s.exe));
// True if current window is ignored AND switch equals OR matches last window
bool ignore =
(ignored && (title == s.exe.toStdString() ||
QString::fromStdString(title).contains(
QRegularExpression(s.exe))));
if ((equals || matches) && (focus || ignore)) {
match = true;
scene = s.getScene();
transition = s.transition;
if (VerboseLoggingEnabled()) {
s.logMatch();
}
break;
}
}
return match;
}
void SwitcherData::saveExecutableSwitches(obs_data_t *obj)
{
obs_data_array_t *executableArray = obs_data_array_create();
for (ExecutableSwitch &s : executableSwitches) {
obs_data_t *array_obj = obs_data_create();
s.save(array_obj);
obs_data_array_push_back(executableArray, array_obj);
obs_data_release(array_obj);
}
obs_data_set_array(obj, "executableSwitches", executableArray);
obs_data_array_release(executableArray);
}
void SwitcherData::loadExecutableSwitches(obs_data_t *obj)
{
executableSwitches.clear();
obs_data_array_t *executableArray =
obs_data_get_array(obj, "executableSwitches");
size_t count = obs_data_array_count(executableArray);
for (size_t i = 0; i < count; i++) {
obs_data_t *array_obj = obs_data_array_item(executableArray, i);
executableSwitches.emplace_back();
executableSwitches.back().load(array_obj);
obs_data_release(array_obj);
}
obs_data_array_release(executableArray);
}
void AdvSceneSwitcher::SetupExecutableTab()
{
for (auto &s : switcher->executableSwitches) {
QListWidgetItem *item;
item = new QListWidgetItem(ui->executables);
ui->executables->addItem(item);
ExecutableSwitchWidget *sw =
new ExecutableSwitchWidget(this, &s);
item->setSizeHint(sw->minimumSizeHint());
ui->executables->setItemWidget(item, sw);
}
if (switcher->executableSwitches.size() == 0) {
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->executableAdd,
QColor(Qt::green));
}
ui->exeHelp->setVisible(true);
} else {
ui->exeHelp->setVisible(false);
}
}
void ExecutableSwitch::save(obs_data_t *obj)
{
SceneSwitcherEntry::save(obj);
obs_data_set_string(obj, "exefile", exe.toUtf8());
obs_data_set_bool(obj, "infocus", inFocus);
}
void ExecutableSwitch::load(obs_data_t *obj)
{
SceneSwitcherEntry::load(obj);
exe = obs_data_get_string(obj, "exefile");
inFocus = obs_data_get_bool(obj, "infocus");
}
ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
ExecutableSwitch *s)
: SwitchWidget(parent, s, true, true)
{
processes = new QComboBox();
requiresFocus = new QCheckBox(obs_module_text(
"AdvSceneSwitcher.executableTab.requiresFocus"));
QWidget::connect(processes, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(ProcessChanged(const QString &)));
QWidget::connect(requiresFocus, SIGNAL(stateChanged(int)), this,
SLOT(FocusChanged(int)));
PopulateProcessSelection(processes);
processes->setEditable(true);
processes->setMaxVisibleItems(20);
if (s) {
processes->setCurrentText(s->exe);
requiresFocus->setChecked(s->inFocus);
}
QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{processes}}", processes},
{"{{requiresFocus}}", requiresFocus},
{"{{scenes}}", scenes},
{"{{transitions}}", transitions}};
PlaceWidgets(obs_module_text("AdvSceneSwitcher.executableTab.entry"),
mainLayout, widgetPlaceholders);
setLayout(mainLayout);
switchData = s;
loading = false;
}
ExecutableSwitch *ExecutableSwitchWidget::getSwitchData()
{
return switchData;
}
void ExecutableSwitchWidget::setSwitchData(ExecutableSwitch *s)
{
switchData = s;
}
void ExecutableSwitchWidget::swapSwitchData(ExecutableSwitchWidget *s1,
ExecutableSwitchWidget *s2)
{
SwitchWidget::swapSwitchData(s1, s2);
ExecutableSwitch *t = s1->getSwitchData();
s1->setSwitchData(s2->getSwitchData());
s2->setSwitchData(t);
}
void ExecutableSwitchWidget::ProcessChanged(const QString &text)
{
if (loading || !switchData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switchData->exe = text;
}
void ExecutableSwitchWidget::FocusChanged(int state)
{
if (loading || !switchData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switchData->inFocus = state;
}
} // namespace advss