diff --git a/cockatrice/src/chatview.cpp b/cockatrice/src/chatview.cpp
index 4863b2c1..87548832 100644
--- a/cockatrice/src/chatview.cpp
+++ b/cockatrice/src/chatview.cpp
@@ -53,14 +53,15 @@ QTextCursor ChatView::prepareBlock(bool same)
QTextCursor cursor(document()->lastBlock());
cursor.movePosition(QTextCursor::End);
- if (!same) {
+ if (same) {
+ cursor.insertHtml("
");
+ } else {
QTextBlockFormat blockFormat;
if ((evenNumber = !evenNumber))
blockFormat.setBackground(palette().alternateBase());
blockFormat.setBottomMargin(4);
cursor.insertBlock(blockFormat);
- } else
- cursor.insertHtml("
");
+ }
return cursor;
}
@@ -120,6 +121,7 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
QTextCursor cursor = prepareBlock(sameSender);
lastSender = sender;
+ // timestamp
if (showTimestamps && !sameSender) {
QTextCharFormat timeFormat;
timeFormat.setForeground(QColor(SERVER_MESSAGE_COLOR));
@@ -128,7 +130,8 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
cursor.setCharFormat(timeFormat);
cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm:ss] "));
}
-
+
+ // nickname
QTextCharFormat senderFormat;
if (tabSupervisor && tabSupervisor->getUserInfo() && (sender == QString::fromStdString(tabSupervisor->getUserInfo()->name()))) {
senderFormat.setForeground(QBrush(getCustomMentionColor()));
@@ -140,7 +143,9 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
}
senderFormat.setAnchor(true);
senderFormat.setAnchorHref("user://" + QString::number(userLevel) + "_" + sender);
- if (!sameSender) {
+ if (sameSender) {
+ cursor.insertText(" ");
+ } else {
if (!sender.isEmpty() && tabSupervisor->getUserListsTab()) {
const int pixelSize = QFontInfo(cursor.charFormat().font()).pixelSize();
QMap buddyList = tabSupervisor->getUserListsTab()->getBuddyList()->getUsers();
@@ -151,288 +156,38 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
if (!sender.isEmpty())
sender.append(": ");
cursor.insertText(sender);
- } else
- cursor.insertText(" ");
-
+ }
+
QTextCharFormat messageFormat;
if (sender.isEmpty()) {
messageFormat.setForeground(Qt::darkGreen);
messageFormat.setFontWeight(QFont::Bold);
}
cursor.setCharFormat(messageFormat);
-
- int index = -1, bracketFirstIndex = -1, mentionFirstIndex = -1, urlFirstIndex = -1, highlightWordFirstIndex = -1;
+
bool mentionEnabled = settingsCache->getChatMention();
- const QRegExp urlStarter = QRegExp("https?://|\\bwww\\.");
- const QRegExp phraseEnder = QRegExp("\\s");
- const QRegExp notALetterOrNumber = QRegExp("[^a-zA-Z0-9]");
- const QStringList highlightedWords = settingsCache->getHighlightWords();
-
+ // parse the message
while (message.size())
{
- bracketFirstIndex = message.indexOf('[');
- mentionFirstIndex = message.indexOf('@');
- urlFirstIndex = message.indexOf(urlStarter);
- highlightWordFirstIndex = -1;
-
- foreach (QString word, message.simplified().split(" "))
+ QChar c = message.at(0);
+ switch(c.toLatin1())
{
- if (highlightedWords.contains(word, Qt::CaseInsensitive))
- {
- highlightWordFirstIndex = message.indexOf(word);
+ case '[':
+ checkTag(cursor, message);
break;
- }
- }
-
- bool startsWithBracket = (bracketFirstIndex != -1);
- bool startsWithAtSymbol = (mentionFirstIndex != -1);
- bool startsWithUrl = (urlFirstIndex != -1);
- bool startsWithHighlightWord = (highlightWordFirstIndex != -1);
-
-
- if (!startsWithBracket && !startsWithAtSymbol && !startsWithUrl && !startsWithHighlightWord)
- {
- // No functions need to be run. Send message as normal
- cursor.insertText(message);
- break;
- }
- else if (startsWithBracket && !startsWithAtSymbol && !startsWithUrl && !startsWithHighlightWord)
- {
- // Contains a bracket
- index = bracketFirstIndex;
- }
- else if (!startsWithBracket && startsWithAtSymbol && !startsWithUrl && !startsWithHighlightWord)
- {
- // Contains an @ symbol
- index = mentionFirstIndex;
- }
- else if (!startsWithBracket && !startsWithAtSymbol && startsWithUrl && !startsWithHighlightWord)
- {
- // Contains URL stuff (http or www.)
- index = urlFirstIndex;
- }
- else if (!startsWithBracket && !startsWithAtSymbol && !startsWithUrl && startsWithHighlightWord)
- {
- // Contains a word the user wants highlighted
- index = highlightWordFirstIndex;
- }
- else if (startsWithBracket && startsWithAtSymbol && !startsWithUrl && !startsWithHighlightWord)
- {
- // Contains both a bracket and an @ symbol
- index = std::min(bracketFirstIndex, mentionFirstIndex);
- }
- else if (startsWithBracket && !startsWithAtSymbol && startsWithUrl && !startsWithHighlightWord)
- {
- // Contains both a bracket and URL stuff
- index = std::min(bracketFirstIndex, urlFirstIndex);
- }
- else if (startsWithBracket && !startsWithAtSymbol && !startsWithUrl && startsWithHighlightWord)
- {
- // Contains both a bracket and a word the user wants highlighted
- index = std::min(bracketFirstIndex, highlightWordFirstIndex);
- }
- else if (!startsWithBracket && startsWithAtSymbol && startsWithUrl && !startsWithHighlightWord)
- {
- // Contains both an @ symbol and URL stuff
- index = std::min(mentionFirstIndex, urlFirstIndex);
- }
- else if (!startsWithBracket && startsWithAtSymbol && !startsWithUrl && startsWithHighlightWord)
- {
- // Contains both an @ symbol and a word the user wants highlighted
- index = std::min(mentionFirstIndex, highlightWordFirstIndex);
- }
- else if (!startsWithBracket && !startsWithAtSymbol && startsWithUrl && startsWithHighlightWord)
- {
- // Contains both URL stuff and a word the user wants highlighted
- index = std::min(urlFirstIndex, highlightWordFirstIndex);
- }
- else if (!startsWithBracket && startsWithAtSymbol && startsWithUrl && startsWithHighlightWord)
- {
- // Contains an @ symbol, URL stuff, and a word the user wants highlighted
- index = std::min(mentionFirstIndex, std::min(urlFirstIndex, highlightWordFirstIndex));
- }
- else if (startsWithBracket && !startsWithAtSymbol && startsWithUrl && startsWithHighlightWord)
- {
- // Contains a bracket, URL stuff, and a word the user wants highlighted
- index = std::min(bracketFirstIndex, std::min(urlFirstIndex, highlightWordFirstIndex));
- }
- else if (startsWithBracket && startsWithAtSymbol && !startsWithUrl && startsWithHighlightWord)
- {
- // Contains a bracket, an @ symbol, and a word the user wants highlighted
- index = std::min(bracketFirstIndex, std::min(mentionFirstIndex, highlightWordFirstIndex));
- }
- else if (startsWithBracket && startsWithAtSymbol && startsWithUrl && !startsWithHighlightWord)
- {
- // Contains a bracket, an @ symbol, and URL stuff
- index = std::min(bracketFirstIndex, std::min(mentionFirstIndex, urlFirstIndex));
- }
- else if (startsWithBracket && startsWithAtSymbol && startsWithUrl && startsWithHighlightWord)
- {
- // Contains a bracket, an @ symbol, URL stuff, and a word the user wants highlighted
- index = std::min(highlightWordFirstIndex, std::min(bracketFirstIndex, std::min(mentionFirstIndex, urlFirstIndex)));
- }
-
- if (index > 0)
- {
- cursor.insertText(message.left(index), defaultFormat);
- message = message.mid(index);
- }
-
- if (index == bracketFirstIndex) // The message now starts with a bracket ->> [ <<- that symbol
- {
- if (message.startsWith("[card]"))
- {
- message = message.mid(6);
- int closeTagIndex = message.indexOf("[/card]");
- QString cardName = message.left(closeTagIndex);
- if (closeTagIndex == -1)
- message.clear();
+ case '@':
+ if(mentionEnabled)
+ checkMention(cursor, message, sender, userLevel);
else
- message = message.mid(closeTagIndex + 7);
-
- appendCardTag(cursor, cardName);
- }
- else if (message.startsWith("[["))
- {
- message = message.mid(2);
- int closeTagIndex = message.indexOf("]]");
- QString cardName = message.left(closeTagIndex);
- if (closeTagIndex == -1)
- message.clear();
- else
- message = message.mid(closeTagIndex + 2);
-
- appendCardTag(cursor, cardName);
- }
- else if (message.startsWith("[url]"))
- {
- message = message.mid(5);
- int closeTagIndex = message.indexOf("[/url]");
- QString url = message.left(closeTagIndex);
- if (closeTagIndex == -1)
- message.clear();
- else
- message = message.mid(closeTagIndex + 6);
-
- appendUrlTag(cursor, url);
- }
- else
- {
- // Not a valid tag
- cursor.insertText("[", defaultFormat);
+ checkWord(cursor, message);
+ break;
+ case ' ':
+ cursor.insertText(" ", defaultFormat);
message = message.mid(1);
- }
- }
- else if (index == urlFirstIndex) // The message now starts with either: www. , http:// , or https://
- {
- int urlEndIndex = message.indexOf(phraseEnder, 0);
- if (urlEndIndex == -1)
- urlEndIndex = message.size();
- QString urlText = message.left(urlEndIndex);
- QUrl qUrl(urlText);
- if (qUrl.isValid())
- appendUrlTag(cursor, urlText);
- else
- cursor.insertText(urlText);
- if (urlEndIndex == -1)
- message.clear();
- else
- message = message.mid(urlEndIndex);
- }
- else if (index == mentionFirstIndex)
- {
- int firstSpace = message.indexOf(" ");
- QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
- QString mentionIntact = fullMentionUpToSpaceOrEnd;
-
- if ((!mentionEnabled && !isModeratorSendingGlobal(userLevel, fullMentionUpToSpaceOrEnd)) || tabSupervisor->getIsLocalGame())
- {
- cursor.insertText("@");
- message = message.mid(1);
- }
- else
- {
- QMap userList = tabSupervisor->getUserListsTab()->getAllUsersList()->getUsers();
-
- do
- {
- if (isFullMentionAValidUser(userList, fullMentionUpToSpaceOrEnd)) // Is there a user online named this?
- {
- if (userName.toLower() == fullMentionUpToSpaceOrEnd.toLower()) // Is this user you?
- {
- // You have received a valid mention!!
- mentionFormat.setBackground(QBrush(getCustomMentionColor()));
- mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
- cursor.insertText(mention, mentionFormat);
- message = message.mid(mention.size());
- QApplication::alert(this);
- if (settingsCache->getShowMentionPopup() && shouldShowSystemPopup())
- {
- QString ref = sender.left(sender.length() - 2);
- showSystemPopup(ref);
- }
- }
- else
- {
- QString correctUserName = getNameFromUserList(userList, fullMentionUpToSpaceOrEnd);
- UserListTWI *vlu = userList.value(correctUserName);
- mentionFormatOtherUser.setAnchorHref("user://" + QString::number(vlu->getUserInfo().user_level()) + "_" + correctUserName);
- cursor.insertText("@" + correctUserName, mentionFormatOtherUser);
-
- message = message.mid(correctUserName.size() + 1);
- }
-
- cursor.setCharFormat(defaultFormat);
- break;
- }
- else if (isModeratorSendingGlobal(userLevel, fullMentionUpToSpaceOrEnd))
- {
- // Moderator Sending Global Message
- mentionFormat.setBackground(QBrush(getCustomMentionColor()));
- mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
- cursor.insertText("@" + fullMentionUpToSpaceOrEnd, mentionFormat);
- message = message.mid(fullMentionUpToSpaceOrEnd.size() + 1);
- QApplication::alert(this);
- if (settingsCache->getShowMentionPopup() && shouldShowSystemPopup())
- {
- QString ref = sender.left(sender.length() - 2);
- showSystemPopup(ref);
- }
-
- cursor.setCharFormat(defaultFormat);
- break;
- }
- else if (fullMentionUpToSpaceOrEnd.right(1).indexOf(notALetterOrNumber) == -1 || fullMentionUpToSpaceOrEnd.size() < 2)
- {
- cursor.insertText("@" + mentionIntact, defaultFormat);
- message = message.mid(mentionIntact.size() + 1);
- cursor.setCharFormat(defaultFormat);
- break;
- }
- else
- {
- fullMentionUpToSpaceOrEnd.chop(1);
- }
- }
- while (fullMentionUpToSpaceOrEnd.size());
- }
- }
- else if (index == highlightWordFirstIndex)
- {
- // You have received a valid mention of custom word!!
- int firstSpace = (message.indexOf(" ") == -1 ? message.size() : message.indexOf(" "));
- mentionFormat.setBackground(QBrush(getCustomMentionColor()));
- mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
- cursor.insertText(message.mid(0, firstSpace), mentionFormat);
- cursor.setCharFormat(defaultFormat);
- message = message.mid(firstSpace);
- QApplication::alert(this);
- }
- else
- {
- // Not certain when this would ever be reached, but just incase lets skip the character
- cursor.insertText(message.mid(0), defaultFormat);
- message = message.mid(1);
+ break;
+ default:
+ checkWord(cursor, message);
+ break;
}
}
@@ -440,6 +195,173 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
+void ChatView::checkTag(QTextCursor &cursor, QString &message)
+{
+ if (message.startsWith("[card]"))
+ {
+ message = message.mid(6);
+ int closeTagIndex = message.indexOf("[/card]");
+ QString cardName = message.left(closeTagIndex);
+ if (closeTagIndex == -1)
+ message.clear();
+ else
+ message = message.mid(closeTagIndex + 7);
+
+ appendCardTag(cursor, cardName);
+ return;
+ }
+
+ if (message.startsWith("[["))
+ {
+ message = message.mid(2);
+ int closeTagIndex = message.indexOf("]]");
+ QString cardName = message.left(closeTagIndex);
+ if (closeTagIndex == -1)
+ message.clear();
+ else
+ message = message.mid(closeTagIndex + 2);
+
+ appendCardTag(cursor, cardName);
+ return;
+ }
+
+ if (message.startsWith("[url]"))
+ {
+ message = message.mid(5);
+ int closeTagIndex = message.indexOf("[/url]");
+ QString url = message.left(closeTagIndex);
+ if (closeTagIndex == -1)
+ message.clear();
+ else
+ message = message.mid(closeTagIndex + 6);
+
+ appendUrlTag(cursor, url);
+ return;
+ }
+
+ // no valid tag found
+ checkWord(cursor, message);
+}
+
+void ChatView::checkMention(QTextCursor &cursor, QString &message, QString &sender, UserLevelFlags userLevel)
+{
+ const QRegExp notALetterOrNumber = QRegExp("[^a-zA-Z0-9]");
+
+ int firstSpace = message.indexOf(' ');
+ QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
+ QString mentionIntact = fullMentionUpToSpaceOrEnd;
+
+ QMap userList = tabSupervisor->getUserListsTab()->getAllUsersList()->getUsers();
+
+ while (fullMentionUpToSpaceOrEnd.size())
+ {
+ if (isFullMentionAValidUser(userList, fullMentionUpToSpaceOrEnd)) // Is there a user online named this?
+ {
+ if (userName.toLower() == fullMentionUpToSpaceOrEnd.toLower()) // Is this user you?
+ {
+ // You have received a valid mention!!
+ mentionFormat.setBackground(QBrush(getCustomMentionColor()));
+ mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
+ cursor.insertText(mention, mentionFormat);
+ message = message.mid(mention.size());
+ QApplication::alert(this);
+ if (settingsCache->getShowMentionPopup() && shouldShowSystemPopup())
+ {
+ QString ref = sender.left(sender.length() - 2);
+ showSystemPopup(ref);
+ }
+ } else {
+ QString correctUserName = getNameFromUserList(userList, fullMentionUpToSpaceOrEnd);
+ UserListTWI *vlu = userList.value(correctUserName);
+ mentionFormatOtherUser.setAnchorHref("user://" + QString::number(vlu->getUserInfo().user_level()) + "_" + correctUserName);
+ cursor.insertText("@" + correctUserName, mentionFormatOtherUser);
+
+ message = message.mid(correctUserName.size() + 1);
+ }
+
+ cursor.setCharFormat(defaultFormat);
+ return;
+ }
+
+ if (isModeratorSendingGlobal(userLevel, fullMentionUpToSpaceOrEnd)) {
+ // Moderator Sending Global Message
+ mentionFormat.setBackground(QBrush(getCustomMentionColor()));
+ mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
+ cursor.insertText("@" + fullMentionUpToSpaceOrEnd, mentionFormat);
+ message = message.mid(fullMentionUpToSpaceOrEnd.size() + 1);
+ QApplication::alert(this);
+ if (settingsCache->getShowMentionPopup() && shouldShowSystemPopup())
+ {
+ QString ref = sender.left(sender.length() - 2);
+ showSystemPopup(ref);
+ }
+
+ cursor.setCharFormat(defaultFormat);
+ return;
+ }
+
+ if (fullMentionUpToSpaceOrEnd.right(1).indexOf(notALetterOrNumber) == -1 || fullMentionUpToSpaceOrEnd.size() < 2)
+ {
+ cursor.insertText("@" + mentionIntact, defaultFormat);
+ message = message.mid(mentionIntact.size() + 1);
+ cursor.setCharFormat(defaultFormat);
+ return;
+ }
+
+ fullMentionUpToSpaceOrEnd.chop(1);
+ }
+
+ // no valid mention found
+ checkWord(cursor, message);
+}
+
+void ChatView::checkWord(QTextCursor &cursor, QString &message)
+{
+ // extract the first word
+ int firstSpace = message.indexOf(' ');
+ QString fullWordUpToSpaceOrEnd;
+ if(firstSpace == -1)
+ {
+ fullWordUpToSpaceOrEnd = message;
+ message.clear();
+ } else {
+ fullWordUpToSpaceOrEnd = message.mid(0, firstSpace);
+ message = message.mid(firstSpace);
+ }
+
+ // check urls
+ if (fullWordUpToSpaceOrEnd.startsWith("http://", Qt::CaseInsensitive) ||
+ fullWordUpToSpaceOrEnd.startsWith("https://", Qt::CaseInsensitive) ||
+ fullWordUpToSpaceOrEnd.startsWith("www.", Qt::CaseInsensitive))
+ {
+ QUrl qUrl(fullWordUpToSpaceOrEnd);
+ if (qUrl.isValid())
+ {
+ appendUrlTag(cursor, fullWordUpToSpaceOrEnd);
+ return;
+ }
+ }
+
+ // check word mentions
+ const QStringList highlightedWords = settingsCache->getHighlightWords();
+ foreach (QString word, highlightedWords)
+ {
+ if (fullWordUpToSpaceOrEnd.compare(word, Qt::CaseInsensitive) == 0)
+ {
+ // You have received a valid mention of custom word!!
+ mentionFormat.setBackground(QBrush(getCustomMentionColor()));
+ mentionFormat.setForeground(settingsCache->getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
+ cursor.insertText(fullWordUpToSpaceOrEnd, mentionFormat);
+ cursor.setCharFormat(defaultFormat);
+ QApplication::alert(this);
+ return;
+ }
+ }
+
+ // not a special word; just print it
+ cursor.insertText(fullWordUpToSpaceOrEnd, defaultFormat);
+}
+
bool ChatView::isModeratorSendingGlobal(QFlags userLevelFlag, QString message)
{
int userLevel = QString::number(userLevelFlag).toInt();
diff --git a/cockatrice/src/chatview.h b/cockatrice/src/chatview.h
index 17d73d72..144097f0 100644
--- a/cockatrice/src/chatview.h
+++ b/cockatrice/src/chatview.h
@@ -44,6 +44,9 @@ private:
bool shouldShowSystemPopup();
void showSystemPopup(QString &sender);
bool isModeratorSendingGlobal(QFlags userLevelFlag, QString message);
+ void checkTag(QTextCursor &cursor, QString &message);
+ void checkMention(QTextCursor &cursor, QString &message, QString &sender, UserLevelFlags userLevel);
+ void checkWord(QTextCursor &cursor, QString &message);
private slots:
void openLink(const QUrl &link);
void actMessageClicked();