#include "utility.hpp" #include "obs-module-helper.hpp" #include "obs.hpp" #include #include #include #include #include namespace advss { std::pair GetCursorPos() { auto cursorPos = QCursor::pos(); return {cursorPos.x(), cursorPos.y()}; } bool DoubleEquals(double left, double right, double epsilon) { return (fabs(left - right) < epsilon); } void ReplaceAll(std::string &str, const std::string &from, const std::string &to) { if (from.empty()) { return; } size_t start_pos = 0; while ((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } } std::optional GetJsonField(const std::string &jsonStr, const std::string &fieldToExtract) { try { nlohmann::json json = nlohmann::json::parse(jsonStr); auto it = json.find(fieldToExtract); if (it == json.end()) { return {}; } if (it->is_string()) { return it->get(); } return it->dump(); } catch (const nlohmann::json::exception &) { return {}; } return {}; } bool CompareIgnoringLineEnding(QString &s1, QString &s2) { // Let QT deal with different types of lineendings QTextStream s1stream(&s1); QTextStream s2stream(&s2); while (!s1stream.atEnd() || !s2stream.atEnd()) { QString s1s = s1stream.readLine(); QString s2s = s2stream.readLine(); if (s1s != s2s) { return false; } } if (!s1stream.atEnd() && !s2stream.atEnd()) { return false; } return true; } std::string GetDataFilePath(const std::string &file) { std::string root_path = obs_get_module_data_path(obs_current_module()); if (!root_path.empty()) { return root_path + "/" + file; } return ""; } QString GetDefaultSettingsSaveLocation() { QString desktopPath = QStandardPaths::writableLocation( QStandardPaths::DesktopLocation); auto scName = obs_frontend_get_current_scene_collection(); QString sceneCollectionName(scName); bfree(scName); auto timestamp = QDateTime::currentDateTime(); auto path = desktopPath + "/adv-ss-" + sceneCollectionName + "-" + timestamp.toString("yyyy.MM.dd.hh.mm.ss"); // Check if scene collection name contains invalid path characters QFile file(path); if (file.exists()) { return path; } bool validPath = file.open(QIODevice::WriteOnly); if (validPath) { file.remove(); return path; } return desktopPath + "/adv-ss-" + timestamp.toString("yyyy.MM.dd.hh.mm.ss"); } void listAddClicked(QListWidget *list, QWidget *newWidget, QPushButton *addButton, QMetaObject::Connection *addHighlight) { if (!list || !newWidget) { blog(LOG_WARNING, "listAddClicked called without valid list or widget"); return; } if (addButton && addHighlight) { addButton->disconnect(*addHighlight); } QListWidgetItem *item; item = new QListWidgetItem(list); list->addItem(item); item->setSizeHint(newWidget->minimumSizeHint()); list->setItemWidget(item, newWidget); list->scrollToItem(item); } bool listMoveUp(QListWidget *list) { int index = list->currentRow(); if (index == -1 || index == 0) { return false; } QWidget *row = list->itemWidget(list->currentItem()); QListWidgetItem *itemN = list->currentItem()->clone(); list->insertItem(index - 1, itemN); list->setItemWidget(itemN, row); list->takeItem(index + 1); list->setCurrentRow(index - 1); return true; } bool listMoveDown(QListWidget *list) { int index = list->currentRow(); if (index == -1 || index == list->count() - 1) { return false; } QWidget *row = list->itemWidget(list->currentItem()); QListWidgetItem *itemN = list->currentItem()->clone(); list->insertItem(index + 2, itemN); list->setItemWidget(itemN, row); list->takeItem(index); list->setCurrentRow(index + 1); return true; } } // namespace advss