summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/QtChatView.cpp')
-rw-r--r--Swift/QtUI/QtChatView.cpp164
1 files changed, 151 insertions, 13 deletions
diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index 521b072..7bb5818 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -18,13 +18,16 @@
#include <QMessageBox>
#include <QApplication>
+#include <Swiften/Base/Log.h>
+
#include "QtWebView.h"
#include "QtChatTheme.h"
+#include "QtSwiftUtil.h"
namespace Swift {
-QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent) {
+QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent), fontSizeSteps_(0) {
theme_ = theme;
QVBoxLayout* mainLayout = new QVBoxLayout(this);
@@ -35,6 +38,8 @@ QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent) {
connect(webView_, SIGNAL(loadFinished(bool)), SLOT(handleViewLoadFinished(bool)));
connect(webView_, SIGNAL(gotFocus()), SIGNAL(gotFocus()));
connect(webView_, SIGNAL(clearRequested()), SLOT(handleClearRequested()));
+ connect(webView_, SIGNAL(fontGrowRequested()), SLOT(increaseFontSize()));
+ connect(webView_, SIGNAL(fontShrinkRequested()), SLOT(decreaseFontSize()));
#ifdef Q_WS_X11
/* To give a border on Linux, where it looks bad without */
QStackedWidget* stack = new QStackedWidget(this);
@@ -46,8 +51,15 @@ QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent) {
mainLayout->addWidget(webView_);
#endif
+#ifdef SWIFT_EXPERIMENTAL_FT
+ setAcceptDrops(true);
+#endif
+
webPage_ = new QWebPage(this);
webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
+#ifdef SWIFT_EXPERIMENTAL_FT
+ webPage_->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
+#endif
webView_->setPage(webPage_);
connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
@@ -77,13 +89,14 @@ void QtChatView::addMessage(boost::shared_ptr<ChatSnippet> snippet) {
if (viewReady_) {
addToDOM(snippet);
} else {
- queuedSnippets_.append(snippet);
+ /* If this asserts, the previous queuing code was necessary and should be reinstated */
+ assert(false);
}
}
QWebElement QtChatView::snippetToDOM(boost::shared_ptr<ChatSnippet> snippet) {
QWebElement newElement = newInsertPoint_.clone();
- newElement.setInnerXml(snippet->getContent()); /* FIXME: Outer, surely? */
+ newElement.setInnerXml(snippet->getContent());
Q_ASSERT(!newElement.isNull());
return newElement;
}
@@ -103,12 +116,31 @@ void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) {
newInsertPoint_.prependOutside(newElement);
}
lastElement_ = newElement;
- //qApp->processEvents();
+ if (fontSizeSteps_ != 0) {
+ double size = 1.0 + 0.2 * fontSizeSteps_;
+ QString sizeString(QString().setNum(size, 'g', 3) + "em");
+ const QWebElementCollection spans = lastElement_.findAll("span");
+ foreach (QWebElement span, spans) {
+ span.setStyleProperty("font-size", sizeString);
+ }
+ }
+}
+
+void QtChatView::addLastSeenLine() {
+ if (lineSeparator_.isNull()) {
+ lineSeparator_ = newInsertPoint_.clone();
+ lineSeparator_.setInnerXml(QString("<hr/>"));
+ newInsertPoint_.prependOutside(lineSeparator_);
+ }
+ else {
+ QWebElement lineSeparatorC = lineSeparator_.clone();
+ lineSeparatorC.removeFromDocument();
+ }
+ newInsertPoint_.prependOutside(lineSeparator_);
}
void QtChatView::replaceLastMessage(const QString& newMessage) {
assert(viewReady_);
- /* FIXME: must be queued? */
rememberScrolledToBottom();
assert(!lastElement_.isNull());
QWebElement replace = lastElement_.findFirst("span.swift_message");
@@ -125,6 +157,29 @@ void QtChatView::replaceLastMessage(const QString& newMessage, const QString& no
replace.setInnerXml(ChatSnippet::escape(note));
}
+QString QtChatView::getLastSentMessage() {
+ return lastElement_.toPlainText();
+}
+
+void QtChatView::addToJSEnvironment(const QString& name, QObject* obj) {
+ webView_->page()->currentFrame()->addToJavaScriptWindowObject(name, obj);
+}
+
+void QtChatView::replaceMessage(const QString& newMessage, const QString& id, const QDateTime& editTime) {
+ rememberScrolledToBottom();
+ QWebElement message = document_.findFirst("#" + id);
+ if (!message.isNull()) {
+ QWebElement replaceContent = message.findFirst("span.swift_message");
+ assert(!replaceContent.isNull());
+ QString old = replaceContent.toOuterXml();
+ replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
+ QWebElement replaceTime = message.findFirst("span.swift_time");
+ assert(!replaceTime.isNull());
+ old = replaceTime.toOuterXml();
+ replaceTime.setInnerXml(ChatSnippet::escape(tr("%1 edited").arg(ChatSnippet::timeToEscapedString(editTime))));
+ }
+}
+
void QtChatView::copySelectionToClipboard() {
if (!webPage_->selectedText().isEmpty()) {
webPage_->triggerAction(QWebPage::Copy);
@@ -160,17 +215,35 @@ void QtChatView::handleLinkClicked(const QUrl& url) {
QDesktopServices::openUrl(url);
}
-void QtChatView::addQueuedSnippets() {
- for (int i = 0; i < queuedSnippets_.count(); i++) {
- addToDOM(queuedSnippets_[i]);
- }
- queuedSnippets_.clear();
-}
-
void QtChatView::handleViewLoadFinished(bool ok) {
Q_ASSERT(ok);
viewReady_ = true;
- addQueuedSnippets();
+}
+
+void QtChatView::increaseFontSize(int numSteps) {
+ //qDebug() << "Increasing";
+ fontSizeSteps_ += numSteps;
+ emit fontResized(fontSizeSteps_);
+}
+
+void QtChatView::decreaseFontSize() {
+ fontSizeSteps_--;
+ if (fontSizeSteps_ < 0) {
+ fontSizeSteps_ = 0;
+ }
+ emit fontResized(fontSizeSteps_);
+}
+
+void QtChatView::resizeFont(int fontSizeSteps) {
+ fontSizeSteps_ = fontSizeSteps;
+ double size = 1.0 + 0.2 * fontSizeSteps_;
+ QString sizeString(QString().setNum(size, 'g', 3) + "em");
+ //qDebug() << "Setting to " << sizeString;
+ const QWebElementCollection spans = document_.findAll("span");
+ foreach (QWebElement span, spans) {
+ span.setStyleProperty("font-size", sizeString);
+ }
+ webView_->setFontSizeIsMinimal(size == 1.0);
}
void QtChatView::resetView() {
@@ -204,4 +277,69 @@ void QtChatView::resetView() {
connect(webPage_->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), this, SLOT(handleFrameSizeChanged()), Qt::UniqueConnection);
}
+QWebElement findDivElementWithID(QWebElement document, QString id) {
+ QWebElementCollection divs = document.findAll("div");
+ foreach(QWebElement div, divs) {
+ if (div.attribute("id") == id) {
+ return div;
+ }
+ }
+ return QWebElement();
+}
+
+void QtChatView::setFileTransferProgress(QString id, const int percentageDone) {
+ QWebElement ftElement = findDivElementWithID(document_, id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id!" << std::endl;
+ return;
+ }
+ QWebElement progressBar = ftElement.findFirst("div.progressbar");
+ progressBar.setStyleProperty("width", QString::number(percentageDone) + "%");
+
+ QWebElement progressBarValue = ftElement.findFirst("div.progressbar-value");
+ progressBarValue.setInnerXml(QString::number(percentageDone) + " %");
+}
+
+void QtChatView::setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& /* msg */) {
+ QWebElement ftElement = findDivElementWithID(document_, id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
+
+ QString newInnerHTML = "";
+ if (state == ChatWindow::WaitingForAccept) {
+ newInnerHTML = "Waiting for other side to accept the transfer.<br/>"
+ "<input id=\"discard\" type=\"submit\" value=\"Cancel\" onclick=\"filetransfer.cancel(\'" + id + "\');\">";
+ }
+ if (state == ChatWindow::Negotiating) {
+ // replace with text "Negotiaging" + Cancel button
+ newInnerHTML = "Negotiating...<br/>"
+ "<input id=\"discard\" type=\"submit\" value=\"Cancel\" onclick=\"filetransfer.cancel(\'" + id + "\');\">";
+ }
+ else if (state == ChatWindow::Transferring) {
+ // progress bar + Cancel Button
+ newInnerHTML = "<div style=\"position: relative; width: 90%; height: 20px; border: 2px solid grey; -webkit-border-radius: 10px;\">"
+ "<div class=\"progressbar\" style=\"width: 0%; height: 100%; background: #AAA; -webkit-border-radius: 6px;\">"
+ "<div class=\"progressbar-value\" style=\"position: absolute; top: 0px; left: 0px; width: 100%; text-align: center; padding-top: 2px;\">"
+ "0%"
+ "</div>"
+ "</div>"
+ "</div>"
+ "<input id=\"discard\" type=\"submit\" value=\"Cancel\" onclick=\"filetransfer.cancel(\'" + id + "\');\">";
+ }
+ else if (state == ChatWindow::Canceled) {
+ newInnerHTML = "Transfer has been canceled!";
+ }
+ else if (state == ChatWindow::Finished) {
+ // text "Successful transfer"
+ newInnerHTML = "Transfer completed successfully.";
+ }
+ else if (state == ChatWindow::FTFailed) {
+ newInnerHTML = "Transfer failed.";
+ }
+
+ ftElement.setInnerXml(newInnerHTML);
+}
+
}