2014-11-16 19:58:43 +08:00
|
|
|
|
/*
|
2015-06-06 09:40:08 +08:00
|
|
|
|
Copyright © 2014-2015 by The qTox Project
|
|
|
|
|
|
2014-11-16 19:58:43 +08:00
|
|
|
|
This file is part of qTox, a Qt-based graphical interface for Tox.
|
|
|
|
|
|
2015-06-06 09:40:08 +08:00
|
|
|
|
qTox is libre software: you can redistribute it and/or modify
|
2014-11-16 19:58:43 +08:00
|
|
|
|
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.
|
2015-06-06 09:40:08 +08:00
|
|
|
|
|
|
|
|
|
qTox is distributed in the hope that it will be useful,
|
2014-11-16 19:58:43 +08:00
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-06-06 09:40:08 +08:00
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
2014-11-16 19:58:43 +08:00
|
|
|
|
|
2015-06-06 09:40:08 +08:00
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
2014-11-16 19:58:43 +08:00
|
|
|
|
*/
|
|
|
|
|
|
2014-11-12 21:11:25 +08:00
|
|
|
|
#include "chatmessage.h"
|
2015-01-03 22:03:33 +08:00
|
|
|
|
#include "chatlinecontentproxy.h"
|
2014-11-12 23:45:24 +08:00
|
|
|
|
#include "content/text.h"
|
2015-01-25 21:34:36 +08:00
|
|
|
|
#include "content/timestamp.h"
|
2014-11-12 23:45:24 +08:00
|
|
|
|
#include "content/spinner.h"
|
2015-01-03 22:03:33 +08:00
|
|
|
|
#include "content/filetransferwidget.h"
|
|
|
|
|
#include "content/image.h"
|
2015-01-20 02:04:19 +08:00
|
|
|
|
#include "content/notificationicon.h"
|
2014-11-12 21:11:25 +08:00
|
|
|
|
|
2016-01-23 18:49:11 +08:00
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
2015-06-06 07:44:47 +08:00
|
|
|
|
#include "src/persistence/settings.h"
|
|
|
|
|
#include "src/persistence/smileypack.h"
|
2015-01-03 03:07:45 +08:00
|
|
|
|
|
2015-01-11 05:21:33 +08:00
|
|
|
|
#define NAME_COL_WIDTH 90.0
|
2015-01-05 21:06:14 +08:00
|
|
|
|
#define TIME_COL_WIDTH 90.0
|
2014-11-12 23:45:24 +08:00
|
|
|
|
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::ChatMessage()
|
2014-11-12 23:45:24 +08:00
|
|
|
|
{
|
2014-11-16 19:58:43 +08:00
|
|
|
|
|
2014-11-12 23:45:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-02-15 17:51:54 +08:00
|
|
|
|
ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QString &rawMessage, MessageType type, bool isMe, const QDateTime &date)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-02-16 22:22:29 +08:00
|
|
|
|
QString text = rawMessage.toHtmlEscaped();
|
2015-02-15 17:51:54 +08:00
|
|
|
|
QString senderText = sender;
|
|
|
|
|
|
|
|
|
|
const QColor actionColor = QColor("#1818FF"); // has to match the color in innerStyle.css (div.action)
|
2015-01-04 02:05:38 +08:00
|
|
|
|
|
2015-01-11 05:21:33 +08:00
|
|
|
|
//smileys
|
2015-03-21 02:38:10 +08:00
|
|
|
|
if (Settings::getInstance().getUseEmoticons())
|
2015-01-04 02:05:38 +08:00
|
|
|
|
text = SmileyPack::getInstance().smileyfied(text);
|
|
|
|
|
|
2015-05-24 21:21:15 +08:00
|
|
|
|
//quotes (green text)
|
|
|
|
|
text = detectQuotes(detectAnchors(text), type);
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2016-01-21 18:50:51 +08:00
|
|
|
|
//markdown
|
2016-04-14 04:26:50 +08:00
|
|
|
|
if (Settings::getInstance().getMarkdownPreference() != NONE)
|
2016-01-23 16:06:17 +08:00
|
|
|
|
text = detectMarkdown(text);
|
2016-01-21 18:50:51 +08:00
|
|
|
|
|
2015-02-15 17:51:54 +08:00
|
|
|
|
switch(type)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2015-02-15 17:51:54 +08:00
|
|
|
|
case ACTION:
|
|
|
|
|
senderText = "*";
|
2015-10-02 06:06:06 +08:00
|
|
|
|
text = wrapDiv(QString("%1 %2").arg(sender.toHtmlEscaped(), text), "action");
|
2015-01-03 22:03:33 +08:00
|
|
|
|
msg->setAsAction();
|
2015-02-15 17:51:54 +08:00
|
|
|
|
break;
|
|
|
|
|
case ALERT:
|
|
|
|
|
text = wrapDiv(text, "alert");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
text = wrapDiv(text, "msg");
|
2015-01-04 02:06:10 +08:00
|
|
|
|
}
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-02-15 17:51:54 +08:00
|
|
|
|
// Note: Eliding cannot be enabled for RichText items. (QTBUG-17207)
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
QFont authorFont = baseFont;
|
|
|
|
|
if (isMe)
|
|
|
|
|
authorFont.setBold(true);
|
|
|
|
|
|
|
|
|
|
msg->addColumn(new Text(senderText, authorFont, true, sender, type == ACTION ? actionColor : Qt::black), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
|
|
|
msg->addColumn(new Text(text, baseFont, false, ((type == ACTION) && isMe) ? QString("%1 %2").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
2015-02-06 19:21:13 +08:00
|
|
|
|
msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 360.0/1.6), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-03-21 02:38:10 +08:00
|
|
|
|
if (!date.isNull())
|
2015-01-03 22:03:33 +08:00
|
|
|
|
msg->markAsSent(date);
|
|
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, SystemMessageType type, const QDateTime &date)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
2015-02-16 22:22:29 +08:00
|
|
|
|
QString text = rawMessage.toHtmlEscaped();
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-01-06 21:30:24 +08:00
|
|
|
|
QString img;
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
2015-01-26 18:09:21 +08:00
|
|
|
|
case INFO: img = ":/ui/chatArea/info.svg"; break;
|
|
|
|
|
case ERROR: img = ":/ui/chatArea/error.svg"; break;
|
|
|
|
|
case TYPING: img = ":/ui/chatArea/typing.svg"; break;
|
2015-01-06 21:30:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
|
2015-01-27 18:20:35 +08:00
|
|
|
|
msg->addColumn(new Image(QSize(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2016-06-29 05:59:21 +08:00
|
|
|
|
msg->addColumn(new Text("<b>" + text + "</b>", baseFont, false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left));
|
|
|
|
|
msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), baseFont), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
QFont authorFont = baseFont;
|
|
|
|
|
if (isMe)
|
|
|
|
|
authorFont.setBold(true);
|
|
|
|
|
|
|
|
|
|
msg->addColumn(new Text(sender, authorFont, true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2015-02-16 00:21:00 +08:00
|
|
|
|
msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 320, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
2016-06-29 05:59:21 +08:00
|
|
|
|
msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), baseFont), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-18 19:20:13 +08:00
|
|
|
|
ChatMessage::Ptr ChatMessage::createTypingNotification()
|
|
|
|
|
{
|
|
|
|
|
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
|
|
|
|
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
|
2015-01-25 21:06:06 +08:00
|
|
|
|
// Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping()
|
2015-05-24 21:21:15 +08:00
|
|
|
|
//
|
|
|
|
|
// FIXME: Due to circumstances, placeholder is being used in a case where
|
|
|
|
|
// user received typing notifications constantly since contact came online.
|
|
|
|
|
// This causes "[user]..." to be displayed in place of user nick, as long
|
|
|
|
|
// as user will keep typing. Issue #1280
|
2015-02-02 18:01:01 +08:00
|
|
|
|
msg->addColumn(new NotificationIcon(QSize(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
2016-06-29 05:59:21 +08:00
|
|
|
|
msg->addColumn(new Text("[user]...", baseFont, false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left));
|
2015-01-25 21:06:06 +08:00
|
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ChatMessage::Ptr ChatMessage::createBusyNotification()
|
|
|
|
|
{
|
|
|
|
|
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
baseFont.setPixelSize(baseFont.pixelSize() + 2);
|
|
|
|
|
baseFont.setBold(true);
|
2015-01-25 21:06:06 +08:00
|
|
|
|
|
2016-06-29 05:59:21 +08:00
|
|
|
|
msg->addColumn(new Text(QObject::tr("Resizing"), baseFont, false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center));
|
2015-01-18 19:20:13 +08:00
|
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-12 23:45:24 +08:00
|
|
|
|
void ChatMessage::markAsSent(const QDateTime &time)
|
2014-11-12 21:11:25 +08:00
|
|
|
|
{
|
2016-06-29 05:59:21 +08:00
|
|
|
|
QFont baseFont = Settings::getInstance().getChatMessageFont();
|
|
|
|
|
|
2014-11-12 23:45:24 +08:00
|
|
|
|
// remove the spinner and replace it by $time
|
2016-06-29 05:59:21 +08:00
|
|
|
|
replaceContent(2, new Timestamp(time, Settings::getInstance().getTimestampFormat(), baseFont));
|
2014-11-12 21:11:25 +08:00
|
|
|
|
}
|
2014-11-14 01:27:32 +08:00
|
|
|
|
|
|
|
|
|
QString ChatMessage::toString() const
|
|
|
|
|
{
|
2015-01-05 01:21:35 +08:00
|
|
|
|
ChatLineContent* c = getContent(1);
|
2015-03-21 02:38:10 +08:00
|
|
|
|
if (c)
|
2015-01-05 01:21:35 +08:00
|
|
|
|
return c->getText();
|
|
|
|
|
|
|
|
|
|
return QString();
|
2014-11-14 01:27:32 +08:00
|
|
|
|
}
|
2014-12-14 04:11:03 +08:00
|
|
|
|
|
|
|
|
|
bool ChatMessage::isAction() const
|
|
|
|
|
{
|
|
|
|
|
return action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ChatMessage::setAsAction()
|
|
|
|
|
{
|
|
|
|
|
action = true;
|
|
|
|
|
}
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-01-05 01:21:35 +08:00
|
|
|
|
void ChatMessage::hideSender()
|
|
|
|
|
{
|
|
|
|
|
ChatLineContent* c = getContent(0);
|
2015-03-21 02:38:10 +08:00
|
|
|
|
if (c)
|
2015-01-05 01:21:35 +08:00
|
|
|
|
c->hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ChatMessage::hideDate()
|
|
|
|
|
{
|
|
|
|
|
ChatLineContent* c = getContent(2);
|
2015-03-21 02:38:10 +08:00
|
|
|
|
if (c)
|
2015-01-05 01:21:35 +08:00
|
|
|
|
c->hide();
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-21 18:50:51 +08:00
|
|
|
|
QString ChatMessage::detectMarkdown(const QString &str)
|
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
QString out = str;
|
2016-01-21 18:50:51 +08:00
|
|
|
|
|
|
|
|
|
// Create regex for certain markdown syntax
|
2016-01-23 16:06:17 +08:00
|
|
|
|
QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text**
|
2016-01-30 07:17:41 +08:00
|
|
|
|
"|(\\*)([^\\*]{2,})(\\*)" // Italics *text*
|
2016-01-23 16:06:17 +08:00
|
|
|
|
"|(\\_)([^\\_]{2,})(\\_)" // Italics _text_
|
2016-01-30 07:17:41 +08:00
|
|
|
|
"|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Bold __text__
|
2016-01-23 16:06:17 +08:00
|
|
|
|
"|(\\-)([^\\-]{2,})(\\-)" // Underline -text-
|
|
|
|
|
"|(\\~)([^\\~]{2,})(\\~)" // Strike ~text~
|
|
|
|
|
"|(\\~~)([^\\~\\~]{2,})(\\~~)" // Strike ~~text~~
|
2016-03-13 17:54:09 +08:00
|
|
|
|
"|(\\`)([^\\`]{2,})(\\`)" // Codeblock `text`
|
2016-01-21 18:50:51 +08:00
|
|
|
|
);
|
|
|
|
|
|
2016-03-24 06:55:58 +08:00
|
|
|
|
int offset = 0;
|
|
|
|
|
while ((offset = exp.indexIn(out, offset)) != -1)
|
2016-01-21 18:50:51 +08:00
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
QString snipCheck = out.mid(offset-1,exp.cap(0).length()+2);
|
|
|
|
|
QString snippet = exp.cap(0).trimmed();
|
|
|
|
|
QString htmledSnippet;
|
|
|
|
|
|
|
|
|
|
// Only parse if surrounded by spaces, newline(s) and/or beginning/end of line
|
2016-05-10 04:07:21 +08:00
|
|
|
|
if ((snipCheck.startsWith(' ') || snipCheck.startsWith('>') || offset == 0)
|
|
|
|
|
&& ((snipCheck.endsWith(' ') || snipCheck.endsWith('<')) || offset + snippet.length() == out.length()))
|
2016-01-21 18:50:51 +08:00
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
int mul = 0; // Determines how many characters to strip from markdown text
|
|
|
|
|
// Set mul depending on markdownPreference
|
2016-04-14 04:26:50 +08:00
|
|
|
|
if (Settings::getInstance().getMarkdownPreference() == WITHOUT_CHARS)
|
2016-03-24 06:55:58 +08:00
|
|
|
|
mul = 2;
|
|
|
|
|
|
|
|
|
|
// Match captured string to corresponding md format
|
|
|
|
|
if (exp.cap(1) == "**") // Bold **text**
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<b>%1</b>").arg(snippet.mid(mul,snippet.length()-2*mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text*
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<i>%1</i>").arg(snippet.mid(mul/2,snippet.length()-mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<i>%1</i>").arg(snippet.mid(mul/2,snippet.length()-mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(10) == "__"&& snippet.length() > 4) // Bold __text__
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<b>%1</b>").arg(snippet.mid(mul,snippet.length()-2*mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text-
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<u>%1</u>").arg(snippet.mid(mul/2,snippet.length()-mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<s>%1</s>").arg(snippet.mid(mul/2,snippet.length()-mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(19) == "~~" && snippet.length() > 4) // Strikethrough ~~text~~
|
2016-06-25 16:55:32 +08:00
|
|
|
|
htmledSnippet = QString("<s>%1</s>").arg(snippet.mid(mul,snippet.length()-2*mul));
|
2016-03-24 06:55:58 +08:00
|
|
|
|
else if (exp.cap(22) == "`" && snippet.length() > 2) // Codeblock `text`
|
|
|
|
|
htmledSnippet = QString("<font color=#595959><code>%1</code></font>").arg(snippet.mid(mul/2,snippet.length()-mul));
|
|
|
|
|
else
|
|
|
|
|
htmledSnippet = snippet;
|
|
|
|
|
out.replace(offset, exp.cap().length(), htmledSnippet);
|
|
|
|
|
offset += htmledSnippet.length();
|
|
|
|
|
} else
|
|
|
|
|
offset += snippet.length();
|
2016-01-21 18:50:51 +08:00
|
|
|
|
}
|
2016-03-24 06:55:58 +08:00
|
|
|
|
|
|
|
|
|
return out;
|
2016-01-21 18:50:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-03 22:03:33 +08:00
|
|
|
|
QString ChatMessage::detectAnchors(const QString &str)
|
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
QString out = str;
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
2015-08-30 06:28:21 +08:00
|
|
|
|
// detect URIs
|
|
|
|
|
QRegExp exp("("
|
2015-09-17 17:24:19 +08:00
|
|
|
|
"(?:\\b)((www\\.)|(http[s]?|ftp)://)" // (protocol)://(printable - non-special character)
|
2015-08-30 06:28:21 +08:00
|
|
|
|
// http://ONEORMOREALHPA-DIGIT
|
|
|
|
|
"\\w+\\S+)" // any other character, lets domains and other
|
2016-04-14 12:36:07 +08:00
|
|
|
|
// ↓ link to a file, or samba share
|
|
|
|
|
// https://en.wikipedia.org/wiki/File_URI_scheme
|
|
|
|
|
"|(?:\\b)((file|smb)://)([\\S| ]*)"
|
2016-04-03 20:28:21 +08:00
|
|
|
|
"|(?:\\b)(tox:[a-zA-Z\\d]{76})" //link with full user address
|
2015-09-29 20:33:26 +08:00
|
|
|
|
"|(?:\\b)(mailto:\\S+@\\S+\\.\\S+)" //@mail link
|
2015-09-17 17:24:19 +08:00
|
|
|
|
"|(?:\\b)(tox:\\S+@\\S+)"); // starts with `tox` then : and only alpha-digits till the end
|
2015-08-30 06:28:21 +08:00
|
|
|
|
// also accepts tox:agilob@net as simplified TOX ID
|
2016-03-24 06:55:58 +08:00
|
|
|
|
|
|
|
|
|
int offset = 0;
|
|
|
|
|
while ((offset = exp.indexIn(out, offset)) != -1)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
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:\"")
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2016-03-24 06:55:58 +08:00
|
|
|
|
offset += url.length();
|
|
|
|
|
continue;
|
2015-01-03 22:03:33 +08:00
|
|
|
|
}
|
2016-03-24 06:55:58 +08:00
|
|
|
|
QString htmledUrl;
|
|
|
|
|
// add scheme if not specified
|
|
|
|
|
if (exp.cap(2) == "www.")
|
|
|
|
|
htmledUrl = QString("<a href=\"http://%1\">%1</a>").arg(url);
|
|
|
|
|
else
|
|
|
|
|
htmledUrl = QString("<a href=\"%1\">%1</a>").arg(url);
|
|
|
|
|
out.replace(offset, exp.cap().length(), htmledUrl);
|
|
|
|
|
offset += htmledUrl.length();
|
2015-01-03 22:03:33 +08:00
|
|
|
|
}
|
2016-03-24 06:55:58 +08:00
|
|
|
|
|
|
|
|
|
return out;
|
2015-01-03 22:03:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-24 21:21:15 +08:00
|
|
|
|
QString ChatMessage::detectQuotes(const QString& str, MessageType type)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
|
|
|
|
// detect text quotes
|
|
|
|
|
QStringList messageLines = str.split("\n");
|
|
|
|
|
QString quotedText;
|
2015-05-24 21:21:15 +08:00
|
|
|
|
for (int i = 0; i < messageLines.size(); ++i)
|
2015-01-03 22:03:33 +08:00
|
|
|
|
{
|
2015-05-24 21:21:15 +08:00
|
|
|
|
// don't quote first line in action message. This makes co-existence of
|
|
|
|
|
// quotes and action messages possible, since only first line can cause
|
|
|
|
|
// problems in case where there is quote in it used.
|
2015-05-26 03:52:51 +08:00
|
|
|
|
if (QRegExp("^(>|>).*").exactMatch(messageLines[i])) {
|
2015-05-24 23:16:30 +08:00
|
|
|
|
if (i > 0 || type != ACTION)
|
2015-05-24 21:21:15 +08:00
|
|
|
|
quotedText += "<span class=quote>" + messageLines[i] + "</span>";
|
2015-05-24 23:16:30 +08:00
|
|
|
|
else
|
2015-05-24 21:21:15 +08:00
|
|
|
|
quotedText += messageLines[i];
|
|
|
|
|
} else {
|
2015-01-03 22:03:33 +08:00
|
|
|
|
quotedText += messageLines[i];
|
2015-05-24 21:21:15 +08:00
|
|
|
|
}
|
2015-01-03 22:03:33 +08:00
|
|
|
|
|
|
|
|
|
if (i < messageLines.size() - 1)
|
|
|
|
|
quotedText += "<br/>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return quotedText;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-15 17:51:54 +08:00
|
|
|
|
QString ChatMessage::wrapDiv(const QString &str, const QString &div)
|
|
|
|
|
{
|
2016-03-09 04:19:47 +08:00
|
|
|
|
return QString("<p class=%1>%2</p>").arg(div, /*QChar(0x200E) + */QString(str));
|
2015-02-15 17:51:54 +08:00
|
|
|
|
}
|