/* Copyright (C) 2014 by Project Tox This file is part of qTox, a Qt-based graphical interface for Tox. This program is libre software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the COPYING file for more details. */ #include "chatmessage.h" #include "chatlinecontentproxy.h" #include "content/text.h" #include "content/spinner.h" #include "content/filetransferwidget.h" #include "content/image.h" #include "src/misc/settings.h" #include "src/misc/smileypack.h" #include "src/misc/style.h" #define NAME_COL_WIDTH 75.0 #define TIME_COL_WIDTH 85.0 ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) : ChatLine(scene) , rawString(rawMessage) { } ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) { ChatMessage* msg = new ChatMessage(scene, rawMessage); QString text = detectQuotes(detectAnchors(SmileyPack::getInstance().smileyfied(toHtmlChars(rawMessage)))); if(isAction) { text = QString("
%1 %2
").arg(sender, text); msg->setAsAction(); } else if(alert) text = "
" + text + "
"; msg->addColumn(new Text(isAction ? "*" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); return msg; } ChatMessage *ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const QString &rawMessage, const QString &type, const QDateTime &date) { ChatMessage* msg = new ChatMessage(scene, rawMessage); msg->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; } ChatMessage *ChatMessage::createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date) { ChatMessage* msg = new ChatMessage(scene, rawMessage); msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; } void ChatMessage::markAsSent(const QDateTime &time) { // remove the spinner and replace it by $time replaceContent(2, new Text(time.toString(Settings::getInstance().getTimestampFormat()))); } QString ChatMessage::toString() const { return rawString; } bool ChatMessage::isAction() const { return action; } void ChatMessage::setAsAction() { action = true; } QString ChatMessage::detectAnchors(const QString &str) { QString out = str; // detect urls QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+"); int offset = 0; while ((offset = exp.indexIn(out, offset)) != -1) { QString url = exp.cap(); // If there's a trailing " it's a HTML attribute, e.g. a smiley img's title=":tox:" if (url == "tox:\"") { offset += url.length(); continue; } // add scheme if not specified if (exp.cap(1) == "www.") url.prepend("http://"); QString htmledUrl = QString("%1").arg(url); out.replace(offset, exp.cap().length(), htmledUrl); offset += htmledUrl.length(); } return out; } QString ChatMessage::detectQuotes(const QString& str) { // detect text quotes QStringList messageLines = str.split("\n"); QString quotedText; for (int i=0;i"; else quotedText += messageLines[i]; if (i < messageLines.size() - 1) quotedText += "
"; } return quotedText; } QString ChatMessage::toHtmlChars(const QString &str) { static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; QString res = str; for (auto &it : replaceList) res = res.replace(it.first,it.second); return res; }