aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-31 11:58:57 +0100
committerDanilo M. <danix@danix.xyz>2026-10-31 11:58:57 +0100
commit3474936404df92ac08534c010aed94f97e6fca15 (patch)
tree9a182d3d540519b6c9e217b0ab4f95d45d77281a /src
parentf0786b2bdd9a29531e43f0aa1573c0ab51fc02e1 (diff)
downloadqtmaildir-3474936404df92ac08534c010aed94f97e6fca15.tar.gz
qtmaildir-3474936404df92ac08534c010aed94f97e6fca15.zip
fix: keep the rules banner true after Apply, delete and copy
The dialog stays open after Apply, so a refusal from a failed attempt and the load warnings about a file Apply has just rewritten both outlived what they described. A successful Apply rereads the file and redraws the banner. Deleting the last rule now disables Apply, and copying or deleting a rule re-checks which rules the sync hook will skip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src')
-rw-r--r--src/tagrulesdialog.cpp19
-rw-r--r--src/tagrulesdialog.h7
2 files changed, 26 insertions, 0 deletions
diff --git a/src/tagrulesdialog.cpp b/src/tagrulesdialog.cpp
index 5f503ea..eb3154f 100644
--- a/src/tagrulesdialog.cpp
+++ b/src/tagrulesdialog.cpp
@@ -662,6 +662,9 @@ void TagRulesDialog::reloadList()
if (!m_working.isEmpty())
m_list->setCurrentItem(m_list->topLevelItem(0));
+ // Here as well as on selection: with no rule left, nothing is selected
+ // and onSelectionChanged() never runs to disable it.
+ updateApplyButton();
}
int TagRulesDialog::currentIndex() const
@@ -776,7 +779,11 @@ void TagRulesDialog::applyEditsToCurrentRule()
fillItem(m_list->topLevelItem(index), rule);
updateApplyButton();
+ refreshSkipWarning();
+}
+void TagRulesDialog::refreshSkipWarning()
+{
if (hookSkipWarning() != m_lastSkipWarning)
showWarnings();
}
@@ -837,6 +844,7 @@ void TagRulesDialog::onCopyRule()
m_working.insert(index + 1, copy);
reloadList();
m_list->setCurrentItem(m_list->topLevelItem(index + 1));
+ refreshSkipWarning();
}
void TagRulesDialog::onDeleteRule()
@@ -846,6 +854,7 @@ void TagRulesDialog::onDeleteRule()
return;
m_working.removeAt(index);
reloadList();
+ refreshSkipWarning();
}
QStringList TagRulesDialog::countQueries() const
@@ -915,12 +924,22 @@ void TagRulesDialog::onApply()
// The dialog stays open; only OK closes it.
if (!saveRules())
return;
+ // The dialog stays open, so the banner must stop describing a file that
+ // has just been rewritten: rereading it clears the load warnings, and
+ // showWarnings() replaces any refusal from an earlier attempt.
+ m_rules.load();
+ showWarnings();
const int index = currentIndex();
if (index < 0 || index >= m_working.size())
return;
emit applyRequested(m_working.at(index));
}
+bool TagRulesDialog::applyEnabledForTest() const
+{
+ return m_applyButton->isEnabled();
+}
+
void TagRulesDialog::setArchiveForTest(bool on)
{
m_archive->setChecked(on); // toggled -> applyEditsToCurrentRule
diff --git a/src/tagrulesdialog.h b/src/tagrulesdialog.h
index b43e79a..1c0ae45 100644
--- a/src/tagrulesdialog.h
+++ b/src/tagrulesdialog.h
@@ -98,6 +98,9 @@ public:
void applyForTest() { onApply(); }
/// Ticks or clears the archive box, as a click would.
void setArchiveForTest(bool on);
+ bool applyEnabledForTest() const;
+ void copyRuleForTest() { onCopyRule(); }
+ void deleteRuleForTest() { onDeleteRule(); }
/// Types into the query field and toggles the mode, so the refusal path
/// can be reached without a synthetic click. The refusal reports through
@@ -242,6 +245,10 @@ private:
/// Enables Apply only for a rule worth applying.
void updateApplyButton();
+ /// Re-renders the banner when the skip sentence changed. Not called from
+ /// reloadList(), which runs once before the constructor's showWarnings().
+ void refreshSkipWarning();
+
/// The only way the warning label is written. An empty string hides it.
/// One route in so the icon and the red styling cannot drift between the
/// load path, the save refusal and the text-mode notice.