summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-01-16 19:56:10 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-01-20 21:40:49 (GMT)
commit004dfd8d4305b767b624be10072597ef3e311753 (patch)
tree7f9a70ce336e9eca3bc78397640530939e55fa20
parent03d69bfd11549e1c8dcbf3b5300029ba9892cf8a (diff)
downloadswift-contrib-004dfd8d4305b767b624be10072597ef3e311753.zip
swift-contrib-004dfd8d4305b767b624be10072597ef3e311753.tar.bz2
Use a dedicated Join MUC dialog.
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp79
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h14
-rw-r--r--Swift/Controllers/Chat/MUCSearchController.cpp105
-rw-r--r--Swift/Controllers/Chat/MUCSearchController.h34
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp12
-rw-r--r--Swift/Controllers/DiscoServiceWalker.cpp4
-rw-r--r--Swift/Controllers/DiscoServiceWalker.h4
-rw-r--r--Swift/Controllers/MainController.cpp6
-rw-r--r--Swift/Controllers/MainController.h1
-rw-r--r--Swift/Controllers/UIEvents/JoinMUCUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h23
-rw-r--r--Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h15
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindow.h27
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h18
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindow.h11
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h12
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp38
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h25
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchModel.cpp16
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchServiceItem.h6
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp168
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.h23
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui266
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.cpp53
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.h32
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.ui116
-rw-r--r--Swift/QtUI/QtMainWindow.cpp5
-rw-r--r--Swift/QtUI/QtUIFactory.cpp9
-rw-r--r--Swift/QtUI/QtUIFactory.h3
-rw-r--r--Swift/QtUI/SConscript3
31 files changed, 708 insertions, 424 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 722b98f..b7e8432 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -9,15 +9,20 @@
#include <boost/bind.hpp>
#include "Swift/Controllers/Chat/ChatController.h"
+#include "Swift/Controllers/Chat/MUCSearchController.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
#include "Swift/Controllers/Chat/MUCController.h"
#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
+#include "Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h"
#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h"
#include "Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h"
#include "Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h"
#include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h"
+#include "Swift/Controllers/UIInterfaces/JoinMUCWindow.h"
+#include "Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h"
#include "Swiften/Presence/PresenceSender.h"
+#include "Swiften/Client/NickResolver.h"
#include "Swiften/MUC/MUCManager.h"
#include "Swiften/Elements/ChatState.h"
#include "Swiften/MUC/MUCBookmarkManager.h"
@@ -27,7 +32,30 @@ namespace Swift {
typedef std::pair<JID, ChatController*> JIDChatControllerPair;
typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
-ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager) : jid_(jid), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry), entityCapsProvider_(entityCapsProvider), mucManager(mucManager) {
+ChatsManager::ChatsManager(
+ JID jid, StanzaChannel* stanzaChannel,
+ IQRouter* iqRouter,
+ EventController* eventController,
+ ChatWindowFactory* chatWindowFactory,
+ JoinMUCWindowFactory* joinMUCWindowFactory,
+ NickResolver* nickResolver,
+ PresenceOracle* presenceOracle,
+ PresenceSender* presenceSender,
+ UIEventStream* uiEventStream,
+ ChatListWindowFactory* chatListWindowFactory,
+ bool useDelayForLatency,
+ TimerFactory* timerFactory,
+ MUCRegistry* mucRegistry,
+ EntityCapsProvider* entityCapsProvider,
+ MUCManager* mucManager,
+ MUCSearchWindowFactory* mucSearchWindowFactory,
+ SettingsProvider* settings) :
+ jid_(jid),
+ joinMUCWindowFactory_(joinMUCWindowFactory),
+ useDelayForLatency_(useDelayForLatency),
+ mucRegistry_(mucRegistry),
+ entityCapsProvider_(entityCapsProvider),
+ mucManager(mucManager) {
timerFactory_ = timerFactory;
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
@@ -43,10 +71,14 @@ ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRo
presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1));
uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1));
chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_);
+ joinMUCWindow_ = NULL;
+ mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, settings);
+ mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
setupBookmarks();
}
ChatsManager::~ChatsManager() {
+ delete joinMUCWindow_;
foreach (JIDChatControllerPair controllerPair, chatControllers_) {
delete controllerPair.second;
}
@@ -54,6 +86,7 @@ ChatsManager::~ChatsManager() {
delete controllerPair.second;
}
delete mucBookmarkManager_;
+ delete mucSearchController_;
}
void ChatsManager::setupBookmarks() {
@@ -80,7 +113,7 @@ void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
std::map<JID, MUCController*>::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());
+ handleJoinMUCRequest(bookmark.getRoom(), bookmark.getNick(), false);
}
chatListWindow_->addMUCBookmark(bookmark);
}
@@ -106,11 +139,6 @@ void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
handleChatRequest(chatEvent->getContact());
return;
}
- boost::shared_ptr<JoinMUCUIEvent> joinMUCEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event);
- if (joinMUCEvent) {
- handleJoinMUCRequest(joinMUCEvent->getJID(), joinMUCEvent->getNick());
- return;
- }
boost::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = boost::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event);
if (removeMUCBookmarkEvent) {
mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark());
@@ -121,10 +149,23 @@ void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark());
return;
}
+
boost::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = boost::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event);
if (editMUCBookmarkEvent) {
mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark());
- return;
+ }
+ else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event)) {
+ handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getNick(), false);
+ }
+ else if (boost::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) {
+ if (!joinMUCWindow_) {
+ joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow();
+ joinMUCWindow_->onJoinMUC.connect(boost::bind(&ChatsManager::handleJoinMUCRequest, this, _1, _2, _3));
+ joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this));
+ }
+ joinMUCWindow_->setMUC("");
+ joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_));
+ joinMUCWindow_->show();
}
}
@@ -239,7 +280,16 @@ void ChatsManager::rebindControllerJID(const JID& from, const JID& to) {
chatControllers_[to]->setToJID(to);
}
-void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<String>& nickMaybe) {
+void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<String>& nickMaybe, bool autoJoin) {
+ if (autoJoin) {
+ MUCBookmark bookmark(mucJID, mucJID.getNode());
+ bookmark.setAutojoin(true);
+ if (nickMaybe) {
+ bookmark.setNick(*nickMaybe);
+ }
+ mucBookmarkManager_->addBookmark(bookmark);
+ }
+
std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID);
if (it != mucControllers_.end()) {
it->second->rejoin();
@@ -254,6 +304,10 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional
mucControllers_[mucJID]->activateChatWindow();
}
+void ChatsManager::handleSearchMUCRequest() {
+ mucSearchController_->openSearchWindow();
+}
+
void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
JID jid = message->getFrom();
boost::shared_ptr<MessageEvent> event(new MessageEvent(message));
@@ -278,4 +332,11 @@ void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
getChatControllerOrCreate(jid)->handleIncomingMessage(event);
}
+void ChatsManager::handleMUCSelectedAfterSearch(const JID& muc) {
+ if (joinMUCWindow_) {
+ joinMUCWindow_->setMUC(muc.toString());
+ }
+}
+
+
}
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 2b771eb..62b14d9 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -25,6 +25,8 @@ namespace Swift {
class MUCController;
class MUCManager;
class ChatWindowFactory;
+ class JoinMUCWindow;
+ class JoinMUCWindowFactory;
class NickResolver;
class PresenceOracle;
class AvatarManager;
@@ -37,10 +39,13 @@ namespace Swift {
class TimerFactory;
class EntityCapsProvider;
class DirectedPresenceSender;
+ class MUCSearchWindowFactory;
+ class SettingsProvider;
+ class MUCSearchController;
class ChatsManager {
public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager);
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, SettingsProvider* settings);
virtual ~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setOnline(bool enabled);
@@ -48,7 +53,9 @@ namespace Swift {
void handleIncomingMessage(boost::shared_ptr<Message> message);
private:
void handleChatRequest(const String& contact);
- void handleJoinMUCRequest(const JID& muc, const boost::optional<String>& nick);
+ void handleJoinMUCRequest(const JID& muc, const boost::optional<String>& nick, bool autoJoin);
+ void handleSearchMUCRequest();
+ void handleMUCSelectedAfterSearch(const JID&);
void rebindControllerJID(const JID& from, const JID& to);
void handlePresenceChange(boost::shared_ptr<Presence> newPresence);
void handleUIEvent(boost::shared_ptr<UIEvent> event);
@@ -68,6 +75,7 @@ namespace Swift {
StanzaChannel* stanzaChannel_;
IQRouter* iqRouter_;
ChatWindowFactory* chatWindowFactory_;
+ JoinMUCWindowFactory* joinMUCWindowFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
@@ -76,11 +84,13 @@ namespace Swift {
MUCBookmarkManager* mucBookmarkManager_;
boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
ChatListWindow* chatListWindow_;
+ JoinMUCWindow* joinMUCWindow_;
boost::bsignals::scoped_connection uiEventConnection_;
bool useDelayForLatency_;
TimerFactory* timerFactory_;
MUCRegistry* mucRegistry_;
EntityCapsProvider* entityCapsProvider_;
MUCManager* mucManager;
+ MUCSearchController* mucSearchController_;
};
}
diff --git a/Swift/Controllers/Chat/MUCSearchController.cpp b/Swift/Controllers/Chat/MUCSearchController.cpp
index c254e51..c85f793 100644
--- a/Swift/Controllers/Chat/MUCSearchController.cpp
+++ b/Swift/Controllers/Chat/MUCSearchController.cpp
@@ -11,12 +11,9 @@
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
-#include <Swiften/Disco/GetDiscoInfoRequest.h>
#include <Swiften/Disco/GetDiscoItemsRequest.h>
-
+#include <Swiften/Base/Log.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h>
-#include <Swift/Controllers/UIInterfaces/MUCSearchWindow.h>
#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
#include <Swift/Controllers/DiscoServiceWalker.h>
#include <Swiften/Client/NickResolver.h>
@@ -25,57 +22,43 @@ namespace Swift {
static const String SEARCHED_SERVICES = "searchedServices";
-MUCSearchController::MUCSearchController(const JID& jid, UIEventStream* uiEventStream, MUCSearchWindowFactory* factory, IQRouter* iqRouter, SettingsProvider* settings, NickResolver *nickResolver) : jid_(jid) {
- iqRouter_ = iqRouter;
- settings_ = settings;
- uiEventStream_ = uiEventStream;
- nickResolver_ = nickResolver;
+MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, SettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(NULL), walker_(NULL) {
itemsInProgress_ = 0;
- uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&MUCSearchController::handleUIEvent, this, _1));
- window_ = NULL;
- factory_ = factory;
- loadServices();
+ loadSavedServices();
}
MUCSearchController::~MUCSearchController() {
- foreach (DiscoServiceWalker* walker, walksInProgress_) {
- delete walker;
- }
+ delete walker_;
delete window_;
}
-void MUCSearchController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<RequestMUCSearchUIEvent> searchEvent = boost::dynamic_pointer_cast<RequestMUCSearchUIEvent>(event);
- if (searchEvent) {
- if (!window_) {
- window_ = factory_->createMUCSearchWindow(uiEventStream_);
- window_->onAddService.connect(boost::bind(&MUCSearchController::handleAddService, this, _1));
- window_->addSavedServices(savedServices_);
- handleAddService(JID(jid_.getDomain()));
- }
- window_->setMUC("");
- window_->setNick(nickResolver_->jidToNick(jid_));
- window_->show();
- return;
+void MUCSearchController::openSearchWindow() {
+ if (!window_) {
+ window_ = factory_->createMUCSearchWindow();
+ window_->onSearchService.connect(boost::bind(&MUCSearchController::handleSearchService, this, _1));
+ window_->onFinished.connect(boost::bind(&MUCSearchController::handleMUCSearchFinished, this, _1));
+ window_->addSavedServices(savedServices_);
+ handleSearchService(JID(jid_.getDomain()));
}
+ window_->show();
}
-void MUCSearchController::loadServices() {
+void MUCSearchController::loadSavedServices() {
savedServices_.clear();
foreach (String stringItem, settings_->getStringSetting(SEARCHED_SERVICES).split('\n')) {
savedServices_.push_back(JID(stringItem));
}
}
-void MUCSearchController::addAndSaveServices(const JID& jid) {
+void MUCSearchController::addToSavedServices(const JID& jid) {
savedServices_.erase(std::remove(savedServices_.begin(), savedServices_.end(), jid), savedServices_.end());
- savedServices_.push_back(jid);
+ savedServices_.push_front(jid);
+
String collapsed;
- bool storeThis = savedServices_.size() < 15;
+ int i = 0;
foreach (JID jidItem, savedServices_) {
- if (!storeThis) {
- storeThis = true;
- continue;
+ if (i >= 15) {
+ break;
}
if (!collapsed.isEmpty()) {
collapsed += "\n";
@@ -86,21 +69,32 @@ void MUCSearchController::addAndSaveServices(const JID& jid) {
window_->addSavedServices(savedServices_);
}
-void MUCSearchController::handleAddService(const JID& jid) {
+void MUCSearchController::handleSearchService(const JID& jid) {
if (!jid.isValid()) {
//Set Window to say error this isn't valid
return;
}
- addAndSaveServices(jid);
- services_.push_back(jid);
- serviceDetails_[jid].setComplete(false);
+ addToSavedServices(jid);
+
+ services_.clear();
+ serviceDetails_.clear();
+
window_->setSearchInProgress(true);
refreshView();
- DiscoServiceWalker* walker = new DiscoServiceWalker(jid, iqRouter_);
- walker->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
- walker->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this, walker));
- walksInProgress_.push_back(walker);
- walker->beginWalk();
+
+ if (walker_) {
+ walker_->endWalk();
+ walker_->onServiceFound.disconnect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
+ walker_->onWalkComplete.disconnect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
+ delete walker_;
+ }
+
+ SWIFT_LOG(debug) << "Starting walking MUC services" << std::endl;
+ itemsInProgress_ = 0;
+ walker_ = new DiscoServiceWalker(jid, iqRouter_);
+ walker_->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
+ walker_->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
+ walker_->beginWalk();
}
void MUCSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) {
@@ -116,25 +110,27 @@ void MUCSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_
}
}
if (isMUC) {
- services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end()); /* Bring it back to the end on a refresh */
+ SWIFT_LOG(debug) << "MUC Service found: " << jid << std::endl;
+ services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end());
services_.push_back(jid);
serviceDetails_[jid].setName(name);
serviceDetails_[jid].setJID(jid);
serviceDetails_[jid].setComplete(false);
itemsInProgress_++;
+ SWIFT_LOG(debug) << "Requesting items of " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(jid, iqRouter_);
discoItemsRequest->onResponse.connect(boost::bind(&MUCSearchController::handleRoomsItemsResponse, this, _1, _2, jid));
discoItemsRequest->send();
- } else {
+ }
+ else {
removeService(jid);
}
refreshView();
}
-void MUCSearchController::handleDiscoWalkFinished(DiscoServiceWalker* walker) {
- walksInProgress_.erase(std::remove(walksInProgress_.begin(), walksInProgress_.end(), walker), walksInProgress_.end());
+void MUCSearchController::handleDiscoWalkFinished() {
+ SWIFT_LOG(debug) << "MUC Walk finished" << std::endl;
updateInProgressness();
- delete walker;
}
void MUCSearchController::removeService(const JID& jid) {
@@ -145,6 +141,7 @@ void MUCSearchController::removeService(const JID& jid) {
void MUCSearchController::handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid) {
itemsInProgress_--;
+ SWIFT_LOG(debug) << "Items received for " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
updateInProgressness();
if (error) {
handleDiscoError(jid, error);
@@ -171,7 +168,13 @@ void MUCSearchController::refreshView() {
}
void MUCSearchController::updateInProgressness() {
- window_->setSearchInProgress(walksInProgress_.size() + itemsInProgress_ > 0);
+ window_->setSearchInProgress((walker_ && walker_->isActive()) || itemsInProgress_ > 0);
+}
+
+void MUCSearchController::handleMUCSearchFinished(const boost::optional<JID>& result) {
+ if (result) {
+ onMUCSelected(*result);
+ }
}
}
diff --git a/Swift/Controllers/Chat/MUCSearchController.h b/Swift/Controllers/Chat/MUCSearchController.h
index 6caee54..6d3afd1 100644
--- a/Swift/Controllers/Chat/MUCSearchController.h
+++ b/Swift/Controllers/Chat/MUCSearchController.h
@@ -88,32 +88,38 @@ namespace Swift {
class MUCSearchController {
public:
- MUCSearchController(const JID& jid, UIEventStream* uiEventStream, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, SettingsProvider* settings, NickResolver* nickResolver);
+ MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, SettingsProvider* settings);
~MUCSearchController();
+
+ void openSearchWindow();
+
+ public:
+ boost::signal<void (const JID&)> onMUCSelected;
+
private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleAddService(const JID& jid);
+ void handleSearchService(const JID& jid);
void handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid);
void handleDiscoError(const JID& jid, ErrorPayload::ref error);
void handleDiscoServiceFound(const JID&, boost::shared_ptr<DiscoInfo>);
- void handleDiscoWalkFinished(DiscoServiceWalker* walker);
+ void handleDiscoWalkFinished();
+ void handleMUCSearchFinished(const boost::optional<JID>& result);
void removeService(const JID& jid);
void refreshView();
- void loadServices();
- void addAndSaveServices(const JID& jid);
+ void loadSavedServices();
+ void addToSavedServices(const JID& jid);
void updateInProgressness();
- UIEventStream* uiEventStream_;
- MUCSearchWindow* window_;
+
+ private:
+ JID jid_;
MUCSearchWindowFactory* factory_;
+ IQRouter* iqRouter_;
SettingsProvider* settings_;
- NickResolver* nickResolver_;
- boost::bsignals::scoped_connection uiEventConnection_;
- std::vector<JID> services_;
- std::vector<JID> savedServices_;
+ MUCSearchWindow* window_;
+ DiscoServiceWalker* walker_;
+ std::list<JID> services_;
+ std::list<JID> savedServices_;
std::map<JID, MUCService> serviceDetails_;
std::vector<DiscoServiceWalker*> walksInProgress_;
- IQRouter* iqRouter_;
- JID jid_;
int itemsInProgress_;
};
}
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 6d20f70..be262bc 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -11,8 +11,11 @@
#include "Swift/Controllers/Chat/ChatsManager.h"
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
+#include "Swift/Controllers/Settings/DummySettingsProvider.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h"
+#include "Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h"
+#include "Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h"
#include "Swiften/Client/Client.h"
#include "Swiften/Disco/EntityCapsManager.h"
#include "Swiften/Disco/CapsProvider.h"
@@ -68,6 +71,7 @@ public:
capsProvider_ = new DummyCapsProvider();
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
+ joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
xmppRoster_ = new XMPPRosterImpl();
mucRegistry_ = new MUCRegistry();
nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
@@ -79,8 +83,10 @@ public:
uiEventStream_ = new UIEventStream();
entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
+ mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>();
+ settings_ = new DummySettingsProvider();
mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(NULL);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, settings_);
avatarManager_ = new NullAvatarManager();
manager_->setAvatarManager(avatarManager_);
@@ -88,6 +94,7 @@ public:
void tearDown() {
//delete chatListWindowFactory_;
+ delete settings_;
delete mocks_;
delete avatarManager_;
delete manager_;
@@ -325,6 +332,7 @@ private:
IQRouter* iqRouter_;
EventController* eventController_;
ChatWindowFactory* chatWindowFactory_;
+ JoinMUCWindowFactory* joinMUCWindowFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
@@ -334,11 +342,13 @@ private:
MockRepository* mocks_;
UIEventStream* uiEventStream_;
ChatListWindowFactory* chatListWindowFactory_;
+ MUCSearchWindowFactory* mucSearchWindowFactory_;
MUCRegistry* mucRegistry_;
DirectedPresenceSender* directedPresenceSender_;
EntityCapsManager* entityCapsManager_;
CapsProvider* capsProvider_;
MUCManager* mucManager_;
+ DummySettingsProvider* settings_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/DiscoServiceWalker.cpp b/Swift/Controllers/DiscoServiceWalker.cpp
index 505acb4..15d2aaa 100644
--- a/Swift/Controllers/DiscoServiceWalker.cpp
+++ b/Swift/Controllers/DiscoServiceWalker.cpp
@@ -141,10 +141,12 @@ void DiscoServiceWalker::markNodeCompleted(const JID& jid) {
servicesBeingSearched_.erase(jid);
/* All results are in */
if (servicesBeingSearched_.size() == 0) {
+ active_ = false;
onWalkComplete();
}
/* Check if we're on a rampage */
- if (searchedServices_.size() >= maxSteps_) {
+ else if (searchedServices_.size() >= maxSteps_) {
+ active_ = false;
onWalkComplete();
}
}
diff --git a/Swift/Controllers/DiscoServiceWalker.h b/Swift/Controllers/DiscoServiceWalker.h
index 167174a..00e2436 100644
--- a/Swift/Controllers/DiscoServiceWalker.h
+++ b/Swift/Controllers/DiscoServiceWalker.h
@@ -41,6 +41,10 @@ namespace Swift {
*/
void endWalk();
+ bool isActive() const {
+ return active_;
+ }
+
/** Emitted for each service found. */
boost::signal<void(const JID&, boost::shared_ptr<DiscoInfo>)> onServiceFound;
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index bc40f95..f07a964 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -98,7 +98,6 @@ MainController::MainController(
rosterController_ = NULL;
chatsManager_ = NULL;
eventWindowController_ = NULL;
- mucSearchController_ = NULL;
userSearchControllerChat_ = NULL;
userSearchControllerAdd_ = NULL;
quitRequested_ = false;
@@ -171,8 +170,6 @@ MainController::~MainController() {
void MainController::resetClient() {
resetCurrentError();
resetPendingReconnects();
- delete mucSearchController_;
- mucSearchController_ = NULL;
delete eventWindowController_;
eventWindowController_ = NULL;
delete chatsManager_;
@@ -235,7 +232,7 @@ void MainController::handleConnected() {
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager());
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, settings_);
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
chatsManager_->setAvatarManager(client_->getAvatarManager());
@@ -251,7 +248,6 @@ void MainController::handleConnected() {
client_->getDiscoManager()->setDiscoInfo(discoInfo);
- mucSearchController_ = new MUCSearchController(jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), settings_, client_->getNickResolver());
userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, uiFactory_, client_->getIQRouter());
userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, uiFactory_, client_->getIQRouter());
}
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 900319e..a933a5a 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -139,7 +139,6 @@ namespace Swift {
String certificateFile_;
boost::shared_ptr<ErrorEvent> lastDisconnectError_;
bool useDelayForLatency_;
- MUCSearchController* mucSearchController_;
UserSearchController* userSearchControllerChat_;
UserSearchController* userSearchControllerAdd_;
int timeBeforeNextReconnect_;
diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
index d294fe8..2a2cd96 100644
--- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
@@ -7,6 +7,7 @@
#pragma once
#include <boost/optional.hpp>
+#include <boost/shared_ptr.hpp>
#include "Swiften/Base/String.h"
#include "Swift/Controllers/UIEvents/UIEvent.h"
@@ -14,6 +15,7 @@
namespace Swift {
class JoinMUCUIEvent : public UIEvent {
public:
+ typedef boost::shared_ptr<JoinMUCUIEvent> ref;
JoinMUCUIEvent(const JID& jid, const boost::optional<String>& nick = boost::optional<String>()) : jid_(jid), nick_(nick) {};
boost::optional<String> getNick() {return nick_;};
JID getJID() {return jid_;};
diff --git a/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h
new file mode 100644
index 0000000..1415140
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Base/String.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+ class RequestJoinMUCUIEvent : public UIEvent {
+ public:
+ typedef boost::shared_ptr<RequestJoinMUCUIEvent> ref;
+
+ RequestJoinMUCUIEvent() {
+ }
+ };
+}
diff --git a/Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h b/Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h
deleted file mode 100644
index 623cd00..0000000
--- a/Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-
-namespace Swift {
- class RequestMUCSearchUIEvent : public UIEvent {
-
- };
-}
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
new file mode 100644
index 0000000..8cf712c
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include <Swiften/Base/String.h>
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/JID/JID.h>
+
+namespace Swift {
+ class JoinMUCWindow {
+ public:
+ virtual ~JoinMUCWindow() {};
+
+ virtual void setNick(const String& nick) = 0;
+ virtual void setMUC(const String& nick) = 0;
+ virtual void show() = 0;
+
+ boost::signal<void (const JID& /* muc */, const String& /* nick */, bool /* autoJoin */)> onJoinMUC;
+ boost::signal<void ()> onSearchMUC;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
new file mode 100644
index 0000000..9c8bd77
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
+
+namespace Swift {
+ class JoinMUCWindowFactory {
+ public:
+ virtual ~JoinMUCWindowFactory() {};
+
+ virtual JoinMUCWindow* createJoinMUCWindow() = 0;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
index 3c0ab12..ded2a0a 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
@@ -10,10 +10,10 @@
#include <vector>
+#include <boost/optional.hpp>
#include "Swiften/Base/String.h"
#include "Swiften/JID/JID.h"
-
-#include "Swift/Controllers/Chat/MUCSearchController.h"
+#include <Swift/Controllers/Chat/MUCSearchController.h>
namespace Swift {
@@ -21,15 +21,14 @@ namespace Swift {
public:
virtual ~MUCSearchWindow() {};
- virtual void setNick(const String& nick) = 0;
- virtual void setMUC(const String& nick) = 0;
virtual void clearList() = 0;
virtual void addService(const MUCService& service) = 0;
- virtual void addSavedServices(const std::vector<JID>& services) = 0;
+ virtual void addSavedServices(const std::list<JID>& services) = 0;
virtual void setSearchInProgress(bool searching) = 0;
virtual void show() = 0;
- boost::signal<void (const JID&)> onAddService;
+ boost::signal<void (const JID&)> onSearchService;
+ boost::signal<void (const boost::optional<JID>&)> onFinished;
};
}
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
index 1f0bf90..d334dff 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
@@ -14,6 +14,6 @@ namespace Swift {
public:
virtual ~MUCSearchWindowFactory() {};
- virtual MUCSearchWindow* createMUCSearchWindow(UIEventStream* eventStream) = 0;
+ virtual MUCSearchWindow* createMUCSearchWindow() = 0;
};
}
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index acb7638..4783dc8 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -12,11 +12,21 @@
#include <Swift/Controllers/UIInterfaces/LoginWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h>
namespace Swift {
- class UIFactory : public ChatListWindowFactory, public ChatWindowFactory, public EventWindowFactory, public LoginWindowFactory, public MainWindowFactory, public MUCSearchWindowFactory, public XMLConsoleWidgetFactory, public UserSearchWindowFactory {
+ class UIFactory :
+ public ChatListWindowFactory,
+ public ChatWindowFactory,
+ public EventWindowFactory,
+ public LoginWindowFactory,
+ public MainWindowFactory,
+ public MUCSearchWindowFactory,
+ public XMLConsoleWidgetFactory,
+ public UserSearchWindowFactory,
+ public JoinMUCWindowFactory {
public:
virtual ~UIFactory() {}
};
diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp
new file mode 100644
index 0000000..b1b4175
--- /dev/null
+++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
+#include <QFont>
+#include <QColor>
+
+namespace Swift {
+MUCSearchEmptyItem::MUCSearchEmptyItem(MUCSearchServiceItem* parent) : parent(parent) {
+ parent->addRoom(this);
+}
+
+MUCSearchServiceItem* MUCSearchEmptyItem::getParent() {
+ return parent;
+}
+
+QVariant MUCSearchEmptyItem::data(int role) {
+ switch (role) {
+ case Qt::DisplayRole:
+ return QVariant("No rooms found");
+ case Qt::FontRole: {
+ QFont font;
+ font.setItalic(true);
+ return font;
+ }
+ case Qt::ForegroundRole:
+ return QColor(Qt::gray);
+ default:
+ return QVariant();
+ }
+}
+
+}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h
new file mode 100644
index 0000000..d752ae3
--- /dev/null
+++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/QtUI/MUCSearch/MUCSearchItem.h>
+
+namespace Swift {
+ class MUCSearchServiceItem;
+
+ class MUCSearchEmptyItem : public MUCSearchItem {
+ public:
+ MUCSearchEmptyItem(MUCSearchServiceItem* parent);
+
+ MUCSearchServiceItem* getParent();
+
+ QVariant data(int role);
+
+ private:
+ MUCSearchServiceItem* parent;
+ };
+}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
index 2526039..c657190 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
+++ b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
@@ -5,6 +5,7 @@
*/
#include "Swift/QtUI/MUCSearch/MUCSearchModel.h"
+#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h"
namespace Swift {
@@ -39,7 +40,6 @@ QModelIndex MUCSearchModel::index(int row, int column, const QModelIndex & paren
if (parent.isValid()) {
MUCSearchServiceItem* parentItem = static_cast<MUCSearchServiceItem*>(parent.internalPointer());
return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
-
} else {
return row < services_.size() ? createIndex(row, column, services_[row]) : QModelIndex();
}
@@ -55,10 +55,17 @@ QModelIndex MUCSearchModel::parent(const QModelIndex& index) const {
if (!item) {
return QModelIndex();
}
- if (dynamic_cast<MUCSearchServiceItem*>(item)) {
+ else if (dynamic_cast<MUCSearchServiceItem*>(item)) {
return QModelIndex();
}
- MUCSearchServiceItem* parent = dynamic_cast<MUCSearchRoomItem*>(item)->getParent();
+
+ MUCSearchServiceItem* parent = NULL;
+ if (MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(item)) {
+ parent = roomItem->getParent();
+ }
+ else if (MUCSearchEmptyItem* emptyItem = dynamic_cast<MUCSearchEmptyItem*>(item)) {
+ parent = emptyItem->getParent();
+ }
if (parent) {
int row = services_.indexOf(parent);
return createIndex(row, 1, parent);
@@ -74,7 +81,8 @@ int MUCSearchModel::rowCount(const QModelIndex& parentIndex) const {
}
if (dynamic_cast<MUCSearchServiceItem*>(static_cast<MUCSearchItem*>(parentIndex.internalPointer()))) {
return services_[parentIndex.row()]->rowCount();
- } else {
+ }
+ else {
return 0;
}
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
index 860792f..411727d 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
@@ -15,9 +15,9 @@ namespace Swift {
class MUCSearchServiceItem : public MUCSearchItem {
public:
MUCSearchServiceItem(const QString& jidString) : jidString_(jidString) {}
- void addRoom(MUCSearchRoomItem* room) {rooms_.push_back(room);}
+ void addRoom(MUCSearchItem* room) {rooms_.push_back(room);}
int rowCount() {return rooms_.count();}
- MUCSearchRoomItem* getItem(int i) {return rooms_[i];}
+ MUCSearchItem* getItem(int i) {return rooms_[i];}
QVariant data(int role) {
switch (role) {
case Qt::DisplayRole: return QVariant(jidString_);
@@ -26,7 +26,7 @@ namespace Swift {
}
QString getHost() {return jidString_;}
private:
- QList<MUCSearchRoomItem*> rooms_;
+ QList<MUCSearchItem*> rooms_;
QString jidString_;
};
}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
index 7d2caba..3bdc433 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
@@ -10,43 +10,42 @@
#include <QMovie>
#include <QScrollBar>
#include <QTimer>
+#include <QPushButton>
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h"
#include "Swift/QtUI/MUCSearch/MUCSearchModel.h"
#include "Swift/QtUI/MUCSearch/MUCSearchDelegate.h"
+#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h"
#include "Swift/QtUI/QtSwiftUtil.h"
namespace Swift {
-QtMUCSearchWindow::QtMUCSearchWindow(UIEventStream* eventStream) {
+QtMUCSearchWindow::QtMUCSearchWindow() {
+ ui_.setupUi(this);
#ifndef Q_WS_MAC
setWindowIcon(QIcon(":/logo-icon-16.png"));
#endif
- eventStream_ = eventStream;
- setupUi(this);
- showEmptyRooms_->hide();
- filterLabel_->hide();
- filter_->hide();
+ setModal(true);
+ ui_.filter_->hide();
model_ = new MUCSearchModel();
delegate_ = new MUCSearchDelegate();
- results_->setModel(model_);
- results_->setItemDelegate(delegate_);
- results_->setHeaderHidden(true);
-#ifdef SWIFT_PLATFORM_MACOSX
- results_->setAlternatingRowColors(true);
-#endif
- connect(service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&)));
- connect(room_, SIGNAL(returnPressed()), this, SLOT(handleJoin()));
- connect(nickName_, SIGNAL(returnPressed()), room_, SLOT(setFocus()));
- connect(searchButton_, SIGNAL(clicked()), this, SLOT(handleSearch()));
- connect(joinButton_, SIGNAL(clicked()), this, SLOT(handleJoin()));
- connect(results_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleSelected(const QModelIndex&)));
- connect(results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
- throbber_ = new QLabel("Searching", results_);
+ ui_.results_->setModel(model_);
+ ui_.results_->setItemDelegate(delegate_);
+ ui_.results_->setHeaderHidden(true);
+ ui_.results_->setRootIsDecorated(true);
+ ui_.results_->setAnimated(true);
+ ui_.results_->setAlternatingRowColors(true);
+ connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&)));
+ connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
+ // Not using a button box, because i can't seem to be able to make the ok button non-default (on mac)
+ connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ throbber_ = new QLabel("Searching", ui_.results_);
throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_));
throbber_->setToolTip("Searching");
+
hasHadScrollBars_ = false;
updateThrobberPosition();
setSearchInProgress(false);
@@ -62,8 +61,8 @@ void QtMUCSearchWindow::resizeEvent(QResizeEvent* /*event*/) {
void QtMUCSearchWindow::updateThrobberPosition() {
bool isShown = throbber_->isVisible();
- int resultWidth = results_->width();
- int resultHeight = results_->height();
+ int resultWidth = ui_.results_->width();
+ int resultHeight = ui_.results_->height();
//throbberWidth = throbber_->movie()->scaledSize().width();
//throbberHeight = throbber_->movie()->scaledSize().height();
int throbberWidth = 16; /* This is nasty, but the above doesn't work! */
@@ -72,99 +71,43 @@ void QtMUCSearchWindow::updateThrobberPosition() {
* because if you listen for the expanded/collapsed signals, you seem to get them before the scrollbars are updated.
* This seems an acceptable workaround.
*/
- hasHadScrollBars_ |= results_->verticalScrollBar()->isVisible();
- int hMargin = hasHadScrollBars_ ? results_->verticalScrollBar()->width() + 2 : 2;
+ hasHadScrollBars_ |= ui_.results_->verticalScrollBar()->isVisible();
+ int hMargin = hasHadScrollBars_ ? ui_.results_->verticalScrollBar()->width() + 2 : 2;
int vMargin = 2; /* We don't get horizontal scrollbars */
throbber_->setGeometry(QRect(resultWidth - throbberWidth - hMargin, resultHeight - throbberHeight - vMargin, throbberWidth, throbberHeight)); /* include margins */
throbber_->setVisible(isShown);
}
-void QtMUCSearchWindow::addSavedServices(const std::vector<JID>& services) {
- service_->clear();
- foreach (JID jid, services) {
- service_->addItem(P2QSTRING(jid.toString()));
+void QtMUCSearchWindow::addSavedServices(const std::list<JID>& services) {
+ ui_.service_->clear();
+ foreach (const JID& jid, services) {
+ ui_.service_->addItem(P2QSTRING(jid.toString()));
}
- service_->clearEditText();
-}
-
-void QtMUCSearchWindow::handleActivated(const QModelIndex& index) {
- if (!index.isValid()) {
- return;
+ if (!services.empty()) {
+ ui_.service_->setEditText(P2QSTRING(services.begin()->toString()));
}
- MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(index.internalPointer()));
- if (roomItem) {
- handleSelected(index);
- handleJoin();
+ else {
+ ui_.service_->clearEditText();
}
}
-void QtMUCSearchWindow::handleSelected(const QModelIndex& current) {
- if (!current.isValid()) {
+void QtMUCSearchWindow::handleActivated(const QModelIndex& index) {
+ if (!index.isValid()) {
return;
- }
- MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(current.internalPointer()));
- if (roomItem) {
- room_->setText(roomItem->getNode() + "@" + roomItem->getParent()->getHost());
}
-
-}
-
-void QtMUCSearchWindow::handleSearch(const QString& text) {
- if (text.isEmpty()) {
- return;
+ if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(index.internalPointer()))) {
+ accept();
}
- onAddService(JID(Q2PSTRING(text)));
}
void QtMUCSearchWindow::handleSearch() {
- handleSearch(service_->currentText());
-}
-
-
-void QtMUCSearchWindow::handleJoin() {
- if (room_->text().isEmpty()) {
- handleSelected(results_->currentIndex());
- }
- if (room_->text().isEmpty()) {
- return;
- }
- boost::optional<String> maybeNick;
- if (!nickName_->text().isEmpty()) {
- lastSetNick_ = Q2PSTRING(nickName_->text());
- maybeNick = lastSetNick_;
- }
-
- JID room(Q2PSTRING(room_->text()));
- if (joinAutomatically_->isChecked()) {
- createAutoJoin(room, maybeNick);
- }
- eventStream_->send(boost::shared_ptr<UIEvent>(new JoinMUCUIEvent(room, maybeNick)));
- hide();
+ handleSearch(ui_.service_->currentText());
}
-void QtMUCSearchWindow::createAutoJoin(const JID& room, boost::optional<String> passedNick) {
- String nick = lastSetNick_;
- if (passedNick) {
- nick = passedNick.get();
+void QtMUCSearchWindow::handleSearch(const QString& service) {
+ if (!service.isEmpty()) {
+ onSearchService(JID(Q2PSTRING(service)));
}
- MUCBookmark bookmark(room, room.getNode());
- bookmark.setAutojoin(true);
- if (!nick.isEmpty()) {
- bookmark.setNick(nick);
- }
- //if (!password.isEmpty()) {
- // bookmark.setPassword(password);
- //}
- eventStream_->send(boost::shared_ptr<UIEvent>(new AddMUCBookmarkUIEvent(bookmark)));
-}
-
-void QtMUCSearchWindow::setNick(const String& nick) {
- nickName_->setText(P2QSTRING(nick));
- lastSetNick_ = nick;
-}
-
-void QtMUCSearchWindow::setMUC(const String& nick) {
- room_->setText(P2QSTRING(nick));
}
void QtMUCSearchWindow::show() {
@@ -179,11 +122,16 @@ void QtMUCSearchWindow::clearList() {
void QtMUCSearchWindow::addService(const MUCService& service) {
updateThrobberPosition();
MUCSearchServiceItem* serviceItem = new MUCSearchServiceItem(P2QSTRING(service.getJID().toString()));
- foreach (MUCService::MUCRoom room, service.getRooms()) {
- new MUCSearchRoomItem(P2QSTRING(room.getNode()), serviceItem);
+ if (service.getRooms().size() > 0) {
+ foreach (MUCService::MUCRoom room, service.getRooms()) {
+ new MUCSearchRoomItem(P2QSTRING(room.getNode()), serviceItem);
+ }
+ }
+ else {
+ new MUCSearchEmptyItem(serviceItem);
}
model_->addService(serviceItem);
- results_->expandAll();
+ ui_.results_->expandAll();
}
void QtMUCSearchWindow::setSearchInProgress(bool searching) {
@@ -195,4 +143,24 @@ void QtMUCSearchWindow::setSearchInProgress(bool searching) {
throbber_->setVisible(searching);
}
+void QtMUCSearchWindow::accept() {
+ QModelIndexList selection = ui_.results_->selectionModel()->selectedIndexes();
+ if (selection.isEmpty()) {
+ onFinished(boost::optional<JID>());
+ }
+ else {
+ QModelIndex selectedItem = selection[0];
+ MUCSearchRoomItem* item = dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(selectedItem.internalPointer()));
+ if (item) {
+ onFinished(JID(Q2PSTRING(item->getNode()), Q2PSTRING(item->getParent()->getHost())));
+ }
+ }
+ QDialog::accept();
+}
+
+void QtMUCSearchWindow::reject() {
+ onFinished(boost::optional<JID>());
+ QDialog::reject();
+}
+
}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
index b8cf953..cb4585d 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
@@ -13,37 +13,36 @@
namespace Swift {
class MUCSearchModel;
class MUCSearchDelegate;
- class UIEventStream;
- class QtMUCSearchWindow : public QWidget, public MUCSearchWindow, private Ui::QtMUCSearchWindow {
+
+ class QtMUCSearchWindow : public QDialog, public MUCSearchWindow {
Q_OBJECT
public:
- QtMUCSearchWindow(UIEventStream* eventStream);
+ QtMUCSearchWindow();
virtual ~QtMUCSearchWindow();
- virtual void setNick(const String& nick);
- virtual void setMUC(const String& nick);
virtual void clearList();
virtual void addService(const MUCService& service);
- virtual void addSavedServices(const std::vector<JID>& services);
+ virtual void addSavedServices(const std::list<JID>& services);
virtual void setSearchInProgress(bool searching);
virtual void show();
+ virtual void accept();
+ virtual void reject();
+
protected:
virtual void resizeEvent(QResizeEvent* event);
+
private slots:
- void handleSearch(const QString& text);
void handleSearch();
- void handleJoin();
- void handleSelected(const QModelIndex& current);
+ void handleSearch(const QString&);
void handleActivated(const QModelIndex& index);
void updateThrobberPosition();
+
private:
- void createAutoJoin(const JID& room, boost::optional<String> passedNick);
+ Ui::QtMUCSearchWindow ui_;
MUCSearchModel* model_;
MUCSearchDelegate* delegate_;
- UIEventStream* eventStream_;
QLabel* throbber_;
- String lastSetNick_;
bool hasHadScrollBars_;
};
}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
index ef2524b..f1a1fd5 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
@@ -1,212 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QtMUCSearchWindow</class>
- <widget class="QWidget" name="QtMUCSearchWindow">
+ <widget class="QDialog" name="QtMUCSearchWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>523</width>
- <height>531</height>
+ <height>368</height>
</rect>
</property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
<property name="windowTitle">
- <string>Find Room</string>
+ <string>Dialog</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Service:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="service_">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>2</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="filter_">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QTreeView" name="results_"/>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Available Rooms</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTreeView" name="results_"/>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Your nickname:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="nickName_"/>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Search another service:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="service_">
- <property name="editable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="searchButton_">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="filterLabel_">
- <property name="text">
- <string>Only show rooms matching:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="filter_"/>
- </item>
- <item>
- <widget class="QCheckBox" name="showEmptyRooms_">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>Show Empty Rooms</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>18</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Join Room Directly:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="room_"/>
- </item>
- <item>
- <widget class="QCheckBox" name="joinAutomatically_">
- <property name="text">
- <string>Join automatically in future</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="joinButton_">
- <property name="text">
- <string>Join Room</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>Ok</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
</item>
</layout>
</item>
diff --git a/Swift/QtUI/QtJoinMUCWindow.cpp b/Swift/QtUI/QtJoinMUCWindow.cpp
new file mode 100644
index 0000000..55b285b
--- /dev/null
+++ b/Swift/QtUI/QtJoinMUCWindow.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "QtJoinMUCWindow.h"
+#include "QtSwiftUtil.h"
+
+namespace Swift {
+
+QtJoinMUCWindow::QtJoinMUCWindow() {
+ ui.setupUi(this);
+ connect(ui.room, SIGNAL(returnPressed()), this, SLOT(handleJoin()));
+ connect(ui.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch()));
+ connect(ui.joinButton, SIGNAL(clicked()), this, SLOT(handleJoin()));
+}
+
+void QtJoinMUCWindow::handleJoin() {
+ if (ui.room->text().isEmpty()) {
+ // TODO: Error
+ return;
+ }
+ if (ui.nickName->text().isEmpty()) {
+ // TODO: Error
+ return;
+ }
+
+ lastSetNick = Q2PSTRING(ui.nickName->text());
+ JID room(Q2PSTRING(ui.room->text()));
+ onJoinMUC(room, lastSetNick, ui.joinAutomatically->isChecked());
+ hide();
+}
+
+void QtJoinMUCWindow::handleSearch() {
+ onSearchMUC();
+}
+
+void QtJoinMUCWindow::setNick(const String& nick) {
+ ui.nickName->setText(P2QSTRING(nick));
+ lastSetNick = nick;
+}
+
+void QtJoinMUCWindow::setMUC(const String& nick) {
+ ui.room->setText(P2QSTRING(nick));
+}
+
+void QtJoinMUCWindow::show() {
+ QWidget::show();
+ QWidget::activateWindow();
+}
+
+}
diff --git a/Swift/QtUI/QtJoinMUCWindow.h b/Swift/QtUI/QtJoinMUCWindow.h
new file mode 100644
index 0000000..2d12319
--- /dev/null
+++ b/Swift/QtUI/QtJoinMUCWindow.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/String.h>
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
+#include <Swift/QtUI/ui_QtJoinMUCWindow.h>
+
+namespace Swift {
+ class QtJoinMUCWindow : public QWidget, public JoinMUCWindow {
+ Q_OBJECT
+ public:
+ QtJoinMUCWindow();
+
+ virtual void setNick(const String& nick);
+ virtual void setMUC(const String& nick);
+
+ virtual void show();
+
+ private slots:
+ void handleJoin();
+ void handleSearch();
+
+ private:
+ Ui::QtJoinMUCWindow ui;
+ String lastSetNick;
+ };
+}
diff --git a/Swift/QtUI/QtJoinMUCWindow.ui b/Swift/QtUI/QtJoinMUCWindow.ui
new file mode 100644
index 0000000..2f3608a
--- /dev/null
+++ b/Swift/QtUI/QtJoinMUCWindow.ui
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtJoinMUCWindow</class>
+ <widget class="QWidget" name="QtJoinMUCWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>398</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Join Room</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Room:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QToolButton" name="searchButton">
+ <property name="text">
+ <string>Search ...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Nickname:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="nickName"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="room">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="placeholderText">
+ <string>swift@rooms.swift.im</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>36</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="joinAutomatically">
+ <property name="text">
+ <string>Join automatically in future</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="joinButton">
+ <property name="text">
+ <string>Join Room</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>room</tabstop>
+ <tabstop>nickName</tabstop>
+ <tabstop>joinAutomatically</tabstop>
+ <tabstop>joinButton</tabstop>
+ <tabstop>searchButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index 21d1474..0411c0b 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -8,6 +8,7 @@
#include <boost/optional.hpp>
#include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
#include <QBoxLayout>
#include <QComboBox>
@@ -24,9 +25,9 @@
#include "QtSwiftUtil.h"
#include "QtTabWidget.h"
#include "Roster/QtTreeWidget.h"
+#include "Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h"
#include "Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h"
#include "Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h"
-#include "Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
@@ -143,7 +144,7 @@ void QtMainWindow::handleSignOutAction() {
}
void QtMainWindow::handleJoinMUCAction() {
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestMUCSearchUIEvent()));
+ uiEventStream_->send(boost::make_shared<RequestJoinMUCUIEvent>());
}
void QtMainWindow::handleStatusChanged(StatusShow::Type showType, const QString &statusMessage) {
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index 25a508e..8cb9863 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -16,6 +16,7 @@
#include "QtSettingsProvider.h"
#include "QtMainWindow.h"
#include "QtChatWindow.h"
+#include "QtJoinMUCWindow.h"
#include "QtChatWindowFactory.h"
#include "QtSwiftUtil.h"
#include "MUCSearch/QtMUCSearchWindow.h"
@@ -70,8 +71,8 @@ ChatListWindow* QtUIFactory::createChatListWindow(UIEventStream*) {
return lastMainWindow->getChatListWindow();
}
-MUCSearchWindow* QtUIFactory::createMUCSearchWindow(UIEventStream* eventStream) {
- return new QtMUCSearchWindow(eventStream);
+MUCSearchWindow* QtUIFactory::createMUCSearchWindow() {
+ return new QtMUCSearchWindow();
}
ChatWindow* QtUIFactory::createChatWindow(const JID& contact, UIEventStream* eventStream) {
@@ -82,4 +83,8 @@ UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type typ
return new QtUserSearchWindow(eventStream, type);
};
+JoinMUCWindow* QtUIFactory::createJoinMUCWindow() {
+ return new QtJoinMUCWindow();
+}
+
}
diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h
index 6ddc316..4d80338 100644
--- a/Swift/QtUI/QtUIFactory.h
+++ b/Swift/QtUI/QtUIFactory.h
@@ -31,9 +31,10 @@ namespace Swift {
virtual LoginWindow* createLoginWindow(UIEventStream* eventStream);
virtual EventWindow* createEventWindow();
virtual ChatListWindow* createChatListWindow(UIEventStream*);
- virtual MUCSearchWindow* createMUCSearchWindow(UIEventStream* eventStream);
+ virtual MUCSearchWindow* createMUCSearchWindow();
virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream);
+ virtual JoinMUCWindow* createJoinMUCWindow();
private slots:
void handleLoginWindowGeometryChanged();
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index c0730dc..b0072a6 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -92,6 +92,7 @@ sources = [
"SystemMessageSnippet.cpp",
"QtElidingLabel.cpp",
"QtLineEdit.cpp",
+ "QtJoinMUCWindow.cpp",
"Roster/RosterModel.cpp",
"Roster/QtTreeWidget.cpp",
# "Roster/QtTreeWidgetItem.cpp",
@@ -110,6 +111,7 @@ sources = [
"MUCSearch/QtMUCSearchWindow.cpp",
"MUCSearch/MUCSearchModel.cpp",
"MUCSearch/MUCSearchRoomItem.cpp",
+ "MUCSearch/MUCSearchEmptyItem.cpp",
"MUCSearch/MUCSearchDelegate.cpp",
"UserSearch/QtUserSearchWindow.cpp",
"UserSearch/UserSearchModel.cpp",
@@ -147,6 +149,7 @@ myenv.Uic4("UserSearch/QtUserSearchFieldsPage.ui")
myenv.Uic4("UserSearch/QtUserSearchResultsPage.ui")
myenv.Uic4("QtAddContactDialog.ui")
myenv.Uic4("QtBookmarkDetailWindow.ui")
+myenv.Uic4("QtJoinMUCWindow.ui")
myenv.Qrc("DefaultTheme.qrc")
myenv.Qrc("Swift.qrc")