diff options
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/Controllers/ChatController.cpp | 6 | ||||
-rw-r--r-- | Swift/Controllers/ChatControllerBase.cpp | 14 | ||||
-rw-r--r-- | Swift/Controllers/ChatControllerBase.h | 1 | ||||
-rw-r--r-- | Swift/Controllers/MUCController.cpp | 4 | ||||
-rw-r--r-- | Swift/Controllers/MainController.cpp | 2 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h (renamed from Swift/Controllers/ChatWindow.h) | 1 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindowFactory.h (renamed from Swift/Controllers/ChatWindowFactory.h) | 0 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.h | 3 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.h | 2 |
10 files changed, 26 insertions, 11 deletions
diff --git a/Swift/Controllers/ChatController.cpp b/Swift/Controllers/ChatController.cpp index 90e5567..c4f45d8 100644 --- a/Swift/Controllers/ChatController.cpp +++ b/Swift/Controllers/ChatController.cpp @@ -1,72 +1,72 @@ #include "Swift/Controllers/ChatController.h" #include <boost/bind.hpp> #include "Swiften/Avatars/AvatarManager.h" -#include "Swift/Controllers/ChatWindow.h" -#include "Swift/Controllers/ChatWindowFactory.h" +#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swift/Controllers/NickResolver.h" namespace Swift { /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager) : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager) { nickResolver_ = nickResolver; presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1, _2)); chatWindow_->setName(nickResolver_->jidToNick(toJID_)); } bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) { return false; } void ChatController::preHandleIncomingMessage(boost::shared_ptr<Message> message) { JID from = message->getFrom(); if (!from.equals(toJID_, JID::WithResource)) { if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){ toJID_ = from; } } } void ChatController::postSendMessage(const String& body) { - chatWindow_->addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), String(avatarManager_->getAvatarPath(selfJID_).string())); + addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), String(avatarManager_->getAvatarPath(selfJID_).string())); } String ChatController::senderDisplayNameFromMessage(const JID& from) { return nickResolver_->jidToNick(from); } String ChatController::getStatusChangeString(boost::shared_ptr<Presence> presence) { String nick = senderDisplayNameFromMessage(presence->getFrom()); if (presence->getType() == Presence::Unavailable) { return nick + " has gone offline."; } else if (presence->getType() == Presence::Available) { StatusShow::Type show = presence->getShow(); if (show == StatusShow::Online || show == StatusShow::FFC) { return nick + " has become available."; } else if (show == StatusShow::Away || show == StatusShow::XA) { return nick + " has gone away."; } else if (show == StatusShow::DND) { return nick + " is now busy."; } } return ""; } void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> previousPresence) { if (!(toJID_.isBare() && newPresence->getFrom().equals(toJID_, JID::WithoutResource)) && newPresence->getFrom() != toJID_) { return; } String newStatusChangeString = getStatusChangeString(newPresence); if (!previousPresence || newStatusChangeString != getStatusChangeString(previousPresence)) { chatWindow_->addSystemMessage(newStatusChangeString); } } } diff --git a/Swift/Controllers/ChatControllerBase.cpp b/Swift/Controllers/ChatControllerBase.cpp index 2b873f1..3e1ce5e 100644 --- a/Swift/Controllers/ChatControllerBase.cpp +++ b/Swift/Controllers/ChatControllerBase.cpp @@ -1,146 +1,154 @@ #include "Swift/Controllers/ChatControllerBase.h" #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include "Swiften/Client/StanzaChannel.h" #include "Swiften/Base/foreach.h" -#include "Swift/Controllers/ChatWindow.h" -#include "Swift/Controllers/ChatWindowFactory.h" +#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h" #include "Swiften/Avatars/AvatarManager.h" namespace Swift { ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager) { chatWindow_ = chatWindowFactory_->createChatWindow(toJID); chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this)); chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1)); setEnabled(stanzaChannel->isAvailable() && iqRouter->isAvailable()); } ChatControllerBase::~ChatControllerBase() { delete chatWindow_; } void ChatControllerBase::setEnabled(bool enabled) { chatWindow_->setInputEnabled(enabled); } void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabels)) { chatWindow_->setSecurityLabelsEnabled(true); chatWindow_->setSecurityLabelsError(); boost::shared_ptr<GetSecurityLabelsCatalogRequest> request(new GetSecurityLabelsCatalogRequest(JID(toJID_.toBare()), iqRouter_)); request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2)); request->send(); labelsEnabled_ = true; } else { chatWindow_->setSecurityLabelsEnabled(false); labelsEnabled_ = false; } } void ChatControllerBase::handleAllMessagesRead() { foreach (boost::shared_ptr<MessageEvent> messageEvent, unreadMessages_) { messageEvent->read(); } unreadMessages_.clear(); chatWindow_->setUnreadMessageCount(0); } void ChatControllerBase::handleSendMessageRequest(const String &body) { if (!stanzaChannel_->isAvailable() || body.isEmpty()) { return; } boost::shared_ptr<Message> message(new Message()); message->setTo(toJID_); message->setType(Swift::Message::Chat); message->setBody(body); boost::optional<SecurityLabel> label; if (labelsEnabled_) { message->addPayload(boost::shared_ptr<SecurityLabel>(new SecurityLabel(chatWindow_->getSelectedSecurityLabel()))); label = boost::optional<SecurityLabel>(chatWindow_->getSelectedSecurityLabel()); } preSendMessageRequest(message); stanzaChannel_->sendMessage(message); postSendMessage(message->getBody()); } void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, const boost::optional<ErrorPayload>& error) { if (!error) { if (catalog->getLabels().size() == 0) { chatWindow_->setSecurityLabelsEnabled(false); labelsEnabled_ = false; } else { chatWindow_->setAvailableSecurityLabels(catalog->getLabels()); chatWindow_->setSecurityLabelsEnabled(true); } } else { chatWindow_->setSecurityLabelsError(); } } void ChatControllerBase::showChatWindow() { chatWindow_->show(); } void ChatControllerBase::activateChatWindow() { chatWindow_->activate(); } +void ChatControllerBase::addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) { + if (message.beginsWith("/me ")) { + chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath); + } else { + chatWindow_->addAction(message, senderName, senderIsSelf, label, avatarPath); + } +} + void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { unreadMessages_.push_back(messageEvent); chatWindow_->setUnreadMessageCount(unreadMessages_.size()); boost::shared_ptr<Message> message = messageEvent->getStanza(); preHandleIncomingMessage(message); String body = message->getBody(); if (message->isError()) { String errorMessage = getErrorMessage(message->getPayload<ErrorPayload>()); chatWindow_->addErrorMessage(errorMessage); } else { showChatWindow(); boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>(); boost::optional<SecurityLabel> maybeLabel = label ? boost::optional<SecurityLabel>(*label) : boost::optional<SecurityLabel>(); JID from = message->getFrom(); - chatWindow_->addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), maybeLabel, String(avatarManager_->getAvatarPath(from).string())); + addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), maybeLabel, String(avatarManager_->getAvatarPath(from).string())); } } String ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) { String defaultMessage = "Error sending message"; if (!error->getText().isEmpty()) { return error->getText(); } else { switch (error->getCondition()) { case ErrorPayload::BadRequest: return defaultMessage; break; case ErrorPayload::Conflict: return defaultMessage; break; case ErrorPayload::FeatureNotImplemented: return defaultMessage; break; case ErrorPayload::Forbidden: return defaultMessage; break; case ErrorPayload::Gone: return "Recipient can no longer be contacted"; break; case ErrorPayload::InternalServerError: return "Internal server error"; break; case ErrorPayload::ItemNotFound: return defaultMessage; break; case ErrorPayload::JIDMalformed: return defaultMessage; break; case ErrorPayload::NotAcceptable: return "Message was rejected"; break; case ErrorPayload::NotAllowed: return defaultMessage; break; case ErrorPayload::NotAuthorized: return defaultMessage; break; case ErrorPayload::PaymentRequired: return defaultMessage; break; case ErrorPayload::RecipientUnavailable: return "Recipient is unavailable."; break; case ErrorPayload::Redirect: return defaultMessage; break; case ErrorPayload::RegistrationRequired: return defaultMessage; break; case ErrorPayload::RemoteServerNotFound: return "Recipient's server not found."; break; case ErrorPayload::RemoteServerTimeout: return defaultMessage; break; case ErrorPayload::ResourceConstraint: return defaultMessage; break; case ErrorPayload::ServiceUnavailable: return defaultMessage; break; case ErrorPayload::SubscriptionRequired: return defaultMessage; break; case ErrorPayload::UndefinedCondition: return defaultMessage; break; case ErrorPayload::UnexpectedRequest: return defaultMessage; break; } } return defaultMessage; } } diff --git a/Swift/Controllers/ChatControllerBase.h b/Swift/Controllers/ChatControllerBase.h index c780789..abf0116 100644 --- a/Swift/Controllers/ChatControllerBase.h +++ b/Swift/Controllers/ChatControllerBase.h @@ -1,65 +1,66 @@ #ifndef SWIFTEN_ChatControllerBase_H #define SWIFTEN_ChatControllerBase_H #include <map> #include <vector> #include <boost/shared_ptr.hpp> #include <boost/signals.hpp> #include <boost/filesystem.hpp> #include "Swiften/Base/String.h" #include "Swiften/Elements/DiscoInfo.h" #include "Swiften/Events/MessageEvent.h" #include "Swiften/JID/JID.h" #include "Swiften/Elements/SecurityLabelsCatalog.h" #include "Swiften/Elements/ErrorPayload.h" #include "Swiften/Presence/PresenceOracle.h" #include "Swiften/Queries/IQRouter.h" namespace Swift { class IQRouter; class StanzaChannel; class ChatWindow; class ChatWindowFactory; class AvatarManager; class ChatControllerBase { public: virtual ~ChatControllerBase(); void showChatWindow(); void activateChatWindow(); void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); + void addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath); void setEnabled(bool enabled); void setToJID(const JID& jid) {toJID_ = jid;}; protected: ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager); virtual void postSendMessage(const String&) {}; virtual String senderDisplayNameFromMessage(const JID& from) = 0; virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0; virtual void preHandleIncomingMessage(boost::shared_ptr<Message>) {}; virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}; private: void handleSendMessageRequest(const String &body); void handleAllMessagesRead(); void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, const boost::optional<ErrorPayload>& error); String getErrorMessage(boost::shared_ptr<ErrorPayload>); protected: JID selfJID_; std::vector<boost::shared_ptr<MessageEvent> > unreadMessages_; StanzaChannel* stanzaChannel_; IQRouter* iqRouter_; ChatWindowFactory* chatWindowFactory_; ChatWindow* chatWindow_; JID toJID_; bool labelsEnabled_; PresenceOracle* presenceOracle_; AvatarManager* avatarManager_; }; } #endif diff --git a/Swift/Controllers/MUCController.cpp b/Swift/Controllers/MUCController.cpp index 4d0acca..c85fffa 100644 --- a/Swift/Controllers/MUCController.cpp +++ b/Swift/Controllers/MUCController.cpp @@ -1,55 +1,55 @@ #include "Swift/Controllers/MUCController.h" #include <boost/bind.hpp> #include "Swiften/Base/foreach.h" -#include "Swift/Controllers/ChatWindow.h" -#include "Swift/Controllers/ChatWindowFactory.h" +#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swiften/Avatars/AvatarManager.h" #include "Swiften/MUC/MUC.h" #include "Swiften/Client/StanzaChannel.h" #include "Swiften/Roster/Roster.h" #include "Swiften/Roster/SetAvatar.h" #include "Swiften/Roster/SetPresence.h" #include "Swiften/Roster/TreeWidgetFactory.h" namespace Swift { /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ MUCController::MUCController ( const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager) : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager), muc_(new MUC(stanzaChannel, presenceSender, muc)), nick_(nick), treeWidgetFactory_(treeWidgetFactory) { roster_ = new Roster(chatWindow_->getTreeWidget(), treeWidgetFactory_); chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); muc_->joinAs(nick); muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); chatWindow_->convertToMUC(); chatWindow_->show(); if (avatarManager_ != NULL) { avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1, _2)); } } MUCController::~MUCController() { delete muc_; delete roster_; } void MUCController::handleAvatarChanged(const JID& jid, const String&) { String path = avatarManager_->getAvatarPath(jid).string(); diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 946b7d0..3fd0764 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -1,59 +1,59 @@ #include "Swift/Controllers/MainController.h" #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include <boost/shared_ptr.hpp> #include <stdlib.h> #include "Swiften/Application/Application.h" #include "Swiften/Application/ApplicationMessageDisplay.h" #include "Swift/Controllers/ChatController.h" -#include "Swift/Controllers/ChatWindowFactory.h" +#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swift/Controllers/ChatsManager.h" #include "Swift/Controllers/EventController.h" #include "Swift/Controllers/UIInterfaces/LoginWindow.h" #include "Swift/Controllers/UIInterfaces/LoginWindowFactory.h" #include "Swift/Controllers/MainWindow.h" #include "Swift/Controllers/MainWindowFactory.h" #include "Swift/Controllers/MUCController.h" #include "Swift/Controllers/NickResolver.h" #include "Swift/Controllers/ProfileSettingsProvider.h" #include "Swift/Controllers/RosterController.h" #include "Swift/Controllers/SoundEventController.h" #include "Swift/Controllers/SoundPlayer.h" #include "Swift/Controllers/SystemTray.h" #include "Swift/Controllers/SystemTrayController.h" #include "Swift/Controllers/XMLConsoleController.h" #include "Swift/Controllers/XMPPRosterController.h" #include "Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" #include "Swiften/Base/foreach.h" #include "Swiften/Base/String.h" #include "Swiften/Client/Client.h" #include "Swiften/Presence/PresenceSender.h" #include "Swiften/Elements/Presence.h" #include "Swiften/Elements/VCardUpdate.h" #include "Swiften/Queries/Responders/SoftwareVersionResponder.h" #include "Swiften/Roster/TreeWidgetFactory.h" #include "Swiften/Settings/SettingsProvider.h" #include "Swiften/Elements/DiscoInfo.h" #include "Swiften/Queries/Responders/DiscoInfoResponder.h" #include "Swiften/Disco/CapsInfoGenerator.h" #include "Swiften/Queries/Requests/GetDiscoInfoRequest.h" #include "Swiften/Queries/Requests/GetVCardRequest.h" #include "Swiften/Avatars/AvatarFileStorage.h" #include "Swiften/Avatars/AvatarManager.h" #include "Swiften/StringCodecs/SHA1.h" #include "Swiften/StringCodecs/Hexify.h" namespace Swift { static const String CLIENT_NAME = "Swift"; static const String CLIENT_VERSION = "0.3"; static const String CLIENT_NODE = "http://swift.im"; MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory *treeWidgetFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory) : timerFactory_(&boostIOServiceThread_.getIOService()), idleDetector_(&idleQuerier_, &timerFactory_, 100), client_(NULL), presenceSender_(NULL), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), treeWidgetFactory_(treeWidgetFactory), settings_(settings), xmppRosterController_(NULL), rosterController_(NULL), loginWindow_(NULL), clientVersionResponder_(NULL), nickResolver_(NULL), discoResponder_(NULL) { application_ = application; presenceOracle_ = NULL; diff --git a/Swift/Controllers/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index db1e9e3..59c3152 100644 --- a/Swift/Controllers/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -1,43 +1,44 @@ #ifndef SWIFTEN_CHATWINDOW_H #define SWIFTEN_CHATWINDOW_H #include <boost/optional.hpp> #include <boost/signals.hpp> #include <boost/shared_ptr.hpp> #include <vector> #include "Swiften/Base/String.h" #include "Swiften/Elements/SecurityLabel.h" namespace Swift { class AvatarManager; class TreeWidget; class ChatWindow { public: ChatWindow() {} virtual ~ChatWindow() {}; virtual void addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) = 0; + virtual void addAction(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) = 0; virtual void addSystemMessage(const String& message) = 0; virtual void addErrorMessage(const String& message) = 0; virtual void setName(const String& name) = 0; virtual void show() = 0; virtual void activate() = 0; virtual void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) = 0; virtual void setSecurityLabelsEnabled(bool enabled) = 0; virtual void setUnreadMessageCount(int count) = 0; virtual void convertToMUC() = 0; virtual TreeWidget *getTreeWidget() = 0; virtual void setSecurityLabelsError() = 0; virtual SecurityLabel getSelectedSecurityLabel() = 0; virtual void setInputEnabled(bool enabled) = 0; boost::signal<void ()> onClosed; boost::signal<void ()> onAllMessagesRead; boost::signal<void (const String&)> onSendMessageRequest; }; } #endif diff --git a/Swift/Controllers/ChatWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h index c55ddba..c55ddba 100644 --- a/Swift/Controllers/ChatWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 831dbfd..e982b21 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -127,90 +127,94 @@ void QtChatWindow::setInputEnabled(bool enabled) { void QtChatWindow::showEvent(QShowEvent* event) { emit windowOpening(); QWidget::showEvent(event); } void QtChatWindow::setUnreadMessageCount(int count) { unreadCount_ = count; updateTitleWithUnreadCount(); } bool QtChatWindow::isWidgetAlerting() { return unreadCount_ > 0; } void QtChatWindow::setName(const String& name) { contact_ = P2QSTRING(name); updateTitleWithUnreadCount(); } void QtChatWindow::updateTitleWithUnreadCount() { setWindowTitle(unreadCount_ > 0 ? QString("(%1) %2").arg(unreadCount_).arg(contact_) : contact_); emit titleUpdated(); } void QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) { if (isWidgetSelected()) { onAllMessagesRead(); } QString htmlString; if (label) { htmlString = QString("<span style=\"border: thin dashed grey; padding-left: .5em; padding-right: .5em; color: %1; background-color: %2; font-size: 90%; margin-right: .5em; \">").arg(Qt::escape(P2QSTRING(label->getForegroundColor()))).arg(Qt::escape(P2QSTRING(label->getBackgroundColor()))); htmlString += QString("%3</span> ").arg(Qt::escape(P2QSTRING(label->getDisplayMarking()))); } QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML.replace("\n","<br/>"); messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML))); htmlString += messageHTML; bool appendToPrevious = !previousMessageWasSystem_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName))); QString qAvatarPath = avatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(P2QSTRING(avatarPath)).toEncoded(); messageLog_->addMessage(MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), QDateTime::currentDateTime(), qAvatarPath, senderIsSelf, appendToPrevious)); previousMessageWasSelf_ = senderIsSelf; previousSenderName_ = P2QSTRING(senderName); previousMessageWasSystem_ = false; } +void QtChatWindow::addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) { + addMessage(message, senderName, senderIsSelf, label, avatarPath); +} + void QtChatWindow::addErrorMessage(const String& errorMessage) { if (isWidgetSelected()) { onAllMessagesRead(); } QString errorMessageHTML(Qt::escape(P2QSTRING(errorMessage))); errorMessageHTML.replace("\n","<br/>"); messageLog_->addMessage(SystemMessageSnippet(QString("<span class=\"error\">%1</span>").arg(errorMessageHTML), QDateTime::currentDateTime(),previousMessageWasSystem_)); previousMessageWasSelf_ = false; previousMessageWasSystem_ = true; } void QtChatWindow::addSystemMessage(const String& message) { if (isWidgetSelected()) { onAllMessagesRead(); } QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML.replace("\n","<br/>"); messageLog_->addMessage(SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(),previousMessageWasSystem_)); previousMessageWasSelf_ = false; previousMessageWasSystem_ = true; } void QtChatWindow::returnPressed() { onSendMessageRequest(Q2PSTRING(input_->toPlainText())); messageLog_->scrollToBottom(); input_->clear(); } void QtChatWindow::show() { QWidget::show(); emit windowOpening(); } void QtChatWindow::activate() { emit wantsToActivate(); } } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index b743aaf..e147fb8 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -1,64 +1,65 @@ #ifndef SWIFT_QtChatWindow_H #define SWIFT_QtChatWindow_H -#include "Swift/Controllers/ChatWindow.h" +#include "Swift/Controllers/UIInterfaces/ChatWindow.h" #include "QtTabbable.h" class QTextEdit; class QLineEdit; class QComboBox; namespace Swift { class QtChatView; class QtTreeWidget; class QtTreeWidgetFactory; class TreeWidget; class QtTextEdit; class QtChatWindow : public QtTabbable, public ChatWindow { Q_OBJECT public: QtChatWindow(const QString &contact, QtTreeWidgetFactory* treeWidgetFactory); ~QtChatWindow(); void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath); + void addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath); void addSystemMessage(const String& message); void addErrorMessage(const String& errorMessage); void show(); void activate(); void setUnreadMessageCount(int count); void convertToMUC(); TreeWidget *getTreeWidget(); void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels); void setSecurityLabelsEnabled(bool enabled); void setSecurityLabelsError(); SecurityLabel getSelectedSecurityLabel(); void setName(const String& name); void setInputEnabled(bool enabled); virtual bool isWidgetAlerting(); protected slots: void qAppFocusChanged(QWidget* old, QWidget* now); void closeEvent(QCloseEvent* event); protected: void showEvent(QShowEvent* event); private slots: void returnPressed(); private: void updateTitleWithUnreadCount(); int unreadCount_; QString contact_; QtChatView *messageLog_; QtTextEdit* input_; QComboBox *labelsWidget_; QtTreeWidget *treeWidget_; std::vector<SecurityLabel> availableLabels_; bool previousMessageWasSelf_; bool previousMessageWasSystem_; QString previousSenderName_; }; } #endif diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h index 0c8a092..51db3db 100644 --- a/Swift/QtUI/QtChatWindowFactory.h +++ b/Swift/QtUI/QtChatWindowFactory.h @@ -1,27 +1,27 @@ #ifndef SWIFT_QtChatWindowFactory_H #define SWIFT_QtChatWindowFactory_H -#include "Swift/Controllers/ChatWindowFactory.h" +#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swiften/JID/JID.h" #include "QtSettingsProvider.h" #include <QObject> #include <QSplitter> namespace Swift { class QtTreeWidgetFactory; class QtChatTabs; class QtChatWindowFactory : public QObject, public ChatWindowFactory { Q_OBJECT public: QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory, QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs); ChatWindow* createChatWindow(const JID &contact); private slots: void handleWindowGeometryChanged(); private: QtTreeWidgetFactory* treeWidgetFactory_; QtSettingsProvider* settings_; QtChatTabs* tabs_; }; } #endif |