From a35be95d0704529585b2ed8858fc51d139e5bab3 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 9 Jun 2023 07:39:26 +0200 Subject: [PATCH] fix #948, work on label performance --- src/librssguard/core/message.cpp | 8 ++ src/librssguard/core/message.h | 2 + src/librssguard/core/messagesmodel.cpp | 98 ++++++++++++++++--- src/librssguard/core/messagesmodel.h | 10 +- src/librssguard/gui/feedmessageviewer.cpp | 4 + src/librssguard/gui/messagepreviewer.cpp | 25 ++--- src/librssguard/gui/messagepreviewer.h | 1 + .../gui/settings/settingsfeedsmessages.cpp | 21 +++- .../gui/settings/settingsfeedsmessages.ui | 24 +++-- src/librssguard/miscellaneous/settings.cpp | 4 +- src/librssguard/miscellaneous/settings.h | 4 +- src/librssguard/services/abstract/label.cpp | 2 + 12 files changed, 154 insertions(+), 49 deletions(-) diff --git a/src/librssguard/core/message.cpp b/src/librssguard/core/message.cpp index b8a4282de..74de1be48 100644 --- a/src/librssguard/core/message.cpp +++ b/src/librssguard/core/message.cpp @@ -143,6 +143,14 @@ Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) { message.m_accountId = record.value(MSG_DB_ACCOUNT_ID_INDEX).toInt(); message.m_customId = record.value(MSG_DB_CUSTOM_ID_INDEX).toString(); message.m_customHash = record.value(MSG_DB_CUSTOM_HASH_INDEX).toString(); + message.m_assignedLabelsIds = record.value(MSG_DB_LABELS_IDS) + .toString() + .split('.', +#if QT_VERSION >= 0x050F00 // Qt >= 5.15.0 + Qt::SplitBehaviorFlags::SkipEmptyParts); +#else + QString::SplitBehavior::SkipEmptyParts); +#endif if (result != nullptr) { *result = true; diff --git a/src/librssguard/core/message.h b/src/librssguard/core/message.h index d0fb304d3..a8824e125 100644 --- a/src/librssguard/core/message.h +++ b/src/librssguard/core/message.h @@ -92,6 +92,8 @@ class RSSGUARD_DLLSPEC Message { QList m_assignedLabelsByFilter; QList m_deassignedLabelsByFilter; + QStringList m_assignedLabelsIds; + // Is true if "created" date was obtained directly // from the feed, otherwise is false bool m_createdFromFeed = false; diff --git a/src/librssguard/core/messagesmodel.cpp b/src/librssguard/core/messagesmodel.cpp index 6da8ffd82..6cac4f017 100644 --- a/src/librssguard/core/messagesmodel.cpp +++ b/src/librssguard/core/messagesmodel.cpp @@ -2,6 +2,7 @@ #include "core/messagesmodel.h" +#include "3rd-party/boolinq/boolinq.h" #include "core/messagesmodelcache.h" #include "database/databasefactory.h" #include "database/databasequeries.h" @@ -24,13 +25,15 @@ MessagesModel::MessagesModel(QObject* parent) : QSqlQueryModel(parent), m_view(nullptr), m_cache(new MessagesModelCache(this)), m_messageHighlighter(MessageHighlighter::NoHighlighting), m_customDateFormat(QString()), - m_customTimeFormat(QString()), m_newerArticlesRelativeTime(-1), m_selectedItem(nullptr), m_displayFeedIcons(false), + m_customTimeFormat(QString()), m_newerArticlesRelativeTime(-1), m_selectedItem(nullptr), + m_unreadIconType(MessageUnreadIcon::Dot), m_multilineListItems(qApp->settings()->value(GROUP(Messages), SETTING(Messages::MultilineArticleList)).toBool()) { + updateFeedIconsDisplay(); + updateDateFormat(); + setupFonts(); setupIcons(); setupHeaderData(); - updateDateFormat(); - updateFeedIconsDisplay(); loadMessages(nullptr); } @@ -38,10 +41,13 @@ MessagesModel::~MessagesModel() { qDebugNN << LOGSEC_MESSAGEMODEL << "Destroying MessagesModel instance."; } +#define RAD_COLOR 0, 180, 0 + void MessagesModel::setupIcons() { m_favoriteIcon = qApp->icons()->fromTheme(QSL("mail-mark-important")); m_readIcon = qApp->icons()->fromTheme(QSL("mail-mark-read")); - m_unreadIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread")); + m_unreadIcon = m_unreadIconType == MessageUnreadIcon::Dot ? generateUnreadIcon() + : qApp->icons()->fromTheme(QSL("mail-mark-unread")); m_enclosuresIcon = qApp->icons()->fromTheme(QSL("mail-attachment")); for (int i = int(MSG_SCORE_MIN); i <= int(MSG_SCORE_MAX); i += 10) { @@ -82,6 +88,46 @@ QIcon MessagesModel::generateIconForScore(double score) { return pix; } +QIcon MessagesModel::generateUnreadIcon() { + QPointF center(64, 64); + qreal radius = 32; + + QRadialGradient grad(center, radius); + grad.setColorAt(0.000, QColor(RAD_COLOR, 255)); + grad.setColorAt(0.8, QColor(RAD_COLOR, 0.8 * 255)); + grad.setColorAt(1.000, QColor(RAD_COLOR, 0.000)); + + QPen pen; + pen.setWidth(96); + pen.setBrush(grad); + + QPixmap pix(128, 128); + pix.fill(Qt::GlobalColor::transparent); + + QPainter painter(&pix); + painter.setRenderHint(QPainter::RenderHint::Antialiasing); + painter.setPen(pen); + painter.drawPoint(center); + + return QIcon(pix); +} + +QString MessagesModel::descriptionOfUnreadIcon(MessageUnreadIcon type) { + switch (type) { + case MessagesModel::MessageUnreadIcon::Dot: + return tr("dot"); + + case MessagesModel::MessageUnreadIcon::Envelope: + return tr("envelope"); + + case MessagesModel::MessageUnreadIcon::FeedIcon: + return tr("feed icon"); + + default: + return QString(); + } +} + MessagesView* MessagesModel::view() const { return m_view; } @@ -166,7 +212,7 @@ bool MessagesModel::setMessageImportantById(int id, RootItem::Importance importa bool set = setData(index(i, MSG_DB_IMPORTANT_INDEX), int(important)); if (set) { - emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX)); + emit dataChanged(index(i, 0), index(i, MSG_DB_LABELS_IDS)); } return set; @@ -214,7 +260,8 @@ void MessagesModel::updateDateFormat() { } void MessagesModel::updateFeedIconsDisplay() { - m_displayFeedIcons = qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayFeedIconsInList)).toBool(); + m_unreadIconType = + MessageUnreadIcon(qApp->settings()->value(GROUP(Messages), SETTING(Messages::UnreadIconType)).toInt()); } void MessagesModel::reloadWholeLayout() { @@ -344,6 +391,9 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { return contents; } + else if (index_column == MSG_DB_LABELS_IDS) { + return m_cache->containsData(idx.row()) ? m_cache->data(idx) : QSqlQueryModel::data(idx, role); + } else if (index_column == MSG_DB_AUTHOR_INDEX) { const QString author_name = QSqlQueryModel::data(idx, role).toString(); @@ -477,11 +527,13 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { const int index_column = idx.column(); if (index_column == MSG_DB_READ_INDEX) { - if (m_displayFeedIcons && m_selectedItem != nullptr) { + if (m_unreadIconType == MessageUnreadIcon::FeedIcon && m_selectedItem != nullptr) { QModelIndex idx_feedid = index(idx.row(), MSG_DB_FEED_CUSTOM_ID_INDEX); QVariant dta = m_cache->containsData(idx_feedid.row()) ? m_cache->data(idx_feedid) : QSqlQueryModel::data(idx_feedid); QString feed_custom_id = dta.toString(); + + // TODO: Very slow and repeats itself. auto acc = m_selectedItem->getParentServiceRoot()->feedIconForMessage(feed_custom_id); if (acc.isNull()) { @@ -496,7 +548,12 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read); - return dta.toInt() == 1 ? m_readIcon : m_unreadIcon; + if (m_unreadIconType == MessageUnreadIcon::Dot) { + return dta.toInt() == 1 ? QVariant() : m_unreadIcon; + } + else { + return dta.toInt() == 1 ? m_readIcon : m_unreadIcon; + } } } else if (index_column == MSG_DB_IMPORTANT_INDEX) { @@ -529,7 +586,7 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { } bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) { - if (data(row_index, MSG_DB_READ_INDEX, Qt::EditRole).toInt() == int(read)) { + if (data(row_index, MSG_DB_READ_INDEX, Qt::ItemDataRole::EditRole).toInt() == int(read)) { // Read status is the same is the one currently set. // In that case, no extra work is needed. return true; @@ -565,13 +622,32 @@ bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) { bool MessagesModel::setMessageReadById(int id, RootItem::ReadStatus read) { for (int i = 0; i < rowCount(); i++) { - int found_id = data(i, MSG_DB_ID_INDEX, Qt::EditRole).toInt(); + int found_id = data(i, MSG_DB_ID_INDEX, Qt::ItemDataRole::EditRole).toInt(); if (found_id == id) { bool set = setData(index(i, MSG_DB_READ_INDEX), int(read)); if (set) { - emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX)); + emit dataChanged(index(i, 0), index(i, MSG_DB_LABELS_IDS)); + } + + return set; + } + } + + return false; +} + +bool MessagesModel::setMessageLabelsById(int id, const QStringList& label_ids) { + for (int i = 0; i < rowCount(); i++) { + int found_id = data(i, MSG_DB_ID_INDEX, Qt::ItemDataRole::EditRole).toInt(); + + if (found_id == id) { + QString enc_ids = label_ids.isEmpty() ? QSL(".") : QSL(".") + label_ids.join('.') + QSL("."); + bool set = setData(index(i, MSG_DB_LABELS_IDS), enc_ids); + + if (set) { + emit dataChanged(index(i, 0), index(i, MSG_DB_LABELS_IDS)); } return set; diff --git a/src/librssguard/core/messagesmodel.h b/src/librssguard/core/messagesmodel.h index 8d90c7345..da60dd372 100644 --- a/src/librssguard/core/messagesmodel.h +++ b/src/librssguard/core/messagesmodel.h @@ -24,6 +24,10 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { // for messages. enum class MessageHighlighter { NoHighlighting = 100, HighlightUnread = 101, HighlightImportant = 102 }; + enum class MessageUnreadIcon { Dot = 1, Envelope = 2, FeedIcon = 3 }; + + Q_ENUM(MessageUnreadIcon) + // Constructors and destructors. explicit MessagesModel(QObject* parent = nullptr); virtual ~MessagesModel(); @@ -74,6 +78,8 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { void setView(MessagesView* new_view); static QIcon generateIconForScore(double score); + static QIcon generateUnreadIcon(); + static QString descriptionOfUnreadIcon(MessagesModel::MessageUnreadIcon type); public slots: @@ -81,6 +87,7 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { // These are particularly used by msg browser. bool setMessageImportantById(int id, RootItem::Importance important); bool setMessageReadById(int id, RootItem::ReadStatus read); + bool setMessageLabelsById(int id, const QStringList& label_ids); private: void setupHeaderData(); @@ -105,10 +112,11 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { QIcon m_unreadIcon; QIcon m_enclosuresIcon; QList m_scoreIcons; - bool m_displayFeedIcons; + MessageUnreadIcon m_unreadIconType; bool m_multilineListItems; }; Q_DECLARE_METATYPE(MessagesModel::MessageHighlighter) +Q_DECLARE_METATYPE(MessagesModel::MessageUnreadIcon) #endif // MESSAGESMODEL_H diff --git a/src/librssguard/gui/feedmessageviewer.cpp b/src/librssguard/gui/feedmessageviewer.cpp index 9d3363305..efeda3b32 100644 --- a/src/librssguard/gui/feedmessageviewer.cpp +++ b/src/librssguard/gui/feedmessageviewer.cpp @@ -261,6 +261,10 @@ void FeedMessageViewer::createConnections() { &MessagePreviewer::markMessageImportant, m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById); + connect(m_messagesBrowser, + &MessagePreviewer::setMessageLabelIds, + m_messagesView->sourceModel(), + &MessagesModel::setMessageLabelsById); connect(m_messagesView, &MessagesView::currentMessageRemoved, this, &FeedMessageViewer::onMessageRemoved); connect(m_messagesView, &MessagesView::currentMessageChanged, this, &FeedMessageViewer::displayMessage); diff --git a/src/librssguard/gui/messagepreviewer.cpp b/src/librssguard/gui/messagepreviewer.cpp index 00b8fc04e..8e67c7331 100644 --- a/src/librssguard/gui/messagepreviewer.cpp +++ b/src/librssguard/gui/messagepreviewer.cpp @@ -191,10 +191,14 @@ void MessagePreviewer::switchLabel(bool assign) { if (assign) { lbl->assignToMessage(m_message); + m_message.m_assignedLabelsIds.append(lbl->customId()); } else { lbl->deassignFromMessage(m_message); + m_message.m_assignedLabelsIds.removeOne(lbl->customId()); } + + emit setMessageLabelIds(m_message.m_id, m_message.m_assignedLabelsIds); } void MessagePreviewer::markMessageAsRead() { @@ -276,39 +280,22 @@ void MessagePreviewer::updateLabels(bool only_clear) { if (m_root.data() != nullptr && !m_root.data()->getParentServiceRoot()->labelsNode()->labels().isEmpty()) { m_separator = m_toolBar->addSeparator(); - QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); auto lbls = m_root.data()->getParentServiceRoot()->labelsNode()->labels(); for (auto* label : lbls) { - /* - LabelButton* btn_label = new LabelButton(this); - - btn_label->setLabel(label); - btn_label->setCheckable(true); - btn_label->setIcon(Label::generateIcon(label->color())); - btn_label->setAutoRaise(false); - btn_label->setText(); - btn_label->setToolButtonStyle(Qt::ToolButtonStyle(qApp->settings() - ->value(GROUP(GUI), SETTING(GUI::ToolbarStyle)) - .toInt())); - btn_label->setToolTip(label->title()); - btn_label->setChecked(); - */ - LabelToolbarAction* act_label = new LabelToolbarAction(this); act_label->setIcon(Label::generateIcon(label->color())); act_label->setText(QSL(" ") + label->title()); act_label->setCheckable(true); - act_label->setChecked(DatabaseQueries::isLabelAssignedToMessage(database, label, m_message)); + act_label->setChecked(m_message.m_assignedLabelsIds.contains(label->customId())); act_label->setToolTip(label->title()); act_label->setLabel(label); m_toolBar->addAction(act_label); + m_btnLabels.append(act_label); connect(act_label, &QAction::toggled, this, &MessagePreviewer::switchLabel); - - m_btnLabels.append(act_label); } } } diff --git a/src/librssguard/gui/messagepreviewer.h b/src/librssguard/gui/messagepreviewer.h index 101ada3f7..d8f25fb41 100644 --- a/src/librssguard/gui/messagepreviewer.h +++ b/src/librssguard/gui/messagepreviewer.h @@ -61,6 +61,7 @@ class MessagePreviewer : public QWidget { signals: void markMessageRead(int id, RootItem::ReadStatus read); void markMessageImportant(int id, RootItem::Importance important); + void setMessageLabelIds(int id, const QStringList& ids); private: void createConnections(); diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.cpp b/src/librssguard/gui/settings/settingsfeedsmessages.cpp index 4fd135d48..16d5e8cd4 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.cpp +++ b/src/librssguard/gui/settings/settingsfeedsmessages.cpp @@ -14,6 +14,7 @@ #include #include +#include #include SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent) @@ -65,7 +66,9 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent connect(m_ui->m_cbHideCountsIfNoUnread, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdateOnlyUnfocused, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); - connect(m_ui->m_checkDisplayFeedIcons, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); + connect(m_ui->m_cmbUnreadIconType, &QComboBox::currentIndexChanged, this, &SettingsFeedsMessages::dirtifySettings); + connect(m_ui->m_cmbUnreadIconType, &QComboBox::currentIndexChanged, this, &SettingsFeedsMessages::requireRestart); + connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_cbArticleViewerAlwaysVisible, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkMessagesDateTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); @@ -181,6 +184,14 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent } m_ui->m_spinRelativeArticleTime->setValue(-1); + + QMetaEnum enumer = QMetaEnum::fromType(); + + for (int i = 0; i < enumer.keyCount(); i++) { + auto en = MessagesModel::MessageUnreadIcon(enumer.value(i)); + + m_ui->m_cmbUnreadIconType->addItem(MessagesModel::descriptionOfUnreadIcon(en), int(en)); + } } SettingsFeedsMessages::~SettingsFeedsMessages() { @@ -227,8 +238,9 @@ void SettingsFeedsMessages::loadSettings() { ->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::OnlyBasicShortcutsInLists)).toBool()); m_ui->m_cbHideCountsIfNoUnread ->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::HideCountsIfNoUnread)).toBool()); - m_ui->m_checkDisplayFeedIcons - ->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::DisplayFeedIconsInList)).toBool()); + m_ui->m_cmbUnreadIconType + ->setCurrentIndex(m_ui->m_cmbUnreadIconType + ->findData(settings()->value(GROUP(Messages), SETTING(Messages::UnreadIconType)).toInt())); m_ui->m_checkBringToForegroundAfterMsgOpened ->setChecked(settings() ->value(GROUP(Messages), SETTING(Messages::BringAppToFrontAfterMessageOpenedExternally)) @@ -316,7 +328,7 @@ void SettingsFeedsMessages::saveSettings() { settings()->setValue(GROUP(Feeds), Feeds::OnlyBasicShortcutsInLists, m_ui->m_cbListsRestrictedShortcuts->isChecked()); settings()->setValue(GROUP(Feeds), Feeds::HideCountsIfNoUnread, m_ui->m_cbHideCountsIfNoUnread->isChecked()); - settings()->setValue(GROUP(Messages), Messages::DisplayFeedIconsInList, m_ui->m_checkDisplayFeedIcons->isChecked()); + settings()->setValue(GROUP(Messages), Messages::UnreadIconType, m_ui->m_cmbUnreadIconType->currentData().toInt()); settings()->setValue(GROUP(Messages), Messages::BringAppToFrontAfterMessageOpenedExternally, m_ui->m_checkBringToForegroundAfterMsgOpened->isChecked()); @@ -368,7 +380,6 @@ void SettingsFeedsMessages::saveSettings() { qApp->feedReader()->feedsModel()->reloadWholeLayout(); qApp->feedReader()->messagesModel()->updateDateFormat(); - qApp->feedReader()->messagesModel()->updateFeedIconsDisplay(); qApp->feedReader()->messagesModel()->reloadWholeLayout(); onEndSaveSettings(); diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.ui b/src/librssguard/gui/settings/settingsfeedsmessages.ui index d4f9ad59f..b5c85383e 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.ui +++ b/src/librssguard/gui/settings/settingsfeedsmessages.ui @@ -6,7 +6,7 @@ 0 0 - 495 + 558 531 @@ -411,13 +411,6 @@ Articles list - - - - Display real icons of feeds instead of read/unread icons - - - @@ -601,6 +594,19 @@ + + + + + + + Unread article icon type + + + m_cmbUnreadIconType + + + @@ -642,7 +648,7 @@ m_cbShowEnclosuresDirectly m_spinHeightImageAttachments m_btnChangeMessagesFont - m_checkDisplayFeedIcons + m_cmbUnreadIconType m_checkKeppMessagesInTheMiddle m_checkMultilineArticleList m_spinHeightRowsMessages diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp index c0ebf1821..12ff844c8 100644 --- a/src/librssguard/miscellaneous/settings.cpp +++ b/src/librssguard/miscellaneous/settings.cpp @@ -175,8 +175,8 @@ DVALUE(bool) Messages::ClearReadOnExitDef = false; DKEY Messages::IgnoreContentsChanges = "ignore_contents_changes"; DVALUE(bool) Messages::IgnoreContentsChangesDef = true; -DKEY Messages::DisplayFeedIconsInList = "display_feed_icons_in_message_list"; -DVALUE(bool) Messages::DisplayFeedIconsInListDef = false; +DKEY Messages::UnreadIconType = "unread_icons_in_message_list"; +DVALUE(int) Messages::UnreadIconTypeDef = 1; /* MessagesModel::MessageUnreadIcon::Dot */ DKEY Messages::BringAppToFrontAfterMessageOpenedExternally = "bring_app_to_front_after_msg_opened"; DVALUE(bool) Messages::BringAppToFrontAfterMessageOpenedExternallyDef = false; diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h index ca76eaca8..1fb5f1299 100644 --- a/src/librssguard/miscellaneous/settings.h +++ b/src/librssguard/miscellaneous/settings.h @@ -174,8 +174,8 @@ namespace Messages { KEY IgnoreContentsChanges; VALUE(bool) IgnoreContentsChangesDef; - KEY DisplayFeedIconsInList; - VALUE(bool) DisplayFeedIconsInListDef; + KEY UnreadIconType; + VALUE(int) UnreadIconTypeDef; KEY BringAppToFrontAfterMessageOpenedExternally; VALUE(bool) BringAppToFrontAfterMessageOpenedExternallyDef; diff --git a/src/librssguard/services/abstract/label.cpp b/src/librssguard/services/abstract/label.cpp index 3e05e8325..053899541 100644 --- a/src/librssguard/services/abstract/label.cpp +++ b/src/librssguard/services/abstract/label.cpp @@ -77,6 +77,8 @@ bool Label::deleteViaGui() { void Label::updateCounts(bool including_total_count) { QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className()); int account_id = getParentServiceRoot()->accountId(); + + // TODO: slow auto ac = DatabaseQueries::getMessageCountsForLabel(database, this, account_id); if (including_total_count) {