[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