diff options
author | Richard Maudsley <richard.maudsley@isode.com> | 2014-07-16 12:37:25 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2014-07-29 08:36:54 (GMT) |
commit | 9c5c731845881996f45b32ea6de12e0647f4634d (patch) | |
tree | 70331a822814ade469f07231ff0bf6dfbfa1fcde | |
parent | 690cb7e85ff9dadbfca3e3bc91826161011712f1 (diff) | |
download | swift-9c5c731845881996f45b32ea6de12e0647f4634d.zip swift-9c5c731845881996f45b32ea6de12e0647f4634d.tar.bz2 |
Prevent nick highlight rule highlighting the entire message and remove default highlight colours
Test-Information:
Add a nick highlight rule. Verify that it is triggered correctly in MUCs and that only the nick text is highlighted. Added unit tests.
Change-Id: I9af1c900f4767383745afd36a5eadbe08f606432
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.cpp | 4 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatMessageParser.cpp | 9 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatMessageParser.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp | 36 | ||||
-rw-r--r-- | Swift/Controllers/HighlightAction.cpp | 2 | ||||
-rw-r--r-- | Swift/Controllers/HighlightAction.h | 11 | ||||
-rw-r--r-- | Swift/Controllers/HighlightRule.cpp | 12 | ||||
-rw-r--r-- | Swift/Controllers/HighlightRule.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/Highlighter.h | 1 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightEditor.cpp | 45 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightEditor.ui | 7 | ||||
-rw-r--r-- | Swift/QtUI/QtWebKitChatView.cpp | 8 |
12 files changed, 88 insertions, 53 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 24341e6..519deda 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -205,7 +205,7 @@ std::string ChatControllerBase::addMessage(const std::string& message, const std if (boost::starts_with(message, "/me ")) { return chatWindow_->addAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight); } else { - return chatWindow_->addMessage(chatMessageParser_->parseMessageBody(message,senderIsSelf), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight); + return chatWindow_->addMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight); } } @@ -213,7 +213,7 @@ void ChatControllerBase::replaceMessage(const std::string& message, const std::s if (boost::starts_with(message, "/me ")) { chatWindow_->replaceWithAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), id, time, highlight); } else { - chatWindow_->replaceMessage(chatMessageParser_->parseMessageBody(message,senderIsSelf), id, time, highlight); + chatWindow_->replaceMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), id, time, highlight); } } diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp index 09d93ac..5a608db 100644 --- a/Swift/Controllers/Chat/ChatMessageParser.cpp +++ b/Swift/Controllers/Chat/ChatMessageParser.cpp @@ -26,7 +26,7 @@ namespace Swift { typedef std::pair<std::string, std::string> StringPair; - ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, bool senderIsSelf) { + ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) { ChatWindow::ChatMessage parsedMessage; std::string remaining = body; /* Parse one, URLs */ @@ -57,7 +57,7 @@ namespace Swift { if (!senderIsSelf) { /* do not highlight our own messsages */ /* do word-based color highlighting */ - parsedMessage = splitHighlight(parsedMessage); + parsedMessage = splitHighlight(parsedMessage, nick); } return parsedMessage; @@ -138,7 +138,7 @@ namespace Swift { return parsedMessage; } - ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message) + ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message, const std::string& nick) { ChatWindow::ChatMessage parsedMessage = message; @@ -149,7 +149,8 @@ namespace Swift { } 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()) { + const std::vector<boost::regex> keywordRegex = rule.getKeywordRegex(nick); + foreach(const boost::regex& regex, keywordRegex) { ChatWindow::ChatMessage newMessage; foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) { boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart; diff --git a/Swift/Controllers/Chat/ChatMessageParser.h b/Swift/Controllers/Chat/ChatMessageParser.h index cff4ffa..2f5c171 100644 --- a/Swift/Controllers/Chat/ChatMessageParser.h +++ b/Swift/Controllers/Chat/ChatMessageParser.h @@ -15,10 +15,10 @@ namespace Swift { class ChatMessageParser { public: ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode = false); - ChatWindow::ChatMessage parseMessageBody(const std::string& body, bool senderIsSelf = false); + ChatWindow::ChatMessage parseMessageBody(const std::string& body, const std::string& nick = "", bool senderIsSelf = false); private: ChatWindow::ChatMessage emoticonHighlight(const ChatWindow::ChatMessage& parsedMessage); - ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage); + ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage, const std::string& nick); std::map<std::string, std::string> emoticons_; HighlightRulesListPtr highlightRules_; bool mucMode_; diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp index 5dca63a..2a07654 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp @@ -85,6 +85,18 @@ public: return list; } + static HighlightRulesListPtr ruleListWithNickHighlight() + { + HighlightRule rule; + rule.setMatchChat(true); + rule.setNickIsKeyword(true); + rule.setMatchCase(true); + rule.setMatchWholeWords(true); + boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); + list->addRule(rule); + return list; + } + void testFullBody() { const std::string no_special_message = "a message with no special content"; ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); @@ -174,6 +186,30 @@ public: testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true))); result = testling.parseMessageBody("zeroonetwothree"); assertText(result, 0, "zeroonetwothree"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Alice", "Alice"); + assertHighlight(result, 0, "Alice"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("TextAliceText", "Alice"); + assertText(result, 0, "TextAliceText"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Text Alice Text", "Alice"); + assertText(result, 0, "Text "); + assertHighlight(result, 1, "Alice"); + assertText(result, 2, " Text"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Alice Text", "Alice"); + assertHighlight(result, 0, "Alice"); + assertText(result, 1, " Text"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Text Alice", "Alice"); + assertText(result, 0, "Text "); + assertHighlight(result, 1, "Alice"); } void testOneEmoticon() { diff --git a/Swift/Controllers/HighlightAction.cpp b/Swift/Controllers/HighlightAction.cpp index d4d199d..492d4d2 100644 --- a/Swift/Controllers/HighlightAction.cpp +++ b/Swift/Controllers/HighlightAction.cpp @@ -8,7 +8,7 @@ namespace Swift { -void HighlightAction::setHighlightText(bool highlightText) +void HighlightAction::setHighlightAllText(bool highlightText) { highlightText_ = highlightText; if (!highlightText_) { diff --git a/Swift/Controllers/HighlightAction.h b/Swift/Controllers/HighlightAction.h index de1f201..90768a7 100644 --- a/Swift/Controllers/HighlightAction.h +++ b/Swift/Controllers/HighlightAction.h @@ -25,17 +25,20 @@ namespace Swift { public: HighlightAction() : highlightText_(false), playSound_(false) {} - bool highlightText() const { return highlightText_; } - void setHighlightText(bool highlightText); + /** + * Gets the flag that indicates the entire message should be highlighted. + */ + bool highlightAllText() const { return highlightText_; } + void setHighlightAllText(bool highlightText); /** - * Gets the foreground highlight color. If the string is empty, assume a default color. + * Gets the foreground highlight color. */ const std::string& getTextColor() const { return textColor_; } void setTextColor(const std::string& textColor) { textColor_ = textColor; } /** - * Gets the background highlight color. If the string is empty, assume a default color. + * Gets the background highlight color. */ const std::string& getTextBackground() const { return textBackground_; } void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; } diff --git a/Swift/Controllers/HighlightRule.cpp b/Swift/Controllers/HighlightRule.cpp index f1a5235..3251067 100644 --- a/Swift/Controllers/HighlightRule.cpp +++ b/Swift/Controllers/HighlightRule.cpp @@ -102,6 +102,18 @@ void HighlightRule::setKeywords(const std::vector<std::string>& keywords) updateRegex(); } +std::vector<boost::regex> HighlightRule::getKeywordRegex(const std::string& nick) const { + if (nickIsKeyword_) { + std::vector<boost::regex> regex; + if (!nick.empty()) { + regex.push_back(regexFromString(nick)); + } + return regex; + } else { + return keywordRegex_; + } +} + void HighlightRule::setNickIsKeyword(bool nickIsKeyword) { nickIsKeyword_ = nickIsKeyword; diff --git a/Swift/Controllers/HighlightRule.h b/Swift/Controllers/HighlightRule.h index ae1a3d3..c0226bc 100644 --- a/Swift/Controllers/HighlightRule.h +++ b/Swift/Controllers/HighlightRule.h @@ -40,7 +40,7 @@ namespace Swift { const std::vector<std::string>& getKeywords() const { return keywords_; } void setKeywords(const std::vector<std::string>&); - const std::vector<boost::regex>& getKeywordRegex() const { return keywordRegex_; } + std::vector<boost::regex> getKeywordRegex(const std::string& nick) const; bool getNickIsKeyword() const { return nickIsKeyword_; } void setNickIsKeyword(bool); diff --git a/Swift/Controllers/Highlighter.h b/Swift/Controllers/Highlighter.h index d026f29..d5d846b 100644 --- a/Swift/Controllers/Highlighter.h +++ b/Swift/Controllers/Highlighter.h @@ -22,6 +22,7 @@ namespace Swift { void setMode(Mode mode); void setNick(const std::string& nick) { nick_ = nick; } + std::string getNick() const { return nick_; } HighlightAction findAction(const std::string& body, const std::string& sender) const; diff --git a/Swift/QtUI/QtHighlightEditor.cpp b/Swift/QtUI/QtHighlightEditor.cpp index ce07003..8488d7d 100644 --- a/Swift/QtUI/QtHighlightEditor.cpp +++ b/Swift/QtUI/QtHighlightEditor.cpp @@ -40,7 +40,6 @@ QtHighlightEditor::QtHighlightEditor(QtSettingsProvider* settings, QWidget* pare connect(ui_.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(onOkButtonClick())); connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(colorOtherSelect())); - connect(ui_.defaultColorRadio, SIGNAL(clicked()), SLOT(colorOtherSelect())); connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(colorCustomSelect())); connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect())); @@ -68,7 +67,6 @@ QtHighlightEditor::QtHighlightEditor(QtSettingsProvider* settings, QWidget* pare connect(ui_.matchPartialWords, SIGNAL(clicked()), SLOT(widgetClick())); connect(ui_.matchCase, SIGNAL(clicked()), SLOT(widgetClick())); connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(widgetClick())); - connect(ui_.defaultColorRadio, SIGNAL(clicked()), SLOT(widgetClick())); connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(widgetClick())); connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(widgetClick())); connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(widgetClick())); @@ -305,7 +303,6 @@ void QtHighlightEditor::disableDialog() ui_.matchPartialWords->setEnabled(false); ui_.matchCase->setEnabled(false); ui_.noColorRadio->setEnabled(false); - ui_.defaultColorRadio->setEnabled(false); ui_.customColorRadio->setEnabled(false); ui_.foregroundColor->setEnabled(false); ui_.backgroundColor->setEnabled(false); @@ -399,22 +396,21 @@ HighlightRule QtHighlightEditor::ruleFromDialog() } } - rule.setNickIsKeyword(ui_.nickIsKeyword->isChecked()); - rule.setMatchWholeWords(!ui_.matchPartialWords->isChecked()); - rule.setMatchCase(ui_.matchCase->isChecked()); + if (ui_.nickIsKeyword->isChecked()) { + rule.setNickIsKeyword(true); + rule.setMatchWholeWords(true); + rule.setMatchCase(true); + } else { + rule.setMatchWholeWords(!ui_.matchPartialWords->isChecked()); + rule.setMatchCase(ui_.matchCase->isChecked()); + } HighlightAction& action = rule.getAction(); if (ui_.noColorRadio->isChecked()) { - action.setHighlightText(false); - action.setTextColor(""); - action.setTextBackground(""); - } else if (ui_.defaultColorRadio->isChecked()) { - action.setHighlightText(true); action.setTextColor(""); action.setTextBackground(""); } else { - action.setHighlightText(true); action.setTextColor(Q2PSTRING(ui_.foregroundColor->getColor().name())); action.setTextBackground(Q2PSTRING(ui_.backgroundColor->getColor().name())); } @@ -476,26 +472,19 @@ void QtHighlightEditor::ruleToDialog(const HighlightRule& rule) const HighlightAction& action = rule.getAction(); ui_.noColorRadio->setEnabled(true); - ui_.defaultColorRadio->setEnabled(true); ui_.customColorRadio->setEnabled(true); - if (action.highlightText()) { - if (action.getTextColor().empty() && action.getTextBackground().empty()) { - ui_.defaultColorRadio->setChecked(true); - ui_.foregroundColor->setEnabled(false); - ui_.backgroundColor->setEnabled(false); - } else { - ui_.foregroundColor->setEnabled(true); - ui_.backgroundColor->setEnabled(true); - QColor foregroundColor(P2QSTRING(action.getTextColor())); - ui_.foregroundColor->setColor(foregroundColor); - QColor backgroundColor(P2QSTRING(action.getTextBackground())); - ui_.backgroundColor->setColor(backgroundColor); - ui_.customColorRadio->setChecked(true); - } - } else { + if (action.getTextColor().empty() && action.getTextBackground().empty()) { ui_.noColorRadio->setChecked(true); ui_.foregroundColor->setEnabled(false); ui_.backgroundColor->setEnabled(false); + } else { + ui_.foregroundColor->setEnabled(true); + ui_.backgroundColor->setEnabled(true); + QColor foregroundColor(P2QSTRING(action.getTextColor())); + ui_.foregroundColor->setColor(foregroundColor); + QColor backgroundColor(P2QSTRING(action.getTextBackground())); + ui_.backgroundColor->setColor(backgroundColor); + ui_.customColorRadio->setChecked(true); } ui_.noSoundRadio->setEnabled(true); diff --git a/Swift/QtUI/QtHighlightEditor.ui b/Swift/QtUI/QtHighlightEditor.ui index be2e99b..775771f 100644 --- a/Swift/QtUI/QtHighlightEditor.ui +++ b/Swift/QtUI/QtHighlightEditor.ui @@ -277,13 +277,6 @@ </widget> </item> <item> - <widget class="QRadioButton" name="defaultColorRadio"> - <property name="text"> - <string>Default Color</string> - </property> - </widget> - </item> - <item> <widget class="QRadioButton" name="customColorRadio"> <property name="text"> <string>Custom Color</string> diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp index 1486293..a510e34 100644 --- a/Swift/QtUI/QtWebKitChatView.cpp +++ b/Swift/QtUI/QtWebKitChatView.cpp @@ -608,8 +608,8 @@ std::string QtWebKitChatView::addMessage( QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">"; QString styleSpanEnd = style == "" ? "" : "</span>"; - QString highlightSpanStart = highlight.highlightText() ? getHighlightSpanStart(highlight) : ""; - QString highlightSpanEnd = highlight.highlightText() ? "</span>" : ""; + QString highlightSpanStart = highlight.highlightAllText() ? getHighlightSpanStart(highlight) : ""; + QString highlightSpanEnd = highlight.highlightAllText() ? "</span>" : ""; htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ; bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf); @@ -826,8 +826,8 @@ void QtWebKitChatView::replaceMessage(const QString& message, const std::string& QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">"; QString styleSpanEnd = style == "" ? "" : "</span>"; - QString highlightSpanStart = highlight.highlightText() ? getHighlightSpanStart(highlight) : ""; - QString highlightSpanEnd = highlight.highlightText() ? "</span>" : ""; + QString highlightSpanStart = highlight.highlightAllText() ? getHighlightSpanStart(highlight) : ""; + QString highlightSpanEnd = highlight.highlightAllText() ? "</span>" : ""; messageHTML = styleSpanStart + highlightSpanStart + messageHTML + highlightSpanEnd + styleSpanEnd; replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time)); |