From d62f8088b8cc42417f97a3b5c3f99bf9288593d4 Mon Sep 17 00:00:00 2001 From: dknn Date: Mon, 6 Aug 2012 16:40:13 +0200 Subject: Add support for multiple sharing and control in chat view diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 16b22fe..611f870 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -79,6 +80,9 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ chatWindow_->onWhiteboardSessionAccept.connect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this)); chatWindow_->onWhiteboardSessionCancel.connect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this)); chatWindow_->onWhiteboardWindowShow.connect(boost::bind(&ChatController::handleWhiteboardWindowShow, this)); + chatWindow_->onScreenSharingAccept.connect(boost::bind(&ChatController::handleScreenSharingAccept, this, _1)); + chatWindow_->onScreenSharingCancel.connect(boost::bind(&ChatController::handleScreenSharingCancel, this, _1)); + chatWindow_->onScreenSharingStop.connect(boost::bind(&ChatController::handleScreenSharingStop, this, _1)); handleBareJIDCapsChanged(toJID_); settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1)); @@ -269,6 +273,14 @@ void ChatController::handleWhiteboardStateChange(const ChatWindow::WhiteboardSes chatWindow_->setWhiteboardSessionStatus(lastWbID_, state); } +void ChatController::handleNewScreenSharingController(ScreenSharingController* ssc) +{ + std::string nick = senderDisplayNameFromMessage(ssc->getOtherParty()); + std::string ssID = ssc->setChatWindow(chatWindow_, nick); + + ssControllers[ssID] = ssc; +} + void ChatController::handleFileTransferCancel(std::string id) { SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl; if (ftControllers.find(id) != ftControllers.end()) { @@ -313,6 +325,39 @@ void ChatController::handleWhiteboardWindowShow() { eventStream_->send(boost::make_shared(toJID_)); } +void ChatController::handleScreenSharingAccept(std::string id) +{ + SWIFT_LOG(debug) "handleScreenSharingAccept(" << id << ")" << std::endl; + std::map::iterator controller = ssControllers.find(id); + if (controller != ssControllers.end()) { + controller->second->accept(); + } else { + std::cerr << "unknown screen sharing UI id" << std::endl; + } +} + +void ChatController::handleScreenSharingCancel(std::string id) +{ + SWIFT_LOG(debug) "handleScreenSharingCancel(" << id << ")" << std::endl; + std::map::iterator controller = ssControllers.find(id); + if (controller != ssControllers.end()) { + controller->second->cancel(); + } else { + std::cerr << "unknown screen sharing UI id" << std::endl; + } +} + +void ChatController::handleScreenSharingStop(std::string id) +{ + SWIFT_LOG(debug) "handleScreenSharingStop(" << id << ")" << std::endl; + std::map::iterator controller = ssControllers.find(id); + if (controller != ssControllers.end()) { + controller->second->stop(); + } else { + std::cerr << "unknown screen sharing UI id" << std::endl; + } +} + std::string ChatController::senderDisplayNameFromMessage(const JID& from) { return nickResolver_->jidToNick(from); } diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index 66ec37d..6350cbb 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -32,6 +32,7 @@ namespace Swift { virtual void handleNewFileTransferController(FileTransferController* ftc); virtual void handleWhiteboardSessionRequest(bool senderIsSelf); virtual void handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state); + virtual void handleNewScreenSharingController(ScreenSharingController* ssc); virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/); protected: @@ -63,6 +64,10 @@ namespace Swift { void handleWhiteboardSessionCancel(); void handleWhiteboardWindowShow(); + void handleScreenSharingAccept(std::string id); + void handleScreenSharingCancel(std::string id); + void handleScreenSharingStop(std::string id); + void handleSettingChanged(const std::string& settingPath); void checkForDisplayingDisplayReceiptsAlert(); @@ -83,6 +88,7 @@ namespace Swift { bool receivingPresenceFromUs_; bool userWantsReceipts_; std::map ftControllers; + std::map ssControllers; SettingsProvider* settings_; std::string lastWbID_; }; diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 48ea006..90c39ac 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,7 @@ ChatsManager::ChatsManager( MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, - ScreenSharingController* ssController, + ScreenSharingOverview* ssOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, @@ -85,7 +86,7 @@ ChatsManager::ChatsManager( entityCapsProvider_(entityCapsProvider), mucManager(mucManager), ftOverview_(ftOverview), - ssController_(ssController), + ssOverview_(ssOverview), roster_(roster), eagleMode_(eagleMode), settings_(settings), @@ -116,7 +117,7 @@ ChatsManager::ChatsManager( mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_); mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1)); ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); - ssController->onNewIncomingScreenSharing.connect(boost::bind(&ChatsManager::handleNewIncomingScreenSharing, this, _1)); + ssOverview_->onNewIncomingScreenSharing.connect(boost::bind(&ChatsManager::handleNewIncomingScreenSharing, this, _1)); whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2)); whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted)); whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated)); @@ -526,7 +527,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) ChatController* ChatsManager::createNewChatController(const JID& contact) { assert(chatControllers_.find(contact) == chatControllers_.end()); - ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_); + ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_); chatControllers_[contact] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); @@ -599,7 +600,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional if (createAsReservedIfNew) { muc->setCreateAsReservedIfNew(); } - MUCController* controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_); + 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)); @@ -669,36 +670,13 @@ void ChatsManager::handleNewFileTransferController(FileTransferController* ftc) chatController->activateChatWindow(); } -void ChatsManager::handleNewIncomingScreenSharing(boost::shared_ptr iss) +void ChatsManager::handleNewIncomingScreenSharing(ScreenSharingController* ssc) { - ChatController* chatController = getChatControllerOrCreate(iss->getSender()); -// chatController->handleNewFileTransferController(ftc); + ChatController* chatController = getChatControllerOrCreate(ssc->getOtherParty()); + chatController->handleNewScreenSharingController(ssc); chatController->activateChatWindow(); } -void ChatsManager::handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf) { - ChatController* chatController = getChatControllerOrCreate(contact); - chatController->handleWhiteboardSessionRequest(senderIsSelf); - chatController->activateChatWindow(); -} - -void ChatsManager::handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state) { - ChatController* chatController = getChatControllerOrCreate(contact); - chatController->handleWhiteboardStateChange(state); - chatController->activateChatWindow(); - if (state == ChatWindow::WhiteboardAccepted) { - boost::filesystem::path path; - JID bareJID = contact.toBare(); - if (avatarManager_) { - path = avatarManager_->getAvatarPath(bareJID); - } - ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false); - chatListWindow_->addWhiteboardSession(chat); - } else { - chatListWindow_->removeWhiteboardSession(contact.toBare()); - } -} - void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { if (chat.isMUC) { /* FIXME: This means that recents requiring passwords will just flat-out not work */ diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 31006b0..1ef2987 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -50,12 +50,13 @@ namespace Swift { class SettingsProvider; class WhiteboardManager; class HistoryController; + class ScreenSharingOverview; class ScreenSharingController; class IncomingScreenSharing; class ChatsManager { public: - 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, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, ScreenSharingController* ssController, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager); + 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, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, ScreenSharingOverview* ssOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager); virtual ~ChatsManager(); void setAvatarManager(AvatarManager* avatarManager); void setOnline(bool enabled); @@ -77,7 +78,7 @@ namespace Swift { void handleBookmarksReady(); void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); void handleNewFileTransferController(FileTransferController*); - void handleNewIncomingScreenSharing(boost::shared_ptr iss); + void handleNewIncomingScreenSharing(ScreenSharingController* ssc); void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf); void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state); void appendRecent(const ChatListWindow::Chat& chat); @@ -133,7 +134,7 @@ namespace Swift { std::list recentChats_; ProfileSettingsProvider* profileSettings_; FileTransferOverview* ftOverview_; - ScreenSharingController* ssController_; + ScreenSharingOverview* ssOverview_; XMPPRoster* roster_; bool eagleMode_; bool userWantsReceipts_; diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 17dab36..5774ea6 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -78,7 +78,7 @@ #include #include #include -#include "Swift/Controllers/ScreenSharing/ScreenSharingController.h" +#include "Swift/Controllers/ScreenSharing/ScreenSharingOverview.h" namespace Swift { @@ -111,7 +111,7 @@ MainController::MainController( loginWindow_(NULL) , useDelayForLatency_(useDelayForLatency), ftOverview_(NULL), - ssController_(NULL) { + ssOverview_(NULL) { storages_ = NULL; certificateStorage_ = NULL; statusTracker_ = NULL; @@ -239,8 +239,8 @@ void MainController::resetClient() { #endif delete ftOverview_; ftOverview_ = NULL; - delete ssController_; - ssController_ = NULL; + delete ssOverview_; + ssOverview_ = NULL; delete rosterController_; rosterController_ = NULL; delete eventNotifier_; @@ -306,8 +306,8 @@ void MainController::handleConnected() { client_->getFileTransferManager()->startListeningOnPort(randomPort); ftOverview_ = new FileTransferOverview(client_->getFileTransferManager()); fileTransferListController_->setFileTransferOverview(ftOverview_); - ssController_ = new ScreenSharingController(client_->getScreenSharingManager(), uiFactory_, networkFactories_->getTimerFactory()); - rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, ssController_); + ssOverview_ = new ScreenSharingOverview(client_->getScreenSharingManager(), uiFactory_, networkFactories_->getTimerFactory()); + rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, ssOverview_); rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2)); rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this)); @@ -323,9 +323,9 @@ void MainController::handleConnected() { #ifdef SWIFT_EXPERIMENTAL_HISTORY historyController_ = new HistoryController(storages_->getHistoryStorage()); historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_); - 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_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_); + 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_, profileSettings_, ftOverview_, ssOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_); #else - 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_, profileSettings_, ftOverview_, ssController_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_); + 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_, profileSettings_, ftOverview_, ssOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_); #endif client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1)); diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index ad8fef2..8b40ce5 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -72,6 +72,7 @@ namespace Swift { class FileTransferOverview; class WhiteboardManager; class ScreenSharingController; + class ScreenSharingOverview; class MainController { public: @@ -177,6 +178,6 @@ namespace Swift { static const int SecondsToWaitBeforeForceQuitting; FileTransferOverview* ftOverview_; WhiteboardManager* whiteboardManager_; - ScreenSharingController* ssController_; + ScreenSharingOverview* ssOverview_; }; } diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp index 40fd957..dcb5f60 100644 --- a/Swift/Controllers/Roster/RosterController.cpp +++ b/Swift/Controllers/Roster/RosterController.cpp @@ -45,15 +45,15 @@ #include #include #include -#include "Swift/Controllers/ScreenSharing/ScreenSharingController.h" +#include "Swift/Controllers/ScreenSharing/ScreenSharingOverview.h" namespace Swift { /** * The controller does not gain ownership of these parameters. */ -RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ScreenSharingController *ssController) - : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), ssController_(ssController) { +RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ScreenSharingOverview* screenSharingOverView) + : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), ssOverview_(screenSharingOverView) { assert(fileTransferOverview); iqRouter_ = iqRouter; presenceOracle_ = presenceOracle; @@ -241,8 +241,7 @@ void RosterController::handleUIEvent(boost::shared_ptr event) { ftOverview_->sendFile(sendFileEvent->getJID(), sendFileEvent->getFilename()); } else if (boost::shared_ptr shareScreenEvent = boost::dynamic_pointer_cast(event)) { - std::cout << "Create sharing: " << ssController_->createOugoingScreenSharing(shareScreenEvent->jid); - std::cout << std::endl; + ssOverview_->createOugoingScreenSharing(shareScreenEvent->jid); } } diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h index 2fb642d..57d3017 100644 --- a/Swift/Controllers/Roster/RosterController.h +++ b/Swift/Controllers/Roster/RosterController.h @@ -39,11 +39,11 @@ namespace Swift { class NickManager; class EntityCapsProvider; class FileTransferManager; - class ScreenSharingController; + class ScreenSharingOverview; class RosterController { public: - RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ScreenSharingController* ssController); + RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ScreenSharingOverview* screenSharingOverView); ~RosterController(); void showRosterWindow(); MainWindow* getWindow() {return mainWindow_;}; @@ -95,7 +95,7 @@ namespace Swift { UIEventStream* uiEventStream_; EntityCapsProvider* entityCapsManager_; FileTransferOverview* ftOverview_; - ScreenSharingController* ssController_; + ScreenSharingOverview* ssOverview_; boost::bsignals::scoped_connection changeStatusConnection_; boost::bsignals::scoped_connection signOutConnection_; diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript index 2dba9a9..d884baa 100644 --- a/Swift/Controllers/SConscript +++ b/Swift/Controllers/SConscript @@ -76,6 +76,7 @@ if env["SCONS_STAGE"] == "build" : "SettingConstants.cpp", "WhiteboardManager.cpp", "ScreenSharing/ScreenSharingController.cpp", + "ScreenSharing/ScreenSharingOverview.cpp", ]) env.Append(UNITTEST_SOURCES = [ diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp index fd3357d..b932765 100644 --- a/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp +++ b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp @@ -12,82 +12,118 @@ #include #include #include -#include "Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h" +#include "Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h" #include "Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h" #include "Swift/Controllers/UIInterfaces/RemoteScreenWindow.h" +#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include "Swift/Controllers/Intl.h" #include namespace Swift { -ScreenSharingController::ScreenSharingController(ScreenSharingManager *screenSharingManager, RemoteScreenWindowFactory* remoteScreenViewerFactory, TimerFactory* timerFactory) - : screenSharingManager(screenSharingManager), remoteScreenWindowFactory(remoteScreenViewerFactory), remoteScreenWindow(0), - grabTimer(timerFactory->createTimer(500)), screenGrabber(new QtDesktopScreenGrabber) +ScreenSharingController::ScreenSharingController(ScreenSharingManager* screenSharingManager, TimerFactory* timerFactory, DesktopScreenGrabber* desktopScreenGrabber, const JID& to) + : screenGrabber(desktopScreenGrabber), grabTimer(timerFactory->createTimer(500)), remoteScreenWindowFactory(0), + remoteScreenWindow(0), otherParty(to), incoming(false), chatWindow(0) { - screenSharingManager->onIncomingScreenSharing.connect(boost::bind(&ScreenSharingController::handleIncomingScreenSharing, this, _1)); - grabTimer->onTick.connect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this)); + OutgoingScreenSharing::ref oss = screenSharingManager->createOutgoingScreenSharing(to); + if (oss) { + oss->onReady.connect(boost::bind(&ScreenSharingController::handleReady, this)); + oss->onFinished.connect(boost::bind(&ScreenSharingController::handleFinished, this)); + oss->onStateChange.connect(boost::bind(&ScreenSharingController::handleStateChange, this, _1)); + const Image& image = screenGrabber->grab(); + oss->start(image.width, image.height); + screenSharing = oss; + } else { + std::cerr << "Screen sharing not supported!" << std::endl; + } +} + +ScreenSharingController::ScreenSharingController(boost::shared_ptr screenSharing, RemoteScreenWindowFactory* remoteScreenWindowFactory) + : screenGrabber(0), remoteScreenWindowFactory(remoteScreenWindowFactory), remoteScreenWindow(0), + screenSharing(screenSharing), otherParty(screenSharing->getSender()), incoming(true), chatWindow(0) +{ + screenSharing->onFinished.connect(boost::bind(&ScreenSharingController::handleFinished, this)); + screenSharing->onStateChange.connect(boost::bind(&ScreenSharingController::handleStateChange, this, _1)); } ScreenSharingController::~ScreenSharingController() { - grabTimer->onTick.disconnect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this)); + screenSharing->onStateChange.disconnect(boost::bind(&ScreenSharingController::handleStateChange, this, _1)); delete remoteScreenWindow; } -boost::shared_ptr ScreenSharingController::createOugoingScreenSharing(const JID& to) +const JID& ScreenSharingController::getOtherParty() const { - if (!oss) { - oss = screenSharingManager->createOutgoingScreenSharing(to); - if (oss) { - oss->onReady.connect(boost::bind(&ScreenSharingController::handleOssReady, this)); - oss->onFinished.connect(boost::bind(&ScreenSharingController::handleOutgoingFinished, this)); - const Image& image = screenGrabber->grab(); - oss->start(image.width, image.height); + return otherParty; +} + +std::string ScreenSharingController::setChatWindow(ChatWindow* wnd, std::string nickname) { + chatWindow = wnd; + uiID = wnd->addScreenSharing((incoming ? nickname : QT_TRANSLATE_NOOP("", "me")), incoming); + return uiID; +} + +void ScreenSharingController::accept() +{ + if (incoming) { + if (IncomingScreenSharing::ref iss = boost::dynamic_pointer_cast(screenSharing)) { + iss->accept(); + remoteScreenWindow = remoteScreenWindowFactory->createRemoteScreenViewer(iss); + remoteScreenWindow->onStopRequest.connect(boost::bind(&ScreenSharingController::handleWindowStopRequest, this)); } - return oss; } - return boost::shared_ptr(); } -void ScreenSharingController::handleIncomingScreenSharing(boost::shared_ptr incomingScreenSharing) +void ScreenSharingController::cancel() { - if (iss) { - incomingScreenSharing->cancel(); - } else { - iss = incomingScreenSharing; - iss->accept(); - iss->onFinished.connect(boost::bind(&ScreenSharingController::handleIncomingFinished, this)); - remoteScreenWindow = remoteScreenWindowFactory->createRemoteScreenViewer(iss); -// onNewIncomingScreenSharing(iss); - } + screenSharing->cancel(); +} + +void ScreenSharingController::stop() +{ + screenSharing->stop(); } void ScreenSharingController::handleGrabTimerTick() { - if (oss) { - grabTimer->start(); - oss->addImage(screenGrabber->grab()); + if (screenSharing) { + if (OutgoingScreenSharing::ref oss = boost::dynamic_pointer_cast(screenSharing)) { + grabTimer->start(); + oss->addImage(screenGrabber->grab()); + } + } else { + grabTimer->onTick.disconnect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this)); } } -void ScreenSharingController::handleOssReady() +void ScreenSharingController::handleReady() { - handleGrabTimerTick(); + if (OutgoingScreenSharing::ref oss = boost::dynamic_pointer_cast(screenSharing)) { + oss->onReady.disconnect(boost::bind(&ScreenSharingController::handleReady, this)); + grabTimer->onTick.connect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this)); + handleGrabTimerTick(); + } } -void ScreenSharingController::handleIncomingFinished() +void ScreenSharingController::handleFinished() { - iss->onFinished.disconnect(boost::bind(&ScreenSharingController::handleIncomingFinished, this)); - iss.reset(); + screenSharing->onFinished.disconnect(boost::bind(&ScreenSharingController::handleFinished, this)); + screenSharing.reset(); delete remoteScreenWindow; remoteScreenWindow = 0; } -void ScreenSharingController::handleOutgoingFinished() +void ScreenSharingController::handleStateChange(ScreenSharing::SCState state) +{ + if (chatWindow) + chatWindow->setScreenSharingStatus(uiID, state); +} + +void ScreenSharingController::handleWindowStopRequest() { - oss->onReady.disconnect(boost::bind(&ScreenSharingController::handleOssReady, this)); - oss->onFinished.disconnect(boost::bind(&ScreenSharingController::handleOutgoingFinished, this)); - oss.reset(); + remoteScreenWindow->onStopRequest.disconnect(boost::bind(&ScreenSharingController::handleWindowStopRequest, this)); + screenSharing->stop(); } } diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingController.h b/Swift/Controllers/ScreenSharing/ScreenSharingController.h index 6bae132..11b4504 100644 --- a/Swift/Controllers/ScreenSharing/ScreenSharingController.h +++ b/Swift/Controllers/ScreenSharing/ScreenSharingController.h @@ -6,46 +6,53 @@ #pragma once -#include +#include +#include #include namespace Swift { + class ScreenSharing; class ScreenSharingManager; class IncomingScreenSharing; - class OutgoingScreenSharing; class Timer; class TimerFactory; class DesktopScreenGrabber; class RemoteScreenWindowFactory; class RemoteScreenWindow; - class JID; + class ChatWindow; class ScreenSharingController { public: - ScreenSharingController(ScreenSharingManager* screenSharingManager, RemoteScreenWindowFactory* remoteScreenWindowFactory, TimerFactory* timerFactory); + ScreenSharingController(ScreenSharingManager* screenSharingManager, TimerFactory* timerFactory, DesktopScreenGrabber* desktopScreenGrabber, const JID& to); + ScreenSharingController(boost::shared_ptr screenSharing, RemoteScreenWindowFactory* remoteScreenWindowFactory); ~ScreenSharingController(); - boost::shared_ptr createOugoingScreenSharing(const JID& to); + const JID& getOtherParty() const; - public: - boost::signal)> onNewIncomingScreenSharing; + std::string setChatWindow(ChatWindow *wnd, std::string nickname); + + void accept(); + void cancel(); + void stop(); private: - void handleIncomingScreenSharing(boost::shared_ptr incomingScreenSharing); void handleGrabTimerTick(); - void handleOssReady(); - void handleIncomingFinished(); - void handleOutgoingFinished(); + void handleReady(); + void handleFinished(); + void handleStateChange(ScreenSharing::SCState state); + void handleWindowStopRequest(); private: - ScreenSharingManager* screenSharingManager; + DesktopScreenGrabber* screenGrabber; + boost::shared_ptr grabTimer; RemoteScreenWindowFactory* remoteScreenWindowFactory; - RemoteScreenWindow* remoteScreenWindow; - boost::shared_ptr grabTimer; - DesktopScreenGrabber* screenGrabber; - boost::shared_ptr iss; - boost::shared_ptr oss; + + boost::shared_ptr screenSharing; + JID otherParty; + bool incoming; + std::string uiID; + ChatWindow* chatWindow; }; } diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingOverview.cpp b/Swift/Controllers/ScreenSharing/ScreenSharingOverview.cpp new file mode 100644 index 0000000..91f75b9 --- /dev/null +++ b/Swift/Controllers/ScreenSharing/ScreenSharingOverview.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "ScreenSharingOverview.h" + +#include "Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h" +#include "Swift/Controllers/ScreenSharing/ScreenSharingController.h" +#include + +#include + +namespace Swift { + +ScreenSharingOverview::ScreenSharingOverview(ScreenSharingManager *screenSharingManager, RemoteScreenWindowFactory* remoteScreenViewerFactory, TimerFactory* timerFactory) + : screenSharingManager(screenSharingManager), remoteScreenWindowFactory(remoteScreenViewerFactory), timerFactory(timerFactory), + screenGrabber(new QtDesktopScreenGrabber) +{ + screenSharingManager->onIncomingScreenSharing.connect(boost::bind(&ScreenSharingOverview::handleIncomingScreenSharing, this, _1)); +} + +ScreenSharingOverview::~ScreenSharingOverview() +{ + screenSharingManager->onIncomingScreenSharing.disconnect(boost::bind(&ScreenSharingOverview::handleIncomingScreenSharing, this, _1)); +} + +void ScreenSharingOverview::createOugoingScreenSharing(const JID& to) +{ + ScreenSharingController* ssc = new ScreenSharingController(screenSharingManager, timerFactory, screenGrabber, to); + controllers.push_back(ssc); + onNewScreenSharingController(ssc); +} + +void ScreenSharingOverview::handleIncomingScreenSharing(boost::shared_ptr incomingScreenSharing) +{ + ScreenSharingController* ssc = new ScreenSharingController(incomingScreenSharing, remoteScreenWindowFactory); + controllers.push_back(ssc); + onNewScreenSharingController(ssc); +} + +} diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingOverview.h b/Swift/Controllers/ScreenSharing/ScreenSharingOverview.h new file mode 100644 index 0000000..b43a665 --- /dev/null +++ b/Swift/Controllers/ScreenSharing/ScreenSharingOverview.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include + +#include + +#include + +namespace Swift { + class ScreenSharingManager; + class ScreenSharingController; + class IncomingScreenSharing; + class TimerFactory; + class DesktopScreenGrabber; + class RemoteScreenWindowFactory; + class JID; + + class ScreenSharingOverview { + public: + ScreenSharingOverview(ScreenSharingManager* screenSharingManager, RemoteScreenWindowFactory* remoteScreenWindowFactory, TimerFactory* timerFactory); + ~ScreenSharingOverview(); + + void createOugoingScreenSharing(const JID& to); + + public: + boost::signal onNewScreenSharingController; + + private: + void handleIncomingScreenSharing(boost::shared_ptr incomingScreenSharing); + + private: + ScreenSharingManager* screenSharingManager; + RemoteScreenWindowFactory* remoteScreenWindowFactory; + TimerFactory* timerFactory; + + DesktopScreenGrabber* screenGrabber; + std::vector controllers; + }; +} diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 5db1a54..d54f2aa 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace Swift { @@ -59,6 +60,11 @@ namespace Swift { virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes) = 0; virtual void setFileTransferProgress(std::string, const int percentageDone) = 0; virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0; + + // Screen sharing related stuff + virtual std::string addScreenSharing(const std::string& senderName, bool incoming) = 0; + virtual void setScreenSharingStatus(std::string, const ScreenSharing::SCState state, const std::string& msg = "") = 0; + virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true) = 0; virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0; @@ -137,6 +143,11 @@ namespace Swift { boost::signal onFileTransferAccept; boost::signal onSendFileRequest; + // Screen sharing related + boost::signal onScreenSharingCancel; + boost::signal onScreenSharingStop; + boost::signal onScreenSharingAccept; + //Whiteboard related boost::signal onWhiteboardSessionAccept; boost::signal onWhiteboardSessionCancel; diff --git a/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h b/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h index c31ca91..a5bdb36 100644 --- a/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h +++ b/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h @@ -6,6 +6,8 @@ #pragma once +#include + #include namespace Swift { @@ -18,6 +20,9 @@ namespace Swift { : iss(incScreenSharing) {} virtual ~RemoteScreenWindow() {} + public: + boost::signal onStopRequest; + protected: boost::shared_ptr iss; }; diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp index 81820a3..25b786f 100644 --- a/Swift/QtUI/QtChatView.cpp +++ b/Swift/QtUI/QtChatView.cpp @@ -444,6 +444,48 @@ void QtChatView::setWhiteboardSessionStatus(QString id, const ChatWindow::Whiteb divElement.setInnerXml(newInnerHTML); } +void QtChatView::setScreenSharingStatus(QString id, ScreenSharing::SCState state, const QString& /*msg*/) +{ + QWebElement ftElement = findDivElementWithID(document_, id); + if (ftElement.isNull()) { + SWIFT_LOG(debug) << "Tried to access screen sharing UI via invalid id! id = " << Q2PSTRING(id) << std::endl; + return; + } + + QString newInnerHTML = ""; + if (state == ScreenSharing::WaitingForAccept) { + newInnerHTML = tr("Waiting for other side to accept the sharing.") + "
" + + QtChatWindow::buildChatWindowButton(tr("Cancel"), QtChatWindow::ButtonScreenSharingCancel, id); + } + if (state == ScreenSharing::Negotiating) { + newInnerHTML = tr("Negotiating...") + "
" + + QtChatWindow::buildChatWindowButton(tr("Cancel"), QtChatWindow::ButtonScreenSharingCancel, id); + } + if (state == ScreenSharing::Connecting) { + newInnerHTML = tr("Connecting...") + "
" + + QtChatWindow::buildChatWindowButton(tr("Cancel"), QtChatWindow::ButtonScreenSharingCancel, id); + } + if (state == ScreenSharing::BroadCasting) { + newInnerHTML = tr("Broadcasting the desktop...") + "
" + + QtChatWindow::buildChatWindowButton(tr("Terminate"), QtChatWindow::ButtonScreenSharingStop, id); + } + else if (state == ScreenSharing::Receiving) { + newInnerHTML = tr("Receiving desktop from the other party...") + "
" + + QtChatWindow::buildChatWindowButton(tr("Terminate"), QtChatWindow::ButtonScreenSharingStop, id); + } + else if (state == ScreenSharing::Canceled) { + newInnerHTML = tr("Sharing has been canceled!"); + } + else if (state == ScreenSharing::Finished) { + newInnerHTML = tr("Sharing finished."); + } + else if (state == ScreenSharing::Failed) { + newInnerHTML = tr("Sharing failed."); + } + + ftElement.setInnerXml(newInnerHTML); +} + void QtChatView::setMUCInvitationJoined(QString id) { QWebElement divElement = findElementWithID(document_, "div", id); QWebElement buttonElement = findElementWithID(divElement, "input", "mucinvite"); diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h index 9080808..403dec0 100644 --- a/Swift/QtUI/QtChatView.h +++ b/Swift/QtUI/QtChatView.h @@ -17,6 +17,7 @@ #include "ChatSnippet.h" #include +#include class QWebPage; class QUrl; @@ -43,7 +44,8 @@ namespace Swift { QString getLastSentMessage(); void addToJSEnvironment(const QString&, QObject*); void setFileTransferProgress(QString id, const int percentageDone); - void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg); + void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& /*msg*/); + void setScreenSharingStatus(QString id, ScreenSharing::SCState state, const QString& msg); void setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state); void setMUCInvitationJoined(QString id); void showEmoticons(bool show); diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 314e36c..730195c 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -61,6 +61,9 @@ const QString QtChatWindow::ButtonFileTransferCancel = QString("filetransfer-can const QString QtChatWindow::ButtonFileTransferSetDescription = QString("filetransfer-setdescription"); const QString QtChatWindow::ButtonFileTransferSendRequest = QString("filetransfer-sendrequest"); const QString QtChatWindow::ButtonFileTransferAcceptRequest = QString("filetransfer-acceptrequest"); +const QString QtChatWindow::ButtonScreenSharingCancel = QString("screensharing-cancel"); +const QString QtChatWindow::ButtonScreenSharingStop = QString("screensharing-stop"); +const QString QtChatWindow::ButtonScreenSharingAcceptRequest = QString("screensharing-acceptrequest"); const QString QtChatWindow::ButtonMUCInvite = QString("mucinvite"); @@ -685,6 +688,47 @@ void QtChatWindow::setWhiteboardSessionStatus(std::string id, const ChatWindow:: messageLog_->setWhiteboardSessionStatus(QString::fromStdString(id), state); } +std::string QtChatWindow::addScreenSharing(const std::string& senderName, bool incoming) +{ + SWIFT_LOG(debug) << "addScreenSharing" << std::endl; + QString ss_id = QString("ft%1").arg(P2QSTRING(boost::lexical_cast(idCounter_++))); + + QString htmlString; + if (incoming) { + htmlString = P2QSTRING(senderName) + " shares his screen with you" + "
" + + "
" + + buildChatWindowButton(tr("Accept"), ButtonScreenSharingAcceptRequest, ss_id) + + buildChatWindowButton(tr("Cancel"), ButtonScreenSharingCancel, ss_id) + + "
"; + } else { + htmlString = tr("Sharing screen with ") + contact_ + "
" + + "
" + + buildChatWindowButton(tr("Cancel"), ButtonScreenSharingCancel, ss_id) + + "
"; + } + + bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasFileTransfer, senderName, !incoming); + if (lastLineTracker_.getShouldMoveLastLine()) { + /* should this be queued? */ + messageLog_->addLastSeenLine(); + /* if the line is added we should break the snippet */ + appendToPrevious = false; + } + QString qAvatarPath = "qrc:/icons/avatar.png"; + std::string id = "ssmessage" + boost::lexical_cast(idCounter_++); + messageLog_->addMessage(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, !incoming, appendToPrevious, theme_, P2QSTRING(id)))); + + previousMessageWasSelf_ = !incoming; + previousSenderName_ = P2QSTRING(senderName); + previousMessageKind_ = PreviousMessageWasFileTransfer; + return Q2PSTRING(ss_id); +} + +void QtChatWindow::setScreenSharingStatus(std::string id, const ScreenSharing::SCState state, const std::string& msg) +{ + messageLog_->setScreenSharingStatus(QString::fromStdString(id), state, QString::fromStdString(msg)); +} + void QtChatWindow::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString encodedArgument2, QString encodedArgument3) { QString arg1 = decodeButtonArgument(encodedArgument1); QString arg2 = decodeButtonArgument(encodedArgument2); @@ -731,6 +775,15 @@ void QtChatWindow::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString id = arg1; onWhiteboardWindowShow(); } + else if (id.startsWith(ButtonScreenSharingAcceptRequest)) { + onScreenSharingAccept(Q2PSTRING(arg1)); + } + else if (id.startsWith(ButtonScreenSharingCancel)) { + onScreenSharingCancel(Q2PSTRING(arg1)); + } + else if (id.startsWith(ButtonScreenSharingStop)) { + onScreenSharingStop(Q2PSTRING(arg1)); + } else if (id.startsWith(ButtonMUCInvite)) { QString roomJID = arg1; QString password = arg2; diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 3416b42..d802bf9 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -80,6 +80,9 @@ namespace Swift { static const QString ButtonFileTransferSetDescription; static const QString ButtonFileTransferSendRequest; static const QString ButtonFileTransferAcceptRequest; + static const QString ButtonScreenSharingCancel; + static const QString ButtonScreenSharingStop; + static const QString ButtonScreenSharingAcceptRequest; static const QString ButtonMUCInvite; public: @@ -96,6 +99,10 @@ namespace Swift { std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes); void setFileTransferProgress(std::string id, const int percentageDone); void setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg); + + // Screen sharing related stuff + virtual std::string addScreenSharing(const std::string& senderName, bool incoming); + virtual void setScreenSharingStatus(std::string id, const ScreenSharing::SCState state, const std::string& msg = ""); std::string addWhiteboardRequest(bool senderIsSelf); void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state); diff --git a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp index e6cd291..a1f1a88 100644 --- a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp +++ b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp @@ -8,15 +8,22 @@ #include "RemoteScreenViewerWidget.h" #include +#include #include namespace Swift { QtRemoteScreenWindow::QtRemoteScreenWindow(boost::shared_ptr incScreenSharing, QWidget *parent) - : QMainWindow(parent), RemoteScreenWindow(incScreenSharing) + : QMainWindow(parent), RemoteScreenWindow(incScreenSharing), viewer(new RemoteScreenViewerWidget(iss)) { - setCentralWidget(new RemoteScreenViewerWidget(iss)); + QVBoxLayout* centralLayout = new QVBoxLayout; + centralLayout->addWidget(viewer); + + QWidget* central = new QWidget(this); + central->setLayout(centralLayout); + + setCentralWidget(central); controlToolBar = addToolBar(tr("Control")); closeAction = controlToolBar->addAction(QIcon::fromTheme("window-close"), tr("&Terminate session"), this, SLOT(handleCloseTriggered())); @@ -28,7 +35,7 @@ QtRemoteScreenWindow::~QtRemoteScreenWindow() void QtRemoteScreenWindow::handleCloseTriggered() { - iss->stop(); + onStopRequest(); } } diff --git a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h index 00ac803..d6c783a 100644 --- a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h +++ b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h @@ -13,6 +13,7 @@ class QToolBar; namespace Swift { + class RemoteScreenViewerWidget; class QtRemoteScreenWindow : public QMainWindow, public RemoteScreenWindow { Q_OBJECT @@ -25,6 +26,7 @@ namespace Swift { void handleCloseTriggered(); private: + RemoteScreenViewerWidget* viewer; QAction* closeAction; QToolBar* controlToolBar; }; diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp index f601f1b..7bb3f26 100644 --- a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp +++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp @@ -18,7 +18,7 @@ namespace Swift { RemoteScreenViewerWidget::RemoteScreenViewerWidget(boost::shared_ptr incScreenSharing, QWidget *parent) : - QWidget(parent), iss(incScreenSharing) + QFrame(parent), iss(incScreenSharing) { iss->onNewImageReceived.connect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1)); } @@ -28,10 +28,11 @@ RemoteScreenViewerWidget::~RemoteScreenViewerWidget() iss->onNewImageReceived.disconnect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1)); } -void RemoteScreenViewerWidget::paintEvent(QPaintEvent *) +void RemoteScreenViewerWidget::paintEvent(QPaintEvent* event) { - QPainter painter(this); + QFrame::paintEvent(event); if (!pixmap.isNull()) { + QPainter painter(this); painter.translate(geometry().center()); painter.drawPixmap(-pixmap.rect().center(), pixmap); } @@ -39,15 +40,20 @@ void RemoteScreenViewerWidget::paintEvent(QPaintEvent *) void RemoteScreenViewerWidget::resizeEvent(QResizeEvent *event) { - if (!pixmap.isNull()) - pixmap = pixmap.scaled(event->size(), Qt::KeepAspectRatio); - QWidget::resizeEvent(event); + if (!pixmap.isNull()) { + int frameWidth2 = frameWidth() * 2; + QSize borders(frameWidth2, frameWidth2); + pixmap = pixmap.scaled(event->size() - borders, Qt::KeepAspectRatio); + } + QFrame::resizeEvent(event); } void RemoteScreenViewerWidget::handleNewImageReceived(const Image& image) { QImage qImg(image.data.data(), image.width, image.height, QImage::Format_RGB888); - pixmap = QPixmap::fromImage(qImg).scaled(size(), Qt::KeepAspectRatio); + int frameWidth2 = frameWidth() * 2; + QSize borders(frameWidth2, frameWidth2); + pixmap = QPixmap::fromImage(qImg).scaled(size() - borders, Qt::KeepAspectRatio); update(); } diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h index 622bd26..c074e9f 100644 --- a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h +++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h @@ -6,7 +6,7 @@ #pragma once -#include +#include #include @@ -14,15 +14,15 @@ namespace Swift { class IncomingScreenSharing; class Image; - class RemoteScreenViewerWidget : public QWidget { + class RemoteScreenViewerWidget : public QFrame { Q_OBJECT public: RemoteScreenViewerWidget(boost::shared_ptr incScreenSharing, QWidget *parent = 0); ~RemoteScreenViewerWidget(); protected: - void paintEvent(QPaintEvent *); - void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent* event); + void resizeEvent(QResizeEvent* event); private: void handleNewImageReceived(const Image& image); diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp index bbbfbad..15574c4 100644 --- a/Swiften/ScreenSharing/IncomingScreenSharing.cpp +++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp @@ -91,6 +91,7 @@ JingleContentID IncomingScreenSharing::getContentID() const void IncomingScreenSharing::hangleNewImageDecoded(const Image& image) { + onStateChange(ScreenSharing::Receiving); onNewImageReceived(image); } diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp index 005e204..7cea50e 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp @@ -132,6 +132,7 @@ void OutgoingScreenSharing::startRTPSession() encoder = new VP8Encoder(packetizer, width, height); packetizer->onNewPayloadReady.connect(boost::bind(&OutgoingScreenSharing::handleNewPayloadReady, this, _1, _2)); onReady(); + onStateChange(ScreenSharing::BroadCasting); } } -- cgit v0.10.2-6-g49f6