Fix highlighting bugs in DisasmWidget (#1477)

This commit is contained in:
Paul I 2019-04-22 11:48:06 +03:00 committed by Itay Cohen
parent d0458597d1
commit ce5c0f5d79
2 changed files with 39 additions and 29 deletions

View File

@ -1,7 +1,5 @@
#include "DisassemblyWidget.h" #include "DisassemblyWidget.h"
#include "menus/DisassemblyContextMenu.h" #include "menus/DisassemblyContextMenu.h"
#include "common/HexAsciiHighlighter.h"
#include "common/HexHighlighter.h"
#include "common/Configuration.h" #include "common/Configuration.h"
#include "common/Helpers.h" #include "common/Helpers.h"
#include "common/TempConfig.h" #include "common/TempConfig.h"
@ -56,6 +54,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
topOffset = bottomOffset = RVA_INVALID; topOffset = bottomOffset = RVA_INVALID;
cursorLineOffset = 0; cursorLineOffset = 0;
cursorCharOffset = 0;
seekFromCursor = false; seekFromCursor = false;
setWindowTitle(tr("Disassembly")); setWindowTitle(tr("Disassembly"));
@ -338,7 +337,6 @@ void DisassemblyWidget::highlightCurrentLine()
QColor highlightColor = ConfigColor("highlight"); QColor highlightColor = ConfigColor("highlight");
QColor highlightPCColor = ConfigColor("highlightPC"); QColor highlightPCColor = ConfigColor("highlightPC");
QColor highlightWordColor = ConfigColor("highlightWord");
// Highlight the current word // Highlight the current word
QTextCursor cursor = mDisasTextEdit->textCursor(); QTextCursor cursor = mDisasTextEdit->textCursor();
@ -346,11 +344,6 @@ void DisassemblyWidget::highlightCurrentLine()
QString searchString = cursor.selectedText(); QString searchString = cursor.selectedText();
curHighlightedWord = searchString; curHighlightedWord = searchString;
cursor.movePosition(QTextCursor::StartOfLine);
int listStartPos = cursor.position();
cursor.movePosition(QTextCursor::EndOfLine);
int lineEndPos = cursor.position();
// Highlight the current line // Highlight the current line
QTextEdit::ExtraSelection highlightSelection; QTextEdit::ExtraSelection highlightSelection;
highlightSelection.cursor = cursor; highlightSelection.cursor = cursor;
@ -374,26 +367,7 @@ void DisassemblyWidget::highlightCurrentLine()
} }
// Highlight all the words in the document same as the current one // Highlight all the words in the document same as the current one
QTextDocument *document = mDisasTextEdit->document(); extraSelections.append(getSameWordsSelections());
highlightSelection.cursor = cursor;
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
highlightSelection.cursor = document->find(searchString, highlightSelection.cursor,
QTextDocument::FindWholeWords);
if (!highlightSelection.cursor.isNull()) {
if (highlightSelection.cursor.position() >= listStartPos
&& highlightSelection.cursor.position() <= lineEndPos) {
highlightSelection.format.setBackground(highlightWordColor);
} else {
highlightSelection.format.setBackground(highlightWordColor);
}
extraSelections.append(highlightSelection);
}
}
// highlight PC line // highlight PC line
RVA PCAddr = Core()->getProgramCounterValue(); RVA PCAddr = Core()->getProgramCounterValue();
@ -457,7 +431,7 @@ void DisassemblyWidget::updateCursorPosition()
if (offset < topOffset || (offset > bottomOffset && bottomOffset != RVA_INVALID)) { if (offset < topOffset || (offset > bottomOffset && bottomOffset != RVA_INVALID)) {
mDisasTextEdit->moveCursor(QTextCursor::Start); mDisasTextEdit->moveCursor(QTextCursor::Start);
mDisasTextEdit->setExtraSelections({}); mDisasTextEdit->setExtraSelections(getSameWordsSelections());
} else { } else {
RVA currentCursorOffset = readCurrentDisassemblyOffset(); RVA currentCursorOffset = readCurrentDisassemblyOffset();
QTextCursor originalCursor = mDisasTextEdit->textCursor(); QTextCursor originalCursor = mDisasTextEdit->textCursor();
@ -471,6 +445,10 @@ void DisassemblyWidget::updateCursorPosition()
if (cursorLineOffset > 0) { if (cursorLineOffset > 0) {
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, cursorLineOffset); cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, cursorLineOffset);
} }
if (cursorCharOffset > 0) {
cursor.movePosition(QTextCursor::StartOfLine);
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, cursorCharOffset);
}
mDisasTextEdit->setTextCursor(cursor); mDisasTextEdit->setTextCursor(cursor);
highlightCurrentLine(); highlightCurrentLine();
@ -514,6 +492,7 @@ void DisassemblyWidget::cursorPositionChanged()
cursorLineOffset = 0; cursorLineOffset = 0;
QTextCursor c = mDisasTextEdit->textCursor(); QTextCursor c = mDisasTextEdit->textCursor();
cursorCharOffset = c.positionInBlock();
while (c.blockNumber() > 0) { while (c.blockNumber() > 0) {
c.movePosition(QTextCursor::PreviousBlock); c.movePosition(QTextCursor::PreviousBlock);
if (readDisassemblyOffset(c) != offset) { if (readDisassemblyOffset(c) != offset) {
@ -597,6 +576,33 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
} }
} }
QList<QTextEdit::ExtraSelection> DisassemblyWidget::getSameWordsSelections()
{
QList<QTextEdit::ExtraSelection> selections;
QTextEdit::ExtraSelection highlightSelection;
QTextDocument *document = mDisasTextEdit->document();
QColor highlightWordColor = ConfigColor("highlightWord");
if (curHighlightedWord.isNull()) {
return QList<QTextEdit::ExtraSelection>();
}
highlightSelection.cursor = mDisasTextEdit->textCursor();;
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
highlightSelection.cursor = document->find(curHighlightedWord, highlightSelection.cursor,
QTextDocument::FindWholeWords);
if (!highlightSelection.cursor.isNull()) {
highlightSelection.format.setBackground(highlightWordColor);
selections.append(highlightSelection);
}
}
return selections;
}
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event) bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
{ {
if (event->type() == QEvent::MouseButtonDblClick if (event->type() == QEvent::MouseButtonDblClick
@ -630,6 +636,7 @@ void DisassemblyWidget::on_seekChanged(RVA offset)
{ {
if (!seekFromCursor) { if (!seekFromCursor) {
cursorLineOffset = 0; cursorLineOffset = 0;
cursorCharOffset = 0;
} }
if (topOffset != RVA_INVALID if (topOffset != RVA_INVALID

View File

@ -58,6 +58,7 @@ private:
* offset of lines below the first line of the current seek * offset of lines below the first line of the current seek
*/ */
int cursorLineOffset; int cursorLineOffset;
int cursorCharOffset;
bool seekFromCursor; bool seekFromCursor;
RefreshDeferrer *disasmRefresh; RefreshDeferrer *disasmRefresh;
@ -76,6 +77,8 @@ private:
void connectCursorPositionChanged(bool disconnect); void connectCursorPositionChanged(bool disconnect);
void moveCursorRelative(bool up, bool page); void moveCursorRelative(bool up, bool page);
QList<QTextEdit::ExtraSelection> getSameWordsSelections();
QAction syncIt; QAction syncIt;
CutterSeekable *seekable; CutterSeekable *seekable;
}; };