diff options
Diffstat (limited to 'Swift/QtUI')
-rw-r--r-- | Swift/QtUI/MessageSnippet.cpp | 5 | ||||
-rw-r--r-- | Swift/QtUI/MessageSnippet.h | 2 | ||||
-rw-r--r-- | Swift/QtUI/QtChatView.cpp | 9 | ||||
-rw-r--r-- | Swift/QtUI/QtChatView.h | 1 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 24 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.h | 10 | ||||
-rw-r--r-- | Swift/QtUI/Swift.qrc | 1 |
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> |