diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 3de90e468..3921e32f2 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -152,10 +152,12 @@ void CSMPrefs::State::declare() setRange (0, 10000); declareInt ("error-height", "Initial height of the error panel", 100). setRange (100, 10000); + declareBool ("highlight-occurrences", "Highlight other occurrences of selected names", true); declareSeparator(); declareColour ("colour-int", "Highlight Colour: Integer Literals", QColor ("darkmagenta")); declareColour ("colour-float", "Highlight Colour: Float Literals", QColor ("magenta")); declareColour ("colour-name", "Highlight Colour: Names", QColor ("grey")); + declareColour ("colour-highlight", "Highlight Colour: Highlighting", QColor("palegreen")); declareColour ("colour-keyword", "Highlight Colour: Keywords", QColor ("red")); declareColour ("colour-special", "Highlight Colour: Special Characters", QColor ("darkorange")); declareColour ("colour-comment", "Highlight Colour: Comments", QColor ("green")); diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index bfd07035c..1105404b3 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -51,6 +51,7 @@ CSVWorld::ScriptEdit::ScriptEdit( mDefaultFont(font()), mMonoFont(QFont("Monospace")), mTabCharCount(4), + mMarkOccurrences(true), mDocument(document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) { @@ -87,6 +88,8 @@ CSVWorld::ScriptEdit::ScriptEdit( <toInt(); setTabWidth(); } + else if (*setting == "Scripts/highlight-occurrences") + { + mMarkOccurrences = setting->isTrue(); + mHighlighter->setMarkedWord(""); + updateHighlighting(); + mHighlighter->setMarkOccurrences(mMarkOccurrences); + } } void CSVWorld::ScriptEdit::idListChanged() @@ -296,6 +306,25 @@ void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect &rect, int dy) updateLineNumberAreaWidth(0); } +void CSVWorld::ScriptEdit::markOccurrences() +{ + if (mMarkOccurrences) + { + QTextCursor cursor = textCursor(); + + // prevent infinite recursion with cursor.select(), + // which ends up calling this function again + // could be fixed with blockSignals, but mDocument is const + disconnect(this, SIGNAL(cursorPositionChanged()), this, 0); + cursor.select(QTextCursor::WordUnderCursor); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(markOccurrences())); + + QString word = cursor.selectedText(); + mHighlighter->setMarkedWord(word.toStdString()); + mHighlighter->rehighlight(); + } +} + void CSVWorld::ScriptEdit::commentSelection() { QTextCursor begin = textCursor(); diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index a788eaccf..b0a4b0577 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -55,6 +55,7 @@ namespace CSVWorld QFont mDefaultFont; QFont mMonoFont; int mTabCharCount; + bool mMarkOccurrences; QAction *mCommentAction; QAction *mUncommentAction; @@ -117,9 +118,12 @@ namespace CSVWorld void updateLineNumberArea(const QRect &, int); + void markOccurrences(); + void commentSelection(); void uncommentSelection(); + }; class LineNumberArea : public QWidget diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index 846a61b47..6aba66053 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -72,7 +72,11 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type // compensate for bug in Compiler::Scanner (position of token is the character after the token) index -= length; - setFormat (index, length, mScheme[type]); + QTextCharFormat scheme = mScheme[type]; + if (mMarkOccurrences && type == Type_Name && loc.mLiteral == mMarkedWord) + scheme.merge(mScheme[Type_Highlight]); + + setFormat (index, length, scheme); } CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, Mode mode, @@ -105,6 +109,16 @@ void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text) catch (...) {} // ignore syntax errors } +void CSVWorld::ScriptHighlighter::setMarkOccurrences(bool flag) +{ + mMarkOccurrences = flag; +} + +void CSVWorld::ScriptHighlighter::setMarkedWord(const std::string& name) +{ + mMarkedWord = name; +} + void CSVWorld::ScriptHighlighter::invalidateIds() { mContext.invalidateIds(); @@ -117,7 +131,7 @@ bool CSVWorld::ScriptHighlighter::settingChanged (const CSMPrefs::Setting *setti static const char *const colours[Type_Id+2] = { "colour-int", "colour-float", "colour-name", "colour-keyword", - "colour-special", "colour-comment", "colour-id", + "colour-special", "colour-comment", "colour-highlight", "colour-id", 0 }; @@ -125,7 +139,10 @@ bool CSVWorld::ScriptHighlighter::settingChanged (const CSMPrefs::Setting *setti if (setting->getKey()==colours[i]) { QTextCharFormat format; - format.setForeground (setting->toColor()); + if (i == Type_Highlight) + format.setBackground (setting->toColor()); + else + format.setForeground (setting->toColor()); mScheme[static_cast (i)] = format; return true; } diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index 33824da0d..a7d0fc2a1 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -2,6 +2,7 @@ #define CSV_WORLD_SCRIPTHIGHLIGHTER_H #include +#include #include @@ -30,7 +31,8 @@ namespace CSVWorld Type_Keyword = 3, Type_Special = 4, Type_Comment = 5, - Type_Id = 6 + Type_Highlight = 6, + Type_Id = 7 }; enum Mode @@ -47,6 +49,8 @@ namespace CSVWorld CSMWorld::ScriptContext mContext; std::map mScheme; Mode mMode; + bool mMarkOccurrences; + std::string mMarkedWord; private: @@ -91,6 +95,10 @@ namespace CSVWorld virtual void highlightBlock (const QString& text); + void setMarkOccurrences(bool); + + void setMarkedWord(const std::string& name); + void invalidateIds(); bool settingChanged (const CSMPrefs::Setting *setting);