diff options
Diffstat (limited to 'Swift/QtUI')
| -rw-r--r-- | Swift/QtUI/QtAffiliationEditor.cpp | 79 | ||||
| -rw-r--r-- | Swift/QtUI/QtAffiliationEditor.h | 37 | ||||
| -rw-r--r-- | Swift/QtUI/QtAffiliationEditor.ui | 146 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 44 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.h | 6 | ||||
| -rw-r--r-- | Swift/QtUI/Roster/QtOccupantListWidget.cpp | 1 | ||||
| -rw-r--r-- | Swift/QtUI/SConscript | 6 |
7 files changed, 306 insertions, 13 deletions
diff --git a/Swift/QtUI/QtAffiliationEditor.cpp b/Swift/QtUI/QtAffiliationEditor.cpp new file mode 100644 index 0000000..ed03c23 --- /dev/null +++ b/Swift/QtUI/QtAffiliationEditor.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "QtAffiliationEditor.h" + +#include <QListWidgetItem> +#include <QInputDialog> + +#include "QtSwiftUtil.h" + + +namespace Swift { +QtAffiliationEditor::QtAffiliationEditor(QWidget* parent) : QDialog(parent){ + ui_.setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + connect(ui_.affiliation, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged(int))); + connect(ui_.addJID, SIGNAL(clicked()), this, SLOT(handleAddClicked())); + connect(ui_.removeJID, SIGNAL(clicked()), this, SLOT(handleRemoveClicked())); +} + +QtAffiliationEditor::~QtAffiliationEditor() { + +} + +void QtAffiliationEditor::setAffiliations(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) { + affiliations_[affiliation] = jids; + if (affiliationFromIndex(ui_.affiliation->currentIndex()) == affiliation) { + handleCurrentIndexChanged(ui_.affiliation->currentIndex()); + } +} + +const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& QtAffiliationEditor::getChanges() const { + return changes_; +} + +void QtAffiliationEditor::handleCurrentIndexChanged(int index) { + ui_.list->clear(); + foreach (const JID& jid, affiliations_[affiliationFromIndex(index)]) { + ui_.list->addItem(P2QSTRING(jid.toString())); + } +} + +void QtAffiliationEditor::handleAddClicked() { + bool ok = false; + JID jid = JID(Q2PSTRING(QInputDialog::getText(this, tr("Add User"), tr("Added User's Address:"), QLineEdit::Normal, "", &ok))); + if (ok && jid.isValid()) { + //FIXME: validation + MUCOccupant::Affiliation affiliation = affiliationFromIndex(ui_.affiliation->currentIndex()); + changes_.push_back(ChangePair(affiliation, jid)); + ui_.list->addItem(P2QSTRING(jid.toString())); + affiliations_[affiliation].push_back(jid); + } +} + +void QtAffiliationEditor::handleRemoveClicked() { + QListWidgetItem* item = ui_.list->currentItem(); + if (item) { + JID jid(Q2PSTRING(item->text())); + changes_.push_back(ChangePair(MUCOccupant::NoAffiliation, jid)); + std::vector<JID>& jids = affiliations_[affiliationFromIndex(ui_.affiliation->currentIndex())]; + jids.erase(std::remove(jids.begin(), jids.end(), jid), jids.end()); + handleCurrentIndexChanged(ui_.affiliation->currentIndex()); + } +} + +MUCOccupant::Affiliation QtAffiliationEditor::affiliationFromIndex(int affiliation) { + switch (affiliation) { + case 0: return MUCOccupant::Owner; + case 1: return MUCOccupant::Admin; + case 2: return MUCOccupant::Member; + case 3: return MUCOccupant::Outcast; + default: return MUCOccupant::Outcast; + } +} + +}
\ No newline at end of file diff --git a/Swift/QtUI/QtAffiliationEditor.h b/Swift/QtUI/QtAffiliationEditor.h new file mode 100644 index 0000000..913b2cc --- /dev/null +++ b/Swift/QtUI/QtAffiliationEditor.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> +#include <map> + +#include <QDialog> +#include <Swift/QtUI/ui_QtAffiliationEditor.h> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/MUCOccupant.h> + +namespace Swift { + class QtAffiliationEditor : public QDialog { + Q_OBJECT + public: + QtAffiliationEditor(QWidget* parent = NULL); + ~QtAffiliationEditor(); + void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>& jids); + const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& getChanges() const; + private slots: + void handleCurrentIndexChanged(int); + void handleAddClicked(); + void handleRemoveClicked(); + private: + typedef std::pair<MUCOccupant::Affiliation, JID> ChangePair; + MUCOccupant::Affiliation affiliationFromIndex(int affiliation); + Ui::QtAffiliationEditor ui_; + std::map<MUCOccupant::Affiliation, std::vector<JID> > affiliations_; + std::vector<ChangePair> changes_; + }; +}
\ No newline at end of file diff --git a/Swift/QtUI/QtAffiliationEditor.ui b/Swift/QtUI/QtAffiliationEditor.ui new file mode 100644 index 0000000..1447884 --- /dev/null +++ b/Swift/QtUI/QtAffiliationEditor.ui @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QtAffiliationEditor</class> + <widget class="QDialog" name="QtAffiliationEditor"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>575</width> + <height>466</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Affiliation:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="affiliation"> + <item> + <property name="text"> + <string>Owner</string> + </property> + </item> + <item> + <property name="text"> + <string>Administrator</string> + </property> + </item> + <item> + <property name="text"> + <string>Member</string> + </property> + </item> + <item> + <property name="text"> + <string>Outcast (Banned)</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QListWidget" name="list"/> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="addJID"> + <property name="text"> + <string>Add User</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeJID"> + <property name="text"> + <string>Remove User</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>QtAffiliationEditor</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>224</x> + <y>444</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>QtAffiliationEditor</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>292</x> + <y>450</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 7e47f4d..0635496 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -21,70 +21,71 @@ #include "SwifTools/TabComplete.h" #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include "QtFileTransferJSBridge.h" #include <boost/cstdint.hpp> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> #include <QLabel> #include <QMessageBox> #include <QInputDialog> #include <QApplication> #include <QBoxLayout> #include <QCloseEvent> #include <QComboBox> #include <QFileInfo> #include <QLineEdit> #include <QSplitter> #include <QString> #include <QTextEdit> #include <QTime> #include <QUrl> #include <QPushButton> #include <QFileDialog> #include <QMenu> #include <QDebug> namespace Swift { QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false), previousMessageWasPresence_(false), previousMessageWasFileTransfer_(false), eventStream_(eventStream) { unreadCount_ = 0; inputEnabled_ = true; completer_ = NULL; + affiliationEditor_ = NULL; theme_ = theme; isCorrection_ = false; correctionEnabled_ = Maybe; updateTitleWithUnreadCount(); QtSettingsProvider settings; #ifdef SWIFT_EXPERIMENTAL_FT setAcceptDrops(true); #endif alertStyleSheet_ = "background: rgb(255, 255, 153); color: black"; QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); layout->setContentsMargins(0,0,0,0); layout->setSpacing(2); alertWidget_ = new QWidget(this); QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget_); layout->addWidget(alertWidget_); alertLabel_ = new QLabel(this); alertLayout->addWidget(alertLabel_); alertButton_ = new QPushButton(this); connect (alertButton_, SIGNAL(clicked()), this, SLOT(handleAlertButtonClicked())); alertLayout->addWidget(alertButton_); QPalette palette = alertWidget_->palette(); palette.setColor(QPalette::Window, QColor(Qt::yellow)); palette.setColor(QPalette::WindowText, QColor(Qt::black)); alertWidget_->setStyleSheet(alertStyleSheet_); alertLabel_->setStyleSheet(alertStyleSheet_); alertWidget_->hide(); QBoxLayout* subjectLayout = new QBoxLayout(QBoxLayout::LeftToRight); subject_ = new QLineEdit(this); subjectLayout->addWidget(subject_); setSubject(""); @@ -133,72 +134,72 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt input_->setAcceptRichText(false); inputBarLayout->addWidget(input_); correctingLabel_ = new QLabel(tr("Correcting"), this); inputBarLayout->addWidget(correctingLabel_); correctingLabel_->hide(); layout->addLayout(inputBarLayout); inputClearing_ = false; contactIsTyping_ = false; connect(input_, SIGNAL(unhandledKeyPressEvent(QKeyEvent*)), this, SLOT(handleKeyPressEvent(QKeyEvent*))); connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed())); connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged())); setFocusProxy(input_); logRosterSplitter_->setFocusProxy(input_); midBar->setFocusProxy(input_); messageLog_->setFocusProxy(input_); connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(qAppFocusChanged(QWidget*, QWidget*))); connect(messageLog_, SIGNAL(gotFocus()), input_, SLOT(setFocus())); resize(400,300); connect(messageLog_, SIGNAL(fontResized(int)), this, SIGNAL(fontResized(int))); treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtChatWindow::handleOccupantSelectionChanged, this, _1)); treeWidget_->onOccupantActionSelected.connect(boost::bind(boost::ref(onOccupantActionSelected), _1, _2)); fileTransferJS = new QtFileTransferJSBridge(); 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(); + if (mucConfigurationWindow_) { + delete mucConfigurationWindow_.data(); } } void QtChatWindow::handleOccupantSelectionChanged(RosterItem* item) { onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item)); } void QtChatWindow::handleFontResized(int fontSizeSteps) { messageLog_->resizeFont(fontSizeSteps); } void QtChatWindow::handleAlertButtonClicked() { onAlertButtonClicked(); } void QtChatWindow::setAlert(const std::string& alertText, const std::string& buttonText) { alertLabel_->setText(alertText.c_str()); if (buttonText.empty()) { alertButton_->hide(); } else { alertButton_->setText(buttonText.c_str()); alertButton_->show(); } alertWidget_->show(); } void QtChatWindow::cancelAlert() { alertWidget_->hide(); } void QtChatWindow::setTabComplete(TabComplete* completer) { completer_ = completer; } @@ -309,102 +310,107 @@ void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabelsCa int i = 0; int defaultIndex = 0; foreach (SecurityLabelsCatalog::Item label, labels) { std::string selector = label.getSelector(); std::string displayMarking = label.getLabel() ? label.getLabel()->getDisplayMarking() : ""; QString labelName = selector.empty() ? displayMarking.c_str() : selector.c_str(); labelsWidget_->addItem(labelName, QVariant(i)); if (label.getIsDefault()) { defaultIndex = i; } i++; } labelsWidget_->setCurrentIndex(defaultIndex); } void QtChatWindow::setSecurityLabelsError() { labelsWidget_->setEnabled(false); } void QtChatWindow::setSecurityLabelsEnabled(bool enabled) { if (enabled) { labelsWidget_->setEnabled(true); labelsWidget_->show(); } else { labelsWidget_->hide(); } } void QtChatWindow::setCorrectionEnabled(Tristate enabled) { correctionEnabled_ = enabled; } SecurityLabelsCatalog::Item QtChatWindow::getSelectedSecurityLabel() { assert(labelsWidget_->isEnabled()); - assert(labelsWidget_->currentIndex() >= 0 && labelsWidget_->currentIndex() < availableLabels_.size()); + assert(labelsWidget_->currentIndex() >= 0 && static_cast<size_t>(labelsWidget_->currentIndex()) < availableLabels_.size()); return availableLabels_[labelsWidget_->currentIndex()]; } void QtChatWindow::closeEvent(QCloseEvent* event) { event->accept(); emit windowClosing(); onClosed(); } void QtChatWindow::convertToMUC() { setAcceptDrops(false); treeWidget_->show(); subject_->show(); actionButton_->show(); } void QtChatWindow::qAppFocusChanged(QWidget* /*old*/, QWidget* /*now*/) { if (isWidgetSelected()) { lastLineTracker_.setHasFocus(true); input_->setFocus(); onAllMessagesRead(); } else { lastLineTracker_.setHasFocus(false); } } void QtChatWindow::setInputEnabled(bool enabled) { inputEnabled_ = enabled; - if (!enabled && mucConfigurationWindow) { - delete mucConfigurationWindow.data(); + if (!enabled) { + if (mucConfigurationWindow_) { + delete mucConfigurationWindow_.data(); + } + if (affiliationEditor_) { + delete affiliationEditor_.data(); + } } } void QtChatWindow::showEvent(QShowEvent* event) { emit windowOpening(); QWidget::showEvent(event); } void QtChatWindow::setUnreadMessageCount(int count) { if (unreadCount_ != count) { unreadCount_ = count; updateTitleWithUnreadCount(); emit countUpdated(); } } void QtChatWindow::setContactChatState(ChatState::ChatStateType state) { contactIsTyping_ = (state == ChatState::Composing); emit titleUpdated(); } QtTabbable::AlertType QtChatWindow::getWidgetAlertState() { if (contactIsTyping_) { return ImpendingActivity; } if (unreadCount_ > 0) { return WaitingActivity; } return NoActivity; } void QtChatWindow::setName(const std::string& name) { contact_ = P2QSTRING(name); updateTitleWithUnreadCount(); } @@ -672,94 +678,112 @@ void QtChatWindow::moveEvent(QMoveEvent*) { emit geometryChanged(); } void QtChatWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { // TODO: check whether contact actually supports file transfer event->acceptProposedAction(); } } void QtChatWindow::dropEvent(QDropEvent *event) { if (event->mimeData()->urls().size() == 1) { onSendFileRequest(Q2PSTRING(event->mimeData()->urls().at(0).toLocalFile())); } else { addSystemMessage("Sending of multiple files at once isn't supported at this time."); } } void QtChatWindow::replaceLastMessage(const std::string& message) { messageLog_->replaceLastMessage(P2QSTRING(Linkify::linkify(message))); } void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) { treeWidget_->setAvailableOccupantActions(actions); } 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* affiliations = contextMenu.addAction(tr("Edit affiliations")); QAction* destroy = contextMenu.addAction(tr("Destroy room")); QAction* invite = contextMenu.addAction(tr("Invite person to this 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(Form::ref()); } + else if (result == affiliations) { + if (!affiliationEditor_) { + onGetAffiliationsRequest(); + affiliationEditor_ = new QtAffiliationEditor(this); + connect(affiliationEditor_, SIGNAL(accepted()), this, SLOT(handleAffiliationEditorAccepted())); + } + affiliationEditor_->show(); + } else if (result == destroy) { onDestroyRequest(); } 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)), ""); } } } +void QtChatWindow::handleAffiliationEditorAccepted() { + onChangeAffiliationsRequest(affiliationEditor_->getChanges()); +} + +void QtChatWindow::setAffiliations(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) { + if (!affiliationEditor_) return; + affiliationEditor_->setAffiliations(affiliation, jids); +} + void QtChatWindow::showRoomConfigurationForm(Form::ref form) { - if (mucConfigurationWindow) { - delete mucConfigurationWindow.data(); + if (mucConfigurationWindow_) { + delete mucConfigurationWindow_.data(); } - mucConfigurationWindow = new QtMUCConfigurationWindow(form); - mucConfigurationWindow->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1)); - mucConfigurationWindow->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled))); + mucConfigurationWindow_ = new QtMUCConfigurationWindow(form); + mucConfigurationWindow_->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1)); + mucConfigurationWindow_->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled))); } void QtChatWindow::addMUCInvitation(const JID& jid, const std::string& reason, const std::string& password) { bool accepted = false; QMessageBox msgBox; msgBox.setText(QString("You have been invited to the room %1 by %2.").arg(P2QSTRING(jid.toString())).arg(contact_)); QString reasonString; if (!reason.empty()) { reasonString = QString("\"%1\"").arg(P2QSTRING(reason)); } msgBox.setInformativeText(QString("Accept invitation from %1 to enter %2?\n%3").arg(contact_).arg(P2QSTRING(jid.toString())).arg(reasonString)); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: accepted = true; break; default: break; } if (accepted) { eventStream_->send(boost::make_shared<JoinMUCUIEvent>(jid)); } } } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 8dfe767..e546f12 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -1,158 +1,162 @@ /* * 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/QtUI/QtMUCConfigurationWindow.h> +#include <Swift/QtUI/QtAffiliationEditor.h> #include <QtTabbable.h> #include <SwifTools/LastLineTracker.h> #include <Swiften/Base/IDGenerator.h> #include <map> #include <QPointer> class QTextEdit; class QLineEdit; class QComboBox; class QLabel; class QSplitter; class QPushButton; namespace Swift { class QtChatView; class QtOccupantListWidget; class QtChatTheme; class TreeWidget; class QtTextEdit; class UIEventStream; class QtFileTransferJSBridge; class QtChatWindow : public QtTabbable, public ChatWindow { Q_OBJECT public: QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream); ~QtChatWindow(); std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time); std::string addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time); void addSystemMessage(const std::string& message); void addPresenceMessage(const std::string& message); void addErrorMessage(const std::string& errorMessage); void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time); // File transfer related stuff 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); void show(); void activate(); void setUnreadMessageCount(int count); void convertToMUC(); // TreeWidget *getTreeWidget(); void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels); void setSecurityLabelsEnabled(bool enabled); void setSecurityLabelsError(); SecurityLabelsCatalog::Item getSelectedSecurityLabel(); void setName(const std::string& name); void setInputEnabled(bool enabled); QtTabbable::AlertType getWidgetAlertState(); void setContactChatState(ChatState::ChatStateType state); 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); void addMUCInvitation(const JID& jid, const std::string& reason, const std::string& password); + void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&); 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: void geometryChanged(); void splitterMoved(); void fontResized(int); protected slots: void qAppFocusChanged(QWidget* old, QWidget* now); void closeEvent(QCloseEvent* event); void resizeEvent(QResizeEvent* event); void moveEvent(QMoveEvent* event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); protected: void showEvent(QShowEvent* event); private slots: void returnPressed(); void handleInputChanged(); void handleKeyPressEvent(QKeyEvent* event); void handleSplitterMoved(int pos, int index); void handleAlertButtonClicked(); void handleActionButtonClicked(); void handleFileTransferCancel(QString id); void handleFileTransferSetDescription(QString id); void handleFileTransferStart(QString id); void handleFileTransferAccept(QString id, QString filename); + void handleAffiliationEditorAccepted(); private: void updateTitleWithUnreadCount(); void tabComplete(); void beginCorrection(); void cancelCorrection(); std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time); void handleOccupantSelectionChanged(RosterItem* item); int unreadCount_; bool contactIsTyping_; LastLineTracker lastLineTracker_; QString contact_; QString lastSentMessage_; QtChatView* messageLog_; QtChatTheme* theme_; QtTextEdit* input_; QComboBox* labelsWidget_; QtOccupantListWidget* treeWidget_; QLabel* correctingLabel_; QLabel* alertLabel_; QWidget* alertWidget_; QPushButton* alertButton_; TabComplete* completer_; QLineEdit* subject_; QPushButton* actionButton_; std::vector<SecurityLabelsCatalog::Item> availableLabels_; bool isCorrection_; bool previousMessageWasSelf_; bool previousMessageWasSystem_; bool previousMessageWasPresence_; 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; + QPointer<QtMUCConfigurationWindow> mucConfigurationWindow_; + QPointer<QtAffiliationEditor> affiliationEditor_; }; } diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.cpp b/Swift/QtUI/Roster/QtOccupantListWidget.cpp index 3ee0b7d..3f66585 100644 --- a/Swift/QtUI/Roster/QtOccupantListWidget.cpp +++ b/Swift/QtUI/Roster/QtOccupantListWidget.cpp @@ -13,51 +13,52 @@ #include <QInputDialog> #include "Swift/Controllers/Roster/ContactRosterItem.h" #include "Swift/Controllers/Roster/GroupRosterItem.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" #include "QtSwiftUtil.h" namespace Swift { QtOccupantListWidget::QtOccupantListWidget(UIEventStream* eventStream, QWidget* parent) : QtTreeWidget(eventStream, parent) { } QtOccupantListWidget::~QtOccupantListWidget() { } void QtOccupantListWidget::setAvailableOccupantActions(const std::vector<ChatWindow::OccupantAction>& actions) { availableOccupantActions_ = actions; } void QtOccupantListWidget::contextMenuEvent(QContextMenuEvent* event) { QModelIndex index = indexAt(event->pos()); if (!index.isValid()) { return; } RosterItem* item = static_cast<RosterItem*>(index.internalPointer()); ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); if (contact) { QMenu contextMenu; std::map<QAction*, ChatWindow::OccupantAction> actions; foreach (ChatWindow::OccupantAction availableAction, availableOccupantActions_) { QString text = "Error: missing string"; switch (availableAction) { case ChatWindow::Kick: text = tr("Kick user"); break; + case ChatWindow::Ban: text = tr("Kick and ban user"); break; case ChatWindow::MakeModerator: text = tr("Make moderator"); break; case ChatWindow::MakeParticipant: text = tr("Make participant"); break; case ChatWindow::MakeVisitor: text = tr("Remove voice"); break; } QAction* action = contextMenu.addAction(text); actions[action] = availableAction; } QAction* result = contextMenu.exec(event->globalPos()); if (result) { onOccupantActionSelected(actions[result], contact); } } } } diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 82e4490..71dc59f 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -52,159 +52,161 @@ myenv.Append(CPPPATH = ["."]) if env["PLATFORM"] == "win32" : #myenv["LINKFLAGS"] = ["/SUBSYSTEM:CONSOLE"] myenv.Append(LINKFLAGS = ["/SUBSYSTEM:WINDOWS"]) myenv.Append(LIBS = "qtmain") myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateDefaultTheme(myenv.Dir("#/Swift/resources/themes/Default")))) sources = [ "main.cpp", "QtAboutWidget.cpp", "QtAvatarWidget.cpp", "QtUIFactory.cpp", "QtChatWindowFactory.cpp", "QtChatWindow.cpp", "QtClickableLabel.cpp", "QtLoginWindow.cpp", "QtMainWindow.cpp", "QtProfileWindow.cpp", "QtNameWidget.cpp", "QtSettingsProvider.cpp", "QtStatusWidget.cpp", "QtScaledAvatarCache.cpp", "QtSwift.cpp", "QtURIHandler.cpp", "QtChatView.cpp", "QtChatTheme.cpp", "QtChatTabs.cpp", "QtSoundPlayer.cpp", "QtSystemTray.cpp", "QtCachedImageScaler.cpp", "QtTabbable.cpp", "QtTabWidget.cpp", "QtTextEdit.cpp", "QtXMLConsoleWidget.cpp", - "QtFileTransferListWidget.cpp", - "QtFileTransferListItemModel.cpp", + "QtFileTransferListWidget.cpp", + "QtFileTransferListItemModel.cpp", "QtAdHocCommandWindow.cpp", "QtUtilities.cpp", "QtBookmarkDetailWindow.cpp", "QtAddBookmarkWindow.cpp", "QtEditBookmarkWindow.cpp", "QtContactEditWindow.cpp", "QtContactEditWidget.cpp", "ChatSnippet.cpp", "MessageSnippet.cpp", "SystemMessageSnippet.cpp", "QtElidingLabel.cpp", "QtFormWidget.cpp", "QtLineEdit.cpp", "QtJoinMUCWindow.cpp", "Roster/RosterModel.cpp", "Roster/QtTreeWidget.cpp", # "Roster/QtTreeWidgetItem.cpp", "Roster/RosterDelegate.cpp", "Roster/GroupItemDelegate.cpp", "Roster/DelegateCommons.cpp", "Roster/QtRosterWidget.cpp", "Roster/QtOccupantListWidget.cpp", "EventViewer/EventModel.cpp", "EventViewer/EventDelegate.cpp", "EventViewer/TwoLineDelegate.cpp", "EventViewer/QtEventWindow.cpp", "EventViewer/QtEvent.cpp", "ChatList/QtChatListWindow.cpp", "ChatList/ChatListModel.cpp", "ChatList/ChatListDelegate.cpp", "ChatList/ChatListMUCItem.cpp", "ChatList/ChatListRecentItem.cpp", "MUCSearch/QtMUCSearchWindow.cpp", "MUCSearch/MUCSearchModel.cpp", "MUCSearch/MUCSearchRoomItem.cpp", "MUCSearch/MUCSearchEmptyItem.cpp", "MUCSearch/MUCSearchDelegate.cpp", "UserSearch/QtUserSearchFirstPage.cpp", "UserSearch/QtUserSearchFieldsPage.cpp", "UserSearch/QtUserSearchResultsPage.cpp", "UserSearch/QtUserSearchDetailsPage.cpp", "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", + "QtAffiliationEditor.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") sources += [ "WindowsNotifier.cpp", "#/Swift/resources/Windows/Swift.res" ] if env["PLATFORM"] == "posix" : sources += [ "FreeDesktopNotifier.cpp", "QtDBUSURIHandler.cpp", ] if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" : swiftProgram = myenv.Program("Swift", sources) else : swiftProgram = myenv.Program("swift", sources) if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" : openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp") else : openURIProgram = [] myenv.Uic4("MUCSearch/QtMUCSearchWindow.ui") myenv.Uic4("UserSearch/QtUserSearchWizard.ui") myenv.Uic4("UserSearch/QtUserSearchFirstPage.ui") myenv.Uic4("UserSearch/QtUserSearchFieldsPage.ui") myenv.Uic4("UserSearch/QtUserSearchResultsPage.ui") myenv.Uic4("QtBookmarkDetailWindow.ui") +myenv.Uic4("QtAffiliationEditor.ui") myenv.Uic4("QtJoinMUCWindow.ui") myenv.Qrc("DefaultTheme.qrc") myenv.Qrc("Swift.qrc") # Resources commonResources = { "": ["#/Swift/resources/sounds"] } ################################################################################ # Translation ################################################################################ # Collect available languages translation_languages = [] for file in os.listdir(Dir("#/Swift/Translations").abspath) : if file.startswith("swift_") and file.endswith(".ts") : translation_languages.append(file[6:-3]) # Generate translation modules translation_sources = [env.File("#/Swift/Translations/swift.ts").abspath] translation_modules = [] for lang in translation_languages : translation_resource = "#/Swift/resources/translations/swift_" + lang + ".qm" translation_source = "#/Swift/Translations/swift_" + lang + ".ts" translation_sources.append(env.File(translation_source).abspath) translation_modules.append(env.File(translation_resource).abspath) myenv.Qm(translation_resource, translation_source) commonResources["translations"] = commonResources.get("translations", []) + [translation_resource] # LUpdate translation (if requested) if ARGUMENTS.get("update_translations", False) : myenv.Precious(translation_sources) remove_obsolete_option = "" if ARGUMENTS.get("remove_obsolete_translations", False) : |
Swift