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"
12using namespace Qt::Literals::StringLiterals;
13
14#include "etmcalendar.h"
15
16#include <Akonadi/AgentManager>
17#include <Akonadi/Collection>
18#include <Akonadi/EntityTreeModel>
19
20#include <KCalUtils/ICalDrag>
21
22#include <KLocalizedString>
23
24#include <QMimeData>
25
26using namespace Akonadi;
27
29{
30 // With this try-catch block, we get a 2x performance improvement in retrieving the payload
31 // since we don't call hasPayload()
32 try {
34 } catch (const Akonadi::PayloadException &) {
35 return {};
36 }
37}
38
40{
41 try {
45 }
46 } catch (const Akonadi::PayloadException &) {
47 return {};
48 }
49 return {};
50}
51
53{
54 try {
57 return item.payload<KCalendarCore::Todo::Ptr>();
58 }
59 } catch (const Akonadi::PayloadException &) {
60 return {};
61 }
62 return {};
63}
64
66{
67 try {
71 }
72 } catch (const Akonadi::PayloadException &) {
73 return {};
74 }
75 return {};
76}
77
78static QString displayNameImpl(const Akonadi::EntityTreeModel *model, const Akonadi::Collection &c)
79{
80 Akonadi::Collection fullCollection = c;
81 if (model) {
82 if (const auto col = Akonadi::EntityTreeModel::updatedCollection(model, c); col.isValid()) {
83 fullCollection = col;
84 }
85 }
86
87 QString cName = fullCollection.name();
88 const QString resourceName = fullCollection.resource();
89
90 // Kolab Groupware
91 if (resourceName.contains("kolab"_L1)) {
92 QString typeStr = cName; // contents type: "Calendar", "Tasks", etc
93 QString ownerStr; // folder owner: "fred", "ethel", etc
94 QString nameStr; // folder name: "Public", "Test", etc
95 if (model) {
97 while (p != Akonadi::Collection::root()) {
99 const QString tName = tCol.name();
100 if (tName.startsWith("shared.cal"_L1, Qt::CaseInsensitive)) {
101 ownerStr = QStringLiteral("Shared");
102 nameStr = cName;
103 typeStr = i18n("Calendar");
104 break;
105 } else if (tName.startsWith("shared.tasks"_L1, Qt::CaseInsensitive) || tName.startsWith("shared.todo"_L1, Qt::CaseInsensitive)) {
106 ownerStr = QStringLiteral("Shared");
107 nameStr = cName;
108 typeStr = i18n("Tasks");
109 break;
110 } else if (tName.startsWith("shared.journal"_L1, Qt::CaseInsensitive)) {
111 ownerStr = QStringLiteral("Shared");
112 nameStr = cName;
113 typeStr = i18n("Journal");
114 break;
115 } else if (tName.startsWith("shared.notes"_L1, Qt::CaseInsensitive)) {
116 ownerStr = QStringLiteral("Shared");
117 nameStr = cName;
118 typeStr = i18n("Notes");
119 break;
120 } else if (tName != i18n("Calendar") && tName != i18n("Tasks") && tName != i18n("Journal") && tName != i18n("Notes")) {
121 ownerStr = tName;
122 break;
123 } else {
124 nameStr = typeStr;
125 typeStr = tName;
126 }
127 p = p.parentCollection();
128 }
129 }
130
131 if (!ownerStr.isEmpty()) {
132 if (!ownerStr.compare("INBOX"_L1, Qt::CaseInsensitive)) {
133 return i18nc("%1 is folder contents", "My Kolab %1", typeStr);
134 } else if (!ownerStr.compare("SHARED"_L1, Qt::CaseInsensitive) || !ownerStr.compare("CALENDAR"_L1, Qt::CaseInsensitive)
135 || !ownerStr.compare("RESOURCES"_L1, 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("davgroupware"_L1)) {
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("google"_L1)) {
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(".event"_L1)) {
168 typeStr = i18n("Calendar");
169 } else if (mimeStr.contains(".todo"_L1)) {
170 typeStr = i18n("Tasks");
171 } else if (mimeStr.contains(".journal"_L1)) {
172 typeStr = i18n("Journal");
173 } else if (mimeStr.contains(".note"_L1)) {
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("akonadi_"_L1) ? 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 Fri Oct 11 2024 12:15:47 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.