aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-26 16:13:06 +0200
committerDanilo M. <danix@danix.xyz>2026-08-26 16:13:06 +0200
commit409faeadf013952420963fa1b740d44526d8a95e (patch)
treefdfc02bf1dd4321f6fcab110e7205835ecdb51c9 /src
parentbd90331cba3633754482fc13b99ae39a3b5f79a2 (diff)
downloadqtmaildir-409faeadf013952420963fa1b740d44526d8a95e.tar.gz
qtmaildir-409faeadf013952420963fa1b740d44526d8a95e.zip
feat: load the business-senders list at startup
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp35
-rw-r--r--src/mainwindow.h31
2 files changed, 65 insertions, 1 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 9166588..ec43b3c 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -520,6 +520,17 @@ MainWindow::MainWindow(const Config &config, QWidget *parent)
buildUi();
registerActions();
+ // Both need the delegate, which buildUi() just created. The list is loaded
+ // once at startup and again only on an explicit reload, never per repaint:
+ // the painting path runs on every row of every scroll.
+ loadBusinessSenders();
+ applyCurrentAccountToDelegate();
+ // A change takes effect without a restart. Its own connect, not the one in
+ // buildSavedQueryRow(), which belongs to the filter-buttons row and is
+ // rebuilt with it.
+ connect(m_accountBox, &QComboBox::currentIndexChanged, this,
+ [this]() { applyCurrentAccountToDelegate(); });
+
// After registerActions(), not inside buildUi(): the query bar exists by
// then but the action does not, so wiring this where the field is built
// silently connected nothing and left Save query enabled on an empty
@@ -831,7 +842,8 @@ void MainWindow::buildUi()
// delegate is confined to one column's rectangle.
m_threadView = new ThreadListView(central);
m_threadView->setModel(m_model);
- m_threadView->setItemDelegate(new CardDelegate(this));
+ m_cardDelegate = new CardDelegate(this);
+ m_threadView->setItemDelegate(m_cardDelegate);
m_threadView->setHeaderHidden(true);
m_threadView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_threadView->setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -2794,6 +2806,27 @@ void MainWindow::selectAccountForTesting(const QString &key)
m_accountBox->setCurrentIndex(index);
}
+void MainWindow::loadBusinessSenders(const QString &path)
+{
+ m_businessSenders = BusinessSenders::load(
+ path.isEmpty() ? BusinessSenders::defaultPath() : path);
+ m_cardDelegate->setBusinessSenders(m_businessSenders);
+}
+
+void MainWindow::applyCurrentAccountToDelegate()
+{
+ const QString key = m_accountBox->currentData().toString();
+ if (key.isEmpty()) {
+ m_cardDelegate->setAccountAddress(QString());
+ m_cardDelegate->setAccountLabel(QString());
+ return;
+ }
+ const Account account = m_config.account(key);
+ m_cardDelegate->setAccountAddress(account.address);
+ m_cardDelegate->setAccountLabel(
+ account.name.isEmpty() ? account.key : account.name);
+}
+
void MainWindow::onRulePreviewRequested(const QString &query)
{
// Unscoped, deliberately. runQuery() wraps the bar's text in the selected
diff --git a/src/mainwindow.h b/src/mainwindow.h
index cb8cec4..e65c07d 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -43,6 +43,10 @@
#include "tagcolors.h"
#include "types.h"
+// Held by value: the parsed business-senders list is a member, and the load is
+// asserted through it without reaching into the delegate.
+#include "businesssenders.h"
+
class QAction;
class QLineEdit;
class QMenu;
@@ -57,6 +61,7 @@ class QToolButton;
class QVBoxLayout;
class BusyIndicator;
+class CardDelegate;
class ThreadListModel;
class MessageView;
class MailSync;
@@ -358,6 +363,20 @@ public:
/// The Maildir root as the worker reported it, for the split-index test.
QString mailRootForTesting() const { return m_mailRoot; }
+ /// Reads the business-senders list and hands it to the delegate.
+ ///
+ /// Once at startup and on an explicit reload, never per repaint and never
+ /// stat-per-row: the file is small and the painting path runs on every
+ /// row of every scroll.
+ void loadBusinessSenders(const QString &path = QString());
+
+ /// Test accessor, so the load can be asserted without reaching into the
+ /// delegate.
+ const BusinessSenders::List &businessSendersForTest() const
+ {
+ return m_businessSenders;
+ }
+
/// Runs save_message into \p directory instead of asking for one.
///
/// The file dialog is a modal the offscreen platform cannot click, and the
@@ -625,6 +644,11 @@ private slots:
private:
void buildUi();
+ /// Pushes the selected account's identity into the card delegate, so the
+ /// fallback avatar is seeded from it. Empty selection ("All accounts")
+ /// clears both: the delegate then falls back to "??".
+ void applyCurrentAccountToDelegate();
+
/// Restores window geometry, splitter and thread-list header widths.
/// A missing or rejected blob leaves the buildUi() defaults in place.
void restoreUiState();
@@ -1278,6 +1302,13 @@ private:
/// expander column are ThreadListView's, and holding the base here only
/// hid that from every reader.
ThreadListView *m_threadView = nullptr;
+ /// The card delegate, stored rather than discarded so the window can hand
+ /// it the account identity and the business-senders list.
+ CardDelegate *m_cardDelegate = nullptr;
+
+ /// The parsed business-senders list, for the delegate. Empty until
+ /// loadBusinessSenders() runs.
+ BusinessSenders::List m_businessSenders;
/// Right-click menu for the thread list, holding the same QActions the
/// menu bar does.