aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2012-08-03 15:46:40 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2012-08-03 15:46:40 +0200
commitbecafc386f14967df87659cd408b5cee5835227d (patch)
treefd20c05e26b5118682299db9ecf005241acd2a68
parenta27aaa6f0dd18c859cee848dd5aac48cc6d1c89a (diff)
downloadqxmpp-becafc386f14967df87659cd408b5cee5835227d.tar.gz
add support for phone numbers to vCards
-rw-r--r--CHANGELOG1
-rw-r--r--src/base/QXmppVCardIq.cpp154
-rw-r--r--src/base/QXmppVCardIq.h49
-rw-r--r--tests/vcard.cpp56
-rw-r--r--tests/vcard.h2
5 files changed, 253 insertions, 9 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 5cb6538c..ccd566a0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@ QXmpp 0.6.4 (UNRELEASED)
- Improve vCard support:
* Make it possible to have several e-mail addresses.
+ * Make it possible to have several phone numbers.
- Make it possible to set the client's extended information form (XEP-0128).
- Fix XEP-0115 verification strings (remove duplicate features, sort form values)
- Fix issues:
diff --git a/src/base/QXmppVCardIq.cpp b/src/base/QXmppVCardIq.cpp
index 7fb88a3a..a961c63d 100644
--- a/src/base/QXmppVCardIq.cpp
+++ b/src/base/QXmppVCardIq.cpp
@@ -56,7 +56,7 @@ public:
QXmppVCardEmail::Type type;
};
-/// Constructs an empty vCard e-mail address.
+/// Constructs an empty e-mail address.
QXmppVCardEmail::QXmppVCardEmail()
: d(new QXmppVCardEmailPrivate)
@@ -74,7 +74,7 @@ QXmppVCardEmail::~QXmppVCardEmail()
{
}
-/// Assigns \a other to this vCard e-mail address.
+/// Assigns \a other to this e-mail address.
QXmppVCardEmail& QXmppVCardEmail::operator=(const QXmppVCardEmail &other)
{
@@ -142,6 +142,132 @@ void QXmppVCardEmail::toXml(QXmlStreamWriter *writer) const
writer->writeEndElement();
}
+class QXmppVCardPhonePrivate : public QSharedData
+{
+public:
+ QXmppVCardPhonePrivate() : type(QXmppVCardPhone::None) {};
+ QString number;
+ QXmppVCardPhone::Type type;
+};
+
+/// Constructs an empty phone number.
+
+QXmppVCardPhone::QXmppVCardPhone()
+ : d(new QXmppVCardPhonePrivate)
+{
+}
+
+/// Constructs a copy of \a other.
+
+QXmppVCardPhone::QXmppVCardPhone(const QXmppVCardPhone &other)
+ : d(other.d)
+{
+}
+
+QXmppVCardPhone::~QXmppVCardPhone()
+{
+}
+
+/// Assigns \a other to this phone number.
+
+QXmppVCardPhone& QXmppVCardPhone::operator=(const QXmppVCardPhone &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/// Returns the phone number.
+
+QString QXmppVCardPhone::number() const
+{
+ return d->number;
+}
+
+/// Sets the phone \a number.
+
+void QXmppVCardPhone::setNumber(const QString &number)
+{
+ d->number = number;
+}
+
+/// Returns the e-mail type, which is a combination of TypeFlag.
+
+QXmppVCardPhone::Type QXmppVCardPhone::type() const
+{
+ return d->type;
+}
+
+/// Sets the e-mail \a type, which is a combination of TypeFlag.
+
+void QXmppVCardPhone::setType(QXmppVCardPhone::Type type)
+{
+ d->type = type;
+}
+
+void QXmppVCardPhone::parse(const QDomElement &element)
+{
+ if (!element.firstChildElement("HOME").isNull())
+ d->type |= Home;
+ if (!element.firstChildElement("WORK").isNull())
+ d->type |= Work;
+ if (!element.firstChildElement("VOICE").isNull())
+ d->type |= Voice;
+ if (!element.firstChildElement("FAX").isNull())
+ d->type |= Fax;
+ if (!element.firstChildElement("PAGER").isNull())
+ d->type |= Pager;
+ if (!element.firstChildElement("MSG").isNull())
+ d->type |= Messaging;
+ if (!element.firstChildElement("CELL").isNull())
+ d->type |= Cell;
+ if (!element.firstChildElement("VIDEO").isNull())
+ d->type |= Video;
+ if (!element.firstChildElement("BBS").isNull())
+ d->type |= BBS;
+ if (!element.firstChildElement("MODEM").isNull())
+ d->type |= Modem;
+ if (!element.firstChildElement("ISDN").isNull())
+ d->type |= ISDN;
+ if (!element.firstChildElement("PCS").isNull())
+ d->type |= PCS;
+ if (!element.firstChildElement("PREF").isNull())
+ d->type |= Preferred;
+ d->number = element.firstChildElement("NUMBER").text();
+}
+
+void QXmppVCardPhone::toXml(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement("PHONE");
+ if (d->type & Home)
+ writer->writeEmptyElement("HOME");
+ if (d->type & Work)
+ writer->writeEmptyElement("WORK");
+ if (d->type & Voice)
+ writer->writeEmptyElement("VOICE");
+ if (d->type & Fax)
+ writer->writeEmptyElement("FAX");
+ if (d->type & Pager)
+ writer->writeEmptyElement("PAGER");
+ if (d->type & Messaging)
+ writer->writeEmptyElement("MSG");
+ if (d->type & Cell)
+ writer->writeEmptyElement("CELL");
+ if (d->type & Video)
+ writer->writeEmptyElement("VIDEO");
+ if (d->type & BBS)
+ writer->writeEmptyElement("BBS");
+ if (d->type & Modem)
+ writer->writeEmptyElement("MODEM");
+ if (d->type & ISDN)
+ writer->writeEmptyElement("ISDN");
+ if (d->type & PCS)
+ writer->writeEmptyElement("PCS");
+ if (d->type & Preferred)
+ writer->writeEmptyElement("PREF");
+ writer->writeTextElement("NUMBER", d->number);
+ writer->writeEndElement();
+}
+
class QXmppVCardIqPrivate : public QSharedData
{
public:
@@ -158,6 +284,7 @@ public:
QString photoType;
QList<QXmppVCardEmail> emails;
+ QList<QXmppVCardPhone> phones;
};
/// Constructs a QXmppVCardIq for the specified recipient.
@@ -390,6 +517,19 @@ void QXmppVCardIq::setEmails(const QList<QXmppVCardEmail> &emails)
d->emails = emails;
}
+/// Returns the phone numbers.
+
+QList<QXmppVCardPhone> QXmppVCardIq::phones() const
+{
+ return d->phones;
+}
+
+/// Sets the phone numbers.
+
+void QXmppVCardIq::setPhones(const QList<QXmppVCardPhone> &phones)
+{
+ d->phones = phones;
+}
/// \cond
bool QXmppVCardIq::isVCard(const QDomElement &nodeRecv)
{
@@ -420,6 +560,10 @@ void QXmppVCardIq::parseElementFromChild(const QDomElement& nodeRecv)
QXmppVCardEmail email;
email.parse(child);
d->emails << email;
+ } else if (child.tagName() == "PHONE") {
+ QXmppVCardPhone phone;
+ phone.parse(child);
+ d->phones << phone;
}
child = child.nextSiblingElement();
}
@@ -450,9 +594,9 @@ void QXmppVCardIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
helperToXmlAddTextElement(writer, "MIDDLE", d->middleName);
writer->writeEndElement();
}
- if (!d->url.isEmpty())
- helperToXmlAddTextElement(writer, "URL", d->url);
+ foreach (const QXmppVCardPhone &phone, d->phones)
+ phone.toXml(writer);
if(!photo().isEmpty())
{
writer->writeStartElement("PHOTO");
@@ -463,6 +607,8 @@ void QXmppVCardIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
helperToXmlAddTextElement(writer, "BINVAL", d->photo.toBase64());
writer->writeEndElement();
}
+ if (!d->url.isEmpty())
+ helperToXmlAddTextElement(writer, "URL", d->url);
writer->writeEndElement();
}
diff --git a/src/base/QXmppVCardIq.h b/src/base/QXmppVCardIq.h
index b32cc5f6..0e9a9862 100644
--- a/src/base/QXmppVCardIq.h
+++ b/src/base/QXmppVCardIq.h
@@ -31,6 +31,7 @@
#include <QDomElement>
class QXmppVCardEmailPrivate;
+class QXmppVCardPhonePrivate;
class QXmppVCardIqPrivate;
/// \brief Represents a vCard e-mail address.
@@ -70,6 +71,51 @@ private:
QSharedDataPointer<QXmppVCardEmailPrivate> d;
};
+/// \brief Represents a vCard phone number.
+
+class QXmppVCardPhone
+{
+public:
+ /// \brief Describes phone number types.
+ enum TypeFlag {
+ None = 0x0,
+ Home = 0x1,
+ Work = 0x2,
+ Voice = 0x4,
+ Fax = 0x8,
+ Pager = 0x10,
+ Messaging = 0x20,
+ Cell = 0x40,
+ Video = 0x80,
+ BBS = 0x100,
+ Modem = 0x200,
+ ISDN = 0x400,
+ PCS = 0x800,
+ Preferred = 0x1000
+ };
+ Q_DECLARE_FLAGS(Type, TypeFlag);
+
+ QXmppVCardPhone();
+ QXmppVCardPhone(const QXmppVCardPhone &other);
+ ~QXmppVCardPhone();
+
+ QXmppVCardPhone& operator=(const QXmppVCardPhone &other);
+
+ QString number() const;
+ void setNumber(const QString &number);
+
+ Type type() const;
+ void setType(Type type);
+
+ /// \cond
+ void parse(const QDomElement &element);
+ void toXml(QXmlStreamWriter *stream) const;
+ /// \endcond
+
+private:
+ QSharedDataPointer<QXmppVCardPhonePrivate> d;
+};
+
/// \brief Represents the XMPP vCard.
///
/// The functions names are self explanatory.
@@ -121,6 +167,9 @@ public:
QList<QXmppVCardEmail> emails() const;
void setEmails(const QList<QXmppVCardEmail> &emails);
+
+ QList<QXmppVCardPhone> phones() const;
+ void setPhones(const QList<QXmppVCardPhone> &phones);
/// \cond
static bool isVCard(const QDomElement &element);
diff --git a/tests/vcard.cpp b/tests/vcard.cpp
index 89f8b46a..b92b269b 100644
--- a/tests/vcard.cpp
+++ b/tests/vcard.cpp
@@ -32,8 +32,11 @@ void tst_QXmppVCardIq::testEmail_data()
QTest::addColumn<int>("type");
QTest::newRow("none") << QByteArray("<EMAIL><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::None);
- QTest::newRow("internet") << QByteArray("<EMAIL><INTERNET/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Internet);
- QTest::newRow("x400") << QByteArray("<EMAIL><X400/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::X400);
+ QTest::newRow("HOME") << QByteArray("<EMAIL><HOME/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Home);
+ QTest::newRow("WORK") << QByteArray("<EMAIL><WORK/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Work);
+ QTest::newRow("INTERNET") << QByteArray("<EMAIL><INTERNET/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Internet);
+ QTest::newRow("X400") << QByteArray("<EMAIL><X400/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::X400);
+ QTest::newRow("PREF") << QByteArray("<EMAIL><PREF/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Preferred);
QTest::newRow("all") << QByteArray("<EMAIL><HOME/><WORK/><INTERNET/><PREF/><X400/><USERID>foo.bar@example.com</USERID></EMAIL>") << int(QXmppVCardEmail::Home | QXmppVCardEmail::Work | QXmppVCardEmail::Internet | QXmppVCardEmail::Preferred | QXmppVCardEmail::X400);
}
@@ -49,6 +52,40 @@ void tst_QXmppVCardIq::testEmail()
serializePacket(email, xml);
}
+void tst_QXmppVCardIq::testPhone_data()
+{
+ QTest::addColumn<QByteArray>("xml");
+ QTest::addColumn<int>("type");
+
+ QTest::newRow("none") << QByteArray("<PHONE><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::None);
+ QTest::newRow("HOME") << QByteArray("<PHONE><HOME/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Home);
+ QTest::newRow("WORK") << QByteArray("<PHONE><WORK/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Work);
+ QTest::newRow("VOICE") << QByteArray("<PHONE><VOICE/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Voice);
+ QTest::newRow("FAX") << QByteArray("<PHONE><FAX/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Fax);
+ QTest::newRow("PAGER") << QByteArray("<PHONE><PAGER/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Pager);
+ QTest::newRow("MSG") << QByteArray("<PHONE><MSG/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Messaging);
+ QTest::newRow("CELL") << QByteArray("<PHONE><CELL/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Cell);
+ QTest::newRow("VIDEO") << QByteArray("<PHONE><VIDEO/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Video);
+ QTest::newRow("BBS") << QByteArray("<PHONE><BBS/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::BBS);
+ QTest::newRow("MODEM") << QByteArray("<PHONE><MODEM/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Modem);
+ QTest::newRow("IDSN") << QByteArray("<PHONE><ISDN/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::ISDN);
+ QTest::newRow("PCS") << QByteArray("<PHONE><PCS/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::PCS);
+ QTest::newRow("PREF") << QByteArray("<PHONE><PREF/><NUMBER>12345</NUMBER></PHONE>") << int(QXmppVCardPhone::Preferred);
+}
+
+void tst_QXmppVCardIq::testPhone()
+{
+ QFETCH(QByteArray, xml);
+ QFETCH(int, type);
+
+ QXmppVCardPhone phone;
+ parsePacket(phone, xml);
+ QCOMPARE(phone.number(), QLatin1String("12345"));
+ QCOMPARE(int(phone.type()), type);
+ serializePacket(phone, xml);
+}
+
+
void tst_QXmppVCardIq::testVCard()
{
const QByteArray xml(
@@ -59,6 +96,8 @@ void tst_QXmppVCardIq::testVCard()
"<FN>Foo Bar!</FN>"
"<NICKNAME>FooBar</NICKNAME>"
"<N><GIVEN>Foo</GIVEN><FAMILY>Wiz</FAMILY><MIDDLE>Baz</MIDDLE></N>"
+ "<PHONE><HOME/><NUMBER>12345</NUMBER></PHONE>"
+ "<PHONE><WORK/><NUMBER>67890</NUMBER></PHONE>"
"<PHOTO>"
"<TYPE>image/png</TYPE>"
"<BINVAL>"
@@ -67,6 +106,7 @@ void tst_QXmppVCardIq::testVCard()
"WfgYGBiQEHGJwSAK2BBQ1f3uvpAAAAAElFTkSuQmCC"
"</BINVAL>"
"</PHOTO>"
+ "<URL>http://code.google.com/p/qxmpp/</URL>"
"</vCard>"
"</iq>");
@@ -74,18 +114,24 @@ void tst_QXmppVCardIq::testVCard()
parsePacket(vcard, xml);
QCOMPARE(vcard.birthday(), QDate(1983, 9, 14));
QCOMPARE(vcard.email(), QLatin1String("foo.bar@example.com"));
+ QCOMPARE(vcard.emails().size(), 1);
+ QCOMPARE(vcard.emails()[0].address(), QLatin1String("foo.bar@example.com"));
+ QCOMPARE(int(vcard.emails()[0].type()), int(QXmppVCardEmail::Internet));
QCOMPARE(vcard.nickName(), QLatin1String("FooBar"));
QCOMPARE(vcard.fullName(), QLatin1String("Foo Bar!"));
QCOMPARE(vcard.firstName(), QLatin1String("Foo"));
QCOMPARE(vcard.middleName(), QLatin1String("Baz"));
QCOMPARE(vcard.lastName(), QLatin1String("Wiz"));
+ QCOMPARE(vcard.phones().size(), 2);
+ QCOMPARE(vcard.phones()[0].number(), QLatin1String("12345"));
+ QCOMPARE(int(vcard.phones()[0].type()), int(QXmppVCardEmail::Home));
+ QCOMPARE(vcard.phones()[1].number(), QLatin1String("67890"));
+ QCOMPARE(int(vcard.phones()[1].type()), int(QXmppVCardEmail::Work));
QCOMPARE(vcard.photo(), QByteArray::fromBase64(
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAAXNSR0IArs4c6QAAAAlwSFlzAAA"
"UIgAAFCIBjw1HyAAAAAd0SU1FB9oIHQInNvuJovgAAAAiSURBVAjXY2TQ+s/AwMDAwPD/GiMDlP"
"WfgYGBiQEHGJwSAK2BBQ1f3uvpAAAAAElFTkSuQmCC"));
QCOMPARE(vcard.photoType(), QLatin1String("image/png"));
- QCOMPARE(vcard.emails().size(), 1);
- QCOMPARE(vcard.emails()[0].address(), QLatin1String("foo.bar@example.com"));
- QCOMPARE(int(vcard.emails()[0].type()), int(QXmppVCardEmail::Internet));
+ QCOMPARE(vcard.url(), QLatin1String("http://code.google.com/p/qxmpp/"));
serializePacket(vcard, xml);
}
diff --git a/tests/vcard.h b/tests/vcard.h
index 5f0d6677..cc1527c1 100644
--- a/tests/vcard.h
+++ b/tests/vcard.h
@@ -30,5 +30,7 @@ class tst_QXmppVCardIq : public QObject
private slots:
void testEmail_data();
void testEmail();
+ void testPhone_data();
+ void testPhone();
void testVCard();
};