summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/QtChatWindow.cpp')
-rw-r--r--Swift/QtUI/QtChatWindow.cpp377
1 files changed, 348 insertions, 29 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 1a909fd..07ff47e 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -7,16 +7,28 @@
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
#include "Swift/Controllers/Roster/Roster.h"
-#include "Roster/QtTreeWidget.h"
+#include "Swift/Controllers/Roster/RosterItem.h"
+#include "Swift/Controllers/Roster/ContactRosterItem.h"
+#include "Roster/QtOccupantListWidget.h"
#include "SwifTools/Linkify.h"
#include "QtChatView.h"
#include "MessageSnippet.h"
#include "SystemMessageSnippet.h"
#include "QtTextEdit.h"
+#include "QtSettingsProvider.h"
#include "QtScaledAvatarCache.h"
#include "SwifTools/TabComplete.h"
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
+#include "QtFileTransferJSBridge.h"
+#include <boost/cstdint.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <QLabel>
+#include <QInputDialog>
#include <QApplication>
#include <QBoxLayout>
#include <QCloseEvent>
@@ -28,32 +40,74 @@
#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), eventStream_(eventStream) {
+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;
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);
-
-
- QSplitter *logRosterSplitter = new QSplitter(this);
- logRosterSplitter->setAutoFillBackground(true);
- layout->addWidget(logRosterSplitter);
+ 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("");
+ subject_->setReadOnly(true);
+
+ actionButton_ = new QPushButton(tr("Actions"), this);
+ connect(actionButton_, SIGNAL(clicked()), this, SLOT(handleActionButtonClicked()));
+ subjectLayout->addWidget(actionButton_);
+
+ subject_->hide();
+ actionButton_->hide();
+
+ layout->addLayout(subjectLayout);
+
+ logRosterSplitter_ = new QSplitter(this);
+ logRosterSplitter_->setAutoFillBackground(true);
+ layout->addWidget(logRosterSplitter_);
messageLog_ = new QtChatView(theme, this);
- logRosterSplitter->addWidget(messageLog_);
+ logRosterSplitter_->addWidget(messageLog_);
- treeWidget_ = new QtTreeWidget(eventStream_);
- treeWidget_->setEditable(false);
+ treeWidget_ = new QtOccupantListWidget(eventStream_, this);
treeWidget_->hide();
- logRosterSplitter->addWidget(treeWidget_);
- logRosterSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ logRosterSplitter_->addWidget(treeWidget_);
+ logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ connect(logRosterSplitter_, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
QWidget* midBar = new QWidget(this);
layout->addWidget(midBar);
@@ -69,10 +123,17 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
labelsWidget_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
midBarLayout->addWidget(labelsWidget_,0);
+ QHBoxLayout* inputBarLayout = new QHBoxLayout();
+ inputBarLayout->setContentsMargins(0,0,0,0);
+ inputBarLayout->setSpacing(2);
input_ = new QtTextEdit(this);
input_->setAcceptRichText(false);
- layout->addWidget(input_);
-
+ inputBarLayout->addWidget(input_);
+ correctingLabel_ = new QLabel(tr("Correcting"), this);
+ inputBarLayout->addWidget(correctingLabel_);
+ correctingLabel_->hide();
+ layout->addLayout(inputBarLayout);
+
inputClearing_ = false;
contactIsTyping_ = false;
@@ -80,16 +141,58 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged()));
setFocusProxy(input_);
- logRosterSplitter->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();
+ }
+}
+
+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) {
@@ -118,11 +221,55 @@ void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
emit requestActiveTab();
} else if (key == Qt::Key_Tab) {
tabComplete();
+ } else if ((key == Qt::Key_Up) && input_->toPlainText().isEmpty() && !(lastSentMessage_.isEmpty())) {
+ beginCorrection();
+ } else if (key == Qt::Key_Down && isCorrection_ && input_->textCursor().atBlockEnd()) {
+ cancelCorrection();
+ } else if (key == Qt::Key_Down || key == Qt::Key_Up) {
+ /* Drop */
} else {
messageLog_->handleKeyPressEvent(event);
}
}
+void QtChatWindow::beginCorrection() {
+ if (correctionEnabled_ == ChatWindow::Maybe) {
+ setAlert(Q2PSTRING(tr("This chat may not support message correction. If you send a correction anyway, it may appear as a duplicate message")));
+ } else if (correctionEnabled_ == ChatWindow::No) {
+ setAlert(Q2PSTRING(tr("This chat does not support message correction. If you send a correction anyway, it will appear as a duplicate message")));
+ }
+ QTextCursor cursor = input_->textCursor();
+ cursor.select(QTextCursor::Document);
+ cursor.beginEditBlock();
+ cursor.insertText(QString(lastSentMessage_));
+ cursor.endEditBlock();
+ isCorrection_ = true;
+ correctingLabel_->show();
+ input_->setStyleSheet(alertStyleSheet_);
+}
+
+void QtChatWindow::cancelCorrection() {
+ cancelAlert();
+ QTextCursor cursor = input_->textCursor();
+ cursor.select(QTextCursor::Document);
+ cursor.removeSelectedText();
+ isCorrection_ = false;
+ correctingLabel_->hide();
+ input_->setStyleSheet(qApp->styleSheet());
+}
+
+QByteArray QtChatWindow::getSplitterState() {
+ return logRosterSplitter_->saveState();
+}
+
+void QtChatWindow::handleChangeSplitterState(QByteArray state) {
+ logRosterSplitter_->restoreState(state);
+}
+
+void QtChatWindow::handleSplitterMoved(int, int) {
+ emit splitterMoved();
+}
+
void QtChatWindow::tabComplete() {
if (!completer_) {
return;
@@ -150,7 +297,7 @@ void QtChatWindow::tabComplete() {
}
void QtChatWindow::setRosterModel(Roster* roster) {
- treeWidget_->setRosterModel(roster);
+ treeWidget_->setRosterModel(roster);
}
void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {
@@ -185,6 +332,10 @@ void QtChatWindow::setSecurityLabelsEnabled(bool enabled) {
}
}
+void QtChatWindow::setCorrectionEnabled(Tristate enabled) {
+ correctionEnabled_ = enabled;
+}
+
SecurityLabelsCatalog::Item QtChatWindow::getSelectedSecurityLabel() {
assert(labelsWidget_->isEnabled());
return availableLabels_[labelsWidget_->currentIndex()];
@@ -197,22 +348,28 @@ void QtChatWindow::closeEvent(QCloseEvent* event) {
}
void QtChatWindow::convertToMUC() {
+ setAcceptDrops(false);
treeWidget_->show();
+ subject_->show();
+ actionButton_->show();
}
-void QtChatWindow::qAppFocusChanged(QWidget *old, QWidget *now) {
- Q_UNUSED(old);
- Q_UNUSED(now);
+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;
-// input_->setEnabled(enabled);
+ if (!enabled && mucConfigurationWindow) {
+ delete mucConfigurationWindow.data();
+ }
}
void QtChatWindow::showEvent(QShowEvent* event) {
@@ -236,7 +393,7 @@ void QtChatWindow::setContactChatState(ChatState::ChatStateType state) {
QtTabbable::AlertType QtChatWindow::getWidgetAlertState() {
if (contactIsTyping_) {
return ImpendingActivity;
- }
+ }
if (unreadCount_ > 0) {
return WaitingActivity;
}
@@ -265,7 +422,6 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri
if (isWidgetSelected()) {
onAllMessagesRead();
}
-
QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
QString htmlString;
@@ -280,7 +436,13 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri
QString styleSpanEnd = style == "" ? "" : "</span>";
htmlString += styleSpanStart + messageHTML + styleSpanEnd;
- bool appendToPrevious = !previousMessageWasSystem_ && !previousMessageWasPresence_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName)));
+ bool appendToPrevious = !previousMessageWasFileTransfer_ && !previousMessageWasSystem_ && !previousMessageWasPresence_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName)));
+ if (lastLineTracker_.getShouldMoveLastLine()) {
+ /* should this be queued? */
+ messageLog_->addLastSeenLine();
+ /* if the line is added we should break the snippet */
+ appendToPrevious = false;
+ }
QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
std::string id = id_.generateID();
messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
@@ -289,6 +451,7 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri
previousSenderName_ = P2QSTRING(senderName);
previousMessageWasSystem_ = false;
previousMessageWasPresence_ = false;
+ previousMessageWasFileTransfer_ = false;
return id;
}
@@ -314,6 +477,94 @@ std::string QtChatWindow::addAction(const std::string &message, const std::strin
return addMessage(" *" + message + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time);
}
+std::string formatSize(const boost::uintmax_t bytes) {
+ static const char *siPrefix[] = {"k", "M", "G", "T", "P", "E", "Z", "Y", NULL};
+ int power = 0;
+ double engBytes = bytes;
+ while (engBytes >= 1000) {
+ ++power;
+ engBytes = engBytes / 1000.0;
+ }
+ return str( boost::format("%.1lf %sB") % engBytes % (power > 0 ? siPrefix[power-1] : "") );
+}
+
+std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes) {
+ qDebug() << "addFileTransfer";
+ std::string ft_id = id_.generateID();
+
+ std::string htmlString;
+ if (senderIsSelf) {
+ // outgoing
+ htmlString = "Send file: " + filename + " ( " + formatSize(sizeInBytes) + ") </br>" +
+ "<div id='" + ft_id + "'>" +
+ "<input id='discard' type='submit' value='Cancel' onclick='filetransfer.cancel(\"" + ft_id + "\");' />" +
+ "<input id='description' type='submit' value='Set Description' onclick='filetransfer.setDescription(\"" + ft_id + "\");' />" +
+ "<input id='send' type='submit' value='Send' onclick='filetransfer.sendRequest(\"" + ft_id + "\");' />" +
+ "</div>";
+ } else {
+ // incoming
+ htmlString = "Receiving file: " + filename + " ( " + formatSize(sizeInBytes) + ") </br>" +
+ "<div id='" + ft_id + "'>" +
+ "<input id='discard' type='submit' value='Cancel' onclick='filetransfer.cancel(\"" + ft_id + "\");' />" +
+ "<input id='accept' type='submit' value='Accept' onclick='filetransfer.acceptRequest(\"" + ft_id + "\", \"" + filename + "\");' />" +
+ "</div>";
+ }
+
+ //addMessage(message, senderName, senderIsSelf, boost::shared_ptr<SecurityLabel>(), "", boost::posix_time::second_clock::local_time());
+
+ bool appendToPrevious = !previousMessageWasFileTransfer_ && !previousMessageWasSystem_ && !previousMessageWasPresence_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName)));
+ if (lastLineTracker_.getShouldMoveLastLine()) {
+ /* should this be queued? */
+ messageLog_->addLastSeenLine();
+ /* if the line is added we should break the snippet */
+ appendToPrevious = false;
+ }
+ QString qAvatarPath = "qrc:/icons/avatar.png";
+ std::string id = id_.generateID();
+ messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(QString::fromStdString(htmlString), Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+
+
+ return ft_id;
+}
+
+void QtChatWindow::setFileTransferProgress(std::string id, const int percentageDone) {
+ messageLog_->setFileTransferProgress(QString::fromStdString(id), percentageDone);
+}
+
+void QtChatWindow::setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg) {
+ messageLog_->setFileTransferStatus(QString::fromStdString(id), state, QString::fromStdString(msg));
+}
+
+void QtChatWindow::handleFileTransferCancel(QString id) {
+ qDebug() << "QtChatWindow::handleFileTransferCancel(" << id << ")";
+ onFileTransferCancel(Q2PSTRING(id));
+}
+
+void QtChatWindow::handleFileTransferSetDescription(QString id) {
+ bool ok = false;
+ QString text = QInputDialog::getText(this, tr("File transfer description"),
+ tr("Description:"), QLineEdit::Normal, "", &ok);
+ if (ok) {
+ descriptions[id] = text;
+ }
+}
+
+void QtChatWindow::handleFileTransferStart(QString id) {
+ qDebug() << "QtChatWindow::handleFileTransferStart(" << id << ")";
+
+ QString text = descriptions.find(id) == descriptions.end() ? QString() : descriptions[id];
+ onFileTransferStart(Q2PSTRING(id), Q2PSTRING(text));
+}
+
+void QtChatWindow::handleFileTransferAccept(QString id, QString filename) {
+ qDebug() << "QtChatWindow::handleFileTransferAccept(" << id << ", " << filename << ")";
+
+ QString path = QFileDialog::getSaveFileName(this, tr("Save File"), filename);
+ if (!path.isEmpty()) {
+ onFileTransferAccept(Q2PSTRING(id), Q2PSTRING(path));
+ }
+}
+
void QtChatWindow::addErrorMessage(const std::string& errorMessage) {
if (isWidgetSelected()) {
onAllMessagesRead();
@@ -321,11 +572,12 @@ void QtChatWindow::addErrorMessage(const std::string& errorMessage) {
QString errorMessageHTML(Qt::escape(P2QSTRING(errorMessage)));
errorMessageHTML.replace("\n","<br/>");
- messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(QString("<span class=\"error\">" + tr("Couldn't send message: %1") + "</span>").arg(errorMessageHTML), QDateTime::currentDateTime(), false, theme_)));
+ messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_)));
previousMessageWasSelf_ = false;
previousMessageWasSystem_ = true;
previousMessageWasPresence_ = false;
+ previousMessageWasFileTransfer_ = false;
}
void QtChatWindow::addSystemMessage(const std::string& message) {
@@ -341,6 +593,16 @@ void QtChatWindow::addSystemMessage(const std::string& message) {
previousMessageWasSelf_ = false;
previousMessageWasSystem_ = true;
previousMessageWasPresence_ = false;
+ previousMessageWasFileTransfer_ = false;
+}
+
+void QtChatWindow::replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) {
+ if (!id.empty()) {
+ QString messageHTML(Qt::escape(P2QSTRING(message)));
+ messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML)));
+ messageHTML.replace("\n","<br/>");
+ messageLog_->replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time));
+ }
}
void QtChatWindow::addPresenceMessage(const std::string& message) {
@@ -364,9 +626,11 @@ void QtChatWindow::returnPressed() {
return;
}
messageLog_->scrollToBottom();
- onSendMessageRequest(Q2PSTRING(input_->toPlainText()));
+ lastSentMessage_ = QString(input_->toPlainText());
+ onSendMessageRequest(Q2PSTRING(input_->toPlainText()), isCorrection_);
inputClearing_ = true;
input_->clear();
+ cancelCorrection();
inputClearing_ = false;
}
@@ -382,7 +646,9 @@ void QtChatWindow::handleInputChanged() {
}
void QtChatWindow::show() {
- QWidget::show();
+ if (parentWidget() == NULL) {
+ QWidget::show();
+ }
emit windowOpening();
}
@@ -399,11 +665,64 @@ void QtChatWindow::resizeEvent(QResizeEvent*) {
}
void QtChatWindow::moveEvent(QMoveEvent*) {
- emit geometryChanged();
+ 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* destroy = contextMenu.addAction(tr("Destroy 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 == destroy) {
+ onDestroyRequest();
+ }
+}
+
+void QtChatWindow::showRoomConfigurationForm(Form::ref form) {
+ if (mucConfigurationWindow) {
+ delete mucConfigurationWindow.data();
+ }
+ mucConfigurationWindow = new QtMUCConfigurationWindow(form);
+ mucConfigurationWindow->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1));
+}
+
}