#include "chat_moc.h"
#include "ui_chat_moc.h"
Chat::Chat(QWidget *parent) :
QWidget(parent),
ui(new Ui::Chat)
{
ui->setupUi(this);
namesCompleter.setModel(ui->listUsers->model());
namesCompleter.setCompletionMode(QCompleter::InlineCompletion);
ui->messageEdit->setCompleter(&namesCompleter);
for(auto i : {GLOBAL, ROOM})
chatDocuments.push_back(new QTextDocument(this));
ui->chat->setDocument(chatDocuments[GLOBAL]);
}
Chat::~Chat()
{
delete ui;
}
void Chat::setUsername(const QString & user)
{
username = user;
}
void Chat::setSession(const QString & s)
{
session = s;
if(session.isEmpty())
setChatId(GLOBAL);
else
setChatId(ROOM);
}
void Chat::addUser(const QString & user)
{
ui->listUsers->addItem(new QListWidgetItem("@" + user));
}
void Chat::clearUsers()
{
ui->listUsers->clear();
}
void Chat::chatMessage(const QString & title, QString body, bool isSystem)
{
const QTextCharFormat regularFormat;
const QString boldHtml = "%1";
const QString colorHtml = "%2";
bool meMentioned = false;
bool isScrollBarBottom = (ui->chat->verticalScrollBar()->maximum() - ui->chat->verticalScrollBar()->value() < 24);
QTextCursor curs(ui->chat->document());
curs.movePosition(QTextCursor::End);
QString titleColor = "Olive";
if(isSystem || title == "System")
titleColor = "ForestGreen";
if(title == username)
titleColor = "Gold";
curs.insertHtml(boldHtml.arg(colorHtml.arg(titleColor, title + ": ")));
QRegularExpression mentionRe("@[\\w\\d]+");
auto subBody = body;
int mem = 0;
for(auto match = mentionRe.match(subBody); match.hasMatch(); match = mentionRe.match(subBody))
{
body.insert(mem + match.capturedEnd(), QChar(-1));
body.insert(mem + match.capturedStart(), QChar(-1));
mem += match.capturedEnd() + 2;
subBody = body.right(body.size() - mem);
}
auto pieces = body.split(QChar(-1));
for(auto & block : pieces)
{
if(block.startsWith("@"))
{
if(block == "@" + username)
{
meMentioned = true;
curs.insertHtml(boldHtml.arg(colorHtml.arg("IndianRed", block)));
}
else
curs.insertHtml(colorHtml.arg("DeepSkyBlue", block));
}
else
{
if(isSystem)
curs.insertHtml(colorHtml.arg("ForestGreen", block));
else
curs.insertText(block, regularFormat);
}
}
curs.insertText("\n", regularFormat);
if(meMentioned || isScrollBarBottom)
{
ui->chat->ensureCursorVisible();
ui->chat->verticalScrollBar()->setValue(ui->chat->verticalScrollBar()->maximum());
}
}
void Chat::sysMessage(QString body)
{
chatMessage("System", body, true);
}
void Chat::on_messageEdit_returnPressed()
{
emit messageSent(ui->messageEdit->text());
ui->messageEdit->clear();
}
void Chat::on_sendButton_clicked()
{
emit messageSent(ui->messageEdit->text());
ui->messageEdit->clear();
}
void Chat::on_chatSwitch_clicked()
{
if(chatId == GLOBAL && !session.isEmpty())
setChatId(ROOM);
else
setChatId(GLOBAL);
}
void Chat::setChatId(ChatId _chatId)
{
static const QMap chatNames{{GLOBAL, "Global"}, {ROOM, "Room"}};
chatId = _chatId;
ui->chatSwitch->setText(chatNames[chatId] + " chat");
ui->chat->setDocument(chatDocuments[chatId]);
}