summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/ChatMessageParser.cpp')
-rw-r--r--Swift/Controllers/Chat/ChatMessageParser.cpp75
1 files changed, 71 insertions, 4 deletions
diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp
index 698b766..09d93ac 100644
--- a/Swift/Controllers/Chat/ChatMessageParser.cpp
+++ b/Swift/Controllers/Chat/ChatMessageParser.cpp
@@ -20,13 +20,13 @@
namespace Swift {
- ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons) : emoticons_(emoticons) {
-
+ ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode)
+ : emoticons_(emoticons), highlightRules_(highlightRules), mucMode_(mucMode) {
}
typedef std::pair<std::string, std::string> StringPair;
- ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body) {
+ ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, bool senderIsSelf) {
ChatWindow::ChatMessage parsedMessage;
std::string remaining = body;
/* Parse one, URLs */
@@ -51,8 +51,21 @@ namespace Swift {
}
}
}
-
+ /* do emoticon substitution */
+ parsedMessage = emoticonHighlight(parsedMessage);
+
+ if (!senderIsSelf) { /* do not highlight our own messsages */
+ /* do word-based color highlighting */
+ parsedMessage = splitHighlight(parsedMessage);
+ }
+
+ return parsedMessage;
+ }
+
+ ChatWindow::ChatMessage ChatMessageParser::emoticonHighlight(const ChatWindow::ChatMessage& message)
+ {
+ ChatWindow::ChatMessage parsedMessage = message;
std::string regexString;
/* Parse two, emoticons */
@@ -124,4 +137,58 @@ namespace Swift {
}
return parsedMessage;
}
+
+ ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message)
+ {
+ ChatWindow::ChatMessage parsedMessage = message;
+
+ for (size_t i = 0; i < highlightRules_->getSize(); ++i) {
+ const HighlightRule& rule = highlightRules_->getRule(i);
+ if (rule.getMatchMUC() && !mucMode_) {
+ continue; /* this rule only applies to MUC's, and this is a CHAT */
+ } else if (rule.getMatchChat() && mucMode_) {
+ continue; /* this rule only applies to CHAT's, and this is a MUC */
+ }
+ foreach(const boost::regex &regex, rule.getKeywordRegex()) {
+ ChatWindow::ChatMessage newMessage;
+ foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) {
+ boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ try {
+ boost::match_results<std::string::const_iterator> match;
+ const std::string& text = textPart->text;
+ std::string::const_iterator start = text.begin();
+ while (regex_search(start, text.end(), match, regex)) {
+ std::string::const_iterator matchStart = match[0].first;
+ std::string::const_iterator matchEnd = match[0].second;
+ if (start != matchStart) {
+ /* If we're skipping over plain text since the previous emoticon, record it as plain text */
+ newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart)));
+ }
+ boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = boost::make_shared<ChatWindow::ChatHighlightingMessagePart>();
+ highlightPart->text = match.str();
+ highlightPart->foregroundColor = rule.getAction().getTextColor();
+ highlightPart->backgroundColor = rule.getAction().getTextBackground();
+ newMessage.append(highlightPart);
+ start = matchEnd;
+ }
+ if (start != text.end()) {
+ /* If there's plain text after the last emoticon, record it */
+ newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end())));
+ }
+ }
+ catch (std::runtime_error) {
+ /* Basically too expensive to compute the regex results and it gave up, so pass through as text */
+ newMessage.append(part);
+ }
+ } else {
+ newMessage.append(part);
+ }
+ }
+ parsedMessage = newMessage;
+ }
+ }
+
+ return parsedMessage;
+ }
}