summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
Diffstat (limited to 'Swift')
-rw-r--r--Swift/QtUI/QtChatView.cpp6
-rw-r--r--Swift/QtUI/QtChatView.h2
-rw-r--r--Swift/QtUI/QtChatWindow.cpp2
-rw-r--r--Swift/QtUI/SConscript1
4 files changed, 11 insertions, 0 deletions
diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index 0a02591..12f6beb 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -1,91 +1,97 @@
#include "QtChatView.h"
#include <QtDebug>
#include <QFile>
+#include <QDesktopServices>
#include <QVBoxLayout>
#include <QWebView>
#include <QWebFrame>
#include <QKeyEvent>
#include <QStackedWidget>
namespace Swift {
QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
setFocusPolicy(Qt::NoFocus);
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0,0,0,0);
webView_ = new QWebView(this);
webView_->setFocusPolicy(Qt::NoFocus);
+ connect(webView_, SIGNAL(linkClicked(const QUrl&)), SLOT(handleLinkClicked(const QUrl&)));
#ifdef Q_WS_X11
/* To give a border on Linux, where it looks bad without */
QStackedWidget* stack = new QStackedWidget(this);
stack->addWidget(webView_);
stack->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
stack->setLineWidth(2);
mainLayout->addWidget(stack);
#else
mainLayout->addWidget(webView_);
#endif
webPage_ = new QWebPage(this);
webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
webView_->setPage(webPage_);
connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
QFile file(":/themes/Default/Template.html");
bool result = file.open(QIODevice::ReadOnly);
Q_ASSERT(result);
Q_UNUSED(result);
QString pageHTML = file.readAll();
pageHTML.replace("==bodyBackground==", "background-color:#e3e3e3");
pageHTML.replace(pageHTML.indexOf("%@"), 2, "qrc:/themes/Default/");
pageHTML.replace(pageHTML.indexOf("%@"), 2, "Variants/Blue on Green.css");
pageHTML.replace(pageHTML.indexOf("%@"), 2, "");
pageHTML.replace(pageHTML.indexOf("%@"), 2, "");
file.close();
webPage_->mainFrame()->setHtml(pageHTML);
}
void QtChatView::addMessage(const ChatSnippet& snippet) {
//bool wasScrolledToBottom = isScrolledToBottom();
QString content = snippet.getContent();
content.replace("\\", "\\\\");
content.replace("\"", "\\\"");
content.replace("\n", "\\n");
content.replace("\r", "");
if (previousContinuationElementID_.isEmpty() || !snippet.getAppendToPrevious()) {
webPage_->mainFrame()->evaluateJavaScript("appendMessage(\"" + content + "\");");
}
else {
webPage_->mainFrame()->evaluateJavaScript("appendNextMessage(\"" + content + "\");");
}
//qDebug() << webPage_->mainFrame()->toHtml();
previousContinuationElementID_ = snippet.getContinuationElementID();
/*if (wasScrolledToBottom) {
scrollToBottom();
}*/
}
void QtChatView::copySelectionToClipboard() {
if (!webPage_->selectedText().isEmpty()) {
webPage_->triggerAction(QWebPage::Copy);
}
}
bool QtChatView::isScrolledToBottom() const {
return webPage_->mainFrame()->scrollBarValue(Qt::Vertical) == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical);
}
void QtChatView::scrollToBottom() {
webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical));
}
+void QtChatView::handleLinkClicked(const QUrl& url) {
+ QDesktopServices::openUrl(url);
+}
+
}
diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h
index 2a50129..7340e00 100644
--- a/Swift/QtUI/QtChatView.h
+++ b/Swift/QtUI/QtChatView.h
@@ -1,32 +1,34 @@
#ifndef SWIFT_QtChatView_H
#define SWIFT_QtChatView_H
#include <QString>
#include <QWidget>
#include "ChatSnippet.h"
class QWebView;
class QWebPage;
+class QUrl;
namespace Swift {
class QtChatView : public QWidget {
Q_OBJECT
public:
QtChatView(QWidget* parent);
void addMessage(const ChatSnippet& snippet);
bool isScrolledToBottom() const;
public slots:
void copySelectionToClipboard();
void scrollToBottom();
+ void handleLinkClicked(const QUrl&);
private:
QWebView* webView_;
QWebPage* webPage_;
QString previousContinuationElementID_;
};
}
#endif
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index fc8dc1e..bebebe8 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -1,52 +1,53 @@
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
#include "Roster/QtTreeWidget.h"
#include "Roster/QtTreeWidgetFactory.h"
+#include "SwifTools/Linkify.h"
#include "QtChatView.h"
#include "MessageSnippet.h"
#include "SystemMessageSnippet.h"
#include "QtTextEdit.h"
#include <QApplication>
#include <QBoxLayout>
#include <QCloseEvent>
#include <QComboBox>
#include <QLineEdit>
#include <QSplitter>
#include <QString>
#include <QTextEdit>
#include <QTime>
#include <QUrl>
namespace Swift {
QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidgetFactory) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false) {
unreadCount_ = 0;
updateTitleWithUnreadCount();
QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(2);
QSplitter *logRosterSplitter = new QSplitter(this);
layout->addWidget(logRosterSplitter);
messageLog_ = new QtChatView(this);
logRosterSplitter->addWidget(messageLog_);
treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
treeWidget_->hide();
logRosterSplitter->addWidget(treeWidget_);
QWidget* midBar = new QWidget(this);
layout->addWidget(midBar);
QHBoxLayout *midBarLayout = new QHBoxLayout(midBar);
midBarLayout->setContentsMargins(0,0,0,0);
midBarLayout->setSpacing(2);
midBarLayout->addStretch();
labelsWidget_ = new QComboBox(this);
labelsWidget_->setFocusPolicy(Qt::NoFocus);
labelsWidget_->hide();
labelsWidget_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
midBarLayout->addWidget(labelsWidget_,0);
@@ -110,96 +111,97 @@ void QtChatWindow::convertToMUC() {
treeWidget_->show();
}
void QtChatWindow::qAppFocusChanged(QWidget *old, QWidget *now) {
Q_UNUSED(old);
Q_UNUSED(now);
if (isWidgetSelected()) {
onAllMessagesRead();
}
}
void QtChatWindow::setInputEnabled(bool enabled) {
input_->setEnabled(enabled);
}
void QtChatWindow::showEvent(QShowEvent* event) {
emit windowOpening();
QWidget::showEvent(event);
}
void QtChatWindow::setUnreadMessageCount(int count) {
unreadCount_ = count;
updateTitleWithUnreadCount();
}
void QtChatWindow::setName(const String& name) {
contact_ = P2QSTRING(name);
updateTitleWithUnreadCount();
}
void QtChatWindow::updateTitleWithUnreadCount() {
setWindowTitle(unreadCount_ > 0 ? QString("(%1) %2").arg(unreadCount_).arg(contact_) : contact_);
emit titleUpdated();
}
void QtChatWindow::addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) {
if (isWidgetSelected()) {
onAllMessagesRead();
}
QString htmlString;
if (label) {
htmlString = QString("<span style=\"border: thin dashed grey; padding-left: .5em; padding-right: .5em; color: %1; background-color: %2; font-size: 90%; margin-right: .5em; \">").arg(Qt::escape(P2QSTRING(label->getForegroundColor()))).arg(Qt::escape(P2QSTRING(label->getBackgroundColor())));
htmlString += QString("%3</span> ").arg(Qt::escape(P2QSTRING(label->getDisplayMarking())));
}
QString messageHTML(Qt::escape(P2QSTRING(message)));
messageHTML.replace("\n","<br/>");
+ messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML)));
htmlString += messageHTML;
bool appendToPrevious = !previousMessageWasSystem_ && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_ && previousSenderName_ == P2QSTRING(senderName)));
QString qAvatarPath = avatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(P2QSTRING(avatarPath)).toEncoded();
messageLog_->addMessage(MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), QDateTime::currentDateTime(), qAvatarPath, senderIsSelf, appendToPrevious));
previousMessageWasSelf_ = senderIsSelf;
previousSenderName_ = P2QSTRING(senderName);
previousMessageWasSystem_ = false;
}
void QtChatWindow::addErrorMessage(const String& errorMessage) {
if (isWidgetSelected()) {
onAllMessagesRead();
}
QString errorMessageHTML(Qt::escape(P2QSTRING(errorMessage)));
errorMessageHTML.replace("\n","<br/>");
messageLog_->addMessage(SystemMessageSnippet(QString("<span class=\"error\">%1</span>").arg(errorMessageHTML), QDateTime::currentDateTime(),previousMessageWasSystem_));
previousMessageWasSelf_ = false;
previousMessageWasSystem_ = true;
}
void QtChatWindow::addSystemMessage(const String& message) {
if (isWidgetSelected()) {
onAllMessagesRead();
}
QString messageHTML(Qt::escape(P2QSTRING(message)));
messageHTML.replace("\n","<br/>");
messageLog_->addMessage(SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(),previousMessageWasSystem_));
previousMessageWasSelf_ = false;
previousMessageWasSystem_ = true;
}
void QtChatWindow::returnPressed() {
onSendMessageRequest(Q2PSTRING(input_->toPlainText()));
messageLog_->scrollToBottom();
input_->clear();
}
void QtChatWindow::show() {
QWidget::show();
emit windowOpening();
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index ee1c762..d30f3b9 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -1,71 +1,72 @@
import os, shutil, datetime
import Version
def generateDefaultTheme(env, target, source) :
sourceDir = source[0].abspath
output = open(target[0].abspath, "w")
output.write("<RCC version =\"1.0\">")
output.write("<qresource prefix=\"/themes/Default\">")
for (path, dirs, files) in os.walk(sourceDir) :
for file in files :
filePath = os.path.join(path,file)
output.write("<file alias=\"%(alias)s\">%(path)s</file>" % {
"alias": filePath[len(sourceDir)+1:],
"path": filePath
})
output.write("</qresource>")
output.write("</RCC>")
Import("env")
myenv = env.Clone()
myenv.MergeFlags(env["SWIFT_CONTROLLERS_FLAGS"])
+myenv.MergeFlags(env["SWIFTOOLS_FLAGS"])
myenv.MergeFlags(env["SWIFTEN_FLAGS"])
myenv.MergeFlags(env["CPPUNIT_FLAGS"])
myenv.MergeFlags(env["LIBIDN_FLAGS"])
myenv.MergeFlags(env["BOOST_FLAGS"])
myenv.MergeFlags(env["SQLITE_FLAGS"])
myenv.MergeFlags(env["ZLIB_FLAGS"])
myenv.MergeFlags(env["OPENSSL_FLAGS"])
myenv.MergeFlags(env.get("LIBXML_FLAGS", ""))
myenv.MergeFlags(env.get("EXPAT_FLAGS", ""))
myenv.Tool("qt4", toolpath = ["#/BuildTools/SCons/Tools"])
myenv.Tool("nsis", toolpath = ["#/BuildTools/SCons/Tools"])
myenv.EnableQt4Modules(['QtCore', 'QtGui', 'QtWebKit'], debug = False)
myenv.Append(CPPPATH = ["/usr/include/phonon"])
myenv.Append(CPPPATH = ["."])
if env["PLATFORM"] == "win32" :
#myenv["LINKFLAGS"] = ["/SUBSYSTEM:CONSOLE"]
myenv.Append(LINKFLAGS = ["/SUBSYSTEM:WINDOWS"])
myenv.Append(LIBS = "qtmain")
myenv.Command("DefaultTheme.qrc", "../resources/themes/Default", Action(generateDefaultTheme, cmdstr = "$GENCOMSTR"))
sources = [
"main.cpp",
"QtAboutWidget.cpp",
"QtAddContactDialog.cpp",
"QtChatWindow.cpp",
"QtChatWindowFactory.cpp",
"QtIdleDetector.cpp",
"QtJoinMUCDialog.cpp",
"QtLoginWindow.cpp",
"QtLoginWindowFactory.cpp",
"QtMainWindow.cpp",
"QtMainWindowFactory.cpp",
"QtSettingsProvider.cpp",
"QtStatusWidget.cpp",
"QtSwift.cpp",
"QtChatView.cpp",
"QtChatTabs.cpp",
"QtSoundPlayer.cpp",
"QtSystemTray.cpp",
"QtTabbable.cpp",
"QtTextEdit.cpp",
"ChatSnippet.cpp",
"MessageSnippet.cpp",
"SystemMessageSnippet.cpp",