diff options
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 23 | ||||
-rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h | 10 | ||||
-rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 1 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 23 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.h | 13 | ||||
-rw-r--r-- | Swift/QtUI/QtMUCConfigurationWindow.cpp | 56 | ||||
-rw-r--r-- | Swift/QtUI/QtMUCConfigurationWindow.h | 34 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 1 |
10 files changed, 149 insertions, 18 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index 79d376c..67bd74f 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -64,27 +64,27 @@ namespace Swift { virtual std::string senderDisplayNameFromMessage(const JID& from) = 0; virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0; virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {}; virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {}; virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}; virtual bool isFromContact(const JID& from); virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const = 0; virtual void dayTicked() {}; virtual void handleBareJIDCapsChanged(const JID& jid) = 0; + std::string getErrorMessage(boost::shared_ptr<ErrorPayload>); private: IDGenerator idGenerator_; std::string lastSentMessageStanzaID_; void createDayChangeTimer(); void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage); void handleAllMessagesRead(); void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error); - std::string getErrorMessage(boost::shared_ptr<ErrorPayload>); void handleDayChangeTick(); protected: JID selfJID_; std::vector<boost::shared_ptr<MessageEvent> > unreadMessages_; StanzaChannel* stanzaChannel_; IQRouter* iqRouter_; ChatWindowFactory* chatWindowFactory_; ChatWindow* chatWindow_; diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 178f4b6..56cc639 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -66,25 +66,27 @@ MUCController::MUCController ( roster_ = new Roster(false, true); completer_ = new TabComplete(); chatWindow_->setRosterModel(roster_); chatWindow_->setTabComplete(completer_); chatWindow_->setName(muc->getJID().getNode()); chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1)); chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); - chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this)); + chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); 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_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); + muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); if (timerFactory) { loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS)); loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); loginCheckTimer_->start(); } chatWindow_->convertToMUC(); setOnline(true); if (avatarManager_ != NULL) { avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1))); @@ -571,14 +573,29 @@ std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart result += eventStrings[populatedEvents[i]]; } return result; } void MUCController::handleChangeSubjectRequest(const std::string& subject) { muc_->changeSubject(subject); } -void MUCController::handleConfigureRequest() { - muc_->requestConfigurationForm(); +void MUCController::handleConfigureRequest(Form::ref form) { + if (form) { + muc_->configureRoom(form); + } + else { + muc_->requestConfigurationForm(); + } +} + +void MUCController::handleConfigurationFailed(ErrorPayload::ref error) { + std::string errorMessage = getErrorMessage(error); + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage); + chatWindow_->addErrorMessage(errorMessage); +} + +void MUCController::handleConfigurationFormReceived(Form::ref form) { + chatWindow_->showRoomConfigurationForm(form); } } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 08a3fc3..4be1488 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -82,19 +82,21 @@ namespace Swift { JID nickToJID(const std::string& nick); std::string roleToFriendlyName(MUCOccupant::Role role); void receivedActivity(); bool messageTargetsMe(boost::shared_ptr<Message> message); void updateJoinParts(); bool shouldUpdateJoinParts(); void dayTicked() {lastWasPresence_ = false;} void processUserPart(); void handleBareJIDCapsChanged(const JID& jid); - void handleConfigureRequest(); + void handleConfigureRequest(Form::ref); + void handleConfigurationFailed(ErrorPayload::ref); + void handleConfigurationFormReceived(Form::ref); private: MUC::ref muc_; UIEventStream* events_; std::string nick_; std::string desiredNick_; Roster* roster_; TabComplete* completer_; bool parting_; diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 7004324..75c92d3 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -8,20 +8,22 @@ #define SWIFTEN_CHATWINDOW_H #include <boost/optional.hpp> #include "Swiften/Base/boost_bsignals.h" #include <boost/shared_ptr.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <vector> #include <string> -#include "Swiften/Elements/SecurityLabelsCatalog.h" -#include "Swiften/Elements/ChatState.h" +#include <Swiften/Elements/SecurityLabelsCatalog.h> +#include <Swiften/Elements/ChatState.h> +#include <Swiften/Elements/Form.h> + namespace Swift { class AvatarManager; class TreeWidget; class Roster; class TabComplete; class RosterItem; class ContactRosterItem; class FileTransferController; @@ -81,29 +83,31 @@ namespace Swift { /** * Removes an alert. */ virtual void cancelAlert() = 0; /** * Actions that can be performed on the selected occupant. */ virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0; + + virtual void showRoomConfigurationForm(Form::ref) = 0; boost::signal<void ()> onClosed; boost::signal<void ()> onAllMessagesRead; boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; boost::signal<void ()> onSendCorrectionMessageRequest; boost::signal<void ()> onUserTyping; boost::signal<void ()> onUserCancelsTyping; boost::signal<void ()> onAlertButtonClicked; boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged; boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected; boost::signal<void (const std::string&)> onChangeSubjectRequest; - boost::signal<void ()> onConfigureRequest; + boost::signal<void (Form::ref)> onConfigureRequest; // File transfer related boost::signal<void (std::string /* id */)> onFileTransferCancel; boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart; boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept; boost::signal<void (std::string /* path */)> onSendFileRequest; }; } #endif diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 143e281..ad8856b 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -41,18 +41,19 @@ namespace Swift { virtual void replaceLastMessage(const std::string&) {}; virtual void replaceMessage(const std::string&, const std::string&, const boost::posix_time::ptime&) {}; void setAckState(const std::string& /*id*/, AckState /*state*/) {}; virtual void flash() {}; virtual void setAlert(const std::string& /*alertText*/, const std::string& /*buttonText*/) {}; virtual void cancelAlert() {}; virtual void setCorrectionEnabled(Tristate /*enabled*/) {} void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {} void setSubject(const std::string& /*subject*/) {} + virtual void showRoomConfigurationForm(Form::ref) {} boost::signal<void ()> onClosed; boost::signal<void ()> onAllMessagesRead; boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; std::string name_; std::string lastMessageBody_; std::vector<SecurityLabelsCatalog::Item> labels_; bool labelsEnabled_; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 2e3a225..1576880 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -156,18 +156,21 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt messageLog_->addToJSEnvironment("filetransfer", fileTransferJS); connect(fileTransferJS, SIGNAL(setDescription(QString)), this, SLOT(handleFileTransferSetDescription(QString))); connect(fileTransferJS, SIGNAL(sendRequest(QString)), this, SLOT(handleFileTransferStart(QString))); connect(fileTransferJS, SIGNAL(acceptRequest(QString, QString)), this, SLOT(handleFileTransferAccept(QString, QString))); connect(fileTransferJS, SIGNAL(cancel(QString)), this, SLOT(handleFileTransferCancel(QString))); } QtChatWindow::~QtChatWindow() { delete fileTransferJS; + if (mucConfigurationWindow) { + delete mucConfigurationWindow.data(); + } } void QtChatWindow::handleOccupantSelectionChanged(RosterItem* item) { onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item)); } void QtChatWindow::handleFontResized(int fontSizeSteps) { messageLog_->resizeFont(fontSizeSteps); @@ -358,19 +361,21 @@ void QtChatWindow::qAppFocusChanged(QWidget* /*old*/, QWidget* /*now*/) { onAllMessagesRead(); } else { lastLineTracker_.setHasFocus(false); } } void QtChatWindow::setInputEnabled(bool enabled) { inputEnabled_ = enabled; -// input_->setEnabled(enabled); + if (!enabled && mucConfigurationWindow) { + delete mucConfigurationWindow.data(); + } } void QtChatWindow::showEvent(QShowEvent* event) { emit windowOpening(); QWidget::showEvent(event); } void QtChatWindow::setUnreadMessageCount(int count) { if (unreadCount_ != count) { @@ -688,24 +693,32 @@ void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction> void QtChatWindow::setSubject(const std::string& subject) { //subject_->setVisible(!subject.empty()); subject_->setText(P2QSTRING(subject)); } void QtChatWindow::handleActionButtonClicked() { QMenu contextMenu; QAction* changeSubject = contextMenu.addAction(tr("Change subject")); - //QAction* configure = contextMenu.addAction(tr("Configure room")); + QAction* configure = contextMenu.addAction(tr("Configure room")); QAction* result = contextMenu.exec(QCursor::pos()); if (result == changeSubject) { bool ok; QString subject = QInputDialog::getText(this, tr("Change room subject"), tr("New subject:"), QLineEdit::Normal, subject_->text(), &ok); if (ok) { onChangeSubjectRequest(Q2PSTRING(subject)); } } - //else if (result == configure) { - // onConfigureRequest(); - //} + else if (result == configure) { + onConfigureRequest(Form::ref()); + } +} + +void QtChatWindow::showRoomConfigurationForm(Form::ref form) { + if (mucConfigurationWindow) { + delete mucConfigurationWindow.data(); + } + mucConfigurationWindow = new QtMUCConfigurationWindow(form); + mucConfigurationWindow->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1)); } } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index b8fa478..b011427 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -1,26 +1,28 @@ /* * Copyright (c) 2010-2011 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include "Swift/Controllers/UIInterfaces/ChatWindow.h" +#include <Swift/Controllers/UIInterfaces/ChatWindow.h> +#include <Swift/QtUI/QtMUCConfigurationWindow.h> -#include "QtTabbable.h" +#include <QtTabbable.h> -#include "SwifTools/LastLineTracker.h" +#include <SwifTools/LastLineTracker.h> -#include "Swiften/Base/IDGenerator.h" +#include <Swiften/Base/IDGenerator.h> #include <map> +#include <QPointer> class QTextEdit; class QLineEdit; class QComboBox; class QLabel; class QSplitter; class QPushButton; namespace Swift { @@ -63,18 +65,19 @@ namespace Swift { void setRosterModel(Roster* roster); void setTabComplete(TabComplete* completer); int getCount(); void replaceLastMessage(const std::string& message); void setAckState(const std::string& id, AckState state); void flash(); QByteArray getSplitterState(); virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions); void setSubject(const std::string& subject); + void showRoomConfigurationForm(Form::ref); public slots: void handleChangeSplitterState(QByteArray state); void handleFontResized(int fontSizeSteps); void setAlert(const std::string& alertText, const std::string& buttonText = ""); void cancelAlert(); void setCorrectionEnabled(Tristate enabled); signals: @@ -141,14 +144,14 @@ namespace Swift { bool previousMessageWasFileTransfer_; QString previousSenderName_; bool inputClearing_; UIEventStream* eventStream_; bool inputEnabled_; IDGenerator id_; QSplitter *logRosterSplitter_; Tristate correctionEnabled_; QString alertStyleSheet_; - std::map<QString, QString> descriptions; QtFileTransferJSBridge* fileTransferJS; + QPointer<QtMUCConfigurationWindow> mucConfigurationWindow; }; } diff --git a/Swift/QtUI/QtMUCConfigurationWindow.cpp b/Swift/QtUI/QtMUCConfigurationWindow.cpp new file mode 100644 index 0000000..e6be9b7 --- /dev/null +++ b/Swift/QtUI/QtMUCConfigurationWindow.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/QtUI/QtMUCConfigurationWindow.h> + +#include <boost/bind.hpp> +#include <QBoxLayout> +#include <Swift/QtUI/QtFormWidget.h> + +namespace Swift { +QtMUCConfigurationWindow::QtMUCConfigurationWindow(Form::ref form) { + + setAttribute(Qt::WA_DeleteOnClose); + + QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this); + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(2); + QLabel* label = new QLabel(this); + label->setText(tr("Room configuration")); + layout->addWidget(label); + + formWidget_ = NULL; + formWidget_ = new QtFormWidget(form, this); + layout->addWidget(formWidget_); + + QWidget* buttonsWidget = new QWidget(this); + layout->addWidget(buttonsWidget); + + QBoxLayout* buttonsLayout = new QBoxLayout(QBoxLayout::LeftToRight, buttonsWidget); + cancelButton_ = new QPushButton(tr("Cancel"), buttonsWidget); + buttonsLayout->addWidget(cancelButton_); + connect(cancelButton_, SIGNAL(clicked()), this, SLOT(handleCancelClicked())); + okButton_ = new QPushButton(tr("OK"), buttonsWidget); + buttonsLayout->addWidget(okButton_); + connect(okButton_, SIGNAL(clicked()), this, SLOT(handleOKClicked())); + show(); +} + +QtMUCConfigurationWindow::~QtMUCConfigurationWindow() { + +} + +void QtMUCConfigurationWindow::handleCancelClicked() { + close(); +} + +void QtMUCConfigurationWindow::handleOKClicked() { + onFormComplete(formWidget_->getCompletedForm()); + close(); +} + + +} diff --git a/Swift/QtUI/QtMUCConfigurationWindow.h b/Swift/QtUI/QtMUCConfigurationWindow.h new file mode 100644 index 0000000..2be126b --- /dev/null +++ b/Swift/QtUI/QtMUCConfigurationWindow.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <QWidget> +#include <QPushButton> +#include <QLabel> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Form.h> + +class QBoxLayout; + +namespace Swift { + class QtFormWidget; + class QtMUCConfigurationWindow : public QWidget { + Q_OBJECT + public: + QtMUCConfigurationWindow(Form::ref form); + virtual ~QtMUCConfigurationWindow(); + boost::signal<void (Form::ref)> onFormComplete; + private slots: + void handleCancelClicked(); + void handleOKClicked(); + private: + QtFormWidget* formWidget_; + QPushButton* okButton_; + QPushButton* cancelButton_; + }; +} diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 1d7ab78..82e4490 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -130,18 +130,19 @@ sources = [ "UserSearch/QtUserSearchWindow.cpp", "UserSearch/UserSearchModel.cpp", "UserSearch/UserSearchDelegate.cpp", "QtSubscriptionRequestWindow.cpp", "QtRosterHeader.cpp", "QtWebView.cpp", "qrc_DefaultTheme.cc", "qrc_Swift.cc", "QtFileTransferJSBridge.cpp", + "QtMUCConfigurationWindow.cpp", ] myenv["SWIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift") if env["PLATFORM"] == "win32" : res = myenv.RES("#/Swift/resources/Windows/Swift.rc") # For some reason, SCons isn't picking up the dependency correctly # Adding it explicitly until i figure out why myenv.Depends(res, "../Controllers/BuildVersion.h") |