Akonadi Calendar

calendarutils.cpp
1/*
2 SPDX-FileCopyrightText: 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3 SPDX-FileContributor: Frank Osterfeld <osterfeld@kde.org>
4 SPDX-FileContributor: Andras Mantia <andras@kdab.com>
5 SPDX-FileCopyrightText: 2010-2012 SĂ©rgio Martins <iamsergio@gmail.com>
6 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "calendarutils.h"
12#include "etmcalendar.h"
13
14#include <Akonadi/AgentManager>
15#include <Akonadi/Collection>
16#include <Akonadi/EntityTreeModel>
17
18#include <KCalUtils/ICalDrag>
19
20#include <KLocalizedString>
21
22#include <QMimeData>
23
24using namespace Akonadi;
25
27{
28 // With this try-catch block, we get a 2x performance improvement in retrieving the payload
29 // since we don't call hasPayload()
30 try {
32 } catch (const Akonadi::PayloadException &) {
33 return {};
34 }
35}
36
38{
39 try {
43 }
44 } catch (const Akonadi::PayloadException &) {
45 return {};
46 }
47 return {};
48}
49
51{
52 try {
55 return item.payload<KCalendarCore::Todo::Ptr>();
56 }
57 } catch (const Akonadi::PayloadException &) {
58 return {};
59 }
60 return {};
61}
62
64{
65 try {
69 }
70 } catch (const Akonadi::PayloadException &) {
71 return {};
72 }
73 return {};
74}
75
76static QString displayNameImpl(const Akonadi::EntityTreeModel *model, const Akonadi::Collection &c)
77{
78 Akonadi::Collection fullCollection = c;
79 if (model) {
80 if (const auto col = Akonadi::EntityTreeModel::updatedCollection(model, c); col.isValid()) {
81 fullCollection = col;
82 }
83 }
84
85 QString cName = fullCollection.name();
86 const QString resourceName = fullCollection.resource();
87
88 // Kolab Groupware
89 if (resourceName.contains(QLatin1StringView("kolab"))) {
90 QString typeStr = cName; // contents type: "Calendar", "Tasks", etc
91 QString ownerStr; // folder owner: "fred", "ethel", etc
92 QString nameStr; // folder name: "Public", "Test", etc
93 if (model) {
95 while (p != Akonadi::Collection::root()) {
97 const QString tName = tCol.name();
98 if (tName.startsWith(QLatin1StringView("shared.cal"), Qt::CaseInsensitive)) {
99 ownerStr = QStringLiteral("Shared");
100 nameStr = cName;
101 typeStr = i18n("Calendar");
102 break;
103 } else if (tName.startsWith(QLatin1StringView("shared.tasks"), Qt::CaseInsensitive)
104 || tName.startsWith(QLatin1StringView("shared.todo"), Qt::CaseInsensitive)) {
105 ownerStr = QStringLiteral("Shared");
106 nameStr = cName;
107 typeStr = i18n("Tasks");
108 break;
109 } else if (tName.startsWith(QLatin1StringView("shared.journal"), Qt::CaseInsensitive)) {
110 ownerStr = QStringLiteral("Shared");
111 nameStr = cName;
112 typeStr = i18n("Journal");
113 break;
114 } else if (tName.startsWith(QLatin1StringView("shared.notes"), Qt::CaseInsensitive)) {
115 ownerStr = QStringLiteral("Shared");
116 nameStr = cName;
117 typeStr = i18n("Notes");
118 break;
119 } else if (tName != i18n("Calendar") && tName != i18n("Tasks") && tName != i18n("Journal") && tName != i18n("Notes")) {
120 ownerStr = tName;
121 break;
122 } else {
123 nameStr = typeStr;
124 typeStr = tName;
125 }
126 p = p.parentCollection();
127 }
128 }
129
130 if (!ownerStr.isEmpty()) {
131 if (!ownerStr.compare(QLatin1StringView("INBOX"), Qt::CaseInsensitive)) {
132 return i18nc("%1 is folder contents", "My Kolab %1", typeStr);
133 } else if (!ownerStr.compare(QLatin1StringView("SHARED"), Qt::CaseInsensitive)
134 || !ownerStr.compare(QLatin1StringView("CALENDAR"), Qt::CaseInsensitive)
135 || !ownerStr.compare(QLatin1StringView("RESOURCES"), Qt::CaseInsensitive)) {
136 return i18nc("%1 is folder name, %2 is folder contents", "Shared Kolab %1 %2", nameStr, typeStr);
137 } else {
138 if (nameStr.isEmpty()) {
139 return i18nc("%1 is folder owner name, %2 is folder contents", "%1's Kolab %2", ownerStr, typeStr);
140 } else {
141 return i18nc("%1 is folder owner name, %2 is folder name, %3 is folder contents", "%1's %2 Kolab %3", ownerStr, nameStr, typeStr);
142 }
143 }
144 } else {
145 return i18nc("%1 is folder contents", "Kolab %1", typeStr);
146 }
147 } // end kolab section
148
149 // Dav Groupware
150 if (resourceName.contains(QLatin1StringView("davgroupware"))) {
151 const QString resourceDisplayName = Akonadi::AgentManager::self()->instance(resourceName).name();
152 return i18nc("%1 is the folder name", "%1 in %2", fullCollection.displayName(), resourceDisplayName);
153 } // end caldav section
154
155 // Google
156 if (resourceName.contains(QLatin1StringView("google"))) {
157 QString ownerStr; // folder owner: "user@gmail.com"
158 if (model) {
161 }
162
163 const QString nameStr = c.displayName(); // folder name: can be anything
164
165 QString typeStr;
166 const QString mimeStr = c.contentMimeTypes().join(QLatin1Char(','));
167 if (mimeStr.contains(QLatin1StringView(".event"))) {
168 typeStr = i18n("Calendar");
169 } else if (mimeStr.contains(QLatin1StringView(".todo"))) {
170 typeStr = i18n("Tasks");
171 } else if (mimeStr.contains(QLatin1StringView(".journal"))) {
172 typeStr = i18n("Journal");
173 } else if (mimeStr.contains(QLatin1StringView(".note"))) {
174 typeStr = i18n("Notes");
175 } else {
176 typeStr = mimeStr;
177 }
178
179 if (!ownerStr.isEmpty()) {
180 const int atChar = ownerStr.lastIndexOf(QLatin1Char('@'));
181 if (atChar >= 0) {
182 ownerStr.truncate(atChar);
183 }
184 if (nameStr.isEmpty()) {
185 return i18nc("%1 is folder owner name, %2 is folder contents", "%1's Google %2", ownerStr, typeStr);
186 } else {
187 return i18nc("%1 is folder owner name, %2 is folder name", "%1's %2", ownerStr, nameStr);
188 }
189 } else {
190 return i18nc("%1 is folder contents", "Google %1", typeStr);
191 }
192 } // end google section
193
194 // Not groupware so the collection is "mine"
195 const QString dName = fullCollection.displayName();
196
197 if (!dName.isEmpty()) {
198 return fullCollection.name().startsWith(QLatin1StringView("akonadi_")) ? i18n("My %1", dName) : dName;
199 } else if (!fullCollection.name().isEmpty()) {
200 return fullCollection.name();
201 } else {
202 return i18nc("unknown resource", "Unknown");
203 }
204}
205
207{
208 return displayNameImpl(calendar ? calendar->entityTreeModel() : nullptr, c);
209}
210
212{
213 return displayNameImpl(model, c);
214}
215
217{
218 return displayNameImpl(nullptr, c);
219}
220
222{
223 if (items.isEmpty()) {
224 return nullptr;
225 }
226
228
229 QList<QUrl> urls;
230 int incidencesFound = 0;
231 for (const Akonadi::Item &item : items) {
233 if (!incidence) {
234 continue;
235 }
236 ++incidencesFound;
237 urls.push_back(item.url());
239 cal->addIncidence(i);
240 }
241
242 if (incidencesFound == 0) {
243 return nullptr;
244 }
245
246 auto mimeData = std::make_unique<QMimeData>();
247 mimeData->setUrls(urls);
248
249 if (KCalUtils::ICalDrag::populateMimeData(mimeData.get(), cal)) {
250 return mimeData.release();
251 } else {
252 return nullptr;
253 }
254}
QString name() const
static AgentManager * self()
AgentInstance instance(const QString &identifier) const
QString resource() const
QStringList contentMimeTypes() const
bool isValid() const
QString displayName() const
static Collection root()
QString name() const
Collection & parentCollection()
A KCalendarCore::Calendar that uses an EntityTreeModel to populate itself.
Definition etmcalendar.h:41
Akonadi::EntityTreeModel * entityTreeModel() const
Returns the underlying EntityTreeModel.
static Collection updatedCollection(const QAbstractItemModel *model, qint64 collectionId)
T payload() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
Returns the incidence from an Akonadi item, or a null pointer if the item has no such payload.
AKONADI_CALENDAR_EXPORT KCalendarCore::Journal::Ptr journal(const Akonadi::Item &item)
Returns the journal from an Akonadi item, or a null pointer if the item has no such payload.
AKONADI_CALENDAR_EXPORT KCalendarCore::Todo::Ptr todo(const Akonadi::Item &item)
Returns the todo from an Akonadi item, or a null pointer if the item has no such payload.
AKONADI_CALENDAR_EXPORT QString displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &collection)
Returns a suitable display name for the calendar (or calendar folder) collection.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
Returns the event from an Akonadi item, or a null pointer if the item has no such payload.
AKONADI_CALENDAR_EXPORT QMimeData * createMimeData(const Akonadi::Item::List &items)
Creates a MIME data object for dragging Akonadi items containing calendar incidences.
FreeBusyManager::Singleton.
KCALUTILS_EXPORT bool populateMimeData(QMimeData *e, const KCalendarCore::Calendar::Ptr &cal)
bool isEmpty() const const
void push_back(parameter_type value)
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
void truncate(qsizetype position)
QString join(QChar separator) const const
CaseInsensitive
QTimeZone systemTimeZone()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.