1 /*
2 This file is part of the kcalutils library.
3
4 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org>
5 SPDX-FileCopyrightText: 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net>
7 SPDX-FileCopyrightText: 2009-2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
8 SPDX-FileCopyrightText: 2017 Allen Winter <winter@kde.org>
9
10 SPDX-License-Identifier: LGPL-2.0-or-later
11 */
12 /**
13 @file
14 This file is part of the API for handling calendar data and provides
15 static functions for formatting Incidence properties for various purposes.
16
17 @brief
18 Provides methods to format Incidence properties in various ways for display purposes.
19
20 @author Cornelius Schumacher \<schumacher@kde.org\>
21 @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
22 @author Allen Winter \<allen@kdab.com\>
23 */
24 #include "stringify.h"
25
26 #include <KCalendarCore/Exceptions>
27 using namespace KCalendarCore;
28
29 #include <KLocalizedString>
30
31 #include <QLocale>
32
33 using namespace KCalUtils;
34 using namespace Stringify;
35
incidenceType(Incidence::IncidenceType type)36 QString Stringify::incidenceType(Incidence::IncidenceType type)
37 {
38 switch (type) {
39 case Incidence::TypeEvent:
40 return i18nc("@item incidence type is event", "event");
41 case Incidence::TypeTodo:
42 return i18nc("@item incidence type is to-do/task", "to-do");
43 case Incidence::TypeJournal:
44 return i18nc("@item incidence type is journal", "journal");
45 case Incidence::TypeFreeBusy:
46 return i18nc("@item incidence type is freebusy", "free/busy");
47 default:
48 return QString();
49 }
50 }
51
todoCompletedDateTime(const Todo::Ptr & todo,bool shortfmt)52 QString Stringify::todoCompletedDateTime(const Todo::Ptr &todo, bool shortfmt)
53 {
54 return QLocale().toString(todo->completed(), (shortfmt ? QLocale::ShortFormat : QLocale::LongFormat));
55 }
56
incidenceSecrecy(Incidence::Secrecy secrecy)57 QString Stringify::incidenceSecrecy(Incidence::Secrecy secrecy)
58 {
59 switch (secrecy) {
60 case Incidence::SecrecyPublic:
61 return i18nc("@item incidence access if for everyone", "Public");
62 case Incidence::SecrecyPrivate:
63 return i18nc("@item incidence access is by owner only", "Private");
64 case Incidence::SecrecyConfidential:
65 return i18nc("@item incidence access is by owner and a controlled group", "Confidential");
66 }
67 return QString();
68 }
69
incidenceSecrecyList()70 QStringList Stringify::incidenceSecrecyList()
71 {
72 const QStringList list{incidenceSecrecy(Incidence::SecrecyPublic),
73 incidenceSecrecy(Incidence::SecrecyPrivate),
74 incidenceSecrecy(Incidence::SecrecyConfidential)};
75
76 return list;
77 }
78
incidenceStatus(Incidence::Status status)79 QString Stringify::incidenceStatus(Incidence::Status status)
80 {
81 switch (status) {
82 case Incidence::StatusTentative:
83 return i18nc("@item event is tentative", "Tentative");
84 case Incidence::StatusConfirmed:
85 return i18nc("@item event is definite", "Confirmed");
86 case Incidence::StatusCompleted:
87 return i18nc("@item to-do is complete", "Completed");
88 case Incidence::StatusNeedsAction:
89 return i18nc("@item to-do needs action", "Needs-Action");
90 case Incidence::StatusCanceled:
91 return i18nc("@item event orto-do is canceled; journal is removed", "Canceled");
92 case Incidence::StatusInProcess:
93 return i18nc("@item to-do is in process", "In-Process");
94 case Incidence::StatusDraft:
95 return i18nc("@item journal is in draft form", "Draft");
96 case Incidence::StatusFinal:
97 return i18nc("@item journal is in final form", "Final");
98 case Incidence::StatusX:
99 case Incidence::StatusNone:
100 return QString();
101 }
102 return QString();
103 }
104
incidenceStatus(const Incidence::Ptr & incidence)105 QString Stringify::incidenceStatus(const Incidence::Ptr &incidence)
106 {
107 if (incidence->status() == Incidence::StatusX) {
108 return incidence->customStatus();
109 } else {
110 return incidenceStatus(incidence->status());
111 }
112 }
113
attendeeRole(Attendee::Role role)114 QString Stringify::attendeeRole(Attendee::Role role)
115 {
116 switch (role) {
117 case Attendee::Chair:
118 return i18nc("@item chairperson", "Chair");
119 case Attendee::ReqParticipant:
120 return i18nc("@item participation is required", "Participant");
121 case Attendee::OptParticipant:
122 return i18nc("@item participation is optional", "Optional Participant");
123 case Attendee::NonParticipant:
124 return i18nc("@item non-participant copied for information", "Observer");
125 }
126 return {};
127 }
128
attendeeStatus(Attendee::PartStat status)129 QString Stringify::attendeeStatus(Attendee::PartStat status)
130 {
131 switch (status) {
132 case Attendee::NeedsAction:
133 return i18nc("@item event, to-do or journal needs action", "Needs Action");
134 case Attendee::Accepted:
135 return i18nc("@item event, to-do or journal accepted", "Accepted");
136 case Attendee::Declined:
137 return i18nc("@item event, to-do or journal declined", "Declined");
138 case Attendee::Tentative:
139 return i18nc("@item event or to-do tentatively accepted", "Tentative");
140 case Attendee::Delegated:
141 return i18nc("@item event or to-do delegated", "Delegated");
142 case Attendee::Completed:
143 return i18nc("@item to-do completed", "Completed");
144 case Attendee::InProcess:
145 return i18nc("@item to-do in process of being completed", "In Process");
146 case Attendee::None:
147 return i18nc("@item event or to-do status unknown", "Unknown");
148 }
149 return {};
150 }
151
errorMessage(const Exception & exception)152 QString Stringify::errorMessage(const Exception &exception)
153 {
154 QString message;
155
156 switch (exception.code()) {
157 case Exception::LoadError:
158 message = i18nc("@item", "Load Error");
159 break;
160 case Exception::SaveError:
161 message = i18nc("@item", "Save Error");
162 break;
163 case Exception::ParseErrorIcal:
164 message = i18nc("@item", "Parse Error in libical");
165 break;
166 case Exception::ParseErrorKcal:
167 message = i18nc("@item", "Parse Error in the kcalcore library");
168 break;
169 case Exception::NoCalendar:
170 message = i18nc("@item", "No calendar component found.");
171 break;
172 case Exception::CalVersion1:
173 message = i18nc("@item", "Expected iCalendar, got vCalendar format");
174 break;
175 case Exception::CalVersion2:
176 message = i18nc("@item", "iCalendar Version 2.0 detected.");
177 break;
178 case Exception::CalVersionUnknown:
179 message = i18nc("@item", "Expected iCalendar, got unknown format");
180 break;
181 case Exception::Restriction:
182 message = i18nc("@item", "Restriction violation");
183 break;
184 case Exception::NoWritableFound:
185 message = i18nc("@item", "No writable resource found");
186 break;
187 case Exception::SaveErrorOpenFile:
188 Q_ASSERT(exception.arguments().count() == 1);
189 message = i18nc("@item", "Error saving to '%1'.", exception.arguments().at(0));
190 break;
191 case Exception::SaveErrorSaveFile:
192 Q_ASSERT(exception.arguments().count() == 1);
193 message = i18nc("@item", "Could not save '%1'", exception.arguments().at(0));
194 break;
195 case Exception::LibICalError:
196 message = i18nc("@item", "libical error");
197 break;
198 case Exception::VersionPropertyMissing:
199 message = i18nc("@item", "No VERSION property found");
200 break;
201 case Exception::ExpectedCalVersion2:
202 message = i18nc("@item", "Expected iCalendar, got vCalendar format");
203 break;
204 case Exception::ExpectedCalVersion2Unknown:
205 message = i18nc("@item", "Expected iCalendar, got unknown format");
206 break;
207 case Exception::ParseErrorNotIncidence:
208 message = i18nc("@item", "object is not a freebusy, event, todo or journal");
209 break;
210 case Exception::ParseErrorEmptyMessage:
211 message = i18nc("@item", "messageText is empty, unable to parse into a ScheduleMessage");
212 break;
213 case Exception::ParseErrorUnableToParse:
214 message = i18nc("@item", "icalparser is unable to parse messageText into a ScheduleMessage");
215 break;
216 case Exception::ParseErrorMethodProperty:
217 message = i18nc("@item", "message does not contain ICAL_METHOD_PROPERTY");
218 break;
219 case Exception::UserCancel:
220 // no real error; the user canceled the operation
221 break;
222 }
223
224 return message;
225 }
226
scheduleMessageStatus(ScheduleMessage::Status status)227 QString Stringify::scheduleMessageStatus(ScheduleMessage::Status status)
228 {
229 switch (status) {
230 case ScheduleMessage::PublishNew:
231 return i18nc("@item this is a new scheduling message", "New Scheduling Message");
232 case ScheduleMessage::PublishUpdate:
233 return i18nc("@item this is an update to an existing scheduling message", "Updated Scheduling Message");
234 case ScheduleMessage::Obsolete:
235 return i18nc("@item obsolete status", "Obsolete");
236 case ScheduleMessage::RequestNew:
237 return i18nc("@item this is a request for a new scheduling message", "New Scheduling Message Request");
238 case ScheduleMessage::RequestUpdate:
239 return i18nc("@item this is a request for an update to an existing scheduling message", "Updated Scheduling Message Request");
240 default:
241 return i18nc("@item unknown status", "Unknown Status: %1", int(status));
242 }
243 }
244
tzUTCOffsetStr(const QTimeZone & tz)245 QString Stringify::tzUTCOffsetStr(const QTimeZone &tz)
246 {
247 int currentOffset = tz.offsetFromUtc(QDateTime::currentDateTimeUtc());
248 int absOffset = qAbs(currentOffset);
249 int utcOffsetHrs = absOffset / 3600; // in hours
250 int utcOffsetMins = (absOffset % 3600) / 60; // in minutes
251
252 const QString hrStr = QStringLiteral("%1").arg(utcOffsetHrs, 2, 10, QLatin1Char('0'));
253 const QString mnStr = QStringLiteral("%1").arg(utcOffsetMins, 2, 10, QLatin1Char('0'));
254
255 if (currentOffset < 0) {
256 return QStringLiteral("-%1:%2").arg(hrStr, mnStr);
257 } else {
258 return QStringLiteral("+%1:%2").arg(hrStr, mnStr);
259 }
260 }
261