From 1f4be30a480818458fd841809585681597be831e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 4 Oct 2011 11:02:23 +0100 Subject: Allow both instant and reserved rooms. Resolves: #1006 diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index c0b2a7d..d3060b8 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -199,7 +199,7 @@ void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { std::map::iterator it = mucControllers_.find(bookmark.getRoom()); if (it == mucControllers_.end() && bookmark.getAutojoin()) { //FIXME: need vcard stuff here to get a nick - handleJoinMUCRequest(bookmark.getRoom(), bookmark.getNick(), false); + handleJoinMUCRequest(bookmark.getRoom(), bookmark.getNick(), false, false); } chatListWindow_->addMUCBookmark(bookmark); } @@ -321,7 +321,7 @@ void ChatsManager::handleUIEvent(boost::shared_ptr event) { mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); } else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast(event)) { - handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically()); + handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew()); mucControllers_[joinEvent->getJID()]->activateChatWindow(); } else if (boost::shared_ptr joinEvent = boost::dynamic_pointer_cast(event)) { @@ -481,7 +481,7 @@ void ChatsManager::rebindControllerJID(const JID& from, const JID& to) { chatControllers_[to]->setToJID(to); } -void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional& nickMaybe, bool addAutoJoin) { +void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional& nickMaybe, bool addAutoJoin, bool createAsReservedIfNew) { if (addAutoJoin) { MUCBookmark bookmark(mucJID, mucJID.getNode()); bookmark.setAutojoin(true); @@ -497,6 +497,9 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional } else { std::string nick = nickMaybe ? nickMaybe.get() : jid_.getNode(); MUC::ref muc = mucManager->createMUC(mucJID); + if (createAsReservedIfNew) { + muc->setCreateAsReservedIfNew(); + } MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_); mucControllers_[mucJID] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 57643eb..a82492c 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -58,7 +58,7 @@ namespace Swift { private: ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity); void handleChatRequest(const std::string& contact); - void handleJoinMUCRequest(const JID& muc, const boost::optional& nick, bool addAutoJoin); + void handleJoinMUCRequest(const JID& muc, const boost::optional& nick, bool addAutoJoin, bool createAsReservedIfNew); void handleSearchMUCRequest(); void handleMUCSelectedAfterSearch(const JID&); void rebindControllerJID(const JID& from, const JID& to); diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 87d5a16..d72c0f7 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -73,6 +73,7 @@ MUCController::MUCController ( chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); 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_->onInvitePersonToThisMUCRequest.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1, _2)); muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); @@ -600,6 +601,10 @@ void MUCController::handleConfigurationFormReceived(Form::ref form) { chatWindow_->showRoomConfigurationForm(form); } +void MUCController::handleConfigurationCancelled() { + muc_->cancelConfigureRoom(); +} + void MUCController::handleDestroyRoomRequest() { muc_->destroyRoom(); } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index f83e2af..17dbba4 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -93,6 +93,7 @@ namespace Swift { void handleConfigurationFormReceived(Form::ref); void handleDestroyRoomRequest(); void handleInvitePersonToThisMUCRequest(const JID& jid, const std::string& reason); + void handleConfigurationCancelled(); private: MUC::ref muc_; diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h index dea3ead..e1d65ad 100644 --- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h @@ -18,13 +18,15 @@ namespace Swift { class JoinMUCUIEvent : public UIEvent { public: typedef boost::shared_ptr ref; - JoinMUCUIEvent(const JID& jid, const boost::optional& nick = boost::optional(), bool joinAutomaticallyInFuture = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture){}; + JoinMUCUIEvent(const JID& jid, const boost::optional& nick = boost::optional(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew) {}; boost::optional getNick() {return nick_;}; JID getJID() {return jid_;}; bool getShouldJoinAutomatically() {return joinAutomatically_;} + bool getCreateAsReservedRoomIfNew() {return createAsReservedRoomIfNew_;} private: JID jid_; boost::optional nick_; bool joinAutomatically_; + bool createAsReservedRoomIfNew_; }; } diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 7977940..836a330 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -92,7 +92,12 @@ namespace Swift { */ virtual void setAvailableOccupantActions(const std::vector& 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 onClosed; boost::signal onAllMessagesRead; boost::signal onSendMessageRequest; @@ -106,6 +111,7 @@ namespace Swift { boost::signal onConfigureRequest; boost::signal onDestroyRequest; boost::signal onInvitePersonToThisMUCRequest; + boost::signal onConfigurationFormCancelled; // File transfer related boost::signal onFileTransferCancel; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index df78767..10daa68 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -734,6 +734,7 @@ void QtChatWindow::showRoomConfigurationForm(Form::ref form) { } mucConfigurationWindow = new QtMUCConfigurationWindow(form); mucConfigurationWindow->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1)); + mucConfigurationWindow->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled))); } void QtChatWindow::addMUCInvitation(const JID& jid, const std::string& reason, const std::string& password) { diff --git a/Swift/QtUI/QtJoinMUCWindow.cpp b/Swift/QtUI/QtJoinMUCWindow.cpp index a44cdaf..fec3c4d 100644 --- a/Swift/QtUI/QtJoinMUCWindow.cpp +++ b/Swift/QtUI/QtJoinMUCWindow.cpp @@ -24,6 +24,7 @@ QtJoinMUCWindow::QtJoinMUCWindow(UIEventStream* uiEventStream) : uiEventStream(u // placeholder for the room is visible. This is just because Qt hides // the placeholder when a widget is focused for some reason. ui.nickName->setFocus(); + ui.instantRoom->setChecked(true); } void QtJoinMUCWindow::handleJoin() { @@ -38,7 +39,7 @@ void QtJoinMUCWindow::handleJoin() { lastSetNick = Q2PSTRING(ui.nickName->text()); JID room(Q2PSTRING(ui.room->text())); - uiEventStream->send(boost::make_shared(room, lastSetNick, ui.joinAutomatically->isChecked())); + uiEventStream->send(boost::make_shared(room, lastSetNick, ui.joinAutomatically->isChecked(), !ui.instantRoom->isChecked())); hide(); } diff --git a/Swift/QtUI/QtJoinMUCWindow.ui b/Swift/QtUI/QtJoinMUCWindow.ui index 493fb26..74fe513 100644 --- a/Swift/QtUI/QtJoinMUCWindow.ui +++ b/Swift/QtUI/QtJoinMUCWindow.ui @@ -7,7 +7,7 @@ 0 0 410 - 169 + 212 @@ -56,6 +56,13 @@ + + + Automatically configure newly created rooms + + + + Qt::Vertical diff --git a/Swift/QtUI/QtMUCConfigurationWindow.cpp b/Swift/QtUI/QtMUCConfigurationWindow.cpp index a8dec2a..6fdfd43 100644 --- a/Swift/QtUI/QtMUCConfigurationWindow.cpp +++ b/Swift/QtUI/QtMUCConfigurationWindow.cpp @@ -8,10 +8,11 @@ #include #include +#include #include namespace Swift { -QtMUCConfigurationWindow::QtMUCConfigurationWindow(Form::ref form) { +QtMUCConfigurationWindow::QtMUCConfigurationWindow(Form::ref form) : closed_(false) { setAttribute(Qt::WA_DeleteOnClose); @@ -43,12 +44,19 @@ QtMUCConfigurationWindow::~QtMUCConfigurationWindow() { } +void QtMUCConfigurationWindow::closeEvent(QCloseEvent* event) { + if (!closed_) { + onFormCancelled(); + } +} + void QtMUCConfigurationWindow::handleCancelClicked() { close(); } void QtMUCConfigurationWindow::handleOKClicked() { onFormComplete(formWidget_->getCompletedForm()); + closed_ = true; close(); } diff --git a/Swift/QtUI/QtMUCConfigurationWindow.h b/Swift/QtUI/QtMUCConfigurationWindow.h index 2be126b..f6a22be 100644 --- a/Swift/QtUI/QtMUCConfigurationWindow.h +++ b/Swift/QtUI/QtMUCConfigurationWindow.h @@ -14,6 +14,7 @@ #include class QBoxLayout; +class QCloseEvent; namespace Swift { class QtFormWidget; @@ -23,12 +24,16 @@ namespace Swift { QtMUCConfigurationWindow(Form::ref form); virtual ~QtMUCConfigurationWindow(); boost::signal onFormComplete; + boost::signal onFormCancelled; private slots: void handleCancelClicked(); void handleOKClicked(); + protected: + virtual void closeEvent(QCloseEvent* event); private: QtFormWidget* formWidget_; QPushButton* okButton_; QPushButton* cancelButton_; + bool closed_; }; } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 57f4175..3f65b14 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -151,7 +151,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa // Don't add the first tray (see note above) systemTrays_.push_back(new QtSystemTray()); } - QtUIFactory* uiFactory = new QtUIFactory(settings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, startMinimized); + QtUIFactory* uiFactory = new QtUIFactory(settings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, startMinimized, eagleMode); uiFactories_.push_back(uiFactory); MainController* mainController = new MainController( &clientMainThreadCaller_, diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 9de700c..faeebdc 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -30,7 +30,7 @@ namespace Swift { -QtUIFactory::QtUIFactory(QtSettingsProvider* settings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized) : settings(settings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized) { +QtUIFactory::QtUIFactory(QtSettingsProvider* settings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized, bool eagleMode) : settings(settings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized), eagleMode(eagleMode) { chatFontSize = settings->getIntSetting(CHATWINDOW_FONT_SIZE, 0); } diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index 8fc5395..319613d 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -26,7 +26,7 @@ namespace Swift { class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(QtSettingsProvider* settings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized); + QtUIFactory(QtSettingsProvider* settings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized, bool eagleMode); virtual XMLConsoleWidget* createXMLConsoleWidget(); virtual MainWindow* createMainWindow(UIEventStream* eventStream); @@ -57,5 +57,6 @@ namespace Swift { std::vector > chatWindows; bool startMinimized; int chatFontSize; + bool eagleMode; }; } diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index 4c9e537..08391b4 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -29,7 +29,7 @@ namespace Swift { typedef std::pair StringMUCOccupantPair; -MUC::MUC(StanzaChannel* stanzaChannel, IQRouter* iqRouter, DirectedPresenceSender* presenceSender, const JID &muc, MUCRegistry* mucRegistry) : ownMUCJID(muc), stanzaChannel(stanzaChannel), iqRouter_(iqRouter), presenceSender(presenceSender), mucRegistry(mucRegistry) { +MUC::MUC(StanzaChannel* stanzaChannel, IQRouter* iqRouter, DirectedPresenceSender* presenceSender, const JID &muc, MUCRegistry* mucRegistry) : ownMUCJID(muc), stanzaChannel(stanzaChannel), iqRouter_(iqRouter), presenceSender(presenceSender), mucRegistry(mucRegistry), createAsReservedIfNew(false), unlocking(false) { scopedConnection_ = stanzaChannel->onPresenceReceived.connect(boost::bind(&MUC::handleIncomingPresence, this, _1)); } @@ -192,18 +192,25 @@ void MUC::handleIncomingPresence(Presence::ref presence) { ownMUCJID = presence->getFrom(); presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence); } - MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); - presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); - mucPayload->setPayload(boost::make_shared
(Form::SubmitType)); - GenericRequest* request = new GenericRequest(IQ::Set, getJID(), mucPayload, iqRouter_); - request->onResponse.connect(boost::bind(&MUC::handleCreationConfigResponse, this, _1, _2)); - request->send(); + if (createAsReservedIfNew) { + unlocking = true; + requestConfigurationForm(); + } + else { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); + mucPayload->setPayload(boost::make_shared(Form::SubmitType)); + GenericRequest* request = new GenericRequest(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleCreationConfigResponse, this, _1, _2)); + request->send(); + } } } } } void MUC::handleCreationConfigResponse(MUCOwnerPayload::ref /*unused*/, ErrorPayload::ref error) { + unlocking = false; if (error) { presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence); onJoinFailed(error); @@ -252,6 +259,13 @@ void MUC::requestConfigurationForm() { request->send(); } +void MUC::cancelConfigureRoom() { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + mucPayload->setPayload(boost::make_shared(Form::CancelType)); + GenericRequest* request = new GenericRequest(IQ::Set, getJID(), mucPayload, iqRouter_); + request->send(); +} + void MUC::handleConfigurationFormReceived(MUCOwnerPayload::ref payload, ErrorPayload::ref error) { Form::ref form; if (payload) { @@ -274,7 +288,12 @@ void MUC::configureRoom(Form::ref form) { MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); mucPayload->setPayload(form); GenericRequest* request = new GenericRequest(IQ::Set, getJID(), mucPayload, iqRouter_); - request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + if (unlocking) { + request->onResponse.connect(boost::bind(&MUC::handleCreationConfigResponse, this, _1, _2)); + } + else { + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + } request->send(); } diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 45b8004..adc5707 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -60,9 +60,11 @@ namespace Swift { void changeSubject(const std::string& subject); void requestConfigurationForm(); void configureRoom(Form::ref); + void cancelConfigureRoom(); void destroyRoom(); /** Send an invite for the person to join the MUC */ void invitePerson(const JID& person, const std::string& reason = ""); + void setCreateAsReservedIfNew() {createAsReservedIfNew = true;} public: boost::signal onJoinComplete; boost::signal onJoinFailed; @@ -106,5 +108,7 @@ namespace Swift { bool joinComplete_; boost::bsignals::scoped_connection scopedConnection_; boost::posix_time::ptime joinSince_; + bool createAsReservedIfNew; + bool unlocking; }; } -- cgit v0.10.2-6-g49f6