Akonadi

recentcollectionaction.cpp
1/*
2 * SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "entitytreemodel.h"
8#include "recentcollectionaction_p.h"
9#include <KConfigGroup>
10#include <KLocalizedString>
11#include <KSharedConfig>
12
13#include <QAction>
14#include <QMenu>
15using namespace Akonadi;
16
17static const int s_maximumRecentCollection = 10;
18
19static QStringList readConfig()
20{
21 const KSharedConfig::Ptr akonadiConfig = KSharedConfig::openConfig(QStringLiteral("akonadikderc"));
22 const KConfigGroup group(akonadiConfig, QStringLiteral("Recent Collections"));
23 return (group.readEntry("Collections", QStringList()));
24}
25
26static void writeConfig(const QStringList &list)
27{
28 KSharedConfig::Ptr akonadiConfig = KSharedConfig::openConfig(QStringLiteral("akonadikderc"));
29 KConfigGroup group(akonadiConfig, QStringLiteral("Recent Collections"));
30 group.writeEntry("Collections", list);
31 group.sync();
32}
33
34RecentCollectionAction::RecentCollectionAction(Akonadi::StandardActionManager::Type type,
35 const Akonadi::Collection::List &selectedCollectionsList,
36 const QAbstractItemModel *model,
37 QMenu *menu)
38 : QObject(menu)
39 , mListRecentCollection(readConfig())
40 , mMenu(menu)
41 , mModel(model)
42{
43 mRecentAction = mMenu->addAction(i18n("Recent Folder"));
44 mMenu->addSeparator();
45 fillRecentCollection(type, selectedCollectionsList);
46}
47
48RecentCollectionAction::~RecentCollectionAction()
49{
50 // if (needToDeleteMenu) {
51 // delete mRecentAction->menu();
52 // }
53}
54
55bool RecentCollectionAction::clear()
56{
57 delete mRecentAction->menu();
58 needToDeleteMenu = false;
59 if (mListRecentCollection.isEmpty()) {
60 mRecentAction->setEnabled(false);
61 return true;
62 }
63 return false;
64}
65
66void RecentCollectionAction::fillRecentCollection(Akonadi::StandardActionManager::Type type, const Akonadi::Collection::List &selectedCollectionsList)
67{
68 if (clear()) {
69 return;
70 }
71
72 auto popup = new QMenu;
73 mRecentAction->setMenu(popup);
74 needToDeleteMenu = true;
75
76 const int numberOfRecentCollection(mListRecentCollection.count());
77 for (int i = 0; i < numberOfRecentCollection; ++i) {
78 const QModelIndex index = Akonadi::EntityTreeModel::modelIndexForCollection(mModel, Akonadi::Collection(mListRecentCollection.at(i).toLongLong()));
79 const auto collection = mModel->data(index, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
80 if (index.isValid()) {
81 const bool collectionIsSelected = selectedCollectionsList.contains(collection);
82 if (type == Akonadi::StandardActionManager::MoveCollectionToMenu && collectionIsSelected) {
83 continue;
84 }
85
86 const bool canCreateNewItems = (collection.rights() & Collection::CanCreateItem);
87 QAction *action = popup->addAction(actionName(index));
88 const auto icon = mModel->data(index, Qt::DecorationRole).value<QIcon>();
89 action->setIcon(icon);
91 action->setEnabled(canCreateNewItems);
92 }
93 }
94}
95
96QString RecentCollectionAction::actionName(QModelIndex index)
97{
98 QString name = index.data().toString();
99 name.replace(QLatin1Char('&'), QStringLiteral("&&"));
100
101 index = index.parent();
102 QString topLevelName;
103 while (index != QModelIndex()) {
104 topLevelName = index.data().toString();
105 index = index.parent();
106 }
107 if (topLevelName.isEmpty()) {
108 return name;
109 } else {
110 topLevelName.replace(QLatin1Char('&'), QStringLiteral("&&"));
111 return QStringLiteral("%1 - %2").arg(name, topLevelName);
112 }
113}
114
115void RecentCollectionAction::addRecentCollection(Akonadi::StandardActionManager::Type type, Akonadi::Collection::Id id)
116{
117 mListRecentCollection = addRecentCollection(id);
118 fillRecentCollection(type, Akonadi::Collection::List());
119}
120
121/* static */ QStringList RecentCollectionAction::addRecentCollection(Akonadi::Collection::Id id)
122{
123 QStringList listRecentCollection = readConfig();
124
125 const QString newCollectionID = QString::number(id);
126 if (listRecentCollection.contains(newCollectionID)) {
127 // first() is safe to use if we get here
128 if (listRecentCollection.first() == newCollectionID) {
129 // already most recently used, nothing to do
130 return (listRecentCollection);
131 }
132
133 listRecentCollection.removeAll(newCollectionID);
134 }
135
136 listRecentCollection.prepend(newCollectionID);
137 while (listRecentCollection.count() > s_maximumRecentCollection) {
138 listRecentCollection.removeLast();
139 }
140
141 writeConfig(listRecentCollection);
142 return (listRecentCollection);
143}
144
145void RecentCollectionAction::cleanRecentCollection()
146{
147 mListRecentCollection.clear();
148 writeConfig(mListRecentCollection);
149 clear();
150}
151
152#include "moc_recentcollectionaction_p.cpp"
Represents a collection of PIM items.
Definition collection.h:62
qint64 Id
Describes the unique id type.
Definition collection.h:79
@ CanCreateItem
Can create new items in this collection.
Definition collection.h:92
static QModelIndex modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection)
Returns a QModelIndex in model which points to collection.
@ CollectionRole
The collection.
Type
Describes the supported actions.
@ MoveCollectionToMenu
Menu allowing to move a collection into another collection.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
QAction * clear(const QObject *recvr, const char *slot, QObject *parent)
QString name(StandardAction id)
QVariant data() const const
void setEnabled(bool)
void setIcon(const QIcon &icon)
void setData(const QVariant &data)
bool contains(const AT &value) const const
qsizetype count() const const
T & first()
void prepend(parameter_type value)
qsizetype removeAll(const AT &t)
void removeLast()
QVariant data(int role) const const
bool isValid() const const
QModelIndex parent() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
DecorationRole
QVariant fromValue(T &&value)
QString toString() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:01:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.