chat_moc.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * chat_moc.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "chat_moc.h"
  12. #include "ui_chat_moc.h"
  13. Chat::Chat(QWidget *parent) :
  14. QWidget(parent),
  15. ui(new Ui::Chat)
  16. {
  17. ui->setupUi(this);
  18. namesCompleter.setModel(ui->listUsers->model());
  19. namesCompleter.setCompletionMode(QCompleter::InlineCompletion);
  20. ui->messageEdit->setCompleter(&namesCompleter);
  21. for([[maybe_unused]] auto i : {GLOBAL, ROOM})
  22. chatDocuments.push_back(new QTextDocument(this));
  23. setChatId(GLOBAL);
  24. }
  25. Chat::~Chat()
  26. {
  27. delete ui;
  28. }
  29. void Chat::setUsername(const QString & user)
  30. {
  31. username = user;
  32. }
  33. void Chat::setSession(const QString & s)
  34. {
  35. session = s;
  36. on_chatSwitch_clicked();
  37. }
  38. void Chat::setChannel(const QString & channel)
  39. {
  40. static const QMap<QString, ChatId> chatNames{{"global", GLOBAL}, {"room", ROOM}};
  41. setChatId(chatNames.value(channel));
  42. }
  43. void Chat::addUser(const QString & user)
  44. {
  45. ui->listUsers->addItem(new QListWidgetItem("@" + user));
  46. }
  47. void Chat::clearUsers()
  48. {
  49. ui->listUsers->clear();
  50. }
  51. void Chat::chatMessage(const QString & title, const QString & channel, QString body, bool isSystem)
  52. {
  53. const QTextCharFormat regularFormat;
  54. const QString boldHtml = "<b>%1</b>";
  55. const QString colorHtml = "<font color=\"%1\">%2</font>";
  56. bool meMentioned = false;
  57. bool isScrollBarBottom = (ui->chat->verticalScrollBar()->maximum() - ui->chat->verticalScrollBar()->value() < 24);
  58. static const QMap<QString, ChatId> chatNames{{"global", GLOBAL}, {"room", ROOM}};
  59. QTextDocument * doc = ui->chat->document();
  60. if(chatNames.contains(channel))
  61. doc = chatDocuments[chatNames.value(channel)];
  62. QTextCursor curs(doc);
  63. curs.movePosition(QTextCursor::End);
  64. QString titleColor = "Olive";
  65. if(isSystem || title == "System")
  66. titleColor = "ForestGreen";
  67. if(title == username)
  68. titleColor = "Gold";
  69. curs.insertHtml(boldHtml.arg(colorHtml.arg(titleColor, title + ": ")));
  70. QRegularExpression mentionRe("@[\\w\\d]+");
  71. auto subBody = body;
  72. int mem = 0;
  73. for(auto match = mentionRe.match(subBody); match.hasMatch(); match = mentionRe.match(subBody))
  74. {
  75. body.insert(mem + match.capturedEnd(), QChar(-1));
  76. body.insert(mem + match.capturedStart(), QChar(-1));
  77. mem += match.capturedEnd() + 2;
  78. subBody = body.right(body.size() - mem);
  79. }
  80. auto pieces = body.split(QChar(-1));
  81. for(auto & block : pieces)
  82. {
  83. if(block.startsWith("@"))
  84. {
  85. if(block == "@" + username)
  86. {
  87. meMentioned = true;
  88. curs.insertHtml(boldHtml.arg(colorHtml.arg("IndianRed", block)));
  89. }
  90. else
  91. curs.insertHtml(colorHtml.arg("DeepSkyBlue", block));
  92. }
  93. else
  94. {
  95. if(isSystem)
  96. curs.insertHtml(colorHtml.arg("ForestGreen", block));
  97. else
  98. curs.insertText(block, regularFormat);
  99. }
  100. }
  101. curs.insertText("\n", regularFormat);
  102. if(doc == ui->chat->document() && (meMentioned || isScrollBarBottom))
  103. {
  104. ui->chat->ensureCursorVisible();
  105. ui->chat->verticalScrollBar()->setValue(ui->chat->verticalScrollBar()->maximum());
  106. }
  107. }
  108. void Chat::chatMessage(const QString & title, QString body, bool isSystem)
  109. {
  110. chatMessage(title, "", body, isSystem);
  111. }
  112. void Chat::sysMessage(QString body)
  113. {
  114. chatMessage("System", body, true);
  115. }
  116. void Chat::sendMessage()
  117. {
  118. QString msg(ui->messageEdit->text());
  119. ui->messageEdit->clear();
  120. emit messageSent(msg);
  121. }
  122. void Chat::on_messageEdit_returnPressed()
  123. {
  124. sendMessage();
  125. }
  126. void Chat::on_sendButton_clicked()
  127. {
  128. sendMessage();
  129. }
  130. void Chat::on_chatSwitch_clicked()
  131. {
  132. static const QMap<ChatId, QString> chatNames{{GLOBAL, "global"}, {ROOM, "room"}};
  133. if(chatId == GLOBAL && !session.isEmpty())
  134. emit channelSwitch(chatNames[ROOM]);
  135. else
  136. emit channelSwitch(chatNames[GLOBAL]);
  137. }
  138. void Chat::setChatId(ChatId _chatId)
  139. {
  140. static const QMap<ChatId, QString> chatNames{{GLOBAL, "Global"}, {ROOM, "Room"}};
  141. chatId = _chatId;
  142. ui->chatSwitch->setText(chatNames[chatId] + " chat");
  143. ui->chat->setDocument(chatDocuments[chatId]);
  144. }