diff options
Diffstat (limited to 'Swift/Controllers/Chat/ChatMessageParser.cpp')
| -rw-r--r-- | Swift/Controllers/Chat/ChatMessageParser.cpp | 75 | 
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 ®ex, 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; +	}  } | 
 Swift
 Swift