From 0da93507bea788cf6bd8f327478caddf3ea679e5 Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Sun, 12 Sep 2010 21:36:48 +0100 Subject: Block MUC bookmarks until the server has responded. Else there could be bookmarks overwritten in an infeasibly unlikely race condition. Resolves: #340 diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index acc5e1d..e1a53b4 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -39,11 +39,15 @@ ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRo presenceSender_ = presenceSender; uiEventStream_ = uiEventStream; mucBookmarkManager_ = new MUCBookmarkManager(iqRouter); + mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this)); mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1)); mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1)); presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1, _2)); uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1)); chatListWindow_ = chatListWindowFactory->createWindow(uiEventStream_); + if (chatListWindow_) { + chatListWindow_->setBookmarksEnabled(false); + } } ChatsManager::~ChatsManager() { @@ -56,6 +60,12 @@ ChatsManager::~ChatsManager() { delete mucBookmarkManager_; } +void ChatsManager::handleBookmarksReady() { + if (chatListWindow_) { + chatListWindow_->setBookmarksEnabled(true); + } +} + void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom()); if (it == mucControllers_.end() && bookmark.getAutojoin()) { diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 3efd507..752acff 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -52,6 +52,7 @@ namespace Swift { void handleMUCBookmarkAdded(const MUCBookmark& bookmark); void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); void handleUserLeftMUC(MUCController* mucController); + void handleBookmarksReady(); ChatController* getChatControllerOrFindAnother(const JID &contact); ChatController* createNewChatController(const JID &contact); ChatController* getChatControllerOrCreate(const JID &contact); diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h index fd176a6..3a7c30e 100644 --- a/Swift/Controllers/UIInterfaces/ChatListWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h @@ -15,6 +15,7 @@ namespace Swift { public: virtual ~ChatListWindow(); + virtual void setBookmarksEnabled(bool enabled) = 0; virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0; virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0; }; diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp index 5943078..86dfa8f 100644 --- a/Swift/QtUI/ChatList/QtChatListWindow.cpp +++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp @@ -21,6 +21,7 @@ namespace Swift { QtChatListWindow::QtChatListWindow(UIEventStream *uiEventStream, QWidget* parent) : QTreeView(parent) { eventStream_ = uiEventStream; + bookmarksEnabled_ = false; model_ = new ChatListModel(); setModel(model_); delegate_ = new ChatListDelegate(); @@ -45,6 +46,10 @@ QtChatListWindow::~QtChatListWindow() { delete emptyMenu_; } +void QtChatListWindow::setBookmarksEnabled(bool enabled) { + bookmarksEnabled_ = enabled; +} + void QtChatListWindow::handleClicked(const QModelIndex& index) { ChatListGroupItem* item = dynamic_cast<ChatListGroupItem*>(static_cast<ChatListItem*>(index.internalPointer())); if (item) { @@ -99,6 +104,9 @@ void QtChatListWindow::handleEditBookmark() { void QtChatListWindow::contextMenuEvent(QContextMenuEvent* event) { + if (!bookmarksEnabled_) { + return; + } QModelIndex index = indexAt(event->pos()); ChatListItem* baseItem = index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : NULL; contextMenuItem_ = baseItem; diff --git a/Swift/QtUI/ChatList/QtChatListWindow.h b/Swift/QtUI/ChatList/QtChatListWindow.h index 1215f83..2c13300 100644 --- a/Swift/QtUI/ChatList/QtChatListWindow.h +++ b/Swift/QtUI/ChatList/QtChatListWindow.h @@ -23,6 +23,7 @@ namespace Swift { virtual ~QtChatListWindow(); void addMUCBookmark(const MUCBookmark& bookmark); void removeMUCBookmark(const MUCBookmark& bookmark); + void setBookmarksEnabled(bool enabled); private slots: void handleItemActivated(const QModelIndex&); void handleAddBookmark(); @@ -34,6 +35,7 @@ namespace Swift { void contextMenuEvent(QContextMenuEvent* event); private: void setupContextMenus(); + bool bookmarksEnabled_; UIEventStream* eventStream_; ChatListModel* model_; ChatListDelegate* delegate_; diff --git a/Swiften/MUC/MUCBookmarkManager.cpp b/Swiften/MUC/MUCBookmarkManager.cpp index 77921e9..64615e4 100644 --- a/Swiften/MUC/MUCBookmarkManager.cpp +++ b/Swiften/MUC/MUCBookmarkManager.cpp @@ -18,6 +18,7 @@ namespace Swift { MUCBookmarkManager::MUCBookmarkManager(IQRouter* iqRouter) { iqRouter_ = iqRouter; + ready_ = false; boost::shared_ptr<GetPrivateStorageRequest<Storage> > request(new GetPrivateStorageRequest<Storage>(iqRouter_)); request->onResponse.connect(boost::bind(&MUCBookmarkManager::handleBookmarksReceived, this, _1, _2)); request->send(); @@ -27,6 +28,10 @@ void MUCBookmarkManager::handleBookmarksReceived(boost::shared_ptr<Storage> payl if (error) { return; } + + ready_ = true; + onBookmarksReady(); + storage = payload; std::vector<MUCBookmark> receivedBookmarks; @@ -57,6 +62,7 @@ bool MUCBookmarkManager::containsEquivalent(const std::vector<MUCBookmark>& list } void MUCBookmarkManager::replaceBookmark(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) { + if (!ready_) return; for (size_t i = 0; i < bookmarks_.size(); i++) { if (bookmarks_[i] == oldBookmark) { bookmarks_[i] = newBookmark; @@ -69,6 +75,7 @@ void MUCBookmarkManager::replaceBookmark(const MUCBookmark& oldBookmark, const M } void MUCBookmarkManager::addBookmark(const MUCBookmark& bookmark) { + if (!ready_) return; bookmarks_.push_back(bookmark); onBookmarkAdded(bookmark); flush(); @@ -76,6 +83,7 @@ void MUCBookmarkManager::addBookmark(const MUCBookmark& bookmark) { void MUCBookmarkManager::removeBookmark(const MUCBookmark& bookmark) { + if (!ready_) return; std::vector<MUCBookmark>::iterator it; for (it = bookmarks_.begin(); it != bookmarks_.end(); it++) { if ((*it) == bookmark) { diff --git a/Swiften/MUC/MUCBookmarkManager.h b/Swiften/MUC/MUCBookmarkManager.h index a942595..8067b4b 100644 --- a/Swiften/MUC/MUCBookmarkManager.h +++ b/Swiften/MUC/MUCBookmarkManager.h @@ -32,6 +32,10 @@ namespace Swift { public: boost::signal<void (const MUCBookmark&)> onBookmarkAdded; boost::signal<void (const MUCBookmark&)> onBookmarkRemoved; + /** + * When server bookmarks are ready to be used (request response has been received). + */ + boost::signal<void ()> onBookmarksReady; private: bool containsEquivalent(const std::vector<MUCBookmark>& list, const MUCBookmark& bookmark); @@ -39,6 +43,7 @@ namespace Swift { void flush(); private: + bool ready_; std::vector<MUCBookmark> bookmarks_; IQRouter* iqRouter_; boost::shared_ptr<Storage> storage; -- cgit v0.10.2-6-g49f6