diff --git a/autotests/addresseetest.cpp b/autotests/addresseetest.cpp --- a/autotests/addresseetest.cpp +++ b/autotests/addresseetest.cpp @@ -94,8 +94,7 @@ addressee.setKind(QStringLiteral("foo")); addressee.setChanged(false); KContacts::Impp imp; - imp.setType(KContacts::Impp::GaduGadu); - imp.setAddress(QStringLiteral("foo@kde.org")); + imp.setAddress(QUrl(QStringLiteral("gg:foo@kde.org"))); KContacts::Impp::List listImp; listImp << imp; addressee.setImppList(listImp); diff --git a/autotests/importexportvcardtest.cpp b/autotests/importexportvcardtest.cpp --- a/autotests/importexportvcardtest.cpp +++ b/autotests/importexportvcardtest.cpp @@ -104,7 +104,7 @@ "FN:Sherlock Holmes\r\n" "GENDER:M\r\n" "GEO:geo:51.523701,0.158500\r\n" - "IMPP;X-SERVICE-TYPE=xmpp;PREF=1:detective@sherlockholmes.com\r\n" + "IMPP;PREF=1:xmpp:detective@sherlockholmes.com\r\n" "KEY;MEDIATYPE=application/pgp-keys:https://sherlockholmes.com/sherlock-holm\r\n" " es.pub.asc\r\nKIND:individual\r\n" "LANG;PREF=1;TYPE=work:en\r\n" diff --git a/autotests/impptest.cpp b/autotests/impptest.cpp --- a/autotests/impptest.cpp +++ b/autotests/impptest.cpp @@ -22,7 +22,6 @@ #include "impp.h" #include #include "vcardtool_p.h" -Q_DECLARE_METATYPE(KContacts::Impp::ImppType) ImppTest::ImppTest(QObject *parent) : QObject(parent) @@ -38,37 +37,36 @@ KContacts::Impp impp; QVERIFY(!impp.isValid()); QVERIFY(impp.address().isEmpty()); - QCOMPARE(impp.type(), KContacts::Impp::Unknown); + QVERIFY(impp.serviceType().isEmpty()); QVERIFY(impp.parameters().isEmpty()); } void ImppTest::shouldAssignValue() { - const QString address(QStringLiteral("address")); + const QUrl address(QStringLiteral("icq:address")); QMap params; params.insert(QStringLiteral("Foo1"), QStringList() << QStringLiteral("bla1") << QStringLiteral("blo1")); params.insert(QStringLiteral("Foo2"), QStringList() << QStringLiteral("bla2") << QStringLiteral("blo2")); KContacts::Impp impp; impp.setParameters(params); - impp.setType(KContacts::Impp::Icq); impp.setAddress(address); QVERIFY(impp.isValid()); QVERIFY(!impp.address().isEmpty()); QCOMPARE(impp.address(), address); - QCOMPARE(impp.type(), KContacts::Impp::Icq); + QCOMPARE(impp.serviceType(), QLatin1String("icq")); + QCOMPARE(impp.serviceIcon(), QLatin1String("im-icq")); QVERIFY(!impp.parameters().isEmpty()); QCOMPARE(impp.parameters(), params); } void ImppTest::shouldSerialized() { - const QString address(QStringLiteral("address")); + const QUrl address(QStringLiteral("icq:address")); QMap params; params.insert(QStringLiteral("Foo1"), QStringList() << QStringLiteral("bla1") << QStringLiteral("blo1")); params.insert(QStringLiteral("Foo2"), QStringList() << QStringLiteral("bla2") << QStringLiteral("blo2")); KContacts::Impp impp; impp.setParameters(params); - impp.setType(KContacts::Impp::Icq); impp.setAddress(address); QByteArray data; @@ -84,13 +82,12 @@ void ImppTest::shouldEqualImpp() { - const QString address(QStringLiteral("address")); + const QUrl address(QStringLiteral("icq:address")); QMap params; params.insert(QStringLiteral("Foo1"), QStringList() << QStringLiteral("bla1") << QStringLiteral("blo1")); params.insert(QStringLiteral("Foo2"), QStringList() << QStringLiteral("bla2") << QStringLiteral("blo2")); KContacts::Impp impp; impp.setParameters(params); - impp.setType(KContacts::Impp::Icq); impp.setAddress(address); KContacts::Impp result(impp); @@ -130,8 +127,8 @@ QCOMPARE(lst.count(), 1); QCOMPARE(lst.at(0).imppList().count(), 1); KContacts::Impp impp = lst.at(0).imppList().at(0); - QCOMPARE(impp.address(), QStringLiteral("skype:xxxxxxxx")); - QCOMPARE(impp.type(), KContacts::Impp::Skype); + QCOMPARE(impp.address(), QUrl(QStringLiteral("skype:xxxxxxxx"))); + QCOMPARE(impp.serviceType(), QLatin1String("skype")); } void ImppTest::shouldParseImppVcard4() @@ -151,23 +148,22 @@ QCOMPARE(lst.count(), 1); QCOMPARE(lst.at(0).imppList().count(), 2); KContacts::Impp impp = lst.at(0).imppList().at(0); - QCOMPARE(impp.address(), QStringLiteral("xxxxxxxx")); - QCOMPARE(impp.type(), KContacts::Impp::Skype); + QCOMPARE(impp.address(), QUrl(QStringLiteral("skype:xxxxxxxx"))); + QCOMPARE(impp.serviceType(), QLatin1String("skype")); QVERIFY(impp.isPreferred()); impp = lst.at(0).imppList().at(1); - QCOMPARE(impp.address(), QStringLiteral("1234567890")); - QCOMPARE(impp.type(), KContacts::Impp::Skype); + QCOMPARE(impp.address(), QUrl(QStringLiteral("skype:1234567890"))); + QCOMPARE(impp.serviceType(), QLatin1String("skype")); QVERIFY(!impp.isPreferred()); } -QByteArray createCard(KContacts::Impp::ImppType type) +QByteArray createCard(const QString &type) { QByteArray expected("BEGIN:VCARD\n" "VERSION:3.0\n" "EMAIL:foo@kde.org\n"); - if (type != KContacts::Impp::Unknown) { - const QByteArray baType = KContacts::Impp::typeToString(type).toLatin1(); - expected += "IMPP;X-SERVICE-TYPE=" + baType + ":" + baType + ":address\n"; + if (!type.isEmpty()) { + expected += "IMPP;X-SERVICE-TYPE=" + type.toLatin1() + ":" + type.toLatin1() + ":address\n"; } expected += QByteArray( "N:;;;;\n" @@ -178,19 +174,17 @@ void ImppTest::shouldParseServiceType_data() { - QTest::addColumn("type"); + QTest::addColumn("type"); QTest::addColumn("hasImpp"); - QTest::newRow("withoutimpp") << KContacts::Impp::Unknown << false; - QTest::newRow("skype") << KContacts::Impp::Skype << true; - for (int i = KContacts::Impp::Unknown + 1; i < KContacts::Impp::EndList; ++i) { - KContacts::Impp::ImppType type = static_cast(i); - QTest::newRow(KContacts::Impp::typeToString(type).toLatin1().constData()) << type << true; + QTest::newRow("withoutimpp") << QString() << false; + for (const auto &type : KContacts::Impp::serviceTypes()) { + QTest::newRow(type.toLatin1().constData()) << type << true; } } void ImppTest::shouldParseServiceType() { - QFETCH(KContacts::Impp::ImppType, type); + QFETCH(QString, type); QFETCH(bool, hasImpp); QByteArray vcarddata = createCard(type); @@ -202,19 +196,18 @@ QCOMPARE(!lst.at(0).imppList().isEmpty(), hasImpp); if (hasImpp) { KContacts::Impp impp = lst.at(0).imppList().at(0); - QCOMPARE(impp.address(), QStringLiteral("%1:address").arg(KContacts::Impp::typeToString(type))); - QCOMPARE(impp.type(), type); + QCOMPARE(impp.address(), QUrl(QStringLiteral("%1:address").arg(type))); + QCOMPARE(impp.serviceType(), type); } } -QByteArray expectedVcard(KContacts::Impp::ImppType type) +QByteArray expectedVcard(const QString &type) { QByteArray expected("BEGIN:VCARD\r\n" "VERSION:4.0\r\n" "EMAIL:foo@kde.org\r\n"); - if (type != KContacts::Impp::Unknown) { - const QByteArray baType = KContacts::Impp::typeToString(type).toLatin1(); - expected += "IMPP;X-SERVICE-TYPE=" + baType + ":address\r\n"; + if (!type.isEmpty()) { + expected += "IMPP:" + type.toLatin1() + ":address\r\n"; } expected += ("N:;;;;\r\n" @@ -243,25 +236,23 @@ void ImppTest::shouldExportType_data() { - QTest::addColumn("type"); - for (int i = KContacts::Impp::Unknown + 1; i < KContacts::Impp::EndList; ++i) { - KContacts::Impp::ImppType type = static_cast(i); - QTest::newRow(KContacts::Impp::typeToString(type).toLatin1().constData()) << type; + QTest::addColumn("type"); + for (const auto &type : KContacts::Impp::serviceTypes()) { + QTest::newRow(type.toLatin1().constData()) << type; } } void ImppTest::shouldExportType() { - QFETCH(KContacts::Impp::ImppType, type); + QFETCH(QString, type); QByteArray expected = expectedVcard(type); KContacts::AddresseeList lst; KContacts::Addressee addr; addr.setEmails(QStringList() << QStringLiteral("foo@kde.org")); addr.setUid(QStringLiteral("testuid")); KContacts::Impp impp; - impp.setAddress(QStringLiteral("address")); - impp.setType(type); + impp.setAddress(QUrl(type + QStringLiteral(":address"))); addr.insertImpp(impp); lst << addr; KContacts::VCardTool vcard; @@ -274,7 +265,7 @@ QByteArray expected("BEGIN:VCARD\r\n" "VERSION:4.0\r\n" "EMAIL:foo@kde.org\r\n" - "IMPP;FOO1=bla1,blo1;FOO2=bla2,blo2;X-SERVICE-TYPE=skype:address\r\n" + "IMPP;FOO1=bla1,blo1;FOO2=bla2,blo2:skype:address\r\n" "N:;;;;\r\n" "UID:testuid\r\n" "END:VCARD\r\n\r\n"); @@ -286,8 +277,7 @@ params.insert(QStringLiteral("Foo1"), QStringList() << QStringLiteral("bla1") << QStringLiteral("blo1")); params.insert(QStringLiteral("Foo2"), QStringList() << QStringLiteral("bla2") << QStringLiteral("blo2")); KContacts::Impp impp; - impp.setAddress(QStringLiteral("address")); - impp.setType(KContacts::Impp::Skype); + impp.setAddress(QUrl(QStringLiteral("skype:address"))); impp.setParameters(params); impp.setPreferred(false); addr.insertImpp(impp); @@ -303,7 +293,7 @@ QByteArray expected("BEGIN:VCARD\r\n" "VERSION:4.0\r\n" "EMAIL:foo@kde.org\r\n" - "IMPP;FOO1=bla1,blo1;FOO2=bla2,blo2;X-SERVICE-TYPE=skype;PREF=1:address\r\n" + "IMPP;FOO1=bla1,blo1;FOO2=bla2,blo2;PREF=1:skype:address\r\n" "N:;;;;\r\n" "UID:testuid\r\n" "END:VCARD\r\n\r\n"); @@ -316,8 +306,7 @@ params.insert(QStringLiteral("Foo2"), QStringList() << QStringLiteral("bla2") << QStringLiteral("blo2")); params.insert(QStringLiteral("X-SERVICE-TYPE"), QStringList() << QStringLiteral("aim")); KContacts::Impp impp; - impp.setAddress(QStringLiteral("address")); - impp.setType(KContacts::Impp::Skype); + impp.setAddress(QUrl(QStringLiteral("skype:address"))); impp.setParameters(params); impp.setPreferred(true); addr.insertImpp(impp); diff --git a/src/impp.h b/src/impp.h --- a/src/impp.h +++ b/src/impp.h @@ -39,43 +39,44 @@ class KCONTACTS_EXPORT Impp { Q_GADGET + Q_PROPERTY(bool isValid READ isValid) + Q_PROPERTY(QUrl address READ address WRITE setAddress) Q_PROPERTY(bool isPreferred READ isPreferred WRITE setPreferred) + Q_PROPERTY(QString serviceType READ serviceType) + Q_PROPERTY(QString serviceLabel READ serviceLabel) + Q_PROPERTY(QString serviceIcon READ serviceIcon) friend KCONTACTS_EXPORT QDataStream &operator<<(QDataStream &, const Impp &); friend KCONTACTS_EXPORT QDataStream &operator>>(QDataStream &, Impp &); public: Impp(); Impp(const Impp &other); - Impp(const QString &address); + Impp(const QUrl &address); ~Impp(); typedef QVector List; - enum ImppType { - Unknown = 0, - Skype = 1, - Xmpp = 2, - Jabber = 3, - Sip = 4, - Aim = 5, - Msn = 6, - Twitter = 7, - GoogleTalk = 8, - Yahoo = 9, - Qq = 10, - GaduGadu = 11, - Ownclound = 12, - Icq = 13, - Facebook = 14, - EndList - }; Q_REQUIRED_RESULT bool isValid() const; - Q_REQUIRED_RESULT ImppType type() const; - void setType(ImppType type); + void setAddress(const QUrl &address); + Q_REQUIRED_RESULT QUrl address() const; - void setAddress(const QString &address); - Q_REQUIRED_RESULT QString address() const; + /** + * Returns the messaging service this address is for. + * This is equivalent to address().scheme(). + * @since 5.12 + */ + QString serviceType() const; + /** + * Returns a translated label for the service type. + * @since 5.12 + */ + QString serviceLabel() const; + /** + * Returns the name of an icon representing the service type. + * @since 5.12 + */ + QString serviceIcon() const; /** * Returns whether this is the preferred messaging address. @@ -98,8 +99,6 @@ Q_REQUIRED_RESULT QString toString() const; - Q_REQUIRED_RESULT static QString typeToString(ImppType type); - /** * Returns a translated name of the given IM service. * @since 5.12 diff --git a/src/impp.cpp b/src/impp.cpp --- a/src/impp.cpp +++ b/src/impp.cpp @@ -28,27 +28,22 @@ #include #include #include +#include using namespace KContacts; class Q_DECL_HIDDEN Impp::Private : public QSharedData { public: - Private() - : type(KContacts::Impp::Unknown) - { - } - + Private() = default; Private(const Private &other) : QSharedData(other) { parameters = other.parameters; - type = other.type; } QMap parameters; - QString address; - ImppType type; + QUrl address; }; Impp::Impp() @@ -61,7 +56,7 @@ { } -Impp::Impp(const QString &address) +Impp::Impp(const QUrl &address) : d(new Private) { d->address = address; @@ -73,27 +68,32 @@ bool Impp::isValid() const { - return !d->address.isEmpty() && (d->type != Unknown); + return !d->address.isEmpty() && !d->address.scheme().isEmpty(); } -Impp::ImppType Impp::type() const +void Impp::setAddress(const QUrl &address) { - return d->type; + d->address = address; } -void Impp::setType(Impp::ImppType type) +QUrl Impp::address() const { - d->type = type; + return d->address; } -void Impp::setAddress(const QString &address) +QString Impp::serviceType() const { - d->address = address; + return d->address.scheme(); } -QString Impp::address() const +QString Impp::serviceLabel() const { - return d->address; + return serviceLabel(serviceType()); +} + +QString Impp::serviceIcon() const +{ + return serviceIcon(serviceType()); } bool Impp::isPreferred() const @@ -126,7 +126,7 @@ bool Impp::operator==(const Impp &other) const { - return (d->parameters == other.parameters()) && (d->address == other.address()) && (d->type == other.type()); + return (d->parameters == other.parameters()) && (d->address == other.address()); } bool Impp::operator!=(const Impp &other) const @@ -146,8 +146,8 @@ QString Impp::toString() const { QString str = QLatin1String("Impp {\n"); - str += QStringLiteral(" type: %1\n").arg(typeToString(d->type)); - str += QStringLiteral(" address: %1\n").arg(d->address); + str += QStringLiteral(" type: %1\n").arg(serviceType()); + str += QStringLiteral(" address: %1\n").arg(d->address.url()); if (!d->parameters.isEmpty()) { QString param; QMap::const_iterator it = d->parameters.constBegin(); @@ -162,55 +162,15 @@ return str; } -QString Impp::typeToString(ImppType type) -{ - switch (type) { - case Unknown: - case EndList: - qCWarning(KCONTACTS_LOG) << "Invalid type requested"; - break; - case Skype: - return QStringLiteral("skype"); - case Xmpp: - return QStringLiteral("xmpp"); - case Jabber: - return QStringLiteral("jabber"); - case Sip: - return QStringLiteral("sip"); - case Aim: - return QStringLiteral("aim"); - case Msn: - return QStringLiteral("msn"); - case Twitter: - return QStringLiteral("twitter"); - case GoogleTalk: - return QStringLiteral("googletalk"); - case Yahoo: - return QStringLiteral("yahoo"); - case Qq: - return QStringLiteral("qq"); - case GaduGadu: - return QStringLiteral("gadugadu"); - case Ownclound: - return QStringLiteral("owncloud-handle"); - case Facebook: - return QStringLiteral("facebook"); - case Icq: - return QStringLiteral("icq"); - } - return QString(); -} - QDataStream &KContacts::operator<<(QDataStream &s, const Impp &impp) { - return s << impp.d->parameters << impp.d->address << impp.d->type; + return s << impp.d->parameters << impp.d->address << (uint32_t)(0); } QDataStream &KContacts::operator>>(QDataStream &s, Impp &impp) { int i; s >> impp.d->parameters >> impp.d->address >> i; - impp.d->type = static_cast(i); return s; } @@ -247,3 +207,5 @@ types.erase(std::unique(types.begin(), types.end()), types.end()); return types; } + +#include "moc_impp.cpp" diff --git a/src/vcardtool.cpp b/src/vcardtool.cpp --- a/src/vcardtool.cpp +++ b/src/vcardtool.cpp @@ -652,8 +652,7 @@ // IMPP (supported in vcard 3 too) const QVector lstImpp = (*addrIt).imppList(); for (const Impp &impp : lstImpp) { - VCardLine line(QStringLiteral("IMPP"), impp.address()); - line.addParameter(QStringLiteral("X-SERVICE-TYPE"), Impp::typeToString(impp.type())); + VCardLine line(QStringLiteral("IMPP"), impp.address().url()); QMapIterator i(impp.parameters()); while (i.hasNext()) { i.next(); @@ -873,22 +872,13 @@ } //IMPP else if (identifier == QLatin1String("impp")) { - QString imppStr = (*lineIt).value().toString(); + QUrl imppUrl((*lineIt).value().toString()); Impp impp; impp.setParameters((*lineIt).parameterMap()); - if (!(*lineIt).parameter(QStringLiteral("x-service-type")).isEmpty()) { - impp.setAddress(imppStr); - const QString serviceType = (*lineIt).parameter(QStringLiteral("x-service-type")).toLower(); - imppService(serviceType, impp); - } else { - const int pos = imppStr.indexOf(QLatin1Char(':')); - if (pos != -1) { - const QString serviceType = imppStr.left(pos); - const QString address = imppStr.right(imppStr.length() - pos - 1); - impp.setAddress(address); - imppService(serviceType, impp); - } + if (!(*lineIt).parameter(QStringLiteral("x-service-type")).isEmpty() && imppUrl.scheme().isEmpty()) { + imppUrl.setScheme(normalizeImppServiceType((*lineIt).parameter(QStringLiteral("x-service-type")).toLower())); } + impp.setAddress(imppUrl); addr.insertImpp(impp); } // CLASS @@ -1581,37 +1571,16 @@ return list; } -void VCardTool::imppService(const QString &serviceType, KContacts::Impp &impp) const +QString VCardTool::normalizeImppServiceType(const QString &serviceType) const { - if (serviceType == QLatin1String("facebook")) { - impp.setType(KContacts::Impp::Facebook); - } else if (serviceType == QLatin1String("jabber")) { - impp.setType(KContacts::Impp::Jabber); - } else if (serviceType == QLatin1String("sip")) { - impp.setType(KContacts::Impp::Sip); - } else if (serviceType == QLatin1String("aim")) { - impp.setType(KContacts::Impp::Aim); - } else if (serviceType == QLatin1String("msn")) { - impp.setType(KContacts::Impp::Msn); - } else if (serviceType == QLatin1String("twitter")) { - impp.setType(KContacts::Impp::Twitter); - } else if (serviceType == QLatin1String("googletalk")) { - impp.setType(KContacts::Impp::GoogleTalk); - } else if (serviceType == QLatin1String("xmpp")) { - impp.setType(KContacts::Impp::Xmpp); - } else if (serviceType == QLatin1String("icq")) { - impp.setType(KContacts::Impp::Icq); - } else if (serviceType == QLatin1String("yahoo")) { - impp.setType(KContacts::Impp::Yahoo); - } else if (serviceType == QLatin1String("qq")) { - impp.setType(KContacts::Impp::Qq); - } else if (serviceType == QLatin1String("gadugadu")) { - impp.setType(KContacts::Impp::GaduGadu); - } else if (serviceType == QLatin1String("owncloud-handle")) { - impp.setType(KContacts::Impp::Ownclound); - } else if (serviceType == QLatin1String("skype")) { - impp.setType(KContacts::Impp::Skype); - } else { - qCDebug(KCONTACTS_LOG) << "unknown service type " << serviceType; + if (serviceType == QLatin1String("jabber")) { + return QStringLiteral("xmpp"); + } + if (serviceType == QLatin1String("yahoo")) { + return QStringLiteral("ymsgr"); + } + if (serviceType == QLatin1String("gadugadu")) { + return QStringLiteral("gg"); } + return serviceType; } diff --git a/src/vcardtool_p.h b/src/vcardtool_p.h --- a/src/vcardtool_p.h +++ b/src/vcardtool_p.h @@ -84,7 +84,8 @@ void addParameter(VCardLine &line, VCard::Version version, const QString &key, const QStringList &valueStringList) const; void addParameters(VCardLine &line, const QMap ¶ms) const; - void imppService(const QString &serviceType, KContacts::Impp &impp) const; + /** Translate alternative or legacy IMPP service types. */ + QString normalizeImppServiceType(const QString &serviceType) const; Q_DISABLE_COPY(VCardTool) };