diff options
Diffstat (limited to 'Swift/QtUI/QtWebKitChatView.cpp')
-rw-r--r-- | Swift/QtUI/QtWebKitChatView.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp index ea9a9c6..f3d23e7 100644 --- a/Swift/QtUI/QtWebKitChatView.cpp +++ b/Swift/QtUI/QtWebKitChatView.cpp @@ -1,89 +1,91 @@ /* * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtWebKitChatView.h> #include <QApplication> #include <QDesktopServices> #include <QDesktopWidget> #include <QEventLoop> #include <QFile> #include <QFileDialog> #include <QFileInfo> #include <QFileDevice> #include <QInputDialog> #include <QKeyEvent> #include <QMessageBox> #include <QStackedWidget> #include <QTimer> #include <QVBoxLayout> #include <QWebFrame> #include <QWebSettings> #include <QtDebug> #include <Swiften/Base/FileSize.h> #include <Swiften/Base/Log.h> #include <Swiften/StringCodecs/Base64.h> +#include <Swift/Controllers/SettingConstants.h> +#include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/QtUI/MessageSnippet.h> #include <Swift/QtUI/QtChatWindow.h> #include <Swift/QtUI/QtChatWindowJSBridge.h> #include <Swift/QtUI/QtScaledAvatarCache.h> #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtUtilities.h> #include <Swift/QtUI/QtWebView.h> #include <Swift/QtUI/SystemMessageSnippet.h> namespace Swift { const QString QtWebKitChatView::ButtonWhiteboardSessionCancel = QString("whiteboard-cancel"); const QString QtWebKitChatView::ButtonWhiteboardSessionAcceptRequest = QString("whiteboard-acceptrequest"); const QString QtWebKitChatView::ButtonWhiteboardShowWindow = QString("whiteboard-showwindow"); const QString QtWebKitChatView::ButtonFileTransferCancel = QString("filetransfer-cancel"); const QString QtWebKitChatView::ButtonFileTransferSetDescription = QString("filetransfer-setdescription"); const QString QtWebKitChatView::ButtonFileTransferSendRequest = QString("filetransfer-sendrequest"); const QString QtWebKitChatView::ButtonFileTransferAcceptRequest = QString("filetransfer-acceptrequest"); const QString QtWebKitChatView::ButtonFileTransferOpenFile = QString("filetransfer-openfile"); const QString QtWebKitChatView::ButtonMUCInvite = QString("mucinvite"); namespace { const double minimalFontScaling = 0.7; } -QtWebKitChatView::QtWebKitChatView(QtChatWindow* window, UIEventStream* eventStream, QtChatTheme* theme, QWidget* parent, bool disableAutoScroll) : QtChatView(parent), window_(window), eventStream_(eventStream), fontSizeSteps_(0), disableAutoScroll_(disableAutoScroll), previousMessageKind_(PreviosuMessageWasNone), previousMessageWasSelf_(false), showEmoticons_(false), insertingLastLine_(false), idCounter_(0) { +QtWebKitChatView::QtWebKitChatView(QtChatWindow* window, UIEventStream* eventStream, QtChatTheme* theme, QWidget* parent, SettingsProvider* settings, bool disableAutoScroll /*= false*/) : QtChatView(parent), window_(window), eventStream_(eventStream), fontSizeSteps_(0), disableAutoScroll_(disableAutoScroll), previousMessageKind_(PreviosuMessageWasNone), previousMessageWasSelf_(false), showEmoticons_(false), insertingLastLine_(false), idCounter_(0), settings_(settings) { theme_ = theme; QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0,0,0,0); webView_ = new QtWebView(this); connect(webView_, SIGNAL(linkClicked(const QUrl&)), SLOT(handleLinkClicked(const QUrl&))); 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())); #if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) /* 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 #ifdef SWIFT_EXPERIMENTAL_FT setAcceptDrops(true); #endif webPage_ = new QWebPage(this); webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); if (Log::getLogLevel() == Log::debug) { @@ -528,83 +530,87 @@ QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& messa } if ((emoticonPart = std::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) { QString textStyle = showEmoticons_ ? "style='display:none'" : ""; QString imageStyle = showEmoticons_ ? "" : "style='display:none'"; result += "<span class='swift_emoticon_image' " + imageStyle + "><img src='" + P2QSTRING(emoticonPart->imagePath) + "'/></span><span class='swift_emoticon_text' " + textStyle + ">" + QtUtilities::htmlEscape(P2QSTRING(emoticonPart->alternativeText)) + "</span>"; continue; } if ((highlightPart = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) { QString spanStart = getHighlightSpanStart(highlightPart->action.getFrontColor().get_value_or(""), highlightPart->action.getBackColor().get_value_or("")); result += spanStart + QtUtilities::htmlEscape(P2QSTRING(highlightPart->text)) + "</span>"; continue; } } return result; } std::string QtWebKitChatView::addMessage( const QString& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time, const HighlightAction& highlight, ChatSnippet::Direction direction) { QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str()); + std::string messageMarkingValue = ""; + QString htmlString; if (label) { + messageMarkingValue = label->getDisplayMarking(); 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; \" class='swift_label'>").arg(QtUtilities::htmlEscape(P2QSTRING(label->getForegroundColor()))).arg(QtUtilities::htmlEscape(P2QSTRING(label->getBackgroundColor()))); - htmlString += QString("%1</span> ").arg(QtUtilities::htmlEscape(P2QSTRING(label->getDisplayMarking()))); + htmlString += QString("%1</span> ").arg(QtUtilities::htmlEscape(P2QSTRING(messageMarkingValue))); } QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">"; QString styleSpanEnd = style == "" ? "" : "</span>"; bool highlightWholeMessage = highlight.getFrontColor() || highlight.getBackColor(); QString highlightSpanStart = highlightWholeMessage ? getHighlightSpanStart(highlight) : ""; QString highlightSpanEnd = highlightWholeMessage ? "</span>" : ""; htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ; - bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf); + bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf, label); QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.svg" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded(); std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++); addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), direction)); previousMessageWasSelf_ = senderIsSelf; previousSenderName_ = P2QSTRING(senderName); previousMessageKind_ = PreviousMessageWasMessage; + previousMessageDisplayMarking_ = messageMarkingValue; return id; } std::string QtWebKitChatView::addAction(const ChatWindow::ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getHighlightActionSender(), ChatSnippet::getDirection(message)); } static QString encodeButtonArgument(const QString& str) { return QtUtilities::htmlEscape(P2QSTRING(Base64::encode(createByteArray(Q2PSTRING(str))))); } static QString decodeButtonArgument(const QString& str) { return P2QSTRING(byteArrayToString(Base64::decode(Q2PSTRING(str)))); } QString QtWebKitChatView::buildChatWindowButton(const QString& name, const QString& id, const QString& arg1, const QString& arg2, const QString& arg3, const QString& arg4, const QString& arg5) { QRegExp regex("[A-Za-z][A-Za-z0-9\\-\\_]+"); Q_ASSERT(regex.exactMatch(id)); QString html = QString("<input id='%2' type='submit' value='%1' onclick='chatwindow.buttonClicked(\"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\");' />").arg(name).arg(id).arg(encodeButtonArgument(arg1)).arg(encodeButtonArgument(arg2)).arg(encodeButtonArgument(arg3)).arg(encodeButtonArgument(arg4)).arg(encodeButtonArgument(arg5)); return html; } void QtWebKitChatView::resizeEvent(QResizeEvent* event) { // This code ensures that if the user is scrolled all to the bottom of a chat view, // the view stays scrolled to the bottom if the view is resized or if the message // input widget becomes multi line. if (isAtBottom_) { scrollToBottom(); } QWidget::resizeEvent(event); @@ -951,49 +957,56 @@ void QtWebKitChatView::setAckState(std::string const& id, ChatWindow::AckState s QString xml; switch (state) { case ChatWindow::Pending: xml = "<img src='qrc:/icons/throbber.gif' title='" + tr("This message has not been received by your server yet.") + "'/>"; displayReceiptInfo(P2QSTRING(id), false); break; case ChatWindow::Received: xml = ""; displayReceiptInfo(P2QSTRING(id), true); break; case ChatWindow::Failed: xml = "<img src='qrc:/icons/error.png' title='" + tr("This message may not have been transmitted.") + "'/>"; break; } setAckXML(P2QSTRING(id), xml); } void QtWebKitChatView::setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) { QString xml; switch (state) { case ChatWindow::ReceiptReceived: xml = "<img src='qrc:/icons/delivery-success.svg' title='" + tr("The receipt for this message has been received.") + "'/>"; break; case ChatWindow::ReceiptRequested: xml = "<img src='qrc:/icons/delivery-warning.svg' title='" + tr("The receipt for this message has not yet been received. The recipient(s) might not have received this message.") + "'/>"; break; case ChatWindow::ReceiptFailed: xml = "<img src='qrc:/icons/delivery-failure.svg' title='" + tr("Failed to transmit message to the receipient(s).") + "'/>"; } setReceiptXML(P2QSTRING(id), xml); } -bool QtWebKitChatView::appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf) { +bool QtWebKitChatView::appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf, const std::shared_ptr<SecurityLabel>& label /*=nullptr*/) { bool result = previousMessageKind_ == messageKind && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_&& previousSenderName_ == P2QSTRING(senderName))); if (insertingLastLine_) { insertingLastLine_ = false; return false; } + if (settings_->getSetting(SettingConstants::MUC_MARKING_ELISION)) { + if (label && label->getDisplayMarking() != previousMessageDisplayMarking_) { + if (label->getDisplayMarking() != "") { + return false; + } + } + } return result; } ChatSnippet::Direction QtWebKitChatView::getActualDirection(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) { if (direction == ChatWindow::DefaultDirection) { return QCoreApplication::translate("QApplication", "QT_LAYOUT_DIRECTION") == "RTL" ? ChatSnippet::RTL : ChatSnippet::LTR; } else { return ChatSnippet::getDirection(message); } } } |