summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/QtChatWindow.cpp')
-rw-r--r--Swift/QtUI/QtChatWindow.cpp133
1 files changed, 130 insertions, 3 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index a36bc32..238100a 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -19,8 +19,15 @@
#include "QtScaledAvatarCache.h"
#include "SwifTools/TabComplete.h"
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
+#include "QtFileTransferJSBridge.h"
+
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
#include <QLabel>
+#include <QInputDialog>
#include <QApplication>
#include <QBoxLayout>
#include <QCloseEvent>
@@ -33,9 +40,12 @@
#include <QTime>
#include <QUrl>
#include <QPushButton>
+#include <QFileDialog>
+
+#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;
@@ -45,6 +55,8 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
updateTitleWithUnreadCount();
QtSettingsProvider settings;
+ setAcceptDrops(true);
+
alertStyleSheet_ = "background: rgb(255, 255, 153); color: black";
QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
@@ -117,15 +129,23 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
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;
}
+
void QtChatWindow::handleOccupantSelectionChanged(RosterItem* item) {
onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item));
}
@@ -306,6 +326,7 @@ void QtChatWindow::closeEvent(QCloseEvent* event) {
}
void QtChatWindow::convertToMUC() {
+ setAcceptDrops(false);
treeWidget_->show();
}
@@ -391,7 +412,7 @@ 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();
@@ -406,6 +427,7 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri
previousSenderName_ = P2QSTRING(senderName);
previousMessageWasSystem_ = false;
previousMessageWasPresence_ = false;
+ previousMessageWasFileTransfer_ = false;
return id;
}
@@ -431,6 +453,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 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(id.toStdString());
+}
+
+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(id.toStdString(), text.toStdString());
+}
+
+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(id.toStdString(), path.toStdString());
+ }
+}
+
void QtChatWindow::addErrorMessage(const std::string& errorMessage) {
if (isWidgetSelected()) {
onAllMessagesRead();
@@ -443,6 +553,7 @@ void QtChatWindow::addErrorMessage(const std::string& errorMessage) {
previousMessageWasSelf_ = false;
previousMessageWasSystem_ = true;
previousMessageWasPresence_ = false;
+ previousMessageWasFileTransfer_ = false;
}
void QtChatWindow::addSystemMessage(const std::string& message) {
@@ -458,6 +569,7 @@ 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) {
@@ -532,6 +644,21 @@ 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(event->mimeData()->urls().at(0).toLocalFile().toStdString());
+ } 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)));
}