1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#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&)));
connect(webView_, SIGNAL(loadFinished(bool)), SLOT(handleViewLoadFinished(bool)));
#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();
viewReady_ = false;
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", "");
QString command;
if (previousContinuationElementID_.isEmpty() || !snippet.getAppendToPrevious()) {
command = "appendMessage(\"" + content + "\");";
}
else {
command = "appendNextMessage(\"" + content + "\");";
}
if (viewReady_) {
webPage_->mainFrame()->evaluateJavaScript(command);
}
else {
queuedMessages_ += command;
}
//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);
}
void QtChatView::handleViewLoadFinished(bool ok) {
Q_ASSERT(ok);
viewReady_ = true;
webPage_->mainFrame()->evaluateJavaScript(queuedMessages_);
queuedMessages_.clear();
}
}
|