From c9275affd040ee1ca7c1d599b28df3b363bef888 Mon Sep 17 00:00:00 2001 From: Richard Maudsley <richard.maudsley@isode.com> Date: Fri, 14 Mar 2014 14:15:34 +0000 Subject: Make the impromptu MUCs behave more like a regular chat. This hides occupant types in the participant list and initiates a direct 1-to-1 on occupant double-click instead of MUC-proxied 1-to-1. Change-Id: I76c57fe52beb3e4236524c1d8cfbd583d3dc3f62 diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 14d1767..f83a772 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -104,8 +104,6 @@ MUCController::MUCController ( muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); - muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); - muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2)); muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); @@ -119,9 +117,11 @@ MUCController::MUCController ( } if (isImpromptu) { muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this)); - chatWindow_->convertToMUC(true); + chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC); } else { - chatWindow_->convertToMUC(); + muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); + muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); + chatWindow_->convertToMUC(ChatWindow::StandardMUC); chatWindow_->setName(muc->getJID().getNode()); } setOnline(true); @@ -154,7 +154,7 @@ void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item if (item) { MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation(); MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole(); - if (role == MUCOccupant::Moderator) + if (role == MUCOccupant::Moderator && !isImpromptu_) { if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) { actions.push_back(ChatWindow::Ban); @@ -348,8 +348,12 @@ void MUCController::handleJoinComplete(const std::string& nick) { clearPresenceQueue(); shouldJoinOnReconnect_ = true; setEnabled(true); - MUCOccupant occupant = muc_->getOccupant(nick); - setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); + if (isImpromptu_) { + setAvailableRoomActions(MUCOccupant::NoAffiliation, MUCOccupant::Participant); + } else { + MUCOccupant occupant = muc_->getOccupant(nick); + setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); + } onUserJoined(); if (isImpromptu_) { @@ -384,13 +388,18 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) { currentOccupants_.insert(occupant.getNick()); NickJoinPart event(occupant.getNick(), Join); appendToJoinParts(joinParts_, event); - std::string groupName(roleToGroupName(occupant.getRole())); + MUCOccupant::Role role = MUCOccupant::Participant; + MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; + if (!isImpromptu_) { + role = occupant.getRole(); + affiliation = occupant.getAffiliation(); + } + std::string groupName(roleToGroupName(role)); roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid)); - roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation())); - roster_->getGroup(groupName)->setManualSort(roleToSortName(occupant.getRole())); + roster_->applyOnItems(SetMUC(jid, role, affiliation)); + roster_->getGroup(groupName)->setManualSort(roleToSortName(role)); if (joined_) { std::string joinString; - MUCOccupant::Role role = occupant.getRole(); if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) { joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %3% as a %2%.")) % occupant.getNick() % roleToFriendlyName(role) % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room"))); } diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 0f0062d..771872a 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -92,6 +92,7 @@ namespace Swift { enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected}; enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked}; enum Direction { UnknownDirection, DefaultDirection }; + enum MUCType { StandardMUC, ImpromptuMUC }; ChatWindow() {} virtual ~ChatWindow() {} @@ -132,7 +133,7 @@ namespace Swift { virtual void setSecurityLabelsEnabled(bool enabled) = 0; virtual void setCorrectionEnabled(Tristate enabled) = 0; virtual void setUnreadMessageCount(int count) = 0; - virtual void convertToMUC(bool impromptuMUC = false) = 0; + virtual void convertToMUC(MUCType mucType) = 0; // virtual TreeWidget *getTreeWidget() = 0; virtual void setSecurityLabelsError() = 0; virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0; diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 59ed0f1..8aa645d 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -45,7 +45,7 @@ namespace Swift { virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;} virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;} virtual void setUnreadMessageCount(int /*count*/) {} - virtual void convertToMUC(bool /*impromptuMUC*/) {} + virtual void convertToMUC(MUCType /*mucType*/) {} virtual void setSecurityLabelsError() {} virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;} virtual void setInputEnabled(bool /*enabled*/) {} diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 826ec9e..bd7c817 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -116,7 +116,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt } logRosterSplitter_->addWidget(messageLog_); - treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, this); + treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, QtTreeWidget::MessageDefaultJID, this); treeWidget_->hide(); logRosterSplitter_->addWidget(treeWidget_); logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -396,8 +396,9 @@ void QtChatWindow::closeEvent(QCloseEvent* event) { onClosed(); } -void QtChatWindow::convertToMUC(bool impromptuMUC) { - impromptu_ = impromptuMUC; +void QtChatWindow::convertToMUC(MUCType mucType) { + impromptu_ = (mucType == ImpromptuMUC); + treeWidget_->setMessageTarget(impromptu_ ? QtTreeWidget::MessageDisplayJID : QtTreeWidget::MessageDefaultJID); isMUC_ = true; treeWidget_->show(); subject_->setVisible(!impromptu_); diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index eeb8093..5a4fe95 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -99,7 +99,7 @@ namespace Swift { void show(); void activate(); void setUnreadMessageCount(int count); - void convertToMUC(bool impromptuMUC = false); + void convertToMUC(MUCType mucType); // TreeWidget *getTreeWidget(); void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels); void setSecurityLabelsEnabled(bool enabled); diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp index 9f88258..75eeaad 100644 --- a/Swift/QtUI/QtHistoryWindow.cpp +++ b/Swift/QtUI/QtHistoryWindow.cpp @@ -60,7 +60,7 @@ QtHistoryWindow::QtHistoryWindow(SettingsProvider* settings, UIEventStream* even ui_.bottomLayout_->addWidget(conversation_); delete ui_.conversationRoster_; - conversationRoster_ = new QtTreeWidget(eventStream, settings, this); + conversationRoster_ = new QtTreeWidget(eventStream, settings, QtTreeWidget::MessageDefaultJID, this); QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding); sizePolicy2.setVerticalStretch(80); conversationRoster_->setSizePolicy(sizePolicy2); diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.cpp b/Swift/QtUI/Roster/QtOccupantListWidget.cpp index 12dc1e4..4f1baf3 100644 --- a/Swift/QtUI/Roster/QtOccupantListWidget.cpp +++ b/Swift/QtUI/Roster/QtOccupantListWidget.cpp @@ -1,25 +1,26 @@ /* - * Copyright (c) 2011-2012 Kevin Smith + * Copyright (c) 2011-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Roster/QtOccupantListWidget.h" +#include <Swift/QtUI/Roster/QtOccupantListWidget.h> #include <QContextMenuEvent> #include <QMenu> #include <QAction> #include <QInputDialog> -#include "Swift/Controllers/Roster/ContactRosterItem.h" -#include "Swift/Controllers/Roster/GroupRosterItem.h" -#include "Swift/Controllers/UIEvents/UIEventStream.h" -#include "QtSwiftUtil.h" +#include <Swift/Controllers/Roster/ContactRosterItem.h> +#include <Swift/Controllers/Roster/GroupRosterItem.h> +#include <Swift/Controllers/UIEvents/UIEventStream.h> + +#include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { -QtOccupantListWidget::QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent) : QtTreeWidget(eventStream, settings, parent) { +QtOccupantListWidget::QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget privateMessageTarget, QWidget* parent) : QtTreeWidget(eventStream, settings, privateMessageTarget, parent) { } diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.h b/Swift/QtUI/Roster/QtOccupantListWidget.h index 729115a..c944658 100644 --- a/Swift/QtUI/Roster/QtOccupantListWidget.h +++ b/Swift/QtUI/Roster/QtOccupantListWidget.h @@ -1,15 +1,16 @@ /* - * Copyright (c) 2011-2012 Kevin Smith + * Copyright (c) 2011-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include "Swift/QtUI/Roster/QtTreeWidget.h" +#include <Swift/QtUI/Roster/QtTreeWidget.h> -#include "Swiften/Base/boost_bsignals.h" -#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include <Swiften/Base/boost_bsignals.h> + +#include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { class SettingsProvider; @@ -17,7 +18,7 @@ class SettingsProvider; class QtOccupantListWidget : public QtTreeWidget { Q_OBJECT public: - QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent = 0); + QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget privateMessageTarget, QWidget* parent = NULL); virtual ~QtOccupantListWidget(); void setAvailableOccupantActions(const std::vector<ChatWindow::OccupantAction>& actions); boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected; diff --git a/Swift/QtUI/Roster/QtRosterWidget.cpp b/Swift/QtUI/Roster/QtRosterWidget.cpp index 1436c7c..fff0ccd 100644 --- a/Swift/QtUI/Roster/QtRosterWidget.cpp +++ b/Swift/QtUI/Roster/QtRosterWidget.cpp @@ -28,7 +28,7 @@ namespace Swift { -QtRosterWidget::QtRosterWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent) : QtTreeWidget(eventStream, settings, parent) { +QtRosterWidget::QtRosterWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent) : QtTreeWidget(eventStream, settings, MessageDefaultJID, parent) { } diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp index 91e9a33..ed76a6f 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.cpp +++ b/Swift/QtUI/Roster/QtTreeWidget.cpp @@ -26,12 +26,12 @@ #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/QtUI/QtUISettingConstants.h> - +#include <Swift/QtUI/Roster/RosterModel.h> #include <QtSwiftUtil.h> namespace Swift { -QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent) : QTreeView(parent), tooltipShown_(false) { +QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent) : QTreeView(parent), messageTarget_(messageTarget), tooltipShown_(false) { eventStream_ = eventStream; settings_ = settings; model_ = new RosterModel(this, settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)); @@ -137,12 +137,24 @@ void QtTreeWidget::currentChanged(const QModelIndex& current, const QModelIndex& QTreeView::currentChanged(current, previous); } - void QtTreeWidget::handleItemActivated(const QModelIndex& index) { - RosterItem* item = static_cast<RosterItem*>(index.internalPointer()); - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact) { - eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(contact->getJID()))); + switch (messageTarget_) { + case MessageDisplayJID: { + QString indexJID = index.data(DisplayJIDRole).toString(); + if (!indexJID.isEmpty()) { + JID target = JID(Q2PSTRING(indexJID)).toBare(); + eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target))); + break; + } + } + case MessageDefaultJID: { + QString indexJID = index.data(JIDRole).toString(); + if (!indexJID.isEmpty()) { + JID target = JID(Q2PSTRING(indexJID)); + eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target))); + } + break; + } } } @@ -230,4 +242,8 @@ void QtTreeWidget::show() { QWidget::show(); } +void QtTreeWidget::setMessageTarget(MessageTarget messageTarget) { + messageTarget_ = messageTarget; +} + } diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h index 8884a40..29e985d 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.h +++ b/Swift/QtUI/Roster/QtTreeWidget.h @@ -1,34 +1,40 @@ /* - * Copyright (c) 2010-2012 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include <QTreeView> -#include <QModelIndex> #include <QDragEnterEvent> #include <QDropEvent> #include <QDragMoveEvent> +#include <QModelIndex> +#include <QTreeView> -#include <Swift/QtUI/Roster/RosterModel.h> #include <Swift/QtUI/Roster/RosterDelegate.h> +#include <Swift/QtUI/Roster/RosterModel.h> + +#include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { class UIEventStream; class SettingsProvider; -class QtTreeWidget : public QTreeView{ +class QtTreeWidget : public QTreeView { Q_OBJECT public: - QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent = 0); + enum MessageTarget {MessageDefaultJID, MessageDisplayJID}; + + QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent = 0); ~QtTreeWidget(); void show(); QtTreeWidgetItem* getRoot(); void setRosterModel(Roster* roster); Roster* getRoster() {return roster_;} void refreshTooltip(); + void setMessageTarget(MessageTarget messageTarget); + public: boost::signal<void (RosterItem*)> onSomethingSelectedChanged; private slots: @@ -45,9 +51,8 @@ class QtTreeWidget : public QTreeView{ void dropEvent(QDropEvent* event); void dragMoveEvent(QDragMoveEvent* event); bool event(QEvent* event); - - protected: QModelIndexList getSelectedIndexes() const; + private: void drawBranches(QPainter*, const QRect&, const QModelIndex&) const; @@ -63,6 +68,7 @@ class QtTreeWidget : public QTreeView{ QtTreeWidgetItem* treeRoot_; SettingsProvider* settings_; bool tooltipShown_; + MessageTarget messageTarget_; }; } diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp index fa8c393..2bd0d09 100644 --- a/Swift/QtUI/Roster/RosterModel.cpp +++ b/Swift/QtUI/Roster/RosterModel.cpp @@ -102,6 +102,8 @@ QVariant RosterModel::data(const QModelIndex& index, int role) const { case PresenceIconRole: return getPresenceIcon(item); case ChildCountRole: return getChildCount(item); case IdleRole: return getIsIdle(item); + case JIDRole: return getJID(item); + case DisplayJIDRole: return getDisplayJID(item); default: return QVariant(); } } @@ -181,6 +183,16 @@ QString RosterModel::getStatusText(RosterItem* item) const { return P2QSTRING(contact->getStatusText()); } +QString RosterModel::getJID(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + return contact ? P2QSTRING(contact->getJID().toString()) : QString(); +} + +QString RosterModel::getDisplayJID(RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + return contact ? P2QSTRING(contact->getDisplayJID().toString()) : QString(); +} + QIcon RosterModel::getPresenceIcon(RosterItem* item) const { ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); if (!contact) return QIcon(); diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h index 7f6cdd2..2b05044 100644 --- a/Swift/QtUI/Roster/RosterModel.h +++ b/Swift/QtUI/Roster/RosterModel.h @@ -20,7 +20,9 @@ namespace Swift { PresenceIconRole = Qt::UserRole + 2, StatusShowTypeRole = Qt::UserRole + 3, ChildCountRole = Qt::UserRole + 4, - IdleRole = Qt::UserRole + 5 + IdleRole = Qt::UserRole + 5, + JIDRole = Qt::UserRole + 6, + DisplayJIDRole = Qt::UserRole + 7 }; class QtTreeWidget; @@ -52,6 +54,8 @@ namespace Swift { QString getToolTip(RosterItem* item) const; QString getAvatar(RosterItem* item) const; QString getStatusText(RosterItem* item) const; + QString getJID(RosterItem* item) const; + QString getDisplayJID(RosterItem* item) const; QIcon getPresenceIcon(RosterItem* item) const; int getChildCount(RosterItem* item) const; bool getIsIdle(RosterItem* item) const; -- cgit v0.10.2-6-g49f6