mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
refactoring, fixes
This commit is contained in:
parent
8a1ea18ed4
commit
2938702c1e
|
@ -18,14 +18,6 @@
|
||||||
#include "chatline.h"
|
#include "chatline.h"
|
||||||
#include "chatmessage.h"
|
#include "chatmessage.h"
|
||||||
#include "chatlinecontent.h"
|
#include "chatlinecontent.h"
|
||||||
#include "chatlinecontentproxy.h"
|
|
||||||
#include "content/text.h"
|
|
||||||
#include "content/image.h"
|
|
||||||
#include "content/filetransferwidget.h"
|
|
||||||
#include "content/spinner.h"
|
|
||||||
|
|
||||||
#include "../misc/style.h"
|
|
||||||
#include "../misc/settings.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
@ -35,9 +27,6 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
#define NAME_COL_WIDTH 75.0
|
|
||||||
#define TIME_COL_WIDTH 85.0
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T clamp(T x, T min, T max)
|
T clamp(T x, T min, T max)
|
||||||
{
|
{
|
||||||
|
@ -85,66 +74,49 @@ ChatLog::~ChatLog()
|
||||||
|
|
||||||
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert)
|
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert)
|
||||||
{
|
{
|
||||||
QString txt = msg;
|
ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self);
|
||||||
if(alert)
|
|
||||||
txt = "<div class=alert>" + txt + "</div>";
|
|
||||||
|
|
||||||
ChatMessage* line = new ChatMessage(scene, msg);
|
|
||||||
line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
line->addColumn(new Text(txt, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
|
||||||
line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
|
|
||||||
insertChatline(line);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert)
|
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert)
|
||||||
{
|
{
|
||||||
ChatMessage* line = addChatMessage(sender, msg, self, alert);
|
ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self, timestamp);
|
||||||
line->markAsSent(timestamp);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp)
|
ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp)
|
||||||
{
|
{
|
||||||
ChatMessage* line = addChatAction(sender, msg);
|
ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false, timestamp);
|
||||||
line->markAsSent(timestamp);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg)
|
ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg)
|
||||||
{
|
{
|
||||||
ChatMessage* line = new ChatMessage(scene, msg);
|
ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false);
|
||||||
line->addColumn(new Text(""), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
line->addColumn(new Text("<div class=action>*" + sender + " " + msg + "</div>", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
|
||||||
line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
line->setAsAction();
|
|
||||||
|
|
||||||
insertChatline(line);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp)
|
ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp)
|
||||||
{
|
{
|
||||||
ChatMessage* line = new ChatMessage(scene, msg);
|
ChatMessage* line = ChatMessage::createChatInfoMessage(scene, msg, "", timestamp);
|
||||||
line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
line->addColumn(new Text(msg, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
|
||||||
line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
|
|
||||||
insertChatline(line);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self)
|
ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self)
|
||||||
{
|
{
|
||||||
ChatMessage* line = new ChatMessage(scene, QString());
|
ChatMessage* line = ChatMessage::createFileTransferMessage(scene, sender, "", file, self, timestamp);
|
||||||
line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize));
|
|
||||||
line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
|
||||||
|
|
||||||
insertChatline(line);
|
insertChatline(line);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "chatmessage.h"
|
#include "chatmessage.h"
|
||||||
|
#include "chatlinecontentproxy.h"
|
||||||
#include "content/text.h"
|
#include "content/text.h"
|
||||||
#include "content/spinner.h"
|
#include "content/spinner.h"
|
||||||
|
#include "content/filetransferwidget.h"
|
||||||
|
#include "content/image.h"
|
||||||
|
|
||||||
#include "src/misc/settings.h"
|
#include "src/misc/settings.h"
|
||||||
|
#include "src/misc/smileypack.h"
|
||||||
|
#include "src/misc/style.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#define NAME_COL_WIDTH 75.0
|
||||||
|
#define TIME_COL_WIDTH 85.0
|
||||||
|
|
||||||
ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage)
|
ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage)
|
||||||
: ChatLine(scene)
|
: ChatLine(scene)
|
||||||
|
@ -29,6 +35,52 @@ ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& 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("<div class=action>%1 %2</div>").arg(sender, text);
|
||||||
|
msg->setAsAction();
|
||||||
|
}
|
||||||
|
else if(alert)
|
||||||
|
text = "<div class=alert>" + text + "</div>";
|
||||||
|
|
||||||
|
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)
|
void ChatMessage::markAsSent(const QDateTime &time)
|
||||||
{
|
{
|
||||||
// remove the spinner and replace it by $time
|
// remove the spinner and replace it by $time
|
||||||
|
@ -49,3 +101,64 @@ void ChatMessage::setAsAction()
|
||||||
{
|
{
|
||||||
action = true;
|
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("<a href=\"%1\">%1</a>").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<messageLines.size();++i)
|
||||||
|
{
|
||||||
|
if (QRegExp("^[ ]*>.*").exactMatch(messageLines[i]))
|
||||||
|
quotedText += "<span class=quote>" + messageLines[i] + "</span>";
|
||||||
|
else
|
||||||
|
quotedText += messageLines[i];
|
||||||
|
|
||||||
|
if (i < messageLines.size() - 1)
|
||||||
|
quotedText += "<br/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return quotedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChatMessage::toHtmlChars(const QString &str)
|
||||||
|
{
|
||||||
|
static QList<QPair<QString, QString>> replaceList = {{"&","&"}, {">",">"}, {"<","<"}};
|
||||||
|
QString res = str;
|
||||||
|
|
||||||
|
for (auto &it : replaceList)
|
||||||
|
res = res.replace(it.first,it.second);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#define CHATMESSAGE_H
|
#define CHATMESSAGE_H
|
||||||
|
|
||||||
#include "chatline.h"
|
#include "chatline.h"
|
||||||
|
#include "src/corestructs.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
class QGraphicsScene;
|
class QGraphicsScene;
|
||||||
|
|
||||||
|
@ -26,11 +28,20 @@ class ChatMessage : public ChatLine
|
||||||
public:
|
public:
|
||||||
ChatMessage(QGraphicsScene* scene, const QString& rawMessage);
|
ChatMessage(QGraphicsScene* scene, const QString& rawMessage);
|
||||||
|
|
||||||
|
static ChatMessage* createChatMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime());
|
||||||
|
static ChatMessage* createChatInfoMessage(QGraphicsScene* scene, const QString& rawMessage, const QString& type, const QDateTime& date);
|
||||||
|
static ChatMessage* createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date);
|
||||||
|
|
||||||
void markAsSent(const QDateTime& time);
|
void markAsSent(const QDateTime& time);
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
bool isAction() const;
|
bool isAction() const;
|
||||||
void setAsAction();
|
void setAsAction();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static QString detectAnchors(const QString& str);
|
||||||
|
static QString detectQuotes(const QString& str);
|
||||||
|
static QString toHtmlChars(const QString& str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChatLineContent* midColumn = nullptr;
|
ChatLineContent* midColumn = nullptr;
|
||||||
QString rawString;
|
QString rawString;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
|
||||||
#include "../customtextdocument.h"
|
#include "../customtextdocument.h"
|
||||||
#include "src/misc/smileypack.h"
|
|
||||||
|
|
||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@ -51,10 +50,7 @@ Text::~Text()
|
||||||
|
|
||||||
void Text::setText(const QString& txt)
|
void Text::setText(const QString& txt)
|
||||||
{
|
{
|
||||||
text = SmileyPack::getInstance().smileyfied(toHtmlChars(txt));
|
text = txt;
|
||||||
|
|
||||||
detectAnchors();
|
|
||||||
detectQuotes();
|
|
||||||
|
|
||||||
ensureIntegrity();
|
ensureIntegrity();
|
||||||
freeResources();
|
freeResources();
|
||||||
|
@ -259,60 +255,3 @@ int Text::cursorFromPos(QPointF scenePos) const
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::detectAnchors()
|
|
||||||
{
|
|
||||||
// detect urls
|
|
||||||
QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+");
|
|
||||||
int offset = 0;
|
|
||||||
while ((offset = exp.indexIn(text, 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("<a href=\"%1\">%1</a>").arg(url);
|
|
||||||
text.replace(offset, exp.cap().length(), htmledUrl);
|
|
||||||
|
|
||||||
offset += htmledUrl.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Text::detectQuotes()
|
|
||||||
{
|
|
||||||
// detect text quotes
|
|
||||||
QStringList messageLines = text.split("\n");
|
|
||||||
QString quotedText;
|
|
||||||
for (int i=0;i<messageLines.size();++i)
|
|
||||||
{
|
|
||||||
if (QRegExp("^[ ]*>.*").exactMatch(messageLines[i]))
|
|
||||||
quotedText += "<span class=quote>" + messageLines[i] + "</span>";
|
|
||||||
else
|
|
||||||
quotedText += messageLines[i];
|
|
||||||
|
|
||||||
if (i < messageLines.size() - 1)
|
|
||||||
quotedText += "<br/>";
|
|
||||||
}
|
|
||||||
|
|
||||||
text = quotedText;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Text::toHtmlChars(const QString &str)
|
|
||||||
{
|
|
||||||
static QList<QPair<QString, QString>> replaceList = {{"&","&"}, {">",">"}, {"<","<"}};
|
|
||||||
QString res = str;
|
|
||||||
|
|
||||||
for (auto &it : replaceList)
|
|
||||||
res = res.replace(it.first,it.second);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
|
@ -61,10 +61,6 @@ protected:
|
||||||
|
|
||||||
int cursorFromPos(QPointF scenePos) const;
|
int cursorFromPos(QPointF scenePos) const;
|
||||||
|
|
||||||
void detectAnchors();
|
|
||||||
void detectQuotes();
|
|
||||||
QString toHtmlChars(const QString& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CustomTextDocument* doc = nullptr;
|
CustomTextDocument* doc = nullptr;
|
||||||
QString text;
|
QString text;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user