diff options
| author | Richard Maudsley <richard.maudsley@isode.com> | 2014-05-02 15:57:31 (GMT) |
|---|---|---|
| committer | Swift Review <review@swift.im> | 2014-05-26 19:33:36 (GMT) |
| commit | bf3739c75fcb312a99608488c8741e2ffc15ca1e (patch) | |
| tree | 0eb8697735f82bc33e2e8e59770f7ecfe4bbc8ac /Swift | |
| parent | d9bd353dc90008bd8d723630ec9c037a3c1f5ad2 (diff) | |
| download | swift-contrib-bf3739c75fcb312a99608488c8741e2ffc15ca1e.zip swift-contrib-bf3739c75fcb312a99608488c8741e2ffc15ca1e.tar.bz2 | |
Allow bookmarking of MUCs from cog menu.
Change-Id: I55f696c98598ec9bfd1ac13a2abd3c1ee2b1e9fa
Diffstat (limited to 'Swift')
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 9 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 3 | ||||
| -rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h | 5 | ||||
| -rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 3 | ||||
| -rw-r--r-- | Swift/QtUI/QtAddBookmarkWindow.cpp | 6 | ||||
| -rw-r--r-- | Swift/QtUI/QtAddBookmarkWindow.h | 3 | ||||
| -rw-r--r-- | Swift/QtUI/QtBookmarkDetailWindow.cpp | 26 | ||||
| -rw-r--r-- | Swift/QtUI/QtBookmarkDetailWindow.h | 5 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 10 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.h | 1 |
10 files changed, 64 insertions, 7 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index df99368..cb2616c 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -61,70 +61,71 @@ MUCController::MUCController ( IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* uiEventStream, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ChatMessageParser* chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager) : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false) { parting_ = true; joined_ = false; lastWasPresence_ = false; shouldJoinOnReconnect_ = true; doneGettingHistory_ = false; events_ = uiEventStream; xmppRoster_ = roster; roster_ = new Roster(false, true); rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource); completer_ = new TabComplete(); chatWindow_->setRosterModel(roster_); chatWindow_->setTabComplete(completer_); chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1)); chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); + chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this)); chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this)); chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this)); chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1)); chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this)); chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); 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)); muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2)); muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); highlighter_->setMode(Highlighter::MUCMode); highlighter_->setNick(nick_); if (timerFactory) { loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS)); loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); loginCheckTimer_->start(); } if (isImpromptu) { muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this)); chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC); } else { muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); chatWindow_->convertToMUC(ChatWindow::StandardMUC); chatWindow_->setName(muc->getJID().getNode()); } setOnline(true); if (avatarManager_ != NULL) { avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1))); } @@ -767,70 +768,78 @@ std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart } else { eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% has entered then left the room")); } break; case PartThenJoin: if (sorted[i].size() > 1) { eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% have left then returned to the room")); } else { eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% has left then returned to the room")); } break; } populatedEvents.push_back(static_cast<JoinPart>(i)); eventStrings[i] = str(boost::format(eventString) % names); } } for (size_t i = 0; i < populatedEvents.size(); i++) { if (i > 0) { if (i < populatedEvents.size() - 1) { result += ", "; } else { result += QT_TRANSLATE_NOOP("", " and "); } } result += eventStrings[populatedEvents[i]]; } return result; } void MUCController::handleChangeSubjectRequest(const std::string& subject) { muc_->changeSubject(subject); } +void MUCController::handleBookmarkRequest() { + const JID jid = muc_->getJID(); + MUCBookmark bookmark(jid, jid.toBare().toString()); + bookmark.setPassword(password_); + bookmark.setNick(nick_); + chatWindow_->showBookmarkWindow(bookmark); +} + void MUCController::handleConfigureRequest(Form::ref form) { if (form) { muc_->configureRoom(form); } else { muc_->requestConfigurationForm(); } } void MUCController::handleConfigurationFailed(ErrorPayload::ref error) { std::string errorMessage = getErrorMessage(error); errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage); chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); } void MUCController::handleOccupantRoleChangeFailed(ErrorPayload::ref error, const JID&, MUCOccupant::Role) { std::string errorMessage = getErrorMessage(error); errorMessage = str(format(QT_TRANSLATE_NOOP("", "Occupant role change failed: %1%.")) % errorMessage); chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); } void MUCController::configureAsImpromptuRoom(Form::ref form) { muc_->configureRoom(buildImpromptuRoomConfiguration(form)); isImpromptuAlreadyConfigured_ = true; onImpromptuConfigCompleted(); } void MUCController::handleConfigurationFormReceived(Form::ref form) { if (isImpromptu_) { if (!isImpromptuAlreadyConfigured_) { configureAsImpromptuRoom(form); } } else { chatWindow_->showRoomConfigurationForm(form); } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 317f579..e78ff77 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -1,37 +1,37 @@ /* - * Copyright (c) 2010-2013 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <set> #include <string> #include <map> #include <boost/shared_ptr.hpp> #include <boost/signals/connection.hpp> #include <Swiften/Base/boost_bsignals.h> #include <Swiften/Network/Timer.h> #include <Swiften/Elements/Message.h> #include <Swiften/Elements/DiscoInfo.h> #include <Swiften/JID/JID.h> #include <Swiften/MUC/MUC.h> #include <Swiften/Elements/MUCOccupant.h> #include <Swift/Controllers/Chat/ChatControllerBase.h> #include <Swift/Controllers/Roster/RosterItem.h> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { class StanzaChannel; class IQRouter; class ChatWindowFactory; class Roster; class AvatarManager; class UIEventStream; class TimerFactory; class TabComplete; class XMPPRoster; @@ -61,70 +61,71 @@ namespace Swift { static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu); static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts); bool isJoined(); const std::string& getNick(); bool isImpromptu() const; std::map<std::string, JID> getParticipantJIDs() const; void sendInvites(const std::vector<JID>& jids, const std::string& reason) const; protected: void preSendMessageRequest(boost::shared_ptr<Message> message); bool isIncomingMessageFromMe(boost::shared_ptr<Message> message); std::string senderDisplayNameFromMessage(const JID& from); boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const; void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>); void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&); void cancelReplaces(); void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming); private: void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role); void clearPresenceQueue(); void addPresenceMessage(const std::string& message); void handleWindowOccupantSelectionChanged(ContactRosterItem* item); void handleActionRequestedOnOccupant(ChatWindow::OccupantAction, ContactRosterItem* item); void handleWindowClosed(); void handleAvatarChanged(const JID& jid); void handleOccupantJoined(const MUCOccupant& occupant); void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason); void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence); void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole); void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation); void handleJoinComplete(const std::string& nick); void handleJoinFailed(boost::shared_ptr<ErrorPayload> error); void handleJoinTimeoutTick(); void handleChangeSubjectRequest(const std::string&); + void handleBookmarkRequest(); std::string roleToGroupName(MUCOccupant::Role role); std::string roleToSortName(MUCOccupant::Role role); JID nickToJID(const std::string& nick); std::string roleToFriendlyName(MUCOccupant::Role role); void receivedActivity(); bool messageTargetsMe(boost::shared_ptr<Message> message); void updateJoinParts(); bool shouldUpdateJoinParts(); void dayTicked() {clearPresenceQueue();} void processUserPart(); void handleBareJIDCapsChanged(const JID& jid); void handleConfigureRequest(Form::ref); void handleConfigurationFailed(ErrorPayload::ref); void handleConfigurationFormReceived(Form::ref); void handleDestroyRoomRequest(); void handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite); void handleConfigurationCancelled(); void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role); void handleGetAffiliationsRequest(); void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids); void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes); void handleInviteToMUCWindowDismissed(); void handleInviteToMUCWindowCompleted(); void handleUIEvent(boost::shared_ptr<UIEvent> event); void addRecentLogs(); void checkDuplicates(boost::shared_ptr<Message> newMessage); void setNick(const std::string& nick); void setImpromptuWindowTitle(); void handleRoomUnlocked(); void configureAsImpromptuRoom(Form::ref form); Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm); private: MUC::ref muc_; UIEventStream* events_; diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 771872a..096a59a 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -1,56 +1,57 @@ /* - * Copyright (c) 2010-2012 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <vector> #include <string> #include <boost/optional.hpp> #include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <Swiften/Base/boost_bsignals.h> #include <Swiften/Elements/SecurityLabelsCatalog.h> #include <Swiften/Elements/ChatState.h> #include <Swiften/Elements/Form.h> #include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/MUC/MUCBookmark.h> #include <Swift/Controllers/HighlightManager.h> namespace Swift { class AvatarManager; class TreeWidget; class Roster; class TabComplete; class RosterItem; class ContactRosterItem; class FileTransferController; class UserSearchWindow; class ChatWindow { public: class ChatMessagePart { public: virtual ~ChatMessagePart() {} }; class ChatMessage { public: ChatMessage() {} ChatMessage(const std::string& text) { append(boost::make_shared<ChatTextMessagePart>(text)); } void append(const boost::shared_ptr<ChatMessagePart>& part) { parts_.push_back(part); } const std::vector<boost::shared_ptr<ChatMessagePart> >& getParts() const { return parts_; } private: @@ -116,93 +117,95 @@ namespace Swift { // File transfer related stuff virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes) = 0; virtual void setFileTransferProgress(std::string, const int percentageDone) = 0; virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0; virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false) = 0; virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0; virtual void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) = 0; // message receipts virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0; virtual void setContactChatState(ChatState::ChatStateType state) = 0; virtual void setName(const std::string& name) = 0; virtual void show() = 0; virtual void activate() = 0; virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0; virtual void setSecurityLabelsEnabled(bool enabled) = 0; virtual void setCorrectionEnabled(Tristate enabled) = 0; virtual void setUnreadMessageCount(int count) = 0; virtual void convertToMUC(MUCType mucType) = 0; // virtual TreeWidget *getTreeWidget() = 0; virtual void setSecurityLabelsError() = 0; virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0; virtual void setInputEnabled(bool enabled) = 0; virtual void setRosterModel(Roster* model) = 0; virtual void setTabComplete(TabComplete* completer) = 0; virtual void replaceLastMessage(const ChatMessage& message) = 0; virtual void setAckState(const std::string& id, AckState state) = 0; virtual void flash() = 0; virtual void setSubject(const std::string& subject) = 0; virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0; virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0; virtual void setBlockingState(BlockingState state) = 0; virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0; + virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0; /** * Set an alert on the window. * @param alertText Description of alert (required). * @param buttonText Button text to use (optional, no button is shown if empty). */ virtual void setAlert(const std::string& alertText, const std::string& buttonText = "") = 0; /** * Removes an alert. */ virtual void cancelAlert() = 0; /** * Actions that can be performed on the selected occupant. */ virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0; /** * A room configuration has been requested, show the form. * If the form is cancelled, must emit onConfigurationFormCancelled(). */ virtual void showRoomConfigurationForm(Form::ref) = 0; boost::signal<void ()> onClosed; boost::signal<void ()> onAllMessagesRead; boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; boost::signal<void ()> onSendCorrectionMessageRequest; boost::signal<void ()> onUserTyping; boost::signal<void ()> onUserCancelsTyping; boost::signal<void ()> onAlertButtonClicked; boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged; boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected; boost::signal<void (const std::string&)> onChangeSubjectRequest; + boost::signal<void ()> onBookmarkRequest; boost::signal<void (Form::ref)> onConfigureRequest; boost::signal<void ()> onDestroyRequest; boost::signal<void (const std::vector<JID>&)> onInviteToChat; boost::signal<void ()> onConfigurationFormCancelled; boost::signal<void ()> onGetAffiliationsRequest; boost::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest; boost::signal<void (const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes)> onChangeAffiliationsRequest; boost::signal<void ()> onLogCleared; // File transfer related boost::signal<void (std::string /* id */)> onFileTransferCancel; boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart; boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept; boost::signal<void (std::string /* path */)> onSendFileRequest; //Whiteboard related boost::signal<void ()> onWhiteboardSessionAccept; boost::signal<void ()> onWhiteboardSessionCancel; boost::signal<void ()> onWhiteboardWindowShow; // Blocking Command related boost::signal<void ()> onBlockUserRequest; boost::signal<void ()> onUnblockUserRequest; }; } diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 8aa645d..c2e2c9f 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -1,37 +1,37 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <boost/shared_ptr.hpp> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> #include <Swiften/Base/foreach.h> namespace Swift { class MockChatWindow : public ChatWindow { public: MockChatWindow() : labelsEnabled_(false) {} virtual ~MockChatWindow(); virtual std::string addMessage(const ChatMessage& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) { lastMessageBody_ = bodyFromMessage(message); return "id";} virtual std::string addAction(const ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {return "id";} virtual void addSystemMessage(const ChatMessage& /*message*/, Direction /*direction*/) {} virtual void addPresenceMessage(const ChatMessage& /*message*/, Direction /*direction*/) {} virtual void addErrorMessage(const ChatMessage& /*message*/) {} virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {} virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {} virtual void replaceLastMessage(const ChatMessage& /*message*/) {} // File transfer related stuff virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/) { return 0; } virtual void setFileTransferProgress(std::string /*id*/, const int /*alreadyTransferedBytes*/) { } virtual void setFileTransferStatus(std::string /*id*/, const FileTransferState /*state*/, const std::string& /*msg*/) { } @@ -39,55 +39,56 @@ namespace Swift { virtual void setMessageReceiptState(const std::string &/* id */, ReceiptState /* state */) { } virtual void setContactChatState(ChatState::ChatStateType /*state*/) {} virtual void setName(const std::string& name) {name_ = name;} virtual void show() {} virtual void activate() {} virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;} virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;} virtual void setUnreadMessageCount(int /*count*/) {} virtual void convertToMUC(MUCType /*mucType*/) {} virtual void setSecurityLabelsError() {} virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;} virtual void setInputEnabled(bool /*enabled*/) {} virtual void setRosterModel(Roster* roster) { roster_ = roster; } Roster* getRosterModel() { return roster_; } virtual void setTabComplete(TabComplete*) {} void setAckState(const std::string& /*id*/, AckState /*state*/) {} virtual void flash() {} virtual void setAlert(const std::string& /*alertText*/, const std::string& /*buttonText*/) {} virtual void cancelAlert() {} virtual void setCorrectionEnabled(Tristate /*enabled*/) {} void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {} void setSubject(const std::string& /*subject*/) {} virtual void showRoomConfigurationForm(Form::ref) {} virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true, bool = false, bool = false) {} virtual std::string addWhiteboardRequest(bool) {return "";} virtual void setWhiteboardSessionStatus(std::string, const ChatWindow::WhiteboardSessionState){} virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {} virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {} virtual void setBlockingState(BlockingState) {} virtual void setCanInitiateImpromptuChats(bool /*supportsImpromptu*/) {} + virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {} std::string bodyFromMessage(const ChatMessage& message) { boost::shared_ptr<ChatTextMessagePart> text; foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) { if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) { return text->text; } } return ""; } std::string name_; std::string lastMessageBody_; std::vector<SecurityLabelsCatalog::Item> labels_; bool labelsEnabled_; SecurityLabelsCatalog::Item label_; Roster* roster_; }; } diff --git a/Swift/QtUI/QtAddBookmarkWindow.cpp b/Swift/QtUI/QtAddBookmarkWindow.cpp index 675ea03..230f2ed 100644 --- a/Swift/QtUI/QtAddBookmarkWindow.cpp +++ b/Swift/QtUI/QtAddBookmarkWindow.cpp @@ -1,27 +1,31 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "QtAddBookmarkWindow.h" #include <qdebug.h> namespace Swift { QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream) : eventStream_(eventStream) { } +QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark) : eventStream_(eventStream) { + createFormFromBookmark(bookmark); +} + bool QtAddBookmarkWindow::commit() { boost::optional<MUCBookmark> bookmark = createBookmarkFromForm(); if (bookmark) { eventStream_->send(boost::shared_ptr<UIEvent>(new AddMUCBookmarkUIEvent(*bookmark))); return true; } else { return false; } } } diff --git a/Swift/QtUI/QtAddBookmarkWindow.h b/Swift/QtUI/QtAddBookmarkWindow.h index f026cc3..c0dc214 100644 --- a/Swift/QtUI/QtAddBookmarkWindow.h +++ b/Swift/QtUI/QtAddBookmarkWindow.h @@ -1,23 +1,24 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include "QtBookmarkDetailWindow.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" #include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h" namespace Swift { class QtAddBookmarkWindow : public QtBookmarkDetailWindow { Q_OBJECT public: QtAddBookmarkWindow(UIEventStream* eventStream); + QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark); bool commit(); private: UIEventStream* eventStream_; }; } diff --git a/Swift/QtUI/QtBookmarkDetailWindow.cpp b/Swift/QtUI/QtBookmarkDetailWindow.cpp index ae84b4b..3e501f2 100644 --- a/Swift/QtUI/QtBookmarkDetailWindow.cpp +++ b/Swift/QtUI/QtBookmarkDetailWindow.cpp @@ -1,52 +1,76 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "QtBookmarkDetailWindow.h" #include "QtSwiftUtil.h" #include <QMessageBox> namespace Swift { QtBookmarkDetailWindow::QtBookmarkDetailWindow(QWidget* parent) : QDialog(parent) { setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); //connect(buttons_, SIGNAL(accepted()), SLOT(accept())); //connect(buttons_, SIGNAL(rejected()), SLOT(reject())); } void QtBookmarkDetailWindow::accept() { if (commit()) { QDialog::accept(); } } boost::optional<MUCBookmark> QtBookmarkDetailWindow::createBookmarkFromForm() { //check room //check bookmarkName JID room(Q2PSTRING(room_->text())); if (!room.isValid() || room.getNode().empty() || !room.getResource().empty()) { QMessageBox::warning(this, tr("Bookmark not valid"), tr("You must specify a valid room address (e.g. someroom@rooms.example.com).")); return boost::optional<MUCBookmark>(); } std::string name(Q2PSTRING(name_->text())); if (name.empty()) { name = room.toString(); } MUCBookmark bookmark(room, name); std::string nick(Q2PSTRING(nick_->text())); std::string password(Q2PSTRING(password_->text())); bookmark.setAutojoin(autojoin_->isChecked()); if (!nick.empty()) { bookmark.setNick(nick); } if (!password.empty()) { bookmark.setPassword(password); } return bookmark; } +void QtBookmarkDetailWindow::createFormFromBookmark(const MUCBookmark& bookmark) { + if (bookmark.getRoom().isValid()) { + room_->setText(P2QSTRING(bookmark.getRoom().toString())); + } + + if (!bookmark.getName().empty()) { + name_->setText(P2QSTRING(bookmark.getName())); + } + + if (bookmark.getNick()) { + nick_->setText(P2QSTRING((*bookmark.getNick()))); + } + + if (bookmark.getPassword()) { + password_->setText(P2QSTRING((*bookmark.getPassword()))); + } + + if (bookmark.getAutojoin()) { + autojoin_->setCheckState(Qt::Checked); + } else { + autojoin_->setCheckState(Qt::Unchecked); + } +} + } diff --git a/Swift/QtUI/QtBookmarkDetailWindow.h b/Swift/QtUI/QtBookmarkDetailWindow.h index fd2b7b4..b223719 100644 --- a/Swift/QtUI/QtBookmarkDetailWindow.h +++ b/Swift/QtUI/QtBookmarkDetailWindow.h @@ -1,29 +1,32 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include "ui_QtBookmarkDetailWindow.h" #include <boost/optional.hpp> #include <QDialog> #include "Swiften/MUC/MUCBookmark.h" namespace Swift { class QtBookmarkDetailWindow : public QDialog, protected Ui::QtBookmarkDetailWindow { Q_OBJECT public: QtBookmarkDetailWindow(QWidget* parent = NULL); virtual bool commit() = 0; boost::optional<MUCBookmark> createBookmarkFromForm(); + protected: + void createFormFromBookmark(const MUCBookmark& bookmark); + public slots: void accept(); }; } diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index d3cce6d..f58c11b 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -14,70 +14,71 @@ #include <QApplication> #include <QBoxLayout> #include <QCloseEvent> #include <QComboBox> #include <QFileDialog> #include <QFileInfo> #include <QInputDialog> #include <QLabel> #include <QLineEdit> #include <QMenu> #include <QMessageBox> #include <QMimeData> #include <QPushButton> #include <QSplitter> #include <QString> #include <QTextDocument> #include <QTextEdit> #include <QTime> #include <QToolButton> #include <QUrl> #include <QMimeData> #include <Swiften/Base/Log.h> #include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Roster/RosterItem.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <SwifTools/TabComplete.h> #include <Swift/QtUI/Roster/QtOccupantListWidget.h> +#include <Swift/QtUI/QtAddBookmarkWindow.h> #include <Swift/QtUI/QtPlainChatView.h> #include <Swift/QtUI/QtSettingsProvider.h> #include <Swift/QtUI/QtScaledAvatarCache.h> #include <Swift/QtUI/QtTextEdit.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/QtUI/QtUtilities.h> #include <Swift/QtUI/QtWebKitChatView.h> namespace Swift { QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings) : QtTabbable(), contact_(contact), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false) { settings_ = settings; unreadCount_ = 0; inputEnabled_ = true; completer_ = NULL; affiliationEditor_ = NULL; theme_ = theme; isCorrection_ = false; labelModel_ = NULL; correctionEnabled_ = Maybe; updateTitleWithUnreadCount(); #ifdef SWIFT_EXPERIMENTAL_FT setAcceptDrops(true); #endif alertStyleSheet_ = "background: rgb(255, 255, 153); color: black"; QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); layout->setContentsMargins(0,0,0,0); layout->setSpacing(2); alertWidget_ = new QWidget(this); QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget_); layout->addWidget(alertWidget_); @@ -595,135 +596,144 @@ void QtChatWindow::handleActionButtonClicked() { if (availableRoomActions_.empty()) { if (blockingState_ == IsBlocked) { unblock = contextMenu.addAction(tr("Unblock")); } else if (blockingState_ == IsUnblocked) { block = contextMenu.addAction(tr("Block")); } if (supportsImpromptuChat_) { invite = contextMenu.addAction(tr("Invite person to this chat…")); } } else { foreach(ChatWindow::RoomAction availableAction, availableRoomActions_) { if (impromptu_) { // hide options we don't need in impromptu chats if (availableAction == ChatWindow::ChangeSubject || availableAction == ChatWindow::Configure || availableAction == ChatWindow::Affiliations || availableAction == ChatWindow::Destroy) { continue; } } switch(availableAction) { case ChatWindow::ChangeSubject: changeSubject = contextMenu.addAction(tr("Change subject…")); break; case ChatWindow::Configure: configure = contextMenu.addAction(tr("Configure room…")); break; case ChatWindow::Affiliations: affiliations = contextMenu.addAction(tr("Edit affiliations…")); break; case ChatWindow::Destroy: destroy = contextMenu.addAction(tr("Destroy room")); break; case ChatWindow::Invite: invite = contextMenu.addAction(tr("Invite person to this room…")); break; } } } + QAction* bookmark = contextMenu.addAction(tr("Add boomark...")); + QAction* result = contextMenu.exec(QCursor::pos()); if (result == NULL) { /* Skip processing. Note that otherwise, because the actions could be null they could match */ } else if (result == changeSubject) { bool ok; QString subject = QInputDialog::getText(this, tr("Change room subject"), tr("New subject:"), QLineEdit::Normal, subject_->text(), &ok); if (ok) { onChangeSubjectRequest(Q2PSTRING(subject)); } } else if (result == configure) { onConfigureRequest(Form::ref()); } else if (result == affiliations) { if (!affiliationEditor_) { onGetAffiliationsRequest(); affiliationEditor_ = new QtAffiliationEditor(this); connect(affiliationEditor_, SIGNAL(accepted()), this, SLOT(handleAffiliationEditorAccepted())); } affiliationEditor_->show(); } else if (result == destroy) { QMessageBox msgBox; msgBox.setWindowTitle(tr("Confirm room destruction")); msgBox.setText(tr("Are you sure you want to destroy the room?")); msgBox.setInformativeText(tr("This will destroy the room.")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); if (msgBox.exec() == QMessageBox::Yes) { onDestroyRequest(); } } else if (result == invite) { onInviteToChat(std::vector<JID>()); } else if (result == block) { onBlockUserRequest(); } else if (result == unblock) { onUnblockUserRequest(); + } else if (result == bookmark) { + onBookmarkRequest(); } } void QtChatWindow::handleAffiliationEditorAccepted() { onChangeAffiliationsRequest(affiliationEditor_->getChanges()); } void QtChatWindow::setAffiliations(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) { if (!affiliationEditor_) return; affiliationEditor_->setAffiliations(affiliation, jids); } void QtChatWindow::setAvailableRoomActions(const std::vector<RoomAction>& actions) { availableRoomActions_ = actions; } void QtChatWindow::setBlockingState(BlockingState state) { blockingState_ = state; } void QtChatWindow::setCanInitiateImpromptuChats(bool supportsImpromptu) { supportsImpromptuChat_ = supportsImpromptu; } +void QtChatWindow::showBookmarkWindow(const MUCBookmark& bookmark) { + QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark); + window->show(); +} + void QtChatWindow::showRoomConfigurationForm(Form::ref form) { if (mucConfigurationWindow_) { delete mucConfigurationWindow_.data(); } mucConfigurationWindow_ = new QtMUCConfigurationWindow(form); mucConfigurationWindow_->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1)); mucConfigurationWindow_->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled))); } void QtChatWindow::handleAppendedToLog() { if (lastLineTracker_.getShouldMoveLastLine()) { /* should this be queued? */ messageLog_->addLastSeenLine(); } if (isWidgetSelected()) { onAllMessagesRead(); } } void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) { handleAppendedToLog(); messageLog_->addMUCInvitation(senderName, jid, reason, password, direct, isImpromptu, isContinuation); } std::string QtChatWindow::addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) { handleAppendedToLog(); return messageLog_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time, highlight); } std::string QtChatWindow::addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) { handleAppendedToLog(); return messageLog_->addAction(message, senderName, senderIsSelf, label, avatarPath, time, highlight); } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 5a4fe95..de7e45e 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -96,70 +96,71 @@ namespace Swift { std::string addWhiteboardRequest(bool senderIsSelf); void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state); void show(); void activate(); void setUnreadMessageCount(int count); void convertToMUC(MUCType mucType); // TreeWidget *getTreeWidget(); void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels); void setSecurityLabelsEnabled(bool enabled); void setSecurityLabelsError(); SecurityLabelsCatalog::Item getSelectedSecurityLabel(); void setName(const std::string& name); void setInputEnabled(bool enabled); QtTabbable::AlertType getWidgetAlertState(); void setContactChatState(ChatState::ChatStateType state); void setRosterModel(Roster* roster); void setTabComplete(TabComplete* completer); int getCount(); void replaceLastMessage(const ChatMessage& message); void setAckState(const std::string& id, AckState state); // message receipts void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state); void flash(); QByteArray getSplitterState(); virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions); void setSubject(const std::string& subject); void showRoomConfigurationForm(Form::ref); void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false); void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&); void setAvailableRoomActions(const std::vector<RoomAction>& actions); void setBlockingState(BlockingState state); virtual void setCanInitiateImpromptuChats(bool supportsImpromptu); + virtual void showBookmarkWindow(const MUCBookmark& bookmark); public slots: void handleChangeSplitterState(QByteArray state); void handleFontResized(int fontSizeSteps); void setAlert(const std::string& alertText, const std::string& buttonText = ""); void cancelAlert(); void setCorrectionEnabled(Tristate enabled); signals: void geometryChanged(); void splitterMoved(); void fontResized(int); protected slots: void qAppFocusChanged(QWidget* old, QWidget* now); void closeEvent(QCloseEvent* event); void resizeEvent(QResizeEvent* event); void moveEvent(QMoveEvent* event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); protected: void showEvent(QShowEvent* event); private slots: void handleLogCleared(); void returnPressed(); void handleInputChanged(); void handleCursorPositionChanged(); void handleKeyPressEvent(QKeyEvent* event); void handleSplitterMoved(int pos, int index); void handleAlertButtonClicked(); void handleActionButtonClicked(); void handleAffiliationEditorAccepted(); |
Swift