summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/QtAffiliationEditor.cpp79
-rw-r--r--Swift/QtUI/QtAffiliationEditor.h37
-rw-r--r--Swift/QtUI/QtAffiliationEditor.ui146
-rw-r--r--Swift/QtUI/QtChatWindow.cpp44
-rw-r--r--Swift/QtUI/QtChatWindow.h6
-rw-r--r--Swift/QtUI/Roster/QtOccupantListWidget.cpp1
-rw-r--r--Swift/QtUI/SConscript6
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) :