aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/composewindow.cpp27
-rw-r--r--tests/test_composewindow.cpp119
2 files changed, 141 insertions, 5 deletions
diff --git a/src/composewindow.cpp b/src/composewindow.cpp
index 8236d79..94a3f46 100644
--- a/src/composewindow.cpp
+++ b/src/composewindow.cpp
@@ -406,8 +406,22 @@ void ComposeWindow::buildUi()
for (QLineEdit *field : { m_to, m_cc, m_bcc, m_subject })
connect(field, &QLineEdit::textChanged, this, &ComposeWindow::markDirty);
connect(m_sendHtml, &QCheckBox::toggled, this, &ComposeWindow::markDirty);
- connect(m_from, &QComboBox::currentIndexChanged, this,
- &ComposeWindow::markDirty);
+ connect(m_from, &QComboBox::currentIndexChanged, this, [this]() {
+ markDirty();
+ // The account SEEDS the signature, so a change to it re-seeds. It
+ // stops the moment the user picks one: re-seeding unconditionally is
+ // the one behaviour that can silently discard a deliberate choice
+ // made a moment earlier. Same shape as send_html, which seeds from
+ // context and is then left alone.
+ if (m_signatureChosen)
+ return;
+ const QString seeded = seededSignatureName();
+ if (!Signatures::names(m_signatureDir).contains(seeded)) {
+ applySignature(QString());
+ return;
+ }
+ applySignature(seeded);
+ });
}
void ComposeWindow::buildFormatToolbar()
@@ -708,9 +722,12 @@ QStringList ComposeWindow::knownSignatures() const
QString ComposeWindow::seededSignatureName() const
{
- // The account SEEDS, it does not bind: this is a starting value, and the
- // switch keeps every signature reachable whichever account is selected.
- const Account account = m_config.account(m_context.accountKey);
+ // The COMBO, not m_context: the context records where the composer opened
+ // and does not follow a From: change, so reading it would seed the
+ // original account's signature for ever.
+ const QString key = m_from->currentData().toString();
+ const Account account =
+ m_config.account(key.isEmpty() ? m_context.accountKey : key);
if (!account.signature.isEmpty())
return account.signature;
return m_config.compose().signature;
diff --git a/tests/test_composewindow.cpp b/tests/test_composewindow.cpp
index 04d3115..8221ce3 100644
--- a/tests/test_composewindow.cpp
+++ b/tests/test_composewindow.cpp
@@ -17,6 +17,7 @@
*/
#include <QtTest>
+#include <QComboBox>
#include <QDir>
#include <QFile>
#include <QMenu>
@@ -43,6 +44,8 @@ private slots:
void aResumedDraftSeedsNoSignature();
void anUnknownSignatureNameSeedsNothing();
void theSwitchListsEveryFileAndNone();
+ void changingTheAccountFollowsItsSignature();
+ void changingTheAccountStopsFollowingOnceTheSwitchIsUsed();
private:
/// A config pointing at a signatures directory holding \p files, with one
@@ -216,5 +219,121 @@ void TestComposeWindow::theSwitchListsEveryFileAndNone()
QCOMPARE(button->menu()->actions().size(), 3);
}
+void TestComposeWindow::changingTheAccountFollowsItsSignature()
+{
+ for (const auto &entry :
+ QList<QPair<QString, QString>>{
+ { QStringLiteral("work.md"), QStringLiteral("Work sig") },
+ { QStringLiteral("home.md"), QStringLiteral("Home sig") } }) {
+ QFile file(m_signatureDir + QStringLiteral("/") + entry.first);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ file.write(entry.second.toUtf8());
+ file.close();
+ }
+
+ const QString path = m_dir->path() + QStringLiteral("/qtmaildir.conf");
+ {
+ QFile file(path);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ QTextStream out(&file);
+ out << "[account.work]\n"
+ << "name = Someone\naddress = someone@example.org\n"
+ << "maildir = work\nsend_command = /bin/cat\n"
+ << "signature = work\n"
+ << "\n[account.home]\n"
+ << "name = Someone\naddress = other@example.org\n"
+ << "maildir = home\nsend_command = /bin/cat\n"
+ << "signature = home\n";
+ }
+ Config config;
+ config.load(path);
+
+ ComposeContext context;
+ context.kind = ComposeContext::Kind::New;
+ context.accountKey = QStringLiteral("work");
+
+ ComposeWindow window(context, config, m_dir->path());
+ window.setSignatureDir(m_signatureDir);
+ window.seedSignature();
+
+ auto *body = window.findChild<QPlainTextEdit *>(QStringLiteral("body"));
+ auto *from = window.findChild<QComboBox *>(QStringLiteral("from"));
+ QVERIFY(body);
+ QVERIFY(from);
+ QVERIFY(body->toPlainText().contains(QStringLiteral("Work sig")));
+
+ // Select the other account by its key, never by index: the order of the
+ // combo is the config's and an index assertion would pass on the wrong one.
+ const int home = from->findData(QStringLiteral("home"));
+ QVERIFY(home >= 0);
+ from->setCurrentIndex(home);
+
+ QVERIFY(body->toPlainText().contains(QStringLiteral("Home sig")));
+ QVERIFY(!body->toPlainText().contains(QStringLiteral("Work sig")));
+}
+
+void TestComposeWindow::changingTheAccountStopsFollowingOnceTheSwitchIsUsed()
+{
+ for (const auto &entry :
+ QList<QPair<QString, QString>>{
+ { QStringLiteral("work.md"), QStringLiteral("Work sig") },
+ { QStringLiteral("home.md"), QStringLiteral("Home sig") },
+ { QStringLiteral("chosen.md"), QStringLiteral("Chosen sig") } }) {
+ QFile file(m_signatureDir + QStringLiteral("/") + entry.first);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ file.write(entry.second.toUtf8());
+ file.close();
+ }
+
+ const QString path = m_dir->path() + QStringLiteral("/qtmaildir.conf");
+ {
+ QFile file(path);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ QTextStream out(&file);
+ out << "[account.work]\n"
+ << "name = Someone\naddress = someone@example.org\n"
+ << "maildir = work\nsend_command = /bin/cat\n"
+ << "signature = work\n"
+ << "\n[account.home]\n"
+ << "name = Someone\naddress = other@example.org\n"
+ << "maildir = home\nsend_command = /bin/cat\n"
+ << "signature = home\n";
+ }
+ Config config;
+ config.load(path);
+
+ ComposeContext context;
+ context.kind = ComposeContext::Kind::New;
+ context.accountKey = QStringLiteral("work");
+
+ ComposeWindow window(context, config, m_dir->path());
+ window.setSignatureDir(m_signatureDir);
+ window.seedSignature();
+
+ auto *body = window.findChild<QPlainTextEdit *>(QStringLiteral("body"));
+ auto *from = window.findChild<QComboBox *>(QStringLiteral("from"));
+ auto *button =
+ window.findChild<QToolButton *>(QStringLiteral("signatureSwitch"));
+ QVERIFY(body);
+ QVERIFY(from);
+ QVERIFY(button);
+
+ // The user picks one deliberately.
+ for (QAction *action : button->menu()->actions()) {
+ if (action->data().toString() == QStringLiteral("chosen"))
+ action->trigger();
+ }
+ QVERIFY(body->toPlainText().contains(QStringLiteral("Chosen sig")));
+
+ const int home = from->findData(QStringLiteral("home"));
+ QVERIFY(home >= 0);
+ from->setCurrentIndex(home);
+
+ // The deliberate choice survives the account change. Overwriting it is
+ // the one behaviour that can silently discard something the user just did.
+ QVERIFY(body->toPlainText().contains(QStringLiteral("Chosen sig")));
+ QVERIFY(!body->toPlainText().contains(QStringLiteral("Home sig")));
+}
+
QTEST_MAIN(TestComposeWindow)
#include "test_composewindow.moc"