summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/MessageSnippet.cpp5
-rw-r--r--Swift/QtUI/MessageSnippet.h2
-rw-r--r--Swift/QtUI/QtChatView.cpp9
-rw-r--r--Swift/QtUI/QtChatView.h1
-rw-r--r--Swift/QtUI/QtChatWindow.cpp24
-rw-r--r--Swift/QtUI/QtChatWindow.h10
-rw-r--r--Swift/QtUI/Swift.qrc1
7 files changed, 40 insertions, 12 deletions
diff --git a/Swift/QtUI/MessageSnippet.cpp b/Swift/QtUI/MessageSnippet.cpp
index 0159386..1c8ddca 100644
--- a/Swift/QtUI/MessageSnippet.cpp
+++ b/Swift/QtUI/MessageSnippet.cpp
@@ -11,7 +11,7 @@
namespace Swift {
-MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme) : ChatSnippet(appendToPrevious) {
+MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id) : ChatSnippet(appendToPrevious) {
if (isIncoming) {
if (appendToPrevious) {
content_ = theme->getIncomingNextContent();
@@ -29,10 +29,11 @@ MessageSnippet::MessageSnippet(const QString& message, const QString& sender, co
}
}
- content_.replace("%message%", "<span class='swift_message'>" + escape(message) + "</span>");
+ content_.replace("%message%", "<span class='swift_ack'></span><span class='swift_message'>" + escape(message) + "</span>");
content_.replace("%sender%", escape(sender));
content_.replace("%time%", "<span class='swift_time'>" + escape(time.toString("h:mm")) + "</span>");
content_.replace("%userIconPath%", escape(iconURI));
+ content_ = "<div id='" + id + "'>" + content_ + "</div>";
}
MessageSnippet::~MessageSnippet() {
diff --git a/Swift/QtUI/MessageSnippet.h b/Swift/QtUI/MessageSnippet.h
index 4918c19..c7425e9 100644
--- a/Swift/QtUI/MessageSnippet.h
+++ b/Swift/QtUI/MessageSnippet.h
@@ -15,7 +15,7 @@ class QDateTime;
namespace Swift {
class MessageSnippet : public ChatSnippet {
public:
- MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme);
+ MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id);
virtual ~MessageSnippet();
const QString& getContent() const {
return content_;
diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index d48365b..145371f 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -129,6 +129,15 @@ void QtChatView::copySelectionToClipboard() {
}
}
+void QtChatView::setAckXML(const QString& id, const QString& xml) {
+ QWebElement message = document_.findFirst("#" + id);
+ /* Deliberately not asserting here, so that when we start expiring old messages it won't hit us */
+ if (message.isNull()) return;
+ QWebElement ackElement = message.findFirst("span.swift_ack");
+ assert(!ackElement.isNull());
+ ackElement.setInnerXml(xml);
+}
+
bool QtChatView::isScrolledToBottom() const {
return webPage_->mainFrame()->scrollBarValue(Qt::Vertical) == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical);
}
diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h
index ce1f8bc..e60c92f 100644
--- a/Swift/QtUI/QtChatView.h
+++ b/Swift/QtUI/QtChatView.h
@@ -31,6 +31,7 @@ namespace Swift {
void replaceLastMessage(const QString& newMessage);
void replaceLastMessage(const QString& newMessage, const QString& note);
bool isScrolledToBottom() const;
+ void setAckXML(const QString& id, const QString& xml);
signals:
void gotFocus();
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 70bde4b..2955ee4 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -245,11 +245,11 @@ void QtChatWindow::updateTitleWithUnreadCount() {
emit titleUpdated();
}
-void QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
- addMessage(message, senderName, senderIsSelf, label, avatarPath, "", time);
+String QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
+ return addMessage(message, senderName, senderIsSelf, label, avatarPath, "", time);
}
-void QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const QString& style, const boost::posix_time::ptime& time) {
+String QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const QString& style, const boost::posix_time::ptime& time) {
if (isWidgetSelected()) {
onAllMessagesRead();
}
@@ -268,20 +268,32 @@ void QtChatWindow::addMessage(const String &message, const String &senderName, b
bool appendToPrevious = !previousMessageWasSystem_ && !previousMessageWasPresence_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName)));
QString qAvatarPath = avatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(P2QSTRING(avatarPath)).toEncoded();
- messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_)));
+ String id = id_.generateID();
+ messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
previousMessageWasSelf_ = senderIsSelf;
previousSenderName_ = P2QSTRING(senderName);
previousMessageWasSystem_ = false;
previousMessageWasPresence_ = false;
+ return id;
+}
+
+void QtChatWindow::setAckState(String const& id, ChatWindow::AckState state) {
+ QString xml;
+ switch (state) {
+ case ChatWindow::Pending: xml = "<img src='qrc:/icons/throbber.gif' alt='This message has not been received by your server yet.'/>"; break;
+ case ChatWindow::Received: xml = ""; break;
+ case ChatWindow::Failed: xml = "<img src='qrc:/icons/error.png' alt='This message may not have been transmitted.'/>"; break;
+ }
+ messageLog_->setAckXML(P2QSTRING(id), xml);
}
int QtChatWindow::getCount() {
return unreadCount_;
}
-void QtChatWindow::addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
- addMessage(" *" + message + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time);
+String QtChatWindow::addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
+ return addMessage(" *" + message + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time);
}
void QtChatWindow::addErrorMessage(const String& errorMessage) {
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index a51b866..333aa44 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -11,6 +11,8 @@
#include "QtTabbable.h"
+#include "Swiften/Base/IDGenerator.h"
+
class QTextEdit;
class QLineEdit;
class QComboBox;
@@ -28,8 +30,8 @@ namespace Swift {
public:
QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream);
~QtChatWindow();
- void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
- void addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
+ String addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
+ String addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
void addSystemMessage(const String& message);
void addPresenceMessage(const String& message);
void addErrorMessage(const String& errorMessage);
@@ -50,6 +52,7 @@ namespace Swift {
void setTabComplete(TabComplete* completer);
int getCount();
void replaceLastMessage(const String& message);
+ void setAckState(const String& id, AckState state);
signals:
void geometryChanged();
@@ -71,7 +74,7 @@ namespace Swift {
private:
void updateTitleWithUnreadCount();
void tabComplete();
- void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const QString& style, const boost::posix_time::ptime& time);
+ String addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const QString& style, const boost::posix_time::ptime& time);
int unreadCount_;
bool contactIsTyping_;
@@ -90,6 +93,7 @@ namespace Swift {
bool inputClearing_;
UIEventStream* eventStream_;
bool inputEnabled_;
+ IDGenerator id_;
};
}
diff --git a/Swift/QtUI/Swift.qrc b/Swift/QtUI/Swift.qrc
index 4da687c..6c8e027 100644
--- a/Swift/QtUI/Swift.qrc
+++ b/Swift/QtUI/Swift.qrc
@@ -10,6 +10,7 @@
<file alias="icons/offline.png">../resources/icons/offline.png</file>
<file alias="icons/certificate.png">../resources/icons/certificate.png</file>
<file alias="icons/error.png">../resources/icons/error.png</file>
+ <file alias="icons/throbber.gif">../resources/icons/throbber.gif</file>
<file alias="icons/avatar.png">../resources/icons/avatar.png</file>
<file alias="icons/tray-standard.png">../resources/icons/tray-standard.png</file>
<file alias="icons/new-chat.png">../resources/icons/new-chat.png</file>