diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-13 11:43:16 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-13 11:43:16 +0200 |
| commit | 8913a1190c48ff2672f8783af8594ca11e49ccf7 (patch) | |
| tree | 26e04310efbc3bda7e3988f1fc9c3e7e470537c1 /src | |
| parent | 2ad9b17d53e19418de089cc98820af0776c3bfba (diff) | |
| download | qtmaildir-8913a1190c48ff2672f8783af8594ca11e49ccf7.tar.gz qtmaildir-8913a1190c48ff2672f8783af8594ca11e49ccf7.zip | |
feat(rules): report the text-mode refusal without a modal
Leaving text mode with a query the builder cannot represent has to
refuse, since there are no rows that mean that query. It announced this
with a QMessageBox, which made the branch untestable: a modal blocks the
test that reaches it, so the one path that can strand a user was the one
path shipping unverified.
Say it in the warning label the dialog already has instead. That also
suits the moment better, since it does not interrupt someone mid-edit to
tell them something the label can hold while they keep typing, and it
matches how the tag dialog reports a bad tag.
Returning to the rows now calls showWarnings(), because the refusal
writes into the same label the load warnings use and a stale complaint
would otherwise outlive the query that caused it.
The test drives the refusal and the recovery, and asserts the warning
appears and then clears. Verified by mutation: letting the checkbox clear
regardless fails it.
warningTextForTest uses isVisibleTo rather than isVisible. Every child of
a dialog that was never shown reports isVisible() false, so the seam
would have reported no warning whatever the label held, which is a probe
that cannot see the thing it checks.
Diffstat (limited to 'src')
| -rw-r--r-- | src/tagrulesdialog.cpp | 39 | ||||
| -rw-r--r-- | src/tagrulesdialog.h | 7 |
2 files changed, 42 insertions, 4 deletions
diff --git a/src/tagrulesdialog.cpp b/src/tagrulesdialog.cpp index 1d31d07..86566ba 100644 --- a/src/tagrulesdialog.cpp +++ b/src/tagrulesdialog.cpp @@ -465,6 +465,26 @@ void TagRulesDialog::setRowValueForTest(int index, const QString &value) syncQueryLine(); } +void TagRulesDialog::setQueryTextForTest(const QString &text) +{ + m_query->setText(text); +} + +void TagRulesDialog::setTextModeForTest(bool on) +{ + m_textMode->setChecked(on); +} + +QString TagRulesDialog::warningTextForTest() const +{ + // isVisible() is false for every child of a dialog that was never shown, + // so it would report no warning whatever the label held. isVisibleTo() + // answers the question actually being asked: would this be on screen if + // the dialog were. + return m_warningLabel->isVisibleTo(this) ? m_warningLabel->text() + : QString(); +} + void TagRulesDialog::selectRuleForTest(int index) { if (index >= 0 && index < m_list->topLevelItemCount()) @@ -634,14 +654,19 @@ void TagRulesDialog::setTextMode(bool on) // Going back needs the typed query to be representable. If it is not, the // checkbox cannot clear: there are no rows that mean this query. + // + // Said in the warning label rather than a modal. A modal here would block + // any test that reaches this branch, which is how a refusal path ends up + // shipping unverified, and it interrupts someone who is mid-edit to tell + // them something the label can hold while they keep typing. const RuleQuery parsed = RuleQuery::parse(m_query->text().trimmed()); if (!parsed.parsed) { const QSignalBlocker block(m_textMode); m_textMode->setChecked(true); - QMessageBox::information( - this, tr("Cannot show as rows"), - tr("This query is more than the builder can show, so it stays " - "as text. It is still saved and applied normally.")); + m_warningLabel->setText( + tr("This query is more than the builder can show, so it stays as " + "text. It is still saved and applied normally.")); + m_warningLabel->setVisible(true); return; } @@ -653,6 +678,12 @@ void TagRulesDialog::setTextMode(bool on) m_loadedQuery = parsed; m_builder->setVisible(true); m_query->setReadOnly(true); + + // The refusal above writes into the same label the load warnings use, so + // a successful return to the rows must clear it or a stale complaint + // outlives the query that caused it. showWarnings() restores whatever the + // file itself had to say. + showWarnings(); } void TagRulesDialog::rebuildRows(const RuleQuery &query) diff --git a/src/tagrulesdialog.h b/src/tagrulesdialog.h index 9cee163..948ebe2 100644 --- a/src/tagrulesdialog.h +++ b/src/tagrulesdialog.h @@ -69,6 +69,13 @@ public: /// Runs the Save path without showing the dialog. void saveForTest() { onSave(); } + /// Types into the query field and toggles the mode, so the refusal path + /// can be reached without a synthetic click. The refusal reports through + /// the warning label rather than a modal precisely so this is testable. + void setQueryTextForTest(const QString &text); + void setTextModeForTest(bool on); + QString warningTextForTest() const; + signals: /// Asks the owner to run countQueries() through the worker. void countsRequested(); |
