aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2014-06-23 13:25:54 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2014-06-23 13:25:54 +0200
commit07ae4a63307928e1af97b75b3de23530c74beb3f (patch)
tree8ff1632c2e6a2ecc0fccf60e97525accc77b869d
parentc1dc26549ec15abebfd020dbd9a95b1b9915b95b (diff)
parent754314fe90964d84a3514846ebfa5ec16844bd9b (diff)
downloadqxmpp-07ae4a63307928e1af97b75b3de23530c74beb3f.tar.gz
Merge pull request #8 from trulabs/feature/XEP-0333
XEP-0333: Chat Markers
-rw-r--r--src/base/QXmppConstants.cpp2
-rw-r--r--src/base/QXmppConstants.h2
-rw-r--r--src/base/QXmppMessage.cpp126
-rw-r--r--src/base/QXmppMessage.h23
-rw-r--r--src/client/QXmppDiscoveryManager.cpp3
-rw-r--r--tests/qxmppmessage/tst_qxmppmessage.cpp187
6 files changed, 342 insertions, 1 deletions
diff --git a/src/base/QXmppConstants.cpp b/src/base/QXmppConstants.cpp
index ec314376..76098d58 100644
--- a/src/base/QXmppConstants.cpp
+++ b/src/base/QXmppConstants.cpp
@@ -114,3 +114,5 @@ const char* ns_attention = "urn:xmpp:attention:0";
const char* ns_bob = "urn:xmpp:bob";
// XEP-0249: Direct MUC Invitations
const char* ns_conference = "jabber:x:conference";
+// XEP-0333: Chat Markers
+const char* ns_chat_markers = "urn:xmpp:chat-markers:0";
diff --git a/src/base/QXmppConstants.h b/src/base/QXmppConstants.h
index 85030c12..bf544159 100644
--- a/src/base/QXmppConstants.h
+++ b/src/base/QXmppConstants.h
@@ -115,5 +115,7 @@ extern const char* ns_attention;
extern const char* ns_bob;
// XEP-0249: Direct MUC Invitations
extern const char* ns_conference;
+// XEP-0333: Char Markers
+extern const char* ns_chat_markers;
#endif // QXMPPCONSTANTS_H
diff --git a/src/base/QXmppMessage.cpp b/src/base/QXmppMessage.cpp
index e32465b7..4bdc6329 100644
--- a/src/base/QXmppMessage.cpp
+++ b/src/base/QXmppMessage.cpp
@@ -48,6 +48,13 @@ static const char* message_types[] = {
"headline"
};
+static const char* marker_types[] = {
+ "",
+ "received",
+ "displayed",
+ "acknowledged"
+};
+
static const char *ns_xhtml = "http://www.w3.org/1999/xhtml";
enum StampType
@@ -80,6 +87,12 @@ public:
QString mucInvitationJid;
QString mucInvitationPassword;
QString mucInvitationReason;
+
+ // XEP-0333: Chat Markers
+ bool markable;
+ QXmppMessage::Marker marker;
+ QString markedId;
+ QString markedThread;
};
/// Constructs a QXmppMessage.
@@ -101,6 +114,9 @@ QXmppMessage::QXmppMessage(const QString& from, const QString& to, const
d->body = body;
d->thread = thread;
d->receiptRequested = false;
+
+ d->markable = false;
+ d->marker = NoMarker;
}
/// Constructs a copy of \a other.
@@ -363,6 +379,70 @@ namespace
}
}
+/// Returns true if a message is markable, as defined
+/// XEP-0333: Chat Markers.
+
+bool QXmppMessage::isMarkable() const
+{
+ return d->markable;
+}
+
+/// Sets if the message is markable, as defined
+/// XEP-0333: Chat Markers.
+
+void QXmppMessage::setMarkable(const bool markable)
+{
+ d->markable = markable;
+}
+
+/// Returns the message's marker id, as defined
+/// XEP-0333: Chat Markers.
+
+QString QXmppMessage::markedId() const
+{
+ return d->markedId;
+}
+
+/// Sets the message's marker id, as defined
+/// XEP-0333: Chat Markers.
+
+void QXmppMessage::setMarkerId(const QString &markerId)
+{
+ d->markedId = markerId;
+}
+
+/// Returns the message's marker thread, as defined
+/// XEP-0333: Chat Markers.
+
+QString QXmppMessage::markedThread() const
+{
+ return d->markedThread;
+}
+
+/// Sets the message's marked thread, as defined
+/// XEP-0333: Chat Markers.
+
+void QXmppMessage::setMarkedThread(const QString &markedThread)
+{
+ d->markedThread = markedThread;
+}
+
+/// Returns the message's marker, as defined
+/// XEP-0333: Chat Markers.
+
+QXmppMessage::Marker QXmppMessage::marker() const
+{
+ return d->marker;
+}
+
+/// Sets the message's marker, as defined
+/// XEP-0333: Chat Markers
+
+void QXmppMessage::setMarker(const Marker marker)
+{
+ d->marker = marker;
+}
+
/// \cond
void QXmppMessage::parse(const QDomElement &element)
{
@@ -433,6 +513,36 @@ void QXmppMessage::parse(const QDomElement &element)
// XEP-0224: Attention
d->attentionRequested = element.firstChildElement("attention").namespaceURI() == ns_attention;
+ // XEP-0333: Chat Markers
+ QDomElement markableElement = element.firstChildElement("markable");
+ if (!markableElement.isNull())
+ {
+ d->markable = true;
+ }
+ // check for all the marker types
+ QDomElement chatStateElement;
+ QXmppMessage::Marker marker = QXmppMessage::NoMarker;
+ for (int i = Received; i <= Acknowledged; i++)
+ {
+ chatStateElement = element.firstChildElement(marker_types[i]);
+ if (!chatStateElement.isNull() &&
+ chatStateElement.namespaceURI() == ns_chat_markers)
+ {
+ marker = static_cast<QXmppMessage::Marker>(i);
+ break;
+ }
+ }
+ // if marker is present, check it's the right ns
+ if (!chatStateElement.isNull())
+ {
+ if (chatStateElement.namespaceURI() == ns_chat_markers)
+ {
+ d->marker = marker;
+ d->markedId = chatStateElement.attribute("id", QString());
+ d->markedThread = chatStateElement.attribute("thread", QString());
+ }
+ }
+
const QList<QPair<QString, QString> > &knownElems = knownMessageSubelems();
QXmppElementList extensions;
@@ -555,6 +665,22 @@ void QXmppMessage::toXml(QXmlStreamWriter *xmlWriter) const
xmlWriter->writeEndElement();
}
+ // XEP-0333: Chat Markers
+ if (d->markable) {
+ xmlWriter->writeStartElement("markable");
+ xmlWriter->writeAttribute("xmlns", ns_chat_markers);
+ xmlWriter->writeEndElement();
+ }
+ if (d->marker != NoMarker) {
+ xmlWriter->writeStartElement(marker_types[d->marker]);
+ xmlWriter->writeAttribute("xmlns", ns_chat_markers);
+ xmlWriter->writeAttribute("id", d->markedId);
+ if (!d->markedThread.isNull() && !d->markedThread.isEmpty()) {
+ xmlWriter->writeAttribute("thread", d->markedThread);
+ }
+ xmlWriter->writeEndElement();
+ }
+
// other extensions
QXmppStanza::extensionsToXml(xmlWriter);
diff --git a/src/base/QXmppMessage.h b/src/base/QXmppMessage.h
index e927a85c..119dba3e 100644
--- a/src/base/QXmppMessage.h
+++ b/src/base/QXmppMessage.h
@@ -60,8 +60,18 @@ public:
Paused, ///< User had been composing but now has stopped.
};
+ /// This enum describes a chat marker as defined by
+ /// XEP-0333 : Char Markers
+ enum Marker {
+ NoMarker = 0,
+ Received,
+ Displayed,
+ Acknowledged
+ };
+
QXmppMessage(const QString& from = QString(), const QString& to = QString(),
const QString& body = QString(), const QString& thread = QString());
+
QXmppMessage(const QXmppMessage &other);
~QXmppMessage();
@@ -106,6 +116,19 @@ public:
QString xhtml() const;
void setXhtml(const QString &xhtml);
+ // XEP-0333
+ bool isMarkable() const;
+ void setMarkable(const bool);
+
+ QString markedId() const;
+ void setMarkerId(const QString&);
+
+ QString markedThread() const;
+ void setMarkedThread(const QString&);
+
+ Marker marker() const;
+ void setMarker(const Marker);
+
/// \cond
void parse(const QDomElement &element);
void toXml(QXmlStreamWriter *writer) const;
diff --git a/src/client/QXmppDiscoveryManager.cpp b/src/client/QXmppDiscoveryManager.cpp
index 5188a4e7..7c9a777e 100644
--- a/src/client/QXmppDiscoveryManager.cpp
+++ b/src/client/QXmppDiscoveryManager.cpp
@@ -115,7 +115,8 @@ QXmppDiscoveryIq QXmppDiscoveryManager::capabilities()
<< ns_chat_states // XEP-0085: Chat State Notifications
<< ns_capabilities // XEP-0115: Entity Capabilities
<< ns_ping // XEP-0199: XMPP Ping
- << ns_attention; // XEP-0224: Attention
+ << ns_attention // XEP-0224: Attention
+ << ns_chat_markers; // XEP-0333: Chat Markers
foreach(QXmppClientExtension* extension, client()->extensions())
{
diff --git a/tests/qxmppmessage/tst_qxmppmessage.cpp b/tests/qxmppmessage/tst_qxmppmessage.cpp
index 218ff962..1ec4f18b 100644
--- a/tests/qxmppmessage/tst_qxmppmessage.cpp
+++ b/tests/qxmppmessage/tst_qxmppmessage.cpp
@@ -43,6 +43,7 @@ private slots:
void testState();
void testXhtml();
void testSubextensions();
+ void testChatMarkers();
};
void tst_QXmppMessage::testBasic_data()
@@ -331,5 +332,191 @@ void tst_QXmppMessage::testSubextensions()
serializePacket(message, xml);
}
+void tst_QXmppMessage::testChatMarkers()
+{
+ const QByteArray markableXml(
+ "<message "
+ "from='northumberland@shakespeare.lit/westminster' "
+ "id='message-1' "
+ "to='ingrichard@royalty.england.lit/throne'>"
+ "<thread>sleeping</thread>"
+ "<body>My lord, dispatch; read o'er these articles.</body>"
+ "<markable xmlns='urn:xmpp:chat-markers:0'/>"
+ "</message>");
+
+ QXmppMessage markableMessage;
+ parsePacket(markableMessage, markableXml);
+ QCOMPARE(markableMessage.isMarkable(), true);
+ QCOMPARE(markableMessage.marker(), QXmppMessage::NoMarker);
+ QCOMPARE(markableMessage.id(), QString("message-1"));
+ QCOMPARE(markableMessage.markedId(), QString());
+ QCOMPARE(markableMessage.thread(), QString("sleeping"));
+ QCOMPARE(markableMessage.markedThread(), QString());
+
+ const QByteArray receivedXml(
+ "<message "
+ "from='kingrichard@royalty.england.lit/throne' "
+ "id='message-2' "
+ "to='northumberland@shakespeare.lit/westminster'>"
+ "<received xmlns='urn:xmpp:chat-markers:0' "
+ "id='message-1' "
+ "thread='sleeping'/>"
+ "</message>");
+
+ QXmppMessage receivedMessage;
+ parsePacket(receivedMessage, receivedXml);
+ QCOMPARE(receivedMessage.isMarkable(), false);
+ QCOMPARE(receivedMessage.marker(), QXmppMessage::Received);
+ QCOMPARE(receivedMessage.id(), QString("message-2"));
+ QCOMPARE(receivedMessage.markedId(), QString("message-1"));
+ QCOMPARE(receivedMessage.thread(), QString());
+ QCOMPARE(receivedMessage.markedThread(), QString("sleeping"));
+
+ const QByteArray displayedXml(
+ "<message "
+ "from='kingrichard@royalty.england.lit/throne' "
+ "id='message-2' "
+ "to='northumberland@shakespeare.lit/westminster'>"
+ "<displayed xmlns='urn:xmpp:chat-markers:0' "
+ "id='message-1' "
+ "thread='sleeping'/>"
+ "</message>");
+
+ QXmppMessage displayedMessage;
+ parsePacket(displayedMessage, displayedXml);
+ QCOMPARE(displayedMessage.isMarkable(), false);
+ QCOMPARE(displayedMessage.marker(), QXmppMessage::Displayed);
+ QCOMPARE(displayedMessage.id(), QString("message-2"));
+ QCOMPARE(displayedMessage.markedId(), QString("message-1"));
+ QCOMPARE(displayedMessage.thread(), QString());
+ QCOMPARE(displayedMessage.markedThread(), QString("sleeping"));
+
+ const QByteArray acknowledgedXml(
+ "<message "
+ "from='kingrichard@royalty.england.lit/throne' "
+ "id='message-2' "
+ "to='northumberland@shakespeare.lit/westminster'>"
+ "<acknowledged xmlns='urn:xmpp:chat-markers:0' "
+ "id='message-1' "
+ "thread='sleeping'/>"
+ "</message>");
+
+ QXmppMessage acknowledgedMessage;
+ parsePacket(acknowledgedMessage, acknowledgedXml);
+ QCOMPARE(acknowledgedMessage.isMarkable(), false);
+ QCOMPARE(acknowledgedMessage.marker(), QXmppMessage::Acknowledged);
+ QCOMPARE(acknowledgedMessage.id(), QString("message-2"));
+ QCOMPARE(acknowledgedMessage.markedId(), QString("message-1"));
+ QCOMPARE(acknowledgedMessage.thread(), QString());
+ QCOMPARE(acknowledgedMessage.markedThread(), QString("sleeping"));
+
+ const QByteArray emptyThreadXml(
+ "<message "
+ "from='kingrichard@royalty.england.lit/throne' "
+ "id='message-2' "
+ "to='northumberland@shakespeare.lit/westminster'>"
+ "<received xmlns='urn:xmpp:chat-markers:0' "
+ "id='message-1'/>"
+ "</message>");
+
+ QXmppMessage emptyThreadMessage;
+ parsePacket(emptyThreadMessage, emptyThreadXml);
+ QCOMPARE(emptyThreadMessage.isMarkable(), false);
+ QCOMPARE(emptyThreadMessage.marker(), QXmppMessage::Received);
+ QCOMPARE(emptyThreadMessage.id(), QString("message-2"));
+ QCOMPARE(emptyThreadMessage.markedId(), QString("message-1"));
+ QCOMPARE(emptyThreadMessage.thread(), QString());
+ QCOMPARE(emptyThreadMessage.markedThread(), QString());
+
+ const QByteArray notMarkableSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\"/>");
+
+ QXmppMessage serialisationMessage;
+ serialisationMessage.setFrom("kingrichard@royalty.england.lit/throne");
+ serialisationMessage.setTo("northumberland@shakespeare.lit/westminster");
+ serialisationMessage.setId("message-3");
+ serialisationMessage.setMarkable(false);
+ serializePacket(serialisationMessage, notMarkableSerialisation);
+
+ const QByteArray markableSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\">"
+ "<markable xmlns=\"urn:xmpp:chat-markers:0\"/>"
+ "</message>");
+
+ serialisationMessage.setMarkable(true);
+ serializePacket(serialisationMessage, markableSerialisation);
+
+ const QByteArray receivedSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\">"
+ "<received xmlns=\"urn:xmpp:chat-markers:0\" "
+ "id=\"message-2\"/>"
+ "</message>");
+
+ serialisationMessage.setMarkable(false);
+ serialisationMessage.setMarker(QXmppMessage::Received);
+ serialisationMessage.setMarkerId("message-2");
+ serializePacket(serialisationMessage, receivedSerialisation);
+
+ const QByteArray receivedThreadSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\">"
+ "<received xmlns=\"urn:xmpp:chat-markers:0\" "
+ "id=\"message-2\" "
+ "thread=\"sleeping\"/>"
+ "</message>");
+
+ serialisationMessage.setMarker(QXmppMessage::Received);
+ serialisationMessage.setMarkerId("message-2");
+ serialisationMessage.setMarkedThread("sleeping");
+ serializePacket(serialisationMessage, receivedThreadSerialisation);
+
+ const QByteArray displayedThreadSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\">"
+ "<displayed xmlns=\"urn:xmpp:chat-markers:0\" "
+ "id=\"message-2\" "
+ "thread=\"sleeping\"/>"
+ "</message>");
+
+ serialisationMessage.setMarker(QXmppMessage::Displayed);
+ serialisationMessage.setMarkerId("message-2");
+ serialisationMessage.setMarkedThread("sleeping");
+ serializePacket(serialisationMessage, displayedThreadSerialisation);
+
+ const QByteArray acknowledgedThreadSerialisation(
+ "<message "
+ "id=\"message-3\" "
+ "to=\"northumberland@shakespeare.lit/westminster\" "
+ "from=\"kingrichard@royalty.england.lit/throne\" "
+ "type=\"chat\">"
+ "<acknowledged xmlns=\"urn:xmpp:chat-markers:0\" "
+ "id=\"message-2\" "
+ "thread=\"sleeping\"/>"
+ "</message>");
+
+ serialisationMessage.setMarker(QXmppMessage::Acknowledged);
+ serialisationMessage.setMarkerId("message-2");
+ serialisationMessage.setMarkedThread("sleeping");
+ serializePacket(serialisationMessage, acknowledgedThreadSerialisation);
+}
+
QTEST_MAIN(tst_QXmppMessage)
#include "tst_qxmppmessage.moc"