From 6aeb44a905b0c1955ea3afe4ea2025370544e699 Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Thu, 31 May 2012 18:27:48 +0100 Subject: Very poor prototype of a MUC invite dialog diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index e4209f4..3d04b34 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -19,6 +19,7 @@ #include <Swiften/Base/foreach.h> #include <Swift/Controllers/XMPPEvents/EventController.h> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> +#include <Swift/Controllers/UIInterfaces/InviteToChatWindow.h> #include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> @@ -64,6 +65,7 @@ MUCController::MUCController ( shouldJoinOnReconnect_ = true; doneGettingHistory_ = false; events_ = uiEventStream; + inviteWindow_ = NULL; roster_ = new Roster(false, true); completer_ = new TabComplete(); @@ -77,7 +79,7 @@ MUCController::MUCController ( chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this)); chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this)); - chatWindow_->onInvitePersonToThisMUCRequest.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1, _2)); + chatWindow_->onInvitePersonToThisMUCRequest.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this)); chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this)); chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); @@ -719,8 +721,22 @@ void MUCController::handleDestroyRoomRequest() { muc_->destroyRoom(); } -void MUCController::handleInvitePersonToThisMUCRequest(const JID& jid, const std::string& reason) { - muc_->invitePerson(jid, reason); +void MUCController::handleInvitePersonToThisMUCRequest() { + if (!inviteWindow_) { + inviteWindow_ = chatWindow_->createInviteToChatWindow(); + inviteWindow_->onCompleted.connect(boost::bind(&MUCController::handleInviteToMUCWindowCompleted, this)); + inviteWindow_->onDismissed.connect(boost::bind(&MUCController::handleInviteToMUCWindowDismissed, this)); + } +} + +void MUCController::handleInviteToMUCWindowDismissed() { + inviteWindow_= NULL; +} + +void MUCController::handleInviteToMUCWindowCompleted() { + foreach (const JID& jid, inviteWindow_->getJIDs()) { + muc_->invitePerson(jid, inviteWindow_->getReason()); + } } void MUCController::handleGetAffiliationsRequest() { diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 9550ca9..8b43dcf 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -31,6 +31,7 @@ namespace Swift { class UIEventStream; class TimerFactory; class TabComplete; + class InviteToChatWindow; enum JoinPart {Join, Part, JoinThenPart, PartThenJoin}; @@ -95,12 +96,14 @@ namespace Swift { void handleConfigurationFailed(ErrorPayload::ref); void handleConfigurationFormReceived(Form::ref); void handleDestroyRoomRequest(); - void handleInvitePersonToThisMUCRequest(const JID& jid, const std::string& reason); + void handleInvitePersonToThisMUCRequest(); void handleConfigurationCancelled(); void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role); void handleGetAffiliationsRequest(); void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids); void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes); + void handleInviteToMUCWindowDismissed(); + void handleInviteToMUCWindowCompleted(); private: MUC::ref muc_; @@ -120,6 +123,7 @@ namespace Swift { std::vector<NickJoinPart> joinParts_; boost::posix_time::ptime lastActivity_; boost::optional<std::string> password_; + InviteToChatWindow* inviteWindow_; }; } diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index b5b1604..9188c7f 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -7,7 +7,7 @@ #pragma once #include <boost/optional.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <vector> @@ -27,6 +27,7 @@ namespace Swift { class RosterItem; class ContactRosterItem; class FileTransferController; + class InviteToChatWindow; class ChatWindow { public: @@ -105,6 +106,8 @@ namespace Swift { */ virtual void showRoomConfigurationForm(Form::ref) = 0; + virtual InviteToChatWindow* createInviteToChatWindow() = 0; + boost::signal<void ()> onClosed; boost::signal<void ()> onAllMessagesRead; boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; @@ -117,7 +120,7 @@ namespace Swift { boost::signal<void (const std::string&)> onChangeSubjectRequest; boost::signal<void (Form::ref)> onConfigureRequest; boost::signal<void ()> onDestroyRequest; - boost::signal<void (const JID&, const std::string& /*reason*/)> onInvitePersonToThisMUCRequest; + boost::signal<void ()> onInvitePersonToThisMUCRequest; boost::signal<void ()> onConfigurationFormCancelled; boost::signal<void ()> onGetAffiliationsRequest; boost::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest; diff --git a/Swift/Controllers/UIInterfaces/InviteToChatWindow.h b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h new file mode 100644 index 0000000..f34a485 --- /dev/null +++ b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <string> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> + +namespace Swift { + class InviteToChatWindow { + public: + virtual ~InviteToChatWindow() {}; + + virtual std::string getReason() const = 0; + + virtual std::vector<JID> getJIDs() const = 0; + + boost::signal<void ()> onCompleted; + boost::signal<void ()> onDismissed; + }; +} + diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index e0e18a0..dbfef3e 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -54,6 +54,7 @@ namespace Swift { virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true) {}; virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {} virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}; + virtual InviteToChatWindow* createInviteToChatWindow() {return NULL;} std::string name_; std::string lastMessageBody_; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 52ce701..137c044 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -17,6 +17,7 @@ #include "QtTextEdit.h" #include "QtSettingsProvider.h" #include "QtScaledAvatarCache.h" +#include "QtInviteToChatWindow.h" #include <Swiften/StringCodecs/Base64.h> #include "SwifTools/TabComplete.h" @@ -843,11 +844,7 @@ void QtChatWindow::handleActionButtonClicked() { } } else if (result == invite) { - bool ok; - QString jid = QInputDialog::getText(this, tr("Enter person's address"), tr("Address:"), QLineEdit::Normal, "", &ok); - if (ok) { - onInvitePersonToThisMUCRequest(JID(Q2PSTRING(jid)), ""); - } + onInvitePersonToThisMUCRequest(); } } @@ -908,4 +905,10 @@ void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& ji previousMessageKind_ = PreviousMessageWasMUCInvite; } + +InviteToChatWindow* QtChatWindow::createInviteToChatWindow() { + return new QtInviteToChatWindow(this); +} + + } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 4b888eb..ff26c9c 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -91,6 +91,8 @@ namespace Swift { void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&); void setAvailableRoomActions(const std::vector<RoomAction> &actions); + InviteToChatWindow* createInviteToChatWindow(); + static QString buildChatWindowButton(const QString& name, const QString& id, const QString& arg1 = QString(), const QString& arg2 = QString(), const QString& arg3 = QString()); public slots: diff --git a/Swift/QtUI/QtInviteToChatWindow.cpp b/Swift/QtUI/QtInviteToChatWindow.cpp new file mode 100644 index 0000000..d53c493 --- /dev/null +++ b/Swift/QtUI/QtInviteToChatWindow.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/QtUI/QtInviteToChatWindow.h> + +#include <QHBoxLayout> +#include <QCompleter> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include <QDialogButtonBox> + +#include <Swift/QtUI/QtSwiftUtil.h> + +namespace Swift { + +QtInviteToChatWindow::QtInviteToChatWindow(QWidget* parent) : QDialog(parent) { + QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(2); + + QLabel* description = new QLabel(tr("Users to invite to this chat (one per line):")); + layout->addWidget(description); + + jidsLayout_ = new QBoxLayout(QBoxLayout::TopToBottom); + layout->addLayout(jidsLayout_); + + QLabel* reasonLabel = new QLabel(tr("If you want to provide a reason for the invitation, enter it here")); + layout->addWidget(reasonLabel); + reason_ = new QLineEdit(this); + layout->addWidget(reason_); + addJIDLine(); + + connect(this, SIGNAL(accepted()), this, SLOT(handleAccepting())); + connect(this, SIGNAL(rejected()), this, SLOT(handleRejecting())); + + + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + layout->addWidget(buttonBox); + + setModal(false); + show(); +} + +QtInviteToChatWindow::~QtInviteToChatWindow() { + +} + +void QtInviteToChatWindow::handleAccepting() { + onCompleted(); +} + +void QtInviteToChatWindow::handleRejecting() { + onDismissed(); +} + +std::string QtInviteToChatWindow::getReason() const { + return Q2PSTRING(reason_->text()); +} + +std::vector<JID> QtInviteToChatWindow::getJIDs() const { + std::vector<JID> results; + foreach (QLineEdit* jidEdit, jids_) { + QStringList parts = jidEdit->text().split(" "); + if (parts.size() > 0) { + JID jid(Q2PSTRING(parts.last())); + if (jid.isValid() && !jid.getNode().empty()) { + results.push_back(jid); + } + } + } + return results; +} + +void QtInviteToChatWindow::addJIDLine() { + QLineEdit* jid = new QLineEdit(this); + QCompleter* completer = new QCompleter(completions_, this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + jid->setCompleter(completer); + jids_.push_back(jid); + jidsLayout_->addWidget(jid); + connect(jid, SIGNAL(textChanged(const QString&)), this, SLOT(handleJIDTextChanged())); +} + +void QtInviteToChatWindow::handleJIDTextChanged() { + bool gotEmpty = false; + foreach(QLineEdit* edit, jids_) { + if (edit->text().isEmpty()) { + gotEmpty = true; + } + } + if (!gotEmpty) { + addJIDLine(); + } +} + +} + + + diff --git a/Swift/QtUI/QtInviteToChatWindow.h b/Swift/QtUI/QtInviteToChatWindow.h new file mode 100644 index 0000000..c009861 --- /dev/null +++ b/Swift/QtUI/QtInviteToChatWindow.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swift/Controllers/UIInterfaces/InviteToChatWindow.h> + +#include <QDialog> +#include <QStringList> + +class QLineEdit; +class QBoxLayout; + +namespace Swift { + class QtInviteToChatWindow : public QDialog, public InviteToChatWindow { + Q_OBJECT + public: + QtInviteToChatWindow(QWidget* parent = NULL); + virtual ~QtInviteToChatWindow(); + + virtual std::string getReason() const; + + virtual std::vector<JID> getJIDs() const; + private: + void addJIDLine(); + private slots: + void handleJIDTextChanged(); + void handleAccepting(); + void handleRejecting(); + private: + QStringList completions_; + QLineEdit* reason_; + QBoxLayout* jidsLayout_; + std::vector<QLineEdit*> jids_; + }; +} + + diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 4c53313..042e2a0 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -109,6 +109,7 @@ sources = [ "QtFormResultItemModel.cpp", "QtLineEdit.cpp", "QtJoinMUCWindow.cpp", + "QtInviteToChatWindow.cpp", "Roster/RosterModel.cpp", "Roster/QtTreeWidget.cpp", # "Roster/QtTreeWidgetItem.cpp", -- cgit v0.10.2-6-g49f6