mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-22 09:54:54 -05:00
A crash could occur if the plugin window was closed and reopened and a new resource was added to either the Variable, Action queue, Websocket, or Twitch tab. No context object was provided to the signal handlers. The signal provider is intentionally not deleted when the UI is closed. Because of this, the signal connections were never cleared when the underlying tab widget was destroyed. So, in the case of closing and reopening the settings window, the old connection with the outdated widget pointers would be called again.
228 lines
5.5 KiB
C++
228 lines
5.5 KiB
C++
#include "twitch-tab.hpp"
|
|
#include "obs-module-helper.hpp"
|
|
#include "sync-helpers.hpp"
|
|
#include "tab-helpers.hpp"
|
|
#include "token.hpp"
|
|
#include "ui-helpers.hpp"
|
|
|
|
#include <QTabWidget>
|
|
|
|
namespace advss {
|
|
|
|
static bool registerTab();
|
|
static void setupTab(QTabWidget *);
|
|
static bool registerTabDone = registerTab();
|
|
|
|
static TwitchConnectionsTable *tabWidget = nullptr;
|
|
|
|
static bool registerTab()
|
|
{
|
|
AddSetupTabCallback("twitchConnectionTab",
|
|
TwitchConnectionsTable::Create, setupTab);
|
|
return true;
|
|
}
|
|
|
|
static void setTabVisible(QTabWidget *tabWidget, bool visible)
|
|
{
|
|
SetTabVisibleByName(
|
|
tabWidget, visible,
|
|
obs_module_text("AdvSceneSwitcher.twitchConnectionTab.title"));
|
|
}
|
|
|
|
static bool twitchTabIsSelected(QTabWidget *tabWidget)
|
|
{
|
|
return tabWidget->tabText(tabWidget->currentIndex()) ==
|
|
obs_module_text("AdvSceneSwitcher.twitchConnectionTab.title");
|
|
}
|
|
|
|
TwitchConnectionsTable *TwitchConnectionsTable::Create()
|
|
{
|
|
tabWidget = new TwitchConnectionsTable();
|
|
return tabWidget;
|
|
}
|
|
|
|
void TwitchConnectionsTable::Add()
|
|
{
|
|
auto newToken = std::make_shared<TwitchToken>();
|
|
auto accepted =
|
|
TwitchTokenSettingsDialog::AskForSettings(this, *newToken);
|
|
if (!accepted) {
|
|
return;
|
|
}
|
|
|
|
{
|
|
auto lock = LockContext();
|
|
auto &tokens = GetTwitchTokens();
|
|
tokens.emplace_back(newToken);
|
|
}
|
|
|
|
TwitchConnectionSignalManager::Instance()->Add(
|
|
QString::fromStdString(newToken->Name()));
|
|
}
|
|
|
|
void TwitchConnectionsTable::Remove()
|
|
{
|
|
auto selectedRows =
|
|
tabWidget->Table()->selectionModel()->selectedRows();
|
|
if (selectedRows.empty()) {
|
|
return;
|
|
}
|
|
|
|
QStringList tokenNames;
|
|
for (auto row : selectedRows) {
|
|
auto cell = tabWidget->Table()->item(row.row(), 0);
|
|
if (!cell) {
|
|
continue;
|
|
}
|
|
|
|
tokenNames << cell->text();
|
|
}
|
|
|
|
int tokenNameCount = tokenNames.size();
|
|
if (tokenNameCount == 1) {
|
|
QString deleteWarning = obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.removeSingleConnectionPopup.text");
|
|
if (!DisplayMessage(deleteWarning.arg(tokenNames.at(0)),
|
|
true)) {
|
|
return;
|
|
}
|
|
} else {
|
|
QString deleteWarning = obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.removeMultipleConnectionsPopup.text");
|
|
if (!DisplayMessage(deleteWarning.arg(tokenNameCount), true)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto lock = LockContext();
|
|
RemoveItemsByName(GetTwitchTokens(), tokenNames);
|
|
}
|
|
|
|
for (const auto &name : tokenNames) {
|
|
TwitchConnectionSignalManager::Instance()->Remove(name);
|
|
}
|
|
}
|
|
|
|
static QStringList getCellLabels(TwitchToken *token, bool addName = true)
|
|
{
|
|
assert(token);
|
|
|
|
auto result = QStringList();
|
|
if (addName) {
|
|
result << QString::fromStdString(token->Name());
|
|
}
|
|
result << QString::fromStdString(obs_module_text(
|
|
token->IsValid()
|
|
? "AdvSceneSwitcher.twitchConnectionTab.yes"
|
|
: "AdvSceneSwitcher.twitchConnectionTab.no"))
|
|
<< QString::number(token->PermissionCount());
|
|
return result;
|
|
}
|
|
|
|
static void openSettingsDialog()
|
|
{
|
|
auto selectedRows =
|
|
tabWidget->Table()->selectionModel()->selectedRows();
|
|
if (selectedRows.empty()) {
|
|
return;
|
|
}
|
|
|
|
auto cell = tabWidget->Table()->item(selectedRows.last().row(), 0);
|
|
if (!cell) {
|
|
return;
|
|
}
|
|
|
|
auto weakToken = GetWeakTwitchTokenByQString(cell->text());
|
|
auto token = weakToken.lock();
|
|
if (!token) {
|
|
return;
|
|
}
|
|
|
|
TwitchTokenSettingsDialog::AskForSettings(tabWidget->Table(),
|
|
*token.get());
|
|
}
|
|
|
|
static const QStringList headers =
|
|
QStringList()
|
|
<< obs_module_text("AdvSceneSwitcher.twitchConnectionTab.name.header")
|
|
<< obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.isValid.header")
|
|
<< obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.permissionCount.header");
|
|
|
|
TwitchConnectionsTable::TwitchConnectionsTable(QTabWidget *parent)
|
|
: ResourceTable(
|
|
parent,
|
|
obs_module_text("AdvSceneSwitcher.twitchConnectionTab.help"),
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.twitchConnectionAddButton.tooltip"),
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.twitchConnectionTab.twitchConnectionRemoveButton.tooltip"),
|
|
headers, openSettingsDialog)
|
|
{
|
|
for (const auto &token : GetTwitchTokens()) {
|
|
auto t = std::static_pointer_cast<TwitchToken>(token);
|
|
AddItemTableRow(Table(), getCellLabels(t.get()));
|
|
}
|
|
|
|
SetHelpVisible(GetTwitchTokens().empty());
|
|
}
|
|
|
|
static void updateConnectionStatus(QTableWidget *table)
|
|
{
|
|
for (int row = 0; row < table->rowCount(); row++) {
|
|
auto item = table->item(row, 0);
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
auto weakToken = GetWeakTwitchTokenByQString(item->text());
|
|
auto token = weakToken.lock();
|
|
if (!token) {
|
|
continue;
|
|
}
|
|
|
|
UpdateItemTableRow(table, row,
|
|
getCellLabels(token.get(), false));
|
|
}
|
|
}
|
|
|
|
static void setupTab(QTabWidget *tab)
|
|
{
|
|
if (GetTwitchTokens().empty()) {
|
|
setTabVisible(tab, false);
|
|
}
|
|
|
|
QWidget::connect(
|
|
TwitchConnectionSignalManager::Instance(),
|
|
&TwitchConnectionSignalManager::Add, tab,
|
|
[tab](const QString &name) {
|
|
AddItemTableRow(
|
|
tabWidget->Table(),
|
|
getCellLabels(GetWeakTwitchTokenByQString(name)
|
|
.lock()
|
|
.get()));
|
|
tabWidget->SetHelpVisible(false);
|
|
tabWidget->HighlightAddButton(false);
|
|
setTabVisible(tab, true);
|
|
});
|
|
QWidget::connect(TwitchConnectionSignalManager::Instance(),
|
|
&TwitchConnectionSignalManager::Remove, tab,
|
|
[](const QString &name) {
|
|
RemoveItemTableRow(tabWidget->Table(), name);
|
|
if (tabWidget->Table()->rowCount() == 0) {
|
|
tabWidget->SetHelpVisible(true);
|
|
tabWidget->HighlightAddButton(true);
|
|
}
|
|
});
|
|
|
|
QWidget::connect(tab, &QTabWidget::currentChanged, [tab]() {
|
|
if (twitchTabIsSelected(tab)) {
|
|
updateConnectionStatus(tabWidget->Table());
|
|
}
|
|
});
|
|
}
|
|
|
|
} // namespace advss
|