[SCM] ktp-text-ui packaging branch, master, updated. debian/15.12.1-1-1918-gdf4b0ec

Maximiliano Curia maxy at moszumanska.debian.org
Sat May 28 00:24:40 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-text-ui.git;a=commitdiff;h=bdb3229

The following commit has been merged in the master branch:
commit bdb3229a5b5b5cc5173f6f6dbf10438f2590f7bb
Author: Marcin Ziemiński <zieminn at gmail.com>
Date:   Fri Jun 20 13:08:12 2014 +0200

    OTR notification messages handled in chat area as status messages.
---
 lib/chat-widget.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++-----------
 lib/chat-widget.h   |  2 ++
 lib/otr-constants.h | 35 ++++++++++++++++++++++
 lib/otr-utils.cpp   | 53 ++++++++++++++++++++++++++++-----
 lib/otr-utils.h     | 10 ++++++-
 5 files changed, 159 insertions(+), 25 deletions(-)

diff --git a/lib/chat-widget.cpp b/lib/chat-widget.cpp
index 75a970a..374359e 100644
--- a/lib/chat-widget.cpp
+++ b/lib/chat-widget.cpp
@@ -188,9 +188,6 @@ ChatWidget::ChatWidget(const Tp::TextChannelPtr & channel, const Tp::AccountPtr
     // connect channel signals
     setupChannelSignals();
 
-    // setup new otr channel along with connecting to signals
-    setupOtrChannel();
-
     // create contactModel and start keeping track of contacts.
     d->contactModel = new ChannelContactModel(d->channel, this);
     setupContactModelSignals();
@@ -261,6 +258,9 @@ ChatWidget::ChatWidget(const Tp::TextChannelPtr & channel, const Tp::AccountPtr
     m_previousConversationAvailable = d->logManager->exists();
 
     d->notifyFilter = new NotifyFilter(this);
+
+    // setup new otr channel along with connecting to signals
+    setupOtrChannel();
 }
 
 ChatWidget::~ChatWidget()
@@ -646,21 +646,30 @@ bool ChatWidget::isOnTop() const
     return ( isActiveWindow() && isVisible() );
 }
 
-OtrStatus ChatWidget::otrStatus() const {
+OtrStatus ChatWidget::otrStatus() const 
+{
     return d->otrStatus;
 }
 
-void ChatWidget::startOtrSession() {
+void ChatWidget::startOtrSession() 
+{
     if(!d->otrStatus) return;
     d->otrChannel->Initialize();
+    if(d->otrStatus.otrTrustLevel() == Tp::OTRTrustLevelNotPrivate)
+        d->ui.chatArea->addStatusMessage(i18n("Attempting to start a private OTR session with %1", d->contactName));
+    else
+        d->ui.chatArea->addStatusMessage(i18n("Attempting to restart a private OTR session with %1", d->contactName));
 }
 
-void ChatWidget::stopOtrSession() {
+void ChatWidget::stopOtrSession() 
+{
     if(!d->otrStatus) return;
     d->otrChannel->Stop();
+    d->ui.chatArea->addStatusMessage(i18n("Terminating OTR session"));
 }
 
-void ChatWidget::authenticateBuddy() {
+void ChatWidget::authenticateBuddy() 
+{
     if(!d->otrStatus) return;
 
     QVariant fpReply = Tp::Utils::waitForOperation(d->otrChannel->requestPropertyRemoteFingerprint());
@@ -688,7 +697,8 @@ void ChatWidget::authenticateBuddy() {
     }
 }
 
-void ChatWidget::setupOtrChannel() {
+void ChatWidget::setupOtrChannel() 
+{
 
     QString busName = d->channel->connection()->objectPath();
     busName = busName.replace(QChar::fromAscii('/'), QChar::fromAscii('.')).mid(1) + QString::fromLatin1(".OTR");
@@ -704,6 +714,7 @@ void ChatWidget::setupOtrChannel() {
         if(reply.isValid()) {
             Tp::OTRTrustLevel trustLevel = static_cast<Tp::OTRTrustLevel>(reply.value<int>());
             d->otrStatus = OtrStatus(trustLevel);
+            onOTRTrustLevelChanged(trustLevel, trustLevel);
             kDebug() << "Channel: " << d->channel->objectPath() << " implements OTR";
         } else {
             d->otrStatus.otrImplemented = false;
@@ -714,19 +725,46 @@ void ChatWidget::setupOtrChannel() {
     }
 }
 
-void ChatWidget::onOtrChannelPropertiesChanged(QVariantMap props, QStringList /* ignored */) {
+void ChatWidget::onOtrChannelPropertiesChanged(QVariantMap props, QStringList /* ignored */) 
+{
 
     Q_FOREACH(const QString& key, props.keys()) {
         if(key == QString::fromLatin1("TrustLevel")) {
-            d->otrStatus.trustLevel = static_cast<Tp::OTRTrustLevel>(props[key].toInt(0));
-            kDebug() << "Otr status changed for channel: " << d->channel->objectPath() 
-                << " to: " << (int) d->otrStatus.trustLevel;
+            Tp::OTRTrustLevel trustLevel = static_cast<Tp::OTRTrustLevel>(props[key].toInt(0));
+
+            onOTRTrustLevelChanged(trustLevel, d->otrStatus.otrTrustLevel());
+            d->otrStatus.trustLevel = trustLevel;
 
             Q_EMIT(otrStatusChanged(d->otrStatus, this));
+            kDebug() << "Otr status changed for channel: " << d->channel->objectPath() 
+                << " to: " << (int) d->otrStatus.trustLevel;
         }
     }
 }
 
+void ChatWidget::onOTRTrustLevelChanged(Tp::OTRTrustLevel trustLevel, Tp::OTRTrustLevel previous) 
+{
+    switch(trustLevel) {
+        case Tp::OTRTrustLevelUnverified:
+            if(previous == Tp::OTRTrustLevelPrivate) 
+                d->ui.chatArea->addStatusMessage(i18n("The OTR session is unverified now"));
+            else
+                d->ui.chatArea->addStatusMessage(i18n("Unverified OTR session started"));
+            return;
+        case Tp::OTRTrustLevelPrivate:
+            if(previous == Tp::OTRTrustLevelUnverified) 
+                d->ui.chatArea->addStatusMessage(i18n("The OTR session is private now"));
+            else
+                d->ui.chatArea->addStatusMessage(i18n("Private OTR session started"));
+            return;
+        case Tp::OTRTrustLevelFinished:
+            d->ui.chatArea->addStatusMessage(i18n("%1 has ended the OTR session. You should do the same", d->contactName));
+            return;
+
+        default: return;
+    }
+}
+
 void ChatWidget::handleIncomingMessage(const Tp::ReceivedMessage &message, bool alreadyNotified)
 {
     kDebug() << title() << message.text();
@@ -826,13 +864,19 @@ void ChatWidget::handleIncomingMessage(const Tp::ReceivedMessage &message, bool
 
             d->ui.chatArea->addStatusMessage(text, message.sender()->alias(), message.received());
         } else {
-            KTp::Message processedMessage(KTp::MessageProcessor::instance()->processIncomingMessage(message, d->account, d->channel));
 
-            if (!alreadyNotified) {
-                d->notifyFilter->filterMessage(processedMessage,
-                                               KTp::MessageContext(d->account, d->channel));
+            if(Tp::Utils::isOtrEvent(message)) {
+                // TODO use notify filter to present to user when unencrypted message was received
+                d->ui.chatArea->addStatusMessage(Tp::Utils::processOtrMessage(message));
+            } else {
+                KTp::Message processedMessage(KTp::MessageProcessor::instance()->processIncomingMessage(message, d->account, d->channel));
+
+                if (!alreadyNotified) {
+                    d->notifyFilter->filterMessage(processedMessage,
+                                                   KTp::MessageContext(d->account, d->channel));
+                }
+                d->ui.chatArea->addMessage(processedMessage);
             }
-            d->ui.chatArea->addMessage(processedMessage);
         }
 
         //if the window is on top, ack straight away. Otherwise they stay in the message queue for acking when activated..
@@ -872,6 +916,12 @@ void ChatWidget::chatViewReady()
 
 void ChatWidget::sendMessage()
 {
+    if(d->otrStatus && d->otrStatus.trustLevel == Tp::OTRTrustLevelFinished) {
+        d->ui.chatArea->addStatusMessage(i18n("%1 has already closed his/her private connection to you."
+                    "Your message was not sent. Either end your private conversation, or restart it.", d->contactName));
+        return;
+    }
+
     QString message = d->ui.sendMessageBox->toPlainText();
 
     if (!message.isEmpty()) {
diff --git a/lib/chat-widget.h b/lib/chat-widget.h
index 6bb5868..7500c54 100644
--- a/lib/chat-widget.h
+++ b/lib/chat-widget.h
@@ -23,6 +23,7 @@
 
 #include "ktpchat_export.h"
 #include "otr-utils.h"
+#include "otr-types.h"
 
 #include <QtCore/QString>
 #include <QtGui/QWidget>
@@ -228,6 +229,7 @@ private Q_SLOTS:
     void onShareProviderFinishedFailure(ShareProvider *provider, const QString &errorMessage);
     void onSendFileClicked();
     void onOtrChannelPropertiesChanged(QVariantMap props, QStringList ignored);
+    void onOTRTrustLevelChanged(Tp::OTRTrustLevel trustLevel, Tp::OTRTrustLevel previous);
 
 private:
     /** connects necessary signals for the channel */
diff --git a/lib/otr-constants.h b/lib/otr-constants.h
index 66c5b1d..ebbb791 100644
--- a/lib/otr-constants.h
+++ b/lib/otr-constants.h
@@ -1,6 +1,8 @@
 #ifndef OTR_CONSTANTS_HEADER
 #define OTR_CONSTANTS_HEADER
 
+#include <KGlobal>
+
 namespace Tp
 {
     
@@ -49,6 +51,30 @@ enum OTRTrustLevel
  */
 const int NUM_OTR_TRUST_LEVELS = (3+1);
 
+
+/**
+ * OTR message event enum type - the same as OtrlMessageEvent in libotr
+ */
+enum OTRMessageEvent 
+{
+    OTRL_MSGEVENT_NONE,
+    OTRL_MSGEVENT_ENCRYPTION_REQUIRED,
+    OTRL_MSGEVENT_ENCRYPTION_ERROR,
+    OTRL_MSGEVENT_CONNECTION_ENDED,
+    OTRL_MSGEVENT_SETUP_ERROR,
+    OTRL_MSGEVENT_MSG_REFLECTED,
+    OTRL_MSGEVENT_MSG_RESENT,
+    OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE,
+    OTRL_MSGEVENT_RCVDMSG_UNREADABLE,
+    OTRL_MSGEVENT_RCVDMSG_MALFORMED,
+    OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD,
+    OTRL_MSGEVENT_LOG_HEARTBEAT_SENT,
+    OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR,
+    OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED,
+    OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED,
+    OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE
+};
+
 }
 
 /**
@@ -59,4 +85,13 @@ const int NUM_OTR_TRUST_LEVELS = (3+1);
  */
 #define TP_QT_IFACE_CHANNEL_INTERFACE_OTR1 (QLatin1String("org.freedesktop.Telepathy.Channel.Interface.OTR1"))
 
+
+/**
+ * OTR message headers
+ */
+#define OTR_MESSAGE_EVENT_HEADER       (QLatin1String("otr-message-event"))
+#define OTR_REMOTE_FINGERPRINT_HEADER  (QLatin1String("otr-remote-fingerprint"))
+#define OTR_ERROR_HEADER               (QLatin1String("otr-error"))
+#define OTR_UNENCRYPTED_MESSAGE_HEADER (QLatin1String("otr-unencrypted-message"))
+
 #endif
diff --git a/lib/otr-utils.cpp b/lib/otr-utils.cpp
index 6024cf7..55f6604 100644
--- a/lib/otr-utils.cpp
+++ b/lib/otr-utils.cpp
@@ -1,7 +1,9 @@
 #include "otr-utils.h"
+#include "otr-constants.h"
 
 #include <QEventLoop>
 #include <QTimer>
+#include <KLocalizedString>
 
 OtrStatus::OtrStatus() 
     : otrImplemented(false) { }
@@ -9,43 +11,80 @@ OtrStatus::OtrStatus()
 OtrStatus::OtrStatus(Tp::OTRTrustLevel trustLevel) 
     : otrImplemented(true), trustLevel(trustLevel) { }
 
-OtrStatus::operator bool() const {
+OtrStatus::operator bool() const 
+{
     return otrImplemented;
 }
 
-bool OtrStatus::operator!() const {
+bool OtrStatus::operator!() const 
+{
     return !(OtrStatus::operator bool());
 }
 
-bool OtrStatus::operator==(const OtrStatus &other) const {
+bool OtrStatus::operator==(const OtrStatus &other) const 
+{
 
     if(otrImplemented != other.otrImplemented) return false;
     else if(otrImplemented) return trustLevel == other.trustLevel;
     else return true;
 }
 
-bool OtrStatus::operator!=(const OtrStatus &other) const {
+bool OtrStatus::operator!=(const OtrStatus &other) const 
+{
     return !(*this == other);
 }
 
-Tp::OTRTrustLevel OtrStatus::otrTrustLevel() const {
+Tp::OTRTrustLevel OtrStatus::otrTrustLevel() const 
+{
     return trustLevel;
 }
 
 namespace Tp {
 namespace Utils {
 
-    QVariant waitForOperation(const Tp::PendingVariant *pendingVariant) {
+    QVariant waitForOperation(const Tp::PendingVariant *pendingVariant, int timeout) 
+    {
         QEventLoop loop;
         QTimer timer;
         timer.setSingleShot(true);
         loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
         loop.connect(pendingVariant, SIGNAL(finished(Tp::PendingOperation*)), &loop, SLOT(quit()));
-        timer.start(3000); // 3s
+        timer.start(timeout); // 3s
         loop.exec();
 
         if(timer.isActive()) timer.stop();
         return pendingVariant->result();
     }
+
+    bool isOtrEvent(const Tp::ReceivedMessage &message) 
+    {
+        return message.part(0).contains(OTR_MESSAGE_EVENT_HEADER);
+    }
+
+    QString processOtrMessage(const Tp::ReceivedMessage &message) 
+    {
+        Tp::MessagePart messagePart = message.part(0);
+        OTRMessageEvent otrEvent = static_cast<OTRMessageEvent>(
+                messagePart[OTR_MESSAGE_EVENT_HEADER].variant().toUInt(0));
+
+        switch(otrEvent) {
+
+            case Tp::OTRL_MSGEVENT_SETUP_ERROR:
+            case Tp::OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR:
+                {
+                    QString otrError = messagePart[OTR_ERROR_HEADER].variant().toString();
+                    return i18n("OTR error: %1", otrError);
+                }
+
+            case Tp::OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED:
+                {
+                    QString unencryptedMessage = messagePart[OTR_UNENCRYPTED_MESSAGE_HEADER].variant().toString();
+                    return i18n("Received unencrypted message: [%1]", unencryptedMessage); 
+                }
+
+            default:
+                return message.text();
+        }
+    }
 }
 }
diff --git a/lib/otr-utils.h b/lib/otr-utils.h
index 13fe7b7..040542f 100644
--- a/lib/otr-utils.h
+++ b/lib/otr-utils.h
@@ -4,6 +4,7 @@
 #include "otr-constants.h"
 #include <ktpchat_export.h>
 #include <TelepathyQt/PendingVariant>
+#include <TelepathyQt/Message>
 
 class KDE_TELEPATHY_CHAT_EXPORT OtrStatus 
 {
@@ -33,7 +34,14 @@ class KDE_TELEPATHY_CHAT_EXPORT OtrStatus
 namespace Tp {
 namespace Utils {
 
-    QVariant waitForOperation(const Tp::PendingVariant *pendingVariant);
+    /** Makes a block on pending operation with timout and returns its result */
+    QVariant waitForOperation(const Tp::PendingVariant *pendingVariant, int timout = 3000);
+
+    /** Returns true if message is generated internally by OTR implementation */
+    bool isOtrEvent(const Tp::ReceivedMessage &message);
+
+    /** Returns notification for a user assuming that the message is an otr event */
+    QString processOtrMessage(const Tp::ReceivedMessage &message);
 }
 }
 

-- 
ktp-text-ui packaging



More information about the pkg-kde-commits mailing list