Keep scroll history in decompiler widget. (#3177)

* Keep scroll history in decompiler widget.

This commit adds a `scrollHistory` on top of the rizin-managed
history, that keeps track of the scroll position within decompiled
functions.

* Fix clearing history upon init.
This commit is contained in:
Lucas Hosseini 2023-05-12 23:57:35 +02:00 committed by GitHub
parent f1a421c9f6
commit a6a7667852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 17 deletions

View File

@ -26,8 +26,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main)
ui(new Ui::DecompilerWidget),
decompilerBusy(false),
seekFromCursor(false),
scrollerHorizontal(0),
scrollerVertical(0),
historyPos(0),
previousFunctionAddr(RVA_INVALID),
decompiledFunctionAddr(RVA_INVALID),
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")),
@ -311,13 +310,6 @@ QTextCursor DecompilerWidget::getCursorForAddress(RVA addr)
void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled)
{
bool isDisplayReset = false;
if (previousFunctionAddr == decompiledFunctionAddr) {
scrollerHorizontal = ui->textEdit->horizontalScrollBar()->sliderPosition();
scrollerVertical = ui->textEdit->verticalScrollBar()->sliderPosition();
isDisplayReset = true;
}
ui->progressLabel->setVisible(false);
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
@ -354,10 +346,8 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled)
}
}
if (isDisplayReset) {
ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollerHorizontal);
ui->textEdit->verticalScrollBar()->setSliderPosition(scrollerVertical);
}
ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollHistory[historyPos].first);
ui->textEdit->verticalScrollBar()->setSliderPosition(scrollHistory[historyPos].second);
}
void DecompilerWidget::setAnnotationsAtCursor(size_t pos)
@ -416,11 +406,28 @@ void DecompilerWidget::cursorPositionChanged()
updateSelection();
}
void DecompilerWidget::seekChanged()
void DecompilerWidget::seekChanged(RVA /* addr */, CutterCore::SeekHistoryType type)
{
if (seekFromCursor) {
return;
}
if (!scrollHistory.empty()) { // History is empty upon init.
scrollHistory[historyPos] = { ui->textEdit->horizontalScrollBar()->sliderPosition(),
ui->textEdit->verticalScrollBar()->sliderPosition() };
}
if (type == CutterCore::SeekHistoryType::New) {
// Erase previous history past this point.
if (scrollHistory.size() > historyPos + 1) {
scrollHistory.erase(scrollHistory.begin() + historyPos + 1, scrollHistory.end());
}
scrollHistory.push_back({ 0, 0 });
historyPos = scrollHistory.size() - 1;
} else if (type == CutterCore::SeekHistoryType::Undo) {
--historyPos;
} else if (type == CutterCore::SeekHistoryType::Redo) {
++historyPos;
}
RVA fcnAddr = Core()->getFunctionStart(seekable->getOffset());
if (fcnAddr == RVA_INVALID || fcnAddr != decompiledFunctionAddr) {
doRefresh();

View File

@ -53,7 +53,7 @@ private slots:
* - Seek changed to an offset contained in the decompiled function.
* - Auto-refresh is disabled.
*/
void seekChanged();
void seekChanged(RVA /* addr */, CutterCore::SeekHistoryType type);
void decompilationFinished(RzAnnotatedCode *code);
private:
@ -72,8 +72,8 @@ private:
bool decompilerBusy;
bool seekFromCursor;
int scrollerHorizontal;
int scrollerVertical;
int historyPos;
QVector<QPair<int, int>> scrollHistory;
RVA previousFunctionAddr;
RVA decompiledFunctionAddr;
std::unique_ptr<RzAnnotatedCode, void (*)(RzAnnotatedCode *)> code;