Fix crash when deleting macro

This commit is contained in:
WarmUpTill 2025-05-29 21:48:05 +02:00 committed by WarmUpTill
parent c567e6ef7f
commit 30422aecf3
5 changed files with 80 additions and 45 deletions

View File

@ -35,12 +35,14 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
_enable(new SwitchButton()),
_entryData(entryData)
{
auto actionStateTimer = new QTimer(this);
QWidget::connect(_actionSelection,
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(ActionSelectionChanged(const QString &)));
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
SLOT(ActionEnableChanged(bool)));
QWidget::connect(&_actionStateTimer, SIGNAL(timeout()), this,
QWidget::connect(actionStateTimer, SIGNAL(timeout()), this,
SLOT(UpdateActionState()));
populateActionSelection(_actionSelection);
@ -63,7 +65,7 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
_entryData = entryData;
SetupWidgets(true);
_actionStateTimer.start(300);
actionStateTimer->start(300);
_loading = false;
}

View File

@ -32,7 +32,6 @@ private:
SwitchButton *_enable;
std::shared_ptr<MacroAction> *_entryData;
QTimer _actionStateTimer;
bool _loading = true;
};

View File

@ -42,6 +42,13 @@ MacroSegmentList::MacroSegmentList(QWidget *parent)
[this]() { SetupVisibleMacroSegmentWidgets(); });
}
static void clearWidgetVector(const std::vector<QWidget *> &widgets)
{
for (auto widget : widgets) {
widget->deleteLater();
}
};
MacroSegmentList::~MacroSegmentList()
{
if (_autoScrollThread.joinable()) {
@ -49,13 +56,6 @@ MacroSegmentList::~MacroSegmentList()
_autoScrollThread.join();
}
const auto clearWidgetVector =
[](const std::vector<QWidget *> &widgets) {
for (auto widget : widgets) {
widget->deleteLater();
}
};
for (const auto &[_, widgets] : _widgetCache) {
clearWidgetVector(widgets);
}
@ -185,6 +185,16 @@ bool MacroSegmentList::PopulateWidgetsFromCache(const Macro *macro)
return true;
}
void MacroSegmentList::ClearWidgetsFromCacheFor(const Macro *macro)
{
auto it = _widgetCache.find(macro);
if (it == _widgetCache.end()) {
return;
}
clearWidgetVector(it->second);
_widgetCache.erase(it);
}
void MacroSegmentList::Highlight(int idx, QColor color)
{
auto item = _contentLayout->itemAt(idx);

View File

@ -29,6 +29,7 @@ public:
static void SetCachingEnabled(bool enable);
void CacheCurrentWidgetsFor(const Macro *);
bool PopulateWidgetsFromCache(const Macro *);
void ClearWidgetsFromCacheFor(const Macro *);
void Highlight(int idx, QColor color = QColor(Qt::green));
void SetCollapsed(bool) const;
void SetSelection(int idx) const;

View File

@ -140,6 +140,42 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
emit MacroAdded(QString::fromStdString(name));
}
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> &macros,
const std::shared_ptr<Macro> &group)
{
std::vector<std::shared_ptr<Macro>> subitems;
subitems.reserve(group->GroupSize());
// Find all subitems
auto allMacros = GetMacros();
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
if ((*it)->Name() != group->Name()) {
continue;
}
for (uint32_t i = 1; i <= group->GroupSize(); i++) {
subitems.emplace_back(*std::next(it, i));
}
break;
}
// Remove subitems which were already selected to avoid duplicates
for (const auto &subitem : subitems) {
auto it = std::find(macros.begin(), macros.end(), subitem);
if (it == macros.end()) {
continue;
}
macros.erase(it);
}
// Add group subitems
auto it = std::find(macros.begin(), macros.end(), group);
if (it == macros.end()) {
return;
}
it = std::next(it);
macros.insert(it, subitems.begin(), subitems.end());
}
void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> &macro)
{
if (!macro) {
@ -155,6 +191,28 @@ void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> &macro)
}
}
const auto clearWidgetCache = [this](Macro *macro) {
ui->conditionsList->ClearWidgetsFromCacheFor(macro);
ui->actionsList->ClearWidgetsFromCacheFor(macro);
ui->elseActionsList->ClearWidgetsFromCacheFor(macro);
};
if (macro->IsGroup()) {
std::vector<std::shared_ptr<Macro>> macros = {macro};
addGroupSubitems(macros, macro);
for (auto macro : macros) {
clearWidgetCache(macro.get());
}
} else {
clearWidgetCache(macro.get());
}
// Currently shown macro will always be part of the macros to be
// removed, so, we clear the widgets as they should not be cached
ui->conditionsList->Clear();
ui->actionsList->Clear();
ui->elseActionsList->Clear();
ui->macros->Remove(macro);
emit MacroRemoved(name);
}
@ -254,41 +312,6 @@ void AdvSceneSwitcher::RenameSelectedMacro()
ui->macroName->setText(QString::fromStdString(name));
}
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> &macros,
const std::shared_ptr<Macro> &group)
{
std::vector<std::shared_ptr<Macro>> subitems;
subitems.reserve(group->GroupSize());
// Find all subitems
auto allMacros = GetMacros();
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
if ((*it)->Name() == group->Name()) {
for (uint32_t i = 1; i <= group->GroupSize(); i++) {
subitems.emplace_back(*std::next(it, i));
}
break;
}
}
// Remove subitems which were already selected to avoid duplicates
for (const auto &subitem : subitems) {
auto it = std::find(macros.begin(), macros.end(), subitem);
if (it == macros.end()) {
continue;
}
macros.erase(it);
}
// Add group subitems
auto it = std::find(macros.begin(), macros.end(), group);
if (it == macros.end()) {
return;
}
it = std::next(it);
macros.insert(it, subitems.begin(), subitems.end());
}
void AdvSceneSwitcher::ExportMacros() const
{
auto selectedMacros = GetSelectedMacros();