diff options
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 2 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 14 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 4 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 2 | ||||
| -rw-r--r-- | Swift/Controllers/UIInterfaces/InviteToChatWindow.h | 4 | ||||
| -rw-r--r-- | Swift/QtUI/QtInviteToChatWindow.cpp | 22 | ||||
| -rw-r--r-- | Swift/QtUI/QtInviteToChatWindow.h | 5 |
7 files changed, 43 insertions, 10 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index da96603..4fc3752 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -579,19 +579,19 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID); if (it != mucControllers_.end()) { it->second->rejoin(); } else { std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_); MUC::ref muc = mucManager->createMUC(mucJID); if (createAsReservedIfNew) { muc->setCreateAsReservedIfNew(); } - MUCController* controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_); + MUCController* controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_); mucControllers_[mucJID] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true)); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true)); controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); handleChatActivity(mucJID.toBare(), "", true); } diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 3d04b34..94fd142 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -28,18 +28,19 @@ #include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swiften/Avatars/AvatarManager.h> #include <Swiften/Elements/Delay.h> #include <Swiften/MUC/MUC.h> #include <Swiften/Client/StanzaChannel.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Roster/SetAvatar.h> #include <Swift/Controllers/Roster/SetPresence.h> #include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Roster/XMPPRoster.h> #define MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS 60000 namespace Swift { /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ @@ -51,27 +52,29 @@ MUCController::MUCController ( StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* uiEventStream, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, - EntityCapsProvider* entityCapsProvider) : + EntityCapsProvider* entityCapsProvider, + XMPPRoster* roster) : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password) { parting_ = true; joined_ = false; lastWasPresence_ = false; shouldJoinOnReconnect_ = true; doneGettingHistory_ = false; events_ = uiEventStream; inviteWindow_ = NULL; + xmppRoster_ = roster; roster_ = new Roster(false, true); completer_ = new TabComplete(); chatWindow_->setRosterModel(roster_); chatWindow_->setTabComplete(completer_); chatWindow_->setName(muc->getJID().getNode()); 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)); @@ -721,18 +724,27 @@ void MUCController::handleDestroyRoomRequest() { muc_->destroyRoom(); } void MUCController::handleInvitePersonToThisMUCRequest() { if (!inviteWindow_) { inviteWindow_ = chatWindow_->createInviteToChatWindow(); inviteWindow_->onCompleted.connect(boost::bind(&MUCController::handleInviteToMUCWindowCompleted, this)); inviteWindow_->onDismissed.connect(boost::bind(&MUCController::handleInviteToMUCWindowDismissed, this)); } + std::vector<std::pair<JID, std::string> > autoCompletes; + foreach (XMPPRosterItem item, xmppRoster_->getItems()) { + std::pair<JID, std::string> jidName; + jidName.first = item.getJID(); + jidName.second = item.getName(); + autoCompletes.push_back(jidName); + std::cerr << "MUCController adding " << item.getJID().toString() << std::endl; + } + inviteWindow_->setAutoCompletions(autoCompletes); } void MUCController::handleInviteToMUCWindowDismissed() { inviteWindow_= NULL; } void MUCController::handleInviteToMUCWindowCompleted() { foreach (const JID& jid, inviteWindow_->getJIDs()) { muc_->invitePerson(jid, inviteWindow_->getReason()); diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 8b43dcf..6bf056b 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -26,30 +26,31 @@ namespace Swift { class StanzaChannel; class IQRouter; class ChatWindowFactory; class Roster; class AvatarManager; class UIEventStream; class TimerFactory; class TabComplete; class InviteToChatWindow; + class XMPPRoster; enum JoinPart {Join, Part, JoinThenPart, PartThenJoin}; struct NickJoinPart { NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {}; std::string nick; JoinPart type; }; class MUCController : public ChatControllerBase { public: - MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider); + MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster); ~MUCController(); boost::signal<void ()> onUserLeft; boost::signal<void ()> onUserJoined; virtual void setOnline(bool online); void rejoin(); static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent); static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts); static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts); bool isJoined(); @@ -118,12 +119,13 @@ namespace Swift { bool shouldJoinOnReconnect_; bool doneGettingHistory_; boost::bsignals::scoped_connection avatarChangedConnection_; boost::shared_ptr<Timer> loginCheckTimer_; std::set<std::string> currentOccupants_; std::vector<NickJoinPart> joinParts_; boost::posix_time::ptime lastActivity_; boost::optional<std::string> password_; InviteToChatWindow* inviteWindow_; + XMPPRoster* xmppRoster_; }; } diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index d4fbcfd..04fc2f7 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -57,19 +57,19 @@ public: directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); uiEventStream_ = new UIEventStream(); avatarManager_ = new NullAvatarManager(); TimerFactory* timerFactory = NULL; window_ = new MockChatWindow(); mucRegistry_ = new MUCRegistry(); entityCapsProvider_ = new DummyEntityCapsProvider(); muc_ = boost::make_shared<MUC>(stanzaChannel_, iqRouter_, directedPresenceSender_, mucJID_, mucRegistry_); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); - controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_); + controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL); }; void tearDown() { delete entityCapsProvider_; delete controller_; delete eventController_; delete presenceOracle_; delete mocks_; delete uiEventStream_; diff --git a/Swift/Controllers/UIInterfaces/InviteToChatWindow.h b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h index f34a485..4070e01 100644 --- a/Swift/Controllers/UIInterfaces/InviteToChatWindow.h +++ b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h @@ -1,28 +1,30 @@ /* * Copyright (c) 2012 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <vector> - +#include <utility> #include <string> #include <Swiften/Base/boost_bsignals.h> #include <Swiften/JID/JID.h> namespace Swift { class InviteToChatWindow { public: virtual ~InviteToChatWindow() {}; + virtual void setAutoCompletions(std::vector<std::pair<JID, std::string> > completions) = 0; + virtual std::string getReason() const = 0; virtual std::vector<JID> getJIDs() const = 0; boost::signal<void ()> onCompleted; boost::signal<void ()> onDismissed; }; } diff --git a/Swift/QtUI/QtInviteToChatWindow.cpp b/Swift/QtUI/QtInviteToChatWindow.cpp index d53c493..3b8f1fc 100644 --- a/Swift/QtUI/QtInviteToChatWindow.cpp +++ b/Swift/QtUI/QtInviteToChatWindow.cpp @@ -13,20 +13,20 @@ #include <QPushButton> #include <QDialogButtonBox> #include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { QtInviteToChatWindow::QtInviteToChatWindow(QWidget* parent) : QDialog(parent) { QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); - layout->setContentsMargins(0,0,0,0); - layout->setSpacing(2); + //layout->setContentsMargins(0,0,0,0); + //layout->setSpacing(2); QLabel* description = new QLabel(tr("Users to invite to this chat (one per line):")); layout->addWidget(description); jidsLayout_ = new QBoxLayout(QBoxLayout::TopToBottom); layout->addLayout(jidsLayout_); QLabel* reasonLabel = new QLabel(tr("If you want to provide a reason for the invitation, enter it here")); layout->addWidget(reasonLabel); @@ -39,18 +39,20 @@ QtInviteToChatWindow::QtInviteToChatWindow(QWidget* parent) : QDialog(parent) { QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); layout->addWidget(buttonBox); + jids_[0]->setFocus(); + setModal(false); show(); } QtInviteToChatWindow::~QtInviteToChatWindow() { } void QtInviteToChatWindow::handleAccepting() { @@ -75,19 +77,19 @@ std::vector<JID> QtInviteToChatWindow::getJIDs() const { results.push_back(jid); } } } return results; } void QtInviteToChatWindow::addJIDLine() { QLineEdit* jid = new QLineEdit(this); - QCompleter* completer = new QCompleter(completions_, this); + QCompleter* completer = new QCompleter(&completions_, this); completer->setCaseSensitivity(Qt::CaseInsensitive); jid->setCompleter(completer); jids_.push_back(jid); jidsLayout_->addWidget(jid); connect(jid, SIGNAL(textChanged(const QString&)), this, SLOT(handleJIDTextChanged())); } void QtInviteToChatWindow::handleJIDTextChanged() { bool gotEmpty = false; @@ -95,13 +97,27 @@ void QtInviteToChatWindow::handleJIDTextChanged() { if (edit->text().isEmpty()) { gotEmpty = true; } } if (!gotEmpty) { addJIDLine(); } } +typedef std::pair<JID, std::string> JIDString; + +void QtInviteToChatWindow::setAutoCompletions(std::vector<std::pair<JID, std::string> > completions) { + QStringList list; + foreach (JIDString jidPair, completions) { + QString line = P2QSTRING(jidPair.first.toString()); + if (jidPair.second != jidPair.first.toString() && !jidPair.second.empty()) { + line = P2QSTRING(jidPair.second) + " - " + line; + } + list.append(line); + } + completions_.setStringList(list); +} + } diff --git a/Swift/QtUI/QtInviteToChatWindow.h b/Swift/QtUI/QtInviteToChatWindow.h index c009861..a0167db 100644 --- a/Swift/QtUI/QtInviteToChatWindow.h +++ b/Swift/QtUI/QtInviteToChatWindow.h @@ -3,39 +3,40 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <Swift/Controllers/UIInterfaces/InviteToChatWindow.h> #include <QDialog> -#include <QStringList> +#include <QStringListModel> class QLineEdit; class QBoxLayout; namespace Swift { class QtInviteToChatWindow : public QDialog, public InviteToChatWindow { Q_OBJECT public: QtInviteToChatWindow(QWidget* parent = NULL); virtual ~QtInviteToChatWindow(); virtual std::string getReason() const; virtual std::vector<JID> getJIDs() const; + virtual void setAutoCompletions(std::vector<std::pair<JID, std::string> > completions); private: void addJIDLine(); private slots: void handleJIDTextChanged(); void handleAccepting(); void handleRejecting(); private: - QStringList completions_; + QStringListModel completions_; QLineEdit* reason_; QBoxLayout* jidsLayout_; std::vector<QLineEdit*> jids_; }; } |
Swift