KContacts

ldifconverter.cpp
1/*
2 This file is part of the KContacts framework.
3 SPDX-FileCopyrightText: 2003 Helge Deller <deller@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8/*
9 Useful links:
10 - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html
11 - http://www.faqs.org/rfcs/rfc2849.html
12
13 Not yet handled items:
14 - objectclass microsoftaddressbook
15 - info,
16 - initials,
17 - otherfacsimiletelephonenumber,
18 - otherpager,
19 - physicaldeliveryofficename,
20*/
21
22#include "ldifconverter.h"
23#include "address.h"
24#include "kcontacts_debug.h"
25#include "vcardconverter.h"
26
27#include "ldif_p.h"
28
29#include <KCountry>
30#include <KLocalizedString>
31
32#include <QIODevice>
33#include <QStringList>
34#include <QTextStream>
35
36using namespace KContacts;
37
38/* internal functions - do not use !! */
39
40namespace KContacts
41{
42/**
43 @internal
44
45 Evaluates @p fieldname and sets the @p value at the addressee or the address
46 objects when appropriate.
47
48 @param a The addressee to store information into
49 @param homeAddr The home address to store respective information into
50 @param workAddr The work address to store respective information into
51 @param fieldname LDIF field name to evaluate
52 @param value The value of the field addressed by @p fieldname
53*/
54void evaluatePair(Addressee &a,
55 Address &homeAddr,
56 Address &workAddr,
57 QString &fieldname,
58 QString &value,
59 int &birthday,
60 int &birthmonth,
61 int &birthyear,
62 ContactGroup &contactGroup);
63}
64
65/* generate LDIF stream */
66
67static void ldif_out(QTextStream &t, const QString &formatStr, const QString &value)
68{
69 if (value.isEmpty()) {
70 return;
71 }
72
73 const QByteArray txt = Ldif::assembleLine(formatStr, value, 72);
74
75 // write the string
76 t << QString::fromUtf8(txt) << "\n";
77}
78
79bool LDIFConverter::addresseeAndContactGroupToLDIF(const AddresseeList &addrList, const ContactGroup::List &contactGroupList, QString &str)
80{
81 bool result = addresseeToLDIF(addrList, str);
82 if (!contactGroupList.isEmpty()) {
83 result = (contactGroupToLDIF(contactGroupList, str) || result); // order matters
84 }
85 return result;
86}
87
89{
90 if (contactGroup.dataCount() <= 0) {
91 return false;
92 }
94
95 t << "objectclass: top\n";
96 t << "objectclass: groupOfNames\n";
97
98 for (int i = 0; i < contactGroup.dataCount(); ++i) {
99 const ContactGroup::Data &data = contactGroup.data(i);
100 const QString value = QStringLiteral("cn=%1,mail=%2").arg(data.name(), data.email());
101 ldif_out(t, QStringLiteral("member"), value);
102 }
103
104 t << "\n";
105 return true;
106}
107
109{
110 if (contactGroupList.isEmpty()) {
111 return false;
112 }
113
114 bool result = true;
115 for (const ContactGroup &group : contactGroupList) {
116 result = (contactGroupToLDIF(group, str) || result); // order matters
117 }
118 return result;
119}
120
122{
123 if (addrList.isEmpty()) {
124 return false;
125 }
126
127 bool result = true;
128 for (const Addressee &addr : addrList) {
129 result = (addresseeToLDIF(addr, str) || result); // order matters
130 }
131 return result;
132}
133
134static QString countryName(const QString &isoCodeOrName)
135{
136 const auto c = KCountry::fromAlpha2(isoCodeOrName);
137 return c.isValid() ? c.name() : isoCodeOrName;
138}
139
141{
142 if (addr.isEmpty()) {
143 return false;
144 }
145
147
148 const Address homeAddr = addr.address(Address::Home);
149 const Address workAddr = addr.address(Address::Work);
150
151 ldif_out(t, QStringLiteral("dn"), QStringLiteral("cn=%1,mail=%2").arg(addr.formattedName().simplified(), addr.preferredEmail()));
152 t << "objectclass: top\n";
153 t << "objectclass: person\n";
154 t << "objectclass: organizationalPerson\n";
155
156 ldif_out(t, QStringLiteral("givenname"), addr.givenName());
157 ldif_out(t, QStringLiteral("sn"), addr.familyName());
158 ldif_out(t, QStringLiteral("cn"), addr.formattedName().simplified());
159 ldif_out(t, QStringLiteral("uid"), addr.uid());
160 ldif_out(t, QStringLiteral("nickname"), addr.nickName());
161 ldif_out(t, QStringLiteral("xmozillanickname"), addr.nickName());
162 ldif_out(t, QStringLiteral("mozillanickname"), addr.nickName());
163
164 ldif_out(t, QStringLiteral("mail"), addr.preferredEmail());
165 const QStringList emails = addr.emails();
166 const int numEmails = emails.count();
167 for (int i = 1; i < numEmails; ++i) {
168 if (i == 0) {
169 // nothing
170 } else if (i == 1) {
171 ldif_out(t, QStringLiteral("mozillasecondemail"), emails[1]);
172 } else {
173 ldif_out(t, QStringLiteral("othermailbox"), emails[i]);
174 }
175 }
176 // ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" );
177
178 ldif_out(t, QStringLiteral("telephonenumber"), addr.phoneNumber(PhoneNumber::Work).number());
179 ldif_out(t, QStringLiteral("facsimiletelephonenumber"), addr.phoneNumber(PhoneNumber::Fax).number());
180 ldif_out(t, QStringLiteral("homephone"), addr.phoneNumber(PhoneNumber::Home).number());
181 ldif_out(t, QStringLiteral("mobile"),
182 addr.phoneNumber(PhoneNumber::Cell).number()); // Netscape 7
183 ldif_out(t, QStringLiteral("cellphone"),
184 addr.phoneNumber(PhoneNumber::Cell).number()); // Netscape 4.x
185 ldif_out(t, QStringLiteral("pager"), addr.phoneNumber(PhoneNumber::Pager).number());
186 ldif_out(t, QStringLiteral("pagerphone"), addr.phoneNumber(PhoneNumber::Pager).number());
187
188 ldif_out(t, QStringLiteral("streethomeaddress"), homeAddr.street());
189 ldif_out(t, QStringLiteral("postalcode"), workAddr.postalCode());
190 ldif_out(t, QStringLiteral("postofficebox"), workAddr.postOfficeBox());
191
192 QStringList streets = homeAddr.street().split(QLatin1Char('\n'));
193 const int numberOfStreets(streets.count());
194 if (numberOfStreets > 0) {
195 ldif_out(t, QStringLiteral("homepostaladdress"), streets.at(0)); // Netscape 7
196 }
197 if (numberOfStreets > 1) {
198 ldif_out(t, QStringLiteral("mozillahomepostaladdress2"), streets.at(1)); // Netscape 7
199 }
200 ldif_out(t, QStringLiteral("mozillahomelocalityname"), homeAddr.locality()); // Netscape 7
201 ldif_out(t, QStringLiteral("mozillahomestate"), homeAddr.region());
202 ldif_out(t, QStringLiteral("mozillahomepostalcode"), homeAddr.postalCode());
203 ldif_out(t, QStringLiteral("mozillahomecountryname"), countryName(homeAddr.country()));
204 ldif_out(t, QStringLiteral("locality"), workAddr.locality());
205 ldif_out(t, QStringLiteral("streetaddress"), workAddr.street()); // Netscape 4.x
206
207 streets = workAddr.street().split(QLatin1Char('\n'));
208 const int streetsCount = streets.count();
209 if (streetsCount > 0) {
210 ldif_out(t, QStringLiteral("street"), streets.at(0));
211 }
212 if (streetsCount > 1) {
213 ldif_out(t, QStringLiteral("mozillaworkstreet2"), streets.at(1));
214 }
215 ldif_out(t, QStringLiteral("countryname"), countryName(workAddr.country()));
216 ldif_out(t, QStringLiteral("l"), workAddr.locality());
217 ldif_out(t, QStringLiteral("c"), countryName(workAddr.country()));
218 ldif_out(t, QStringLiteral("st"), workAddr.region());
219
220 ldif_out(t, QStringLiteral("title"), addr.title());
221 ldif_out(t, QStringLiteral("vocation"), addr.prefix());
222 ldif_out(t, QStringLiteral("ou"), addr.role());
223 ldif_out(t, QStringLiteral("o"), addr.organization());
224 ldif_out(t, QStringLiteral("organization"), addr.organization());
225 ldif_out(t, QStringLiteral("organizationname"), addr.organization());
226
227 // Compatibility with older kabc versions.
228 if (!addr.department().isEmpty()) {
229 ldif_out(t, QStringLiteral("department"), addr.department());
230 } else {
231 ldif_out(t, QStringLiteral("department"), addr.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Department")));
232 }
233
234 ldif_out(t, QStringLiteral("workurl"), addr.url().url().toDisplayString());
235 ldif_out(t, QStringLiteral("homeurl"), addr.url().url().toDisplayString());
236 ldif_out(t, QStringLiteral("mozillahomeurl"), addr.url().url().toDisplayString());
237
238 ldif_out(t, QStringLiteral("description"), addr.note());
239 if (addr.revision().isValid()) {
240 ldif_out(t, QStringLiteral("modifytimestamp"), dateToVCardString(addr.revision()));
241 }
242
243 const QDate birthday = addr.birthday().date();
244 if (birthday.isValid()) {
245 const int year = birthday.year();
246 if (year > 0) {
247 ldif_out(t, QStringLiteral("birthyear"), QString::number(year));
248 }
249 ldif_out(t, QStringLiteral("birthmonth"), QString::number(birthday.month()));
250 ldif_out(t, QStringLiteral("birthday"), QString::number(birthday.day()));
251 }
252
253 t << "\n";
254
255 return true;
256}
257
258/* convert from LDIF stream */
259bool LDIFConverter::LDIFToAddressee(const QString &str, AddresseeList &addrList, ContactGroup::List &contactGroupList, const QDateTime &dt)
260{
261 if (str.isEmpty()) {
262 return true;
263 }
264
265 bool endldif = false;
266 bool end = false;
267 Ldif ldif;
268 Ldif::ParseValue ret;
269 Addressee a;
270 Address homeAddr;
271 Address workAddr;
272 int birthday = -1;
273 int birthmonth = -1;
274 int birthyear = -1;
275 ContactGroup contactGroup;
276 ldif.setLdif(str.toLatin1());
277 QDateTime qdt = dt;
278 if (!qdt.isValid()) {
280 }
281 a.setRevision(qdt);
282 homeAddr = Address(Address::Home);
283 workAddr = Address(Address::Work);
284
285 do {
286 ret = ldif.nextItem();
287 switch (ret) {
288 case Ldif::Item: {
289 QString fieldname = ldif.attr().toLower();
290 QString value = QString::fromUtf8(ldif.value());
291 evaluatePair(a, homeAddr, workAddr, fieldname, value, birthday, birthmonth, birthyear, contactGroup);
292 break;
293 }
294 case Ldif::EndEntry:
295 if (contactGroup.count() == 0) {
296 // if the new address is not empty, append it
297 QDate birthDate(birthyear, birthmonth, birthday);
298 if (birthDate.isValid()) {
299 a.setBirthday(birthDate);
300 }
301
302 if (!a.formattedName().isEmpty() || !a.name().isEmpty() || !a.familyName().isEmpty()) {
303 if (!homeAddr.isEmpty()) {
304 a.insertAddress(homeAddr);
305 }
306 if (!workAddr.isEmpty()) {
307 a.insertAddress(workAddr);
308 }
309 addrList.append(a);
310 }
311 } else {
312 contactGroupList.append(contactGroup);
313 }
314 a = Addressee();
315 contactGroup = ContactGroup();
316 a.setRevision(qdt);
317 homeAddr = Address(Address::Home);
318 workAddr = Address(Address::Work);
319 break;
320 case Ldif::MoreData:
321 if (endldif) {
322 end = true;
323 } else {
324 ldif.endLdif();
325 endldif = true;
326 break;
327 }
328 default:
329 break;
330 }
331 } while (!end);
332
333 return true;
334}
335
336void KContacts::evaluatePair(Addressee &a,
337 Address &homeAddr,
338 Address &workAddr,
339 QString &fieldname,
340 QString &value,
341 int &birthday,
342 int &birthmonth,
343 int &birthyear,
344 ContactGroup &contactGroup)
345{
346 if (fieldname == QLatin1String("dn")) { // ignore
347 return;
348 }
349
350 if (fieldname.startsWith(QLatin1Char('#'))) {
351 return;
352 }
353
354 if (fieldname.isEmpty() && !a.note().isEmpty()) {
355 // some LDIF export filters are broken and add additional
356 // comments on stand-alone lines. Just add them to the notes for now.
357 a.setNote(a.note() + QLatin1Char('\n') + value);
358 return;
359 }
360
361 if (fieldname == QLatin1String("givenname")) {
362 a.setGivenName(value);
363 return;
364 }
365
366 if (fieldname == QLatin1String("xmozillanickname") //
367 || fieldname == QLatin1String("nickname") //
368 || fieldname == QLatin1String("mozillanickname")) {
369 a.setNickName(value);
370 return;
371 }
372
373 if (fieldname == QLatin1String("sn")) {
374 a.setFamilyName(value);
375 return;
376 }
377
378 if (fieldname == QLatin1String("uid")) {
379 a.setUid(value);
380 return;
381 }
382 if (fieldname == QLatin1String("mail") //
383 || fieldname == QLatin1String("mozillasecondemail") /* mozilla */
384 || fieldname == QLatin1String("othermailbox") /*TheBat!*/) {
385 if (a.emails().indexOf(value) == -1) {
386 a.addEmail(value);
387 }
388 return;
389 }
390
391 if (fieldname == QLatin1String("title")) {
392 a.setTitle(value);
393 return;
394 }
395
396 if (fieldname == QLatin1String("vocation")) {
397 a.setPrefix(value);
398 return;
399 }
400
401 if (fieldname == QLatin1String("cn")) {
402 a.setFormattedName(value);
403 return;
404 }
405
406 if (fieldname == QLatin1Char('o') || fieldname == QLatin1String("organization") // Exchange
407 || fieldname == QLatin1String("organizationname")) { // Exchange
408 a.setOrganization(value);
409 return;
410 }
411
412 // clang-format off
413 if (fieldname == QLatin1String("description")
414 || fieldname == QLatin1String("mozillacustom1")
415 || fieldname == QLatin1String("mozillacustom2")
416 || fieldname == QLatin1String("mozillacustom3")
417 || fieldname == QLatin1String("mozillacustom4")
418 || fieldname == QLatin1String("custom1")
419 || fieldname == QLatin1String("custom2")
420 || fieldname == QLatin1String("custom3")
421 || fieldname == QLatin1String("custom4")) {
422 if (!a.note().isEmpty()) {
423 a.setNote(a.note() + QLatin1Char('\n'));
424 }
425 a.setNote(a.note() + value);
426 return;
427 }
428 // clang-format on
429
430 if (fieldname == QLatin1String("homeurl") //
431 || fieldname == QLatin1String("workurl") //
432 || fieldname == QLatin1String("mozillahomeurl")) {
433 if (a.url().url().isEmpty()) {
435 url.setUrl(QUrl(value));
436 a.setUrl(url);
437 return;
438 }
439 if (a.url().url().toDisplayString() == QUrl(value).toDisplayString()) {
440 return;
441 }
442 // TODO: current version of kabc only supports one URL.
443 // TODO: change this with KDE 4
444 }
445
446 if (fieldname == QLatin1String("homephone")) {
448 return;
449 }
450
451 if (fieldname == QLatin1String("telephonenumber")) {
453 return;
454 }
455 if (fieldname == QLatin1String("mobile") /* mozilla/Netscape 7 */
456 || fieldname == QLatin1String("cellphone")) {
458 return;
459 }
460
461 if (fieldname == QLatin1String("pager") // mozilla
462 || fieldname == QLatin1String("pagerphone")) { // mozilla
464 return;
465 }
466
467 if (fieldname == QLatin1String("facsimiletelephonenumber")) {
469 return;
470 }
471
472 if (fieldname == QLatin1String("xmozillaanyphone")) { // mozilla
474 return;
475 }
476
477 if (fieldname == QLatin1String("streethomeaddress") //
478 || fieldname == QLatin1String("mozillahomestreet")) { // thunderbird
479 homeAddr.setStreet(value);
480 return;
481 }
482
483 if (fieldname == QLatin1String("street") //
484 || fieldname == QLatin1String("postaladdress")) { // mozilla
485 workAddr.setStreet(value);
486 return;
487 }
488 if (fieldname == QLatin1String("mozillapostaladdress2") //
489 || fieldname == QLatin1String("mozillaworkstreet2")) { // mozilla
490 workAddr.setStreet(workAddr.street() + QLatin1Char('\n') + value);
491 return;
492 }
493
494 if (fieldname == QLatin1String("postalcode")) {
495 workAddr.setPostalCode(value);
496 return;
497 }
498
499 if (fieldname == QLatin1String("postofficebox")) {
500 workAddr.setPostOfficeBox(value);
501 return;
502 }
503
504 if (fieldname == QLatin1String("homepostaladdress")) { // Netscape 7
505 homeAddr.setStreet(value);
506 return;
507 }
508
509 if (fieldname == QLatin1String("mozillahomepostaladdress2")) { // mozilla
510 homeAddr.setStreet(homeAddr.street() + QLatin1Char('\n') + value);
511 return;
512 }
513
514 if (fieldname == QLatin1String("mozillahomelocalityname")) { // mozilla
515 homeAddr.setLocality(value);
516 return;
517 }
518
519 if (fieldname == QLatin1String("mozillahomestate")) { // mozilla
520 homeAddr.setRegion(value);
521 return;
522 }
523
524 if (fieldname == QLatin1String("mozillahomepostalcode")) { // mozilla
525 homeAddr.setPostalCode(value);
526 return;
527 }
528
529 if (fieldname == QLatin1String("mozillahomecountryname")) { // mozilla
530 if (value.length() <= 2) {
531 value = countryName(value);
532 }
533 homeAddr.setCountry(value);
534 return;
535 }
536
537 if (fieldname == QLatin1String("locality")) {
538 workAddr.setLocality(value);
539 return;
540 }
541
542 if (fieldname == QLatin1String("streetaddress")) { // Netscape 4.x
543 workAddr.setStreet(value);
544 return;
545 }
546
547 if (fieldname == QLatin1String("countryname") //
548 || fieldname == QLatin1Char('c')) { // mozilla
549 if (value.length() <= 2) {
550 value = countryName(value);
551 }
552 workAddr.setCountry(value);
553 return;
554 }
555
556 if (fieldname == QLatin1Char('l')) { // mozilla
557 workAddr.setLocality(value);
558 return;
559 }
560
561 if (fieldname == QLatin1String("st")) {
562 workAddr.setRegion(value);
563 return;
564 }
565
566 if (fieldname == QLatin1String("ou")) {
567 a.setRole(value);
568 return;
569 }
570
571 if (fieldname == QLatin1String("department")) {
572 a.setDepartment(value);
573 return;
574 }
575
576 if (fieldname == QLatin1String("member")) {
577 // this is a mozilla list member (cn=xxx, mail=yyy)
578 const QStringList list = value.split(QLatin1Char(','));
580 QString email;
581
582 const QLatin1String cnTag("cn=");
583 const QLatin1String mailTag("mail=");
584 for (const auto &str : list) {
585 if (str.startsWith(cnTag)) {
586 name = QStringView(str).mid(cnTag.size()).trimmed().toString();
587 } else if (str.startsWith(mailTag)) {
588 email = QStringView(str).mid(mailTag.size()).trimmed().toString();
589 }
590 }
591
592 if (!name.isEmpty() && !email.isEmpty()) {
593 email = QLatin1String(" <") + email + QLatin1Char('>');
594 }
596 data.setEmail(email);
597 data.setName(name);
598 contactGroup.append(data);
599 return;
600 }
601
602 if (fieldname == QLatin1String("modifytimestamp")) {
603 if (value == QLatin1String("0Z")) { // ignore
604 return;
605 }
606 QDateTime dt = VCardStringToDate(value);
607 if (dt.isValid()) {
608 a.setRevision(dt);
609 return;
610 }
611 }
612
613 if (fieldname == QLatin1String("display-name")) {
614 contactGroup.setName(value);
615 return;
616 }
617
618 if (fieldname == QLatin1String("objectclass")) { // ignore
619 return;
620 }
621
622 if (fieldname == QLatin1String("birthyear")) {
623 bool ok;
624 birthyear = value.toInt(&ok);
625 if (!ok) {
626 birthyear = -1;
627 }
628 return;
629 }
630 if (fieldname == QLatin1String("birthmonth")) {
631 birthmonth = value.toInt();
632 return;
633 }
634 if (fieldname == QLatin1String("birthday")) {
635 birthday = value.toInt();
636 return;
637 }
638 if (fieldname == QLatin1String("xbatbirthday")) {
639 const QStringView str{value};
640 QDate dt(str.mid(0, 4).toInt(), str.mid(4, 2).toInt(), str.mid(6, 2).toInt());
641 if (dt.isValid()) {
642 a.setBirthday(dt);
643 }
644 return;
645 }
646 qCWarning(KCONTACTS_LOG) << QStringLiteral("LDIFConverter: Unknown field for '%1': '%2=%3'\n").arg(a.formattedName(), fieldname, value);
647}
Postal address information.
Definition address.h:31
void setStreet(const QString &street)
Sets the street (including house number).
Definition address.cpp:243
void setCountry(const QString &country)
Sets the country.
Definition address.cpp:307
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
Definition address.cpp:211
void setRegion(const QString &region)
Sets the region, e.g.
Definition address.cpp:275
@ Work
address at work
Definition address.h:84
@ Home
home address
Definition address.h:83
void setPostalCode(const QString &code)
Sets the postal code.
Definition address.cpp:291
void setLocality(const QString &locality)
Sets the locality, e.g.
Definition address.cpp:259
address book entry
Definition addressee.h:70
void addEmail(const Email &email)
Adds an email address.
void setBirthday(const QDateTime &birthday, bool withTime=true)
Set birthday (date and time).
void setOrganization(const QString &organization)
Set organization.
void insertPhoneNumber(const PhoneNumber &phoneNumber)
Insert a phone number.
void setPrefix(const QString &prefix)
Set honorific prefixes.
QString custom(const QString &app, const QString &name) const
Return value of custom entry, identified by app and entry name.
void setRevision(const QDateTime &revision)
Set revision date.
Address address(Address::Type type) const
Return address, which matches the given type.
void setGivenName(const QString &givenName)
Set given name.
PhoneNumber phoneNumber(PhoneNumber::Type type) const
Return phone number, which matches the given type.
void setNickName(const QString &nickName)
Set nick name.
void setDepartment(const QString &department)
Set department.
void setNote(const QString &note)
Set note.
void insertAddress(const Address &address)
Insert an address.
void setRole(const QString &role)
Set role.
void setFormattedName(const QString &formattedName)
Set formatted name.
void setFamilyName(const QString &familyName)
Set family name.
void setTitle(const QString &title)
Set title.
void setUid(const QString &uid)
Set unique identifier.
void setUrl(const ResourceLocatorUrl &url)
Set homepage.
This class represents a contact data object.
QString name() const
Returns the name of the contact data object.
void setName(const QString &name)
Sets the name of the contact data object.
void setEmail(const QString &email)
Sets the email address of the contact data object.
QString email() const
Returns the email address of the contact data object.
This class represents a group of contacts.
void append(const ContactReference &reference)
Appends a new contact reference to the contact group.
void setName(const QString &name)
Sets the i18n'd name of the contact group.
Data & data(int index)
Returns the contact data object at the given index.
int count() const
Returns the number of contacts in this group.
int dataCount() const
Returns the number of contact data objects in this group.
Phonenumber information.
Definition phonenumber.h:31
@ Work
Office number.
Definition phonenumber.h:53
Class that holds a Resource Locator.
static KCountry fromAlpha2(const char *alpha2Code)
KCONTACTS_EXPORT bool LDIFToAddressee(const QString &str, AddresseeList &addrList, QList< KContacts::ContactGroup > &contactGroupList, const QDateTime &dt=QDateTime::currentDateTime())
Converts a LDIF string to a list of addressees.
KCONTACTS_EXPORT bool addresseeToLDIF(const AddresseeList &addrList, QString &str)
Converts a list of addressees to a LDIF string.
KCONTACTS_EXPORT bool contactGroupToLDIF(const ContactGroup::List &contactGroupList, QString &str)
Converts a list of contact group to a LDIF string.
KCONTACTS_EXPORT bool addresseeAndContactGroupToLDIF(const AddresseeList &addrList, const QList< KContacts::ContactGroup > &contactGroupList, QString &str)
Converts a list of addressees and contactgrouplist to a LDIF string.
QString name(GameStandardAction id)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
int day() const const
bool isValid(int year, int month, int day)
int month() const const
int year() const const
QDateTime currentDateTime()
QDate date() const const
bool isValid() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
QString arg(Args &&... args) const const
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
QString simplified() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
QByteArray toLatin1() const const
QString toLower() const const
QStringView mid(qsizetype start, qsizetype length) const const
QString toString() const const
QStringView trimmed() const const
bool isEmpty() const const
QString toDisplayString(FormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:06:34 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.