mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
parent
81f7169379
commit
86473e3465
@ -652,3 +652,13 @@ void Configuration::setSelectedDecompiler(const QString &id)
|
||||
{
|
||||
s.setValue("selectedDecompiler", id);
|
||||
}
|
||||
|
||||
bool Configuration::getDecompilerAutoRefreshEnabled()
|
||||
{
|
||||
return s.value("decompilerAutoRefresh", true).toBool();
|
||||
}
|
||||
|
||||
void Configuration::setDecompilerAutoRefreshEnabled(bool enabled)
|
||||
{
|
||||
s.setValue("decompilerAutoRefresh", enabled);
|
||||
}
|
||||
|
@ -154,6 +154,9 @@ public:
|
||||
QString getSelectedDecompiler();
|
||||
void setSelectedDecompiler(const QString &id);
|
||||
|
||||
bool getDecompilerAutoRefreshEnabled();
|
||||
void setDecompilerAutoRefreshEnabled(bool enabled);
|
||||
|
||||
signals:
|
||||
void fontsUpdated();
|
||||
void colorsUpdated();
|
||||
|
@ -29,9 +29,24 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
|
||||
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
|
||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
||||
|
||||
// TODO Use RefreshDeferrer and remove the refresh button
|
||||
decompiledFunctionAddr = RVA_INVALID;
|
||||
decompilerWasBusy = false;
|
||||
|
||||
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
|
||||
doRefresh(Core()->getOffset());
|
||||
doRefresh();
|
||||
});
|
||||
|
||||
refreshDeferrer = createRefreshDeferrer([this]() {
|
||||
doRefresh();
|
||||
});
|
||||
|
||||
autoRefreshEnabled = Config()->getDecompilerAutoRefreshEnabled();
|
||||
ui->autoRefreshCheckBox->setChecked(autoRefreshEnabled);
|
||||
setAutoRefresh(autoRefreshEnabled);
|
||||
connect(ui->autoRefreshCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
setAutoRefresh(state == Qt::Checked);
|
||||
Config()->setDecompilerAutoRefreshEnabled(autoRefreshEnabled);
|
||||
doAutoRefresh();
|
||||
});
|
||||
|
||||
auto decompilers = Core()->getDecompilers();
|
||||
@ -64,19 +79,66 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
|
||||
|
||||
ui->progressLabel->setVisible(false);
|
||||
doRefresh(RVA_INVALID);
|
||||
|
||||
connect(Core(), &CutterCore::refreshAll, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::functionRenamed, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::varsChanged, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::functionsChanged, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::flagsChanged, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::commentsChanged, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::instructionChanged, this, &PseudocodeWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::refreshCodeViews, this, &PseudocodeWidget::doAutoRefresh);
|
||||
}
|
||||
|
||||
PseudocodeWidget::~PseudocodeWidget() = default;
|
||||
|
||||
Decompiler *PseudocodeWidget::getCurrentDecompiler()
|
||||
{
|
||||
return Core()->getDecompilerById(ui->decompilerComboBox->currentData().toString());
|
||||
}
|
||||
|
||||
void PseudocodeWidget::setAutoRefresh(bool enabled)
|
||||
{
|
||||
autoRefreshEnabled = enabled;
|
||||
updateRefreshButton();
|
||||
}
|
||||
|
||||
void PseudocodeWidget::doAutoRefresh()
|
||||
{
|
||||
if (!autoRefreshEnabled) {
|
||||
return;
|
||||
}
|
||||
doRefresh();
|
||||
}
|
||||
|
||||
void PseudocodeWidget::updateRefreshButton()
|
||||
{
|
||||
Decompiler *dec = getCurrentDecompiler();
|
||||
ui->refreshButton->setEnabled(!autoRefreshEnabled && dec && !dec->isRunning());
|
||||
if (dec && dec->isRunning() && dec->isCancelable()) {
|
||||
ui->refreshButton->setText(tr("Cancel"));
|
||||
} else {
|
||||
ui->refreshButton->setText(tr("Refresh"));
|
||||
}
|
||||
}
|
||||
|
||||
void PseudocodeWidget::doRefresh(RVA addr)
|
||||
{
|
||||
if (!refreshDeferrer->attemptRefresh(nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui->decompilerComboBox->currentIndex() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Decompiler *dec = Core()->getDecompilerById(ui->decompilerComboBox->currentData().toString());
|
||||
if (!dec || dec->isRunning()) {
|
||||
Decompiler *dec = getCurrentDecompiler();
|
||||
if (!dec) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dec->isRunning()) {
|
||||
decompilerWasBusy = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -89,26 +151,21 @@ void PseudocodeWidget::doRefresh(RVA addr)
|
||||
if (dec->isRunning()) {
|
||||
ui->progressLabel->setVisible(true);
|
||||
ui->decompilerComboBox->setEnabled(false);
|
||||
if (dec->isCancelable()) {
|
||||
ui->refreshButton->setText(tr("Cancel"));
|
||||
} else {
|
||||
ui->refreshButton->setEnabled(false);
|
||||
}
|
||||
updateRefreshButton();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PseudocodeWidget::refreshPseudocode()
|
||||
{
|
||||
doRefresh(Core()->getOffset());
|
||||
doRefresh();
|
||||
}
|
||||
|
||||
void PseudocodeWidget::decompilationFinished(AnnotatedCode code)
|
||||
{
|
||||
ui->progressLabel->setVisible(false);
|
||||
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
|
||||
ui->refreshButton->setText(tr("Refresh"));
|
||||
ui->refreshButton->setEnabled(true);
|
||||
updateRefreshButton();
|
||||
|
||||
this->code = code;
|
||||
if (code.code.isEmpty()) {
|
||||
@ -118,13 +175,21 @@ void PseudocodeWidget::decompilationFinished(AnnotatedCode code)
|
||||
connectCursorPositionChanged(true);
|
||||
ui->textEdit->setPlainText(code.code);
|
||||
connectCursorPositionChanged(false);
|
||||
seekChanged();
|
||||
updateCursorPosition();
|
||||
}
|
||||
|
||||
if (decompilerWasBusy) {
|
||||
decompilerWasBusy = false;
|
||||
doAutoRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
void PseudocodeWidget::decompilerSelected()
|
||||
{
|
||||
Config()->setSelectedDecompiler(ui->decompilerComboBox->currentData().toString());
|
||||
if (autoRefreshEnabled) {
|
||||
doRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
void PseudocodeWidget::connectCursorPositionChanged(bool disconnect)
|
||||
@ -154,6 +219,15 @@ void PseudocodeWidget::seekChanged()
|
||||
if (seekFromCursor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (autoRefreshEnabled) {
|
||||
auto fcnAddr = Core()->getFunctionStart(Core()->getOffset());
|
||||
if (fcnAddr == RVA_INVALID || fcnAddr != decompiledFunctionAddr) {
|
||||
doRefresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
updateCursorPosition();
|
||||
}
|
||||
|
||||
@ -212,5 +286,5 @@ void PseudocodeWidget::colorsUpdatedSlot()
|
||||
void PseudocodeWidget::showDisasContextMenu(const QPoint &pt)
|
||||
{
|
||||
mCtxMenu->exec(ui->textEdit->mapToGlobal(pt));
|
||||
doRefresh(Core()->getOffset());
|
||||
doRefresh();
|
||||
}
|
@ -41,14 +41,29 @@ private slots:
|
||||
private:
|
||||
std::unique_ptr<Ui::PseudocodeWidget> ui;
|
||||
|
||||
RefreshDeferrer *refreshDeferrer;
|
||||
|
||||
QSyntaxHighlighter *syntaxHighlighter;
|
||||
bool decompilerSelectionEnabled;
|
||||
bool autoRefreshEnabled;
|
||||
|
||||
/**
|
||||
* True if doRefresh() was called, but the decompiler was still running
|
||||
* This means, after the decompiler has finished, it should be refreshed immediately.
|
||||
*/
|
||||
bool decompilerWasBusy;
|
||||
|
||||
RVA decompiledFunctionAddr;
|
||||
AnnotatedCode code;
|
||||
|
||||
bool seekFromCursor = false;
|
||||
|
||||
void doRefresh(RVA addr);
|
||||
Decompiler *getCurrentDecompiler();
|
||||
|
||||
void setAutoRefresh(bool enabled);
|
||||
void doAutoRefresh();
|
||||
void doRefresh(RVA addr = Core()->getOffset());
|
||||
void updateRefreshButton();
|
||||
void setupFonts();
|
||||
void updateSelection();
|
||||
void connectCursorPositionChanged(bool disconnect);
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<width>555</width>
|
||||
<height>393</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -42,6 +42,13 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoRefreshCheckBox">
|
||||
<property name="text">
|
||||
<string>Auto Refresh</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refreshButton">
|
||||
<property name="text">
|
||||
|
Loading…
Reference in New Issue
Block a user