File indexing completed on 2024-06-02 05:29:52

0001 /*
0002   This file is part of KMail, the KDE mail client.
0003   SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
0004 
0005   SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 #include "messagelistutil.h"
0008 #include "messagelistsettings.h"
0009 #include "messagelistutil_p.h"
0010 
0011 #include <Akonadi/Item>
0012 #include <KColorScheme>
0013 #include <KConfigGroup>
0014 #include <KLocalizedString>
0015 #include <KMime/Message>
0016 #include <QIcon>
0017 #include <QMenu>
0018 
0019 QString MessageList::Util::messageSortingConfigName()
0020 {
0021     return QStringLiteral("MessageSorting");
0022 }
0023 
0024 QString MessageList::Util::messageSortDirectionConfigName()
0025 {
0026     return QStringLiteral("MessageSortDirection");
0027 }
0028 
0029 QString MessageList::Util::groupSortingConfigName()
0030 {
0031     return QStringLiteral("GroupSorting");
0032 }
0033 
0034 QString MessageList::Util::groupSortDirectionConfigName()
0035 {
0036     return QStringLiteral("GroupSortDirection");
0037 }
0038 
0039 QString MessageList::Util::messageUniqueIdConfigName()
0040 {
0041     return QStringLiteral("MessageUniqueIdForStorageModel%1");
0042 }
0043 
0044 QString MessageList::Util::storageModelSortOrderGroup()
0045 {
0046     return QStringLiteral("MessageListView::StorageModelSortOrder");
0047 }
0048 
0049 QString MessageList::Util::storageModelThemesGroup()
0050 {
0051     return QStringLiteral("MessageListView::StorageModelThemes");
0052 }
0053 
0054 QString MessageList::Util::storageModelAggregationsGroup()
0055 {
0056     return QStringLiteral("MessageListView::StorageModelAggregations");
0057 }
0058 
0059 QString MessageList::Util::setForStorageModelConfigName()
0060 {
0061     return QStringLiteral("SetForStorageModel%1");
0062 }
0063 
0064 QString MessageList::Util::storageModelSelectedMessageGroup()
0065 {
0066     return QStringLiteral("MessageListView::StorageModelSelectedMessages");
0067 }
0068 
0069 void MessageList::Util::deleteConfig(const QString &collectionId)
0070 {
0071     KConfigGroup confselectedMessage(MessageListSettings::self()->config(), MessageList::Util::storageModelSelectedMessageGroup());
0072     confselectedMessage.deleteEntry(MessageList::Util::messageUniqueIdConfigName().arg(collectionId));
0073 
0074     KConfigGroup storageModelOrder(MessageListSettings::self()->config(), MessageList::Util::storageModelSortOrderGroup());
0075     storageModelOrder.deleteEntry(collectionId + groupSortDirectionConfigName());
0076     storageModelOrder.deleteEntry(collectionId + groupSortingConfigName());
0077     storageModelOrder.deleteEntry(collectionId + messageSortDirectionConfigName());
0078     storageModelOrder.deleteEntry(collectionId + messageSortingConfigName());
0079 
0080     KConfigGroup storageModelTheme(MessageListSettings::self()->config(), MessageList::Util::storageModelThemesGroup());
0081     storageModelTheme.deleteEntry(collectionId + setForStorageModelConfigName());
0082 
0083     KConfigGroup storageModelAggregation(MessageListSettings::self()->config(), MessageList::Util::storageModelAggregationsGroup());
0084     storageModelAggregation.deleteEntry(collectionId + setForStorageModelConfigName());
0085 }
0086 
0087 QColor MessageList::Util::unreadDefaultMessageColor()
0088 {
0089     return KColorScheme(QPalette::Active).foreground(KColorScheme::ActiveText).color();
0090 }
0091 
0092 QColor MessageList::Util::importantDefaultMessageColor()
0093 {
0094     return KColorScheme(QPalette::Active).foreground(KColorScheme::NeutralText).color();
0095 }
0096 
0097 QColor MessageList::Util::todoDefaultMessageColor()
0098 {
0099     return KColorScheme(QPalette::Active).foreground(KColorScheme::PositiveText).color();
0100 }
0101 
0102 void MessageList::Util::fillViewMenu(QMenu *menu, QObject *receiver)
0103 {
0104     auto sortingMenu = new QMenu(i18n("Sorting"), menu);
0105     sortingMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sort-ascending")));
0106     menu->addMenu(sortingMenu);
0107     QObject::connect(sortingMenu, SIGNAL(aboutToShow()), receiver, SLOT(sortOrderMenuAboutToShow()));
0108 
0109     auto aggregationMenu = new QMenu(i18n("Aggregation"), menu);
0110     aggregationMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-process-tree")));
0111     menu->addMenu(aggregationMenu);
0112     QObject::connect(aggregationMenu, SIGNAL(aboutToShow()), receiver, SLOT(aggregationMenuAboutToShow()));
0113 
0114     auto themeMenu = new QMenu(i18n("Theme"), menu);
0115     themeMenu->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-theme")));
0116     menu->addMenu(themeMenu);
0117     QObject::connect(themeMenu, SIGNAL(aboutToShow()), receiver, SLOT(themeMenuAboutToShow()));
0118 }
0119 
0120 QString MessageList::Util::contentSummary(const Akonadi::Item &item)
0121 {
0122     if (!item.hasPayload<KMime::Message::Ptr>()) {
0123         return {};
0124     }
0125 
0126     auto message = item.payload<KMime::Message::Ptr>();
0127     KMime::Content *textContent = message->textContent();
0128     if (!textContent) {
0129         return {};
0130     }
0131     const QString content = textContent->decodedText(true, true);
0132     if (content.isEmpty()) {
0133         return {};
0134     }
0135 
0136     // Extract the first 5 non-empty, non-quoted lines from the content and return it
0137     int numLines = 0;
0138     const int maxLines = 5;
0139     const QStringList lines = content.split(QLatin1Char('\n'));
0140     if (lines.isEmpty()) {
0141         return {};
0142     }
0143     if (lines.count() == 1 && content.length() > 100) {
0144         return content.left(100);
0145     }
0146     QString ret;
0147     for (const QString &line : lines) {
0148         const QString lineTrimmed = line.trimmed();
0149         const bool isQuoted = lineTrimmed.startsWith(QLatin1Char('>')) || lineTrimmed.startsWith(QLatin1Char('|'));
0150         if (!isQuoted && !lineTrimmed.isEmpty()) {
0151             ret += line + QLatin1Char('\n');
0152             numLines++;
0153             if (numLines >= maxLines) {
0154                 break;
0155             }
0156         }
0157     }
0158     return ret.toHtmlEscaped();
0159 }