diff options
author | Kevin Smith <git@kismith.co.uk> | 2010-08-29 22:32:59 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2010-08-30 14:53:32 (GMT) |
commit | b9b535ffd46382c413504a1781400c1a554e04a8 (patch) | |
tree | 723b1e948930478e0324c374f74f1fabc88699ec /Swift | |
parent | 5546afc2bbf8ab0fd49647150da7a5f3df01deaf (diff) | |
download | swift-b9b535ffd46382c413504a1781400c1a554e04a8.zip swift-b9b535ffd46382c413504a1781400c1a554e04a8.tar.bz2 |
Render the Chat view directly with DOM commands, not javascript.
Tested locally, but it's conceivable there will be regressions.
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/QtUI/ChatSnippet.cpp | 10 | ||||
-rw-r--r-- | Swift/QtUI/ChatSnippet.h | 2 | ||||
-rw-r--r-- | Swift/QtUI/MessageSnippet.cpp | 14 | ||||
-rw-r--r-- | Swift/QtUI/MessageSnippet.h | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTheme.cpp | 67 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTheme.h | 40 | ||||
-rw-r--r-- | Swift/QtUI/QtChatView.cpp | 112 | ||||
-rw-r--r-- | Swift/QtUI/QtChatView.h | 22 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 13 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.h | 10 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.cpp | 18 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.h | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 5 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 1 | ||||
-rw-r--r-- | Swift/QtUI/SystemMessageSnippet.cpp | 8 | ||||
-rw-r--r-- | Swift/QtUI/SystemMessageSnippet.h | 7 |
16 files changed, 260 insertions, 79 deletions
diff --git a/Swift/QtUI/ChatSnippet.cpp b/Swift/QtUI/ChatSnippet.cpp index 5eb6268..2218c07 100644 --- a/Swift/QtUI/ChatSnippet.cpp +++ b/Swift/QtUI/ChatSnippet.cpp @@ -16,16 +16,6 @@ ChatSnippet::ChatSnippet(bool appendToPrevious) : appendToPrevious_(appendToPrev ChatSnippet::~ChatSnippet() { } -QString ChatSnippet::loadTemplate(const QString& filename) { - QFile file(filename); - bool result = file.open(QIODevice::ReadOnly); - Q_ASSERT(result); - Q_UNUSED(result); - QString content = file.readAll(); - file.close(); - return content; -} - QString ChatSnippet::escape(const QString& original) { QString result(original); result.replace("%message%", "%message%"); diff --git a/Swift/QtUI/ChatSnippet.h b/Swift/QtUI/ChatSnippet.h index 8a574c6..9345f61 100644 --- a/Swift/QtUI/ChatSnippet.h +++ b/Swift/QtUI/ChatSnippet.h @@ -7,6 +7,7 @@ #pragma once #include <QString> +#include "QtChatTheme.h" namespace Swift { class ChatSnippet { @@ -22,7 +23,6 @@ namespace Swift { } protected: - QString loadTemplate(const QString& file); static QString escape(const QString&); private: diff --git a/Swift/QtUI/MessageSnippet.cpp b/Swift/QtUI/MessageSnippet.cpp index 995248a..ebcc829 100644 --- a/Swift/QtUI/MessageSnippet.cpp +++ b/Swift/QtUI/MessageSnippet.cpp @@ -11,21 +11,21 @@ namespace Swift { -MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious) : ChatSnippet(appendToPrevious) { +MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme) : ChatSnippet(appendToPrevious) { if (isIncoming) { if (appendToPrevious) { - content_ = loadTemplate(":/themes/Default/Incoming/NextContent.html"); + content_ = theme->getIncomingNextContent(); } else { - content_ = loadTemplate(":/themes/Default/Incoming/Content.html"); + content_ = theme->getIncomingContent(); } } else { if (appendToPrevious) { - content_ = loadTemplate(":/themes/Default/Outgoing/NextContent.html"); + content_ = theme->getOutgoingNextContent(); } else { - content_ = loadTemplate(":/themes/Default/Outgoing/Content.html"); + content_ = theme->getOutgoingContent(); } } @@ -35,4 +35,8 @@ MessageSnippet::MessageSnippet(const QString& message, const QString& sender, co content_.replace("%userIconPath%", escape(iconURI)); } +MessageSnippet::~MessageSnippet() { + +} + } diff --git a/Swift/QtUI/MessageSnippet.h b/Swift/QtUI/MessageSnippet.h index 8e624f8..4918c19 100644 --- a/Swift/QtUI/MessageSnippet.h +++ b/Swift/QtUI/MessageSnippet.h @@ -15,8 +15,8 @@ class QDateTime; namespace Swift { class MessageSnippet : public ChatSnippet { public: - MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious); - + MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme); + virtual ~MessageSnippet(); const QString& getContent() const { return content_; } diff --git a/Swift/QtUI/QtChatTheme.cpp b/Swift/QtUI/QtChatTheme.cpp new file mode 100644 index 0000000..afcf665 --- /dev/null +++ b/Swift/QtUI/QtChatTheme.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010 Kevin Smith. + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "QtChatTheme.h" + +#include <QFile> +#include <qdebug.h> + +namespace Swift { + +/** + * Load Adium themes, as http://trac.adium.im/wiki/CreatingMessageStyles + */ +QtChatTheme::QtChatTheme(const QString& themePath) : qrc_(themePath.isEmpty()), themePath_(qrc_ ? ":/themes/Default/" : themePath + "/Contents/Resources/") { + QString fileNames[EndMarker]; + fileNames[Header] = "Header.html"; + fileNames[Footer] = "Footer.html"; + fileNames[Content] = "Content.html"; + fileNames[Status] = "Status.html"; + fileNames[Topic] = "Topic.html"; + fileNames[FileTransferRequest] = "FileTransferRequest.html"; + fileNames[IncomingContent] = "Incoming/Content.html"; + fileNames[IncomingNextContent] = "Incoming/NextContent.html"; + fileNames[IncomingContext] = "Incoming/Context.html"; + fileNames[IncomingNextContext] = "Incoming/NextContext.html"; + fileNames[OutgoingContent] = "Outgoing/Content.html"; + fileNames[OutgoingNextContent] = "Outgoing/NextContent.html"; + fileNames[OutgoingContext] = "Outgoing/Context.html"; + fileNames[OutgoingNextContext] = "Outgoing/NextContext.html"; + fileNames[Template] = "Template.html"; + fileNames[MainCSS] = "main.css"; + fileNames[TemplateDefault] = ":/themes/Template.html"; + for (int i = 0; i < EndMarker; i++) { + QString source; + QFile sourceFile((i != TemplateDefault ? themePath_ : "") + fileNames[i]); + if (sourceFile.exists() && sourceFile.open(QIODevice::ReadOnly)) { + source = sourceFile.readAll(); + sourceFile.close(); + } else { + //qWarning() << "Couldn't load file " << sourceFile.fileName(); + } + fileContents_.append(source); + } + + /* Fallbacks */ + if (fileContents_[Template].isEmpty()) fileContents_[Template] = fileContents_[TemplateDefault]; + if (fileContents_[Status].isEmpty()) fileContents_[Status] = fileContents_[Content]; + if (fileContents_[IncomingContent].isEmpty()) fileContents_[IncomingContent] = fileContents_[Content]; + if (fileContents_[IncomingNextContent].isEmpty()) fileContents_[IncomingNextContent] = fileContents_[IncomingContent]; + if (fileContents_[FileTransferRequest].isEmpty()) fileContents_[FileTransferRequest] = fileContents_[Status]; + if (fileContents_[IncomingContext].isEmpty()) fileContents_[IncomingContext] = fileContents_[IncomingContent]; + if (fileContents_[IncomingNextContext].isEmpty()) fileContents_[IncomingNextContext] = fileContents_[IncomingNextContent]; + if (fileContents_[OutgoingContent].isEmpty()) fileContents_[OutgoingContent] = fileContents_[IncomingContent]; + if (fileContents_[OutgoingContext].isEmpty()) fileContents_[OutgoingContext] = fileContents_[OutgoingContent]; + if (fileContents_[OutgoingNextContent].isEmpty()) fileContents_[OutgoingNextContent] = fileContents_[OutgoingContent]; + if (fileContents_[OutgoingNextContext].isEmpty()) fileContents_[OutgoingNextContext] = fileContents_[OutgoingNextContent]; + +} + +QString QtChatTheme::getBase() { + return qrc_ ? "qrc" + themePath_ : "file://" + themePath_; +} + +} diff --git a/Swift/QtUI/QtChatTheme.h b/Swift/QtUI/QtChatTheme.h new file mode 100644 index 0000000..199c66d --- /dev/null +++ b/Swift/QtUI/QtChatTheme.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010 Kevin Smith. + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <QString> +#include <QList> + +namespace Swift { + class QtChatTheme { + public: + QtChatTheme(const QString& themePath); + QString getHeader() {return fileContents_[Header];}; + QString getFooter() {return fileContents_[Footer];}; + QString getContent() {return fileContents_[Content];}; + QString getStatus() {return fileContents_[Status];}; + QString getTopic() {return fileContents_[Topic];}; + QString getFileTransferRequest() {return fileContents_[FileTransferRequest];}; + QString getIncomingContent() {return fileContents_[IncomingContent];}; + QString getIncomingNextContent() {return fileContents_[IncomingNextContent];}; + QString getIncomingContext() {return fileContents_[IncomingContext];}; + QString getIncomingNextContext() {return fileContents_[IncomingNextContext];}; + QString getOutgoingContent() {return fileContents_[OutgoingContent];}; + QString getOutgoingNextContent() {return fileContents_[OutgoingNextContent];}; + QString getOutgoingContext() {return fileContents_[OutgoingContext];}; + QString getOutgoingNextContext() {return fileContents_[OutgoingNextContext];}; + QString getTemplate() {return fileContents_[Template];} + QString getMainCSS() {return fileContents_[MainCSS];} + QString getBase(); + + private: + enum files {Header = 0, Footer, Content, Status, Topic, FileTransferRequest, IncomingContent, IncomingNextContent, IncomingContext, IncomingNextContext, OutgoingContent, OutgoingNextContent, OutgoingContext, OutgoingNextContext, Template, MainCSS, TemplateDefault, EndMarker}; + bool qrc_; + QList<QString> fileContents_; + QString themePath_; + }; +} diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp index 90b567f..1c4ed18 100644 --- a/Swift/QtUI/QtChatView.cpp +++ b/Swift/QtUI/QtChatView.cpp @@ -15,10 +15,13 @@ #include <QStackedWidget> #include "QtWebView.h" +#include "QtChatTheme.h" + namespace Swift { -QtChatView::QtChatView(QWidget* parent) : QWidget(parent) { +QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent) { + theme_ = theme; QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->setSpacing(0); @@ -46,54 +49,79 @@ QtChatView::QtChatView(QWidget* parent) : QWidget(parent) { 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(); + viewReady_ = false; + QString pageHTML = theme_->getTemplate(); pageHTML.replace("==bodyBackground==", "background-color:#e3e3e3"); - pageHTML.replace(pageHTML.indexOf("%@"), 2, "qrc:/themes/Default/"); + pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getBase()); + if (pageHTML.count("%@") > 3) { + pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getMainCSS()); + } pageHTML.replace(pageHTML.indexOf("%@"), 2, "Variants/Blue on Green.css"); - pageHTML.replace(pageHTML.indexOf("%@"), 2, ""); - pageHTML.replace(pageHTML.indexOf("%@"), 2, ""); - file.close(); - - viewReady_ = false; + pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*headerSnippet.getContent()*/); + pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*footerSnippet.getContent()*/); webPage_->mainFrame()->setHtml(pageHTML); + document_ = webPage_->mainFrame()->documentElement(); + QWebElement chatElement = document_.findFirst("#Chat"); + newInsertPoint_ = chatElement.clone(); + newInsertPoint_.setOuterXml("<div id='insert'/>"); + chatElement.appendInside(newInsertPoint_); + if (newInsertPoint_.isNull()) { + qWarning() << "Warning, initial insert point element is null!"; + } } void QtChatView::handleKeyPressEvent(QKeyEvent* event) { webView_->keyPressEvent(event); } -void QtChatView::addMessage(const ChatSnippet& snippet) { - //bool wasScrolledToBottom = isScrolledToBottom(); - - QString content = snippet.getContent(); - content.replace("\\", "\\\\"); - content.replace("\"", "\\\""); - content.replace("\n", "\\n"); - content.replace("\r", ""); - QString command; - if (previousContinuationElementID_.isEmpty() || !snippet.getAppendToPrevious()) { - command = "appendMessage(\"" + content + "\");"; - } - else { - command = "appendNextMessage(\"" + content + "\");"; - } +void QtChatView::addMessage(boost::shared_ptr<ChatSnippet> snippet) { if (viewReady_) { - webPage_->mainFrame()->evaluateJavaScript(command); - } - else { - queuedMessages_ += command; + addToDOM(snippet); + } else { + queuedSnippets_.append(snippet); } +// QString content = snippet.getContent(); +// content.replace("\\", "\\\\"); +// content.replace("\"", "\\\""); +// content.replace("\n", "\\n"); +// content.replace("\r", ""); +// QString command; +// if (previousContinuationElementID_.isEmpty() || !snippet.getAppendToPrevious()) { +// command = "appendMessage(\"" + content + "\");"; +// } +// else { +// command = "appendNextMessage(\"" + content + "\");"; +// } +// if (viewReady_) { +// webPage_->mainFrame()->evaluateJavaScript(command); +// } +// else { +// queuedMessages_ += command; +// } +// +// previousContinuationElementID_ = snippet.getContinuationElementID(); - //qDebug() << webPage_->mainFrame()->toHtml(); - previousContinuationElementID_ = snippet.getContinuationElementID(); +} - /*if (wasScrolledToBottom) { - scrollToBottom(); - }*/ +QWebElement QtChatView::snippetToDOM(boost::shared_ptr<ChatSnippet> snippet) { + QWebElement newElement = newInsertPoint_.clone(); + newElement.setInnerXml(snippet->getContent()); /* FIXME: Outer, surely? */ + if (newElement.isNull()) { + qWarning() << "Warning, new element is null!"; + } + return newElement; +} + +void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) { + QWebElement newElement = snippetToDOM(snippet); + QWebElement continuationElement = lastElement_.findFirst("#insert"); + if (snippet->getAppendToPrevious()) { + continuationElement.replace(newElement); + } else { + continuationElement.removeFromDocument(); + newInsertPoint_.prependOutside(newElement); + } + lastElement_ = newElement; } void QtChatView::copySelectionToClipboard() { @@ -114,11 +142,19 @@ 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; - webPage_->mainFrame()->evaluateJavaScript(queuedMessages_); - queuedMessages_.clear(); + addQueuedSnippets(); +// webPage_->mainFrame()->evaluateJavaScript(queuedMessages_); +// queuedMessages_.clear(); } } diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h index f60d049..3936c18 100644 --- a/Swift/QtUI/QtChatView.h +++ b/Swift/QtUI/QtChatView.h @@ -9,6 +9,10 @@ #include <QString> #include <QWidget> +#include <QList> +#include <QWebElement> + +#include <boost/shared_ptr.hpp> #include "ChatSnippet.h" @@ -17,12 +21,13 @@ class QUrl; namespace Swift { class QtWebView; + class QtChatTheme; class QtChatView : public QWidget { Q_OBJECT public: - QtChatView(QWidget* parent); + QtChatView(QtChatTheme* theme, QWidget* parent); - void addMessage(const ChatSnippet& snippet); + void addMessage(boost::shared_ptr<ChatSnippet> snippet); bool isScrolledToBottom() const; signals: @@ -38,11 +43,22 @@ namespace Swift { void handleViewLoadFinished(bool); private: + void headerEncode(); + void messageEncode(); + void addQueuedSnippets(); + void addToDOM(boost::shared_ptr<ChatSnippet> snippet); + QWebElement snippetToDOM(boost::shared_ptr<ChatSnippet> snippet); + bool viewReady_; QtWebView* webView_; QWebPage* webPage_; QString previousContinuationElementID_; - QString queuedMessages_; + QList<boost::shared_ptr<ChatSnippet> > queuedSnippets_; + + QtChatTheme* theme_; + QWebElement newInsertPoint_; + QWebElement lastElement_; + QWebElement document_; }; } diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index de681d5..73bf2c2 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -28,10 +28,11 @@ #include <QUrl> namespace Swift { -QtChatWindow::QtChatWindow(const QString &contact, 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), eventStream_(eventStream) { unreadCount_ = 0; inputEnabled_ = true; completer_ = NULL; + theme_ = theme; updateTitleWithUnreadCount(); QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); @@ -43,7 +44,7 @@ QtChatWindow::QtChatWindow(const QString &contact, UIEventStream* eventStream) : logRosterSplitter->setAutoFillBackground(true); layout->addWidget(logRosterSplitter); - messageLog_ = new QtChatView(this); + messageLog_ = new QtChatView(theme, this); logRosterSplitter->addWidget(messageLog_); treeWidget_ = new QtTreeWidget(eventStream_); @@ -267,7 +268,7 @@ void QtChatWindow::addMessage(const String &message, const String &senderName, b bool appendToPrevious = !previousMessageWasSystem_ && !previousMessageWasPresence_ && ((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)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious)); + messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_))); previousMessageWasSelf_ = senderIsSelf; previousSenderName_ = P2QSTRING(senderName); @@ -290,7 +291,7 @@ void QtChatWindow::addErrorMessage(const String& errorMessage) { QString errorMessageHTML(Qt::escape(P2QSTRING(errorMessage))); errorMessageHTML.replace("\n","<br/>"); - messageLog_->addMessage(SystemMessageSnippet(QString("<span class=\"error\">%1</span>").arg(errorMessageHTML), QDateTime::currentDateTime(),previousMessageWasSystem_)); + messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(QString("<span class=\"error\">%1</span>").arg(errorMessageHTML), QDateTime::currentDateTime(),previousMessageWasSystem_, theme_))); previousMessageWasSelf_ = false; previousMessageWasSystem_ = true; @@ -304,7 +305,7 @@ void QtChatWindow::addSystemMessage(const String& message) { QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML.replace("\n","<br/>"); - messageLog_->addMessage(SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(),previousMessageWasSystem_)); + messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(),previousMessageWasSystem_, theme_))); previousMessageWasSelf_ = false; previousMessageWasSystem_ = true; @@ -318,7 +319,7 @@ void QtChatWindow::addPresenceMessage(const String& message) { QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML.replace("\n","<br/>"); - messageLog_->addMessage(SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), previousMessageWasPresence_)); + messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), previousMessageWasPresence_, theme_))); previousMessageWasSelf_ = false; previousMessageWasSystem_ = false; diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 1770186..2b006d9 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -19,13 +19,14 @@ namespace Swift { class QtChatView; class QtTreeWidget; class QtTreeWidgetFactory; + class QtChatTheme; class TreeWidget; class QtTextEdit; class UIEventStream; class QtChatWindow : public QtTabbable, public ChatWindow { Q_OBJECT public: - QtChatWindow(const QString &contact, UIEventStream* eventStream); + QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream); ~QtChatWindow(); void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time); void addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time); @@ -74,10 +75,11 @@ namespace Swift { int unreadCount_; bool contactIsTyping_; QString contact_; - QtChatView *messageLog_; + QtChatView* messageLog_; + QtChatTheme* theme_; QtTextEdit* input_; - QComboBox *labelsWidget_; - QtTreeWidget *treeWidget_; + QComboBox* labelsWidget_; + QtTreeWidget* treeWidget_; TabComplete* completer_; std::vector<SecurityLabel> availableLabels_; bool previousMessageWasSelf_; diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp index 9787c2c..d146474 100644 --- a/Swift/QtUI/QtChatWindowFactory.cpp +++ b/Swift/QtUI/QtChatWindowFactory.cpp @@ -11,12 +11,15 @@ #include "QtChatTabs.h" #include "QtChatWindow.h" #include "QtSwiftUtil.h" +#include "QtChatTheme.h" +#include <qdebug.h> namespace Swift { -QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs) { +QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs, const QString& themePath) : themePath_(themePath) { settings_ = settings; tabs_ = tabs; + theme_ = NULL; if (splitter) { splitter->addWidget(tabs_); } else if (tabs_) { @@ -28,8 +31,19 @@ QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider } } +QtChatWindowFactory::~QtChatWindowFactory() { + delete theme_; +} + ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStream* eventStream) { - QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), eventStream); + if (!theme_) { + theme_ = new QtChatTheme(themePath_); + if (theme_->getIncomingContent().isEmpty()) { + delete theme_; + theme_ = new QtChatTheme(""); /* Use the inbuilt theme */ + } + } + QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream); if (tabs_) { tabs_->addTab(chatWindow); } else { diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h index 4ffac88..0d47854 100644 --- a/Swift/QtUI/QtChatWindowFactory.h +++ b/Swift/QtUI/QtChatWindowFactory.h @@ -14,17 +14,21 @@ #include <QSplitter> namespace Swift { class QtChatTabs; + class QtChatTheme; class UIEventStream; class QtChatWindowFactory : public QObject, public ChatWindowFactory { Q_OBJECT public: - QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs); + QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs, const QString& themePath); + ~QtChatWindowFactory(); ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); private slots: void handleWindowGeometryChanged(); private: + QString themePath_; QtSettingsProvider* settings_; QtChatTabs* tabs_; + QtChatTheme* theme_; }; } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 0405681..e1f5e89 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -6,6 +6,8 @@ #include "QtSwift.h" +#include <string> + #include "QtLoginWindowFactory.h" #include "QtChatWindowFactory.h" #include "QtLoginWindow.h" @@ -13,6 +15,7 @@ #include "QtMainWindowFactory.h" #include "QtSystemTray.h" #include "QtSoundPlayer.h" +#include "QtSwiftUtil.h" #include "QtXMLConsoleWidgetFactory.h" #include "ChatList/QtChatListWindowFactory.h" #include "EventViewer/QtEventWindowFactory.h" @@ -81,7 +84,7 @@ QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) { applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME); avatarStorage_ = new AvatarFileStorage(applicationPathProvider_->getAvatarDir()); vcardStorageFactory_ = new VCardFileStorageFactory(applicationPathProvider_->getDataDir()); - chatWindowFactory_ = new QtChatWindowFactory(splitter_, settings_, tabs_); + chatWindowFactory_ = new QtChatWindowFactory(splitter_, settings_, tabs_, ""); soundPlayer_ = new QtSoundPlayer(applicationPathProvider_); if (splitter_) { splitter_->show(); diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index f119397..9f08f4f 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -64,6 +64,7 @@ sources = [ "QtStatusWidget.cpp", "QtSwift.cpp", "QtChatView.cpp", + "QtChatTheme.cpp", "QtChatTabs.cpp", "QtSoundPlayer.cpp", "QtSystemTray.cpp", diff --git a/Swift/QtUI/SystemMessageSnippet.cpp b/Swift/QtUI/SystemMessageSnippet.cpp index ba0ec1b..db57b1f 100644 --- a/Swift/QtUI/SystemMessageSnippet.cpp +++ b/Swift/QtUI/SystemMessageSnippet.cpp @@ -10,12 +10,16 @@ namespace Swift { -SystemMessageSnippet::SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious) : ChatSnippet(appendToPrevious) { - content_ = loadTemplate(":/themes/Default/Status.html"); +SystemMessageSnippet::SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme) : ChatSnippet(appendToPrevious) { + content_ = theme->getStatus(); content_.replace("%message%", escape(message)); content_.replace("%shortTime%", escape(time.toString("h:mm"))); content_.replace("%time%", escape(time.toString("h:mm"))); } +SystemMessageSnippet::~SystemMessageSnippet() { + +} + } diff --git a/Swift/QtUI/SystemMessageSnippet.h b/Swift/QtUI/SystemMessageSnippet.h index 8342476..69d231f 100644 --- a/Swift/QtUI/SystemMessageSnippet.h +++ b/Swift/QtUI/SystemMessageSnippet.h @@ -15,11 +15,10 @@ class QDateTime; namespace Swift { class SystemMessageSnippet : public ChatSnippet { public: - SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious); + SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme); + virtual ~SystemMessageSnippet(); - const QString& getContent() const { - return content_; - } + const QString& getContent() const {return content_;} /*QString getContinuationElementID() const { return "insert"; |