mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +00:00
WIP First PoC to draw only visible after seek
This commit is contained in:
parent
7f80f96c55
commit
f4c720cffa
@ -177,44 +177,44 @@ void MainWindow::initUI()
|
||||
|
||||
disassemblyDock = new DisassemblyWidget(this, ui->actionDisassembly);
|
||||
hexdumpDock = new HexdumpWidget(this, ui->actionHexdump);
|
||||
pseudocodeDock = new PseudocodeWidget(this, ui->actionPseudocode);
|
||||
//pseudocodeDock = new PseudocodeWidget(this, ui->actionPseudocode);
|
||||
consoleDock = new ConsoleWidget(this, ui->actionConsole);
|
||||
|
||||
// Add graph view as dockable
|
||||
graphDock = new GraphWidget(this, ui->actionGraph);
|
||||
|
||||
sectionsDock = new SectionsWidget(this, ui->actionSections);
|
||||
segmentsDock = new SegmentsWidget(this, ui->actionSegments);
|
||||
entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
||||
//sectionsDock = new SectionsWidget(this, ui->actionSections);
|
||||
//segmentsDock = new SegmentsWidget(this, ui->actionSegments);
|
||||
//entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
||||
functionsDock = new FunctionsWidget(this, ui->actionFunctions);
|
||||
importsDock = new ImportsWidget(this, ui->actionImports);
|
||||
exportsDock = new ExportsWidget(this, ui->actionExports);
|
||||
headersDock = new HeadersWidget(this, ui->actionHeaders);
|
||||
zignaturesDock = new ZignaturesWidget(this, ui->actionZignatures);
|
||||
typesDock = new TypesWidget(this, ui->actionTypes);
|
||||
searchDock = new SearchWidget(this, ui->actionSearch);
|
||||
symbolsDock = new SymbolsWidget(this, ui->actionSymbols);
|
||||
relocsDock = new RelocsWidget(this, ui->actionRelocs);
|
||||
commentsDock = new CommentsWidget(this, ui->actionComments);
|
||||
stringsDock = new StringsWidget(this, ui->actionStrings);
|
||||
flagsDock = new FlagsWidget(this, ui->actionFlags);
|
||||
stackDock = new StackWidget(this, ui->actionStack);
|
||||
backtraceDock = new BacktraceWidget(this, ui->actionBacktrace);
|
||||
registersDock = new RegistersWidget(this, ui->actionRegisters);
|
||||
memoryMapDock = new MemoryMapWidget(this, ui->actionMemoryMap);
|
||||
breakpointDock = new BreakpointWidget(this, ui->actionBreakpoint);
|
||||
registerRefsDock = new RegisterRefsWidget(this, ui->actionRegisterRefs);
|
||||
//importsDock = new ImportsWidget(this, ui->actionImports);
|
||||
//exportsDock = new ExportsWidget(this, ui->actionExports);
|
||||
//headersDock = new HeadersWidget(this, ui->actionHeaders);
|
||||
//zignaturesDock = new ZignaturesWidget(this, ui->actionZignatures);
|
||||
//typesDock = new TypesWidget(this, ui->actionTypes);
|
||||
//searchDock = new SearchWidget(this, ui->actionSearch);
|
||||
//symbolsDock = new SymbolsWidget(this, ui->actionSymbols);
|
||||
//relocsDock = new RelocsWidget(this, ui->actionRelocs);
|
||||
//commentsDock = new CommentsWidget(this, ui->actionComments);
|
||||
//stringsDock = new StringsWidget(this, ui->actionStrings);
|
||||
//flagsDock = new FlagsWidget(this, ui->actionFlags);
|
||||
//stackDock = new StackWidget(this, ui->actionStack);
|
||||
//backtraceDock = new BacktraceWidget(this, ui->actionBacktrace);
|
||||
//registersDock = new RegistersWidget(this, ui->actionRegisters);
|
||||
//memoryMapDock = new MemoryMapWidget(this, ui->actionMemoryMap);
|
||||
//breakpointDock = new BreakpointWidget(this, ui->actionBreakpoint);
|
||||
//registerRefsDock = new RegisterRefsWidget(this, ui->actionRegisterRefs);
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
jupyterDock = new JupyterWidget(this, ui->actionJupyter);
|
||||
//jupyterDock = new JupyterWidget(this, ui->actionJupyter);
|
||||
#else
|
||||
ui->actionJupyter->setEnabled(false);
|
||||
ui->actionJupyter->setVisible(false);
|
||||
#endif
|
||||
dashboardDock = new Dashboard(this, ui->actionDashboard);
|
||||
sdbDock = new SdbDock(this, ui->actionSDBBrowser);
|
||||
classesDock = new ClassesWidget(this, ui->actionClasses);
|
||||
resourcesDock = new ResourcesWidget(this, ui->actionResources);
|
||||
vTablesDock = new VTablesWidget(this, ui->actionVTables);
|
||||
//sdbDock = new SdbDock(this, ui->actionSDBBrowser);
|
||||
//classesDock = new ClassesWidget(this, ui->actionClasses);
|
||||
//resourcesDock = new ResourcesWidget(this, ui->actionResources);
|
||||
//vTablesDock = new VTablesWidget(this, ui->actionVTables);
|
||||
|
||||
|
||||
// Set up dock widgets default layout
|
||||
@ -543,7 +543,7 @@ void MainWindow::lockUnlock_Docks(bool what)
|
||||
void MainWindow::restoreDocks()
|
||||
{
|
||||
// In the upper half the functions are the first widget
|
||||
addDockWidget(Qt::TopDockWidgetArea, functionsDock);
|
||||
//addDockWidget(Qt::TopDockWidgetArea, functionsDock);
|
||||
|
||||
// Function | Dashboard
|
||||
splitDockWidget(functionsDock, dashboardDock, Qt::Horizontal);
|
||||
@ -552,41 +552,41 @@ void MainWindow::restoreDocks()
|
||||
addDockWidget(Qt::BottomDockWidgetArea, consoleDock);
|
||||
|
||||
// Console | Sections
|
||||
splitDockWidget(consoleDock, sectionsDock, Qt::Horizontal);
|
||||
splitDockWidget(consoleDock, segmentsDock, Qt::Horizontal);
|
||||
//splitDockWidget(consoleDock, sectionsDock, Qt::Horizontal);
|
||||
//splitDockWidget(consoleDock, segmentsDock, Qt::Horizontal);
|
||||
|
||||
// Tabs for center (must be applied after splitDockWidget())
|
||||
tabifyDockWidget(sectionsDock, commentsDock);
|
||||
tabifyDockWidget(segmentsDock, commentsDock);
|
||||
//tabifyDockWidget(sectionsDock, commentsDock);
|
||||
//tabifyDockWidget(segmentsDock, commentsDock);
|
||||
tabifyDockWidget(dashboardDock, disassemblyDock);
|
||||
tabifyDockWidget(dashboardDock, graphDock);
|
||||
tabifyDockWidget(dashboardDock, hexdumpDock);
|
||||
tabifyDockWidget(dashboardDock, pseudocodeDock);
|
||||
tabifyDockWidget(dashboardDock, entrypointDock);
|
||||
tabifyDockWidget(dashboardDock, flagsDock);
|
||||
tabifyDockWidget(dashboardDock, stringsDock);
|
||||
tabifyDockWidget(dashboardDock, relocsDock);
|
||||
tabifyDockWidget(dashboardDock, importsDock);
|
||||
tabifyDockWidget(dashboardDock, exportsDock);
|
||||
tabifyDockWidget(dashboardDock, typesDock);
|
||||
tabifyDockWidget(dashboardDock, searchDock);
|
||||
tabifyDockWidget(dashboardDock, headersDock);
|
||||
tabifyDockWidget(dashboardDock, zignaturesDock);
|
||||
tabifyDockWidget(dashboardDock, symbolsDock);
|
||||
tabifyDockWidget(dashboardDock, classesDock);
|
||||
tabifyDockWidget(dashboardDock, resourcesDock);
|
||||
tabifyDockWidget(dashboardDock, vTablesDock);
|
||||
//tabifyDockWidget(dashboardDock, pseudocodeDock);
|
||||
//tabifyDockWidget(dashboardDock, entrypointDock);
|
||||
//tabifyDockWidget(dashboardDock, flagsDock);
|
||||
//tabifyDockWidget(dashboardDock, stringsDock);
|
||||
//tabifyDockWidget(dashboardDock, relocsDock);
|
||||
//tabifyDockWidget(dashboardDock, importsDock);
|
||||
//tabifyDockWidget(dashboardDock, exportsDock);
|
||||
//tabifyDockWidget(dashboardDock, typesDock);
|
||||
//tabifyDockWidget(dashboardDock, searchDock);
|
||||
//tabifyDockWidget(dashboardDock, headersDock);
|
||||
//tabifyDockWidget(dashboardDock, zignaturesDock);
|
||||
//tabifyDockWidget(dashboardDock, symbolsDock);
|
||||
//tabifyDockWidget(dashboardDock, classesDock);
|
||||
//tabifyDockWidget(dashboardDock, resourcesDock);
|
||||
//tabifyDockWidget(dashboardDock, vTablesDock);
|
||||
|
||||
// Add Stack, Registers and Backtrace vertically stacked
|
||||
addDockWidget(Qt::TopDockWidgetArea, stackDock);
|
||||
splitDockWidget(stackDock, registersDock, Qt::Vertical);
|
||||
tabifyDockWidget(stackDock, backtraceDock);
|
||||
//addDockWidget(Qt::TopDockWidgetArea, stackDock);
|
||||
//splitDockWidget(stackDock, registersDock, Qt::Vertical);
|
||||
//tabifyDockWidget(stackDock, backtraceDock);
|
||||
// MemoryMap/Breakpoint/RegRefs widget goes in the center tabs
|
||||
tabifyDockWidget(dashboardDock, memoryMapDock);
|
||||
tabifyDockWidget(dashboardDock, breakpointDock);
|
||||
tabifyDockWidget(dashboardDock, registerRefsDock);
|
||||
//tabifyDockWidget(dashboardDock, memoryMapDock);
|
||||
//tabifyDockWidget(dashboardDock, breakpointDock);
|
||||
//tabifyDockWidget(dashboardDock, registerRefsDock);
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
tabifyDockWidget(dashboardDock, jupyterDock);
|
||||
//tabifyDockWidget(dashboardDock, jupyterDock);
|
||||
#endif
|
||||
|
||||
updateDockActionsChecked();
|
||||
|
@ -57,6 +57,8 @@ private:
|
||||
void removeLastLine();
|
||||
void executeCommand(const QString &command);
|
||||
|
||||
void refreshContent() override { }
|
||||
|
||||
QSharedPointer<CommandTask> commandTask;
|
||||
|
||||
std::unique_ptr<Ui::ConsoleWidget> ui;
|
||||
|
@ -11,8 +11,21 @@ CutterDockWidget::CutterDockWidget(MainWindow *main, QAction *action) :
|
||||
main->addDockWidgetAction(this, action);
|
||||
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
|
||||
}
|
||||
|
||||
// Install event filter to catch redraw widgets when needed
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
CutterDockWidget::~CutterDockWidget() {}
|
||||
|
||||
bool CutterDockWidget::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FocusIn || event->type() == QEvent::Paint) {
|
||||
qDebug() << object << "is now focused in";
|
||||
refreshIfNeeded();
|
||||
}
|
||||
return QDockWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void CutterDockWidget::toggleDockWidget(bool show)
|
||||
{
|
||||
@ -21,6 +34,15 @@ void CutterDockWidget::toggleDockWidget(bool show)
|
||||
} else {
|
||||
this->show();
|
||||
this->raise();
|
||||
this->refreshIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
void CutterDockWidget::refreshIfNeeded()
|
||||
{
|
||||
if (doRefresh) {
|
||||
refreshContent();
|
||||
doRefresh = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,4 +54,13 @@ void CutterDockWidget::closeEvent(QCloseEvent *event)
|
||||
QDockWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
CutterDockWidget::~CutterDockWidget() {}
|
||||
bool CutterDockWidget::isVisibleToUser()
|
||||
{
|
||||
// Check if the user can actually see the widget.
|
||||
bool visibleToUser = this->isVisible() && !this->visibleRegion().isEmpty();
|
||||
if (!visibleToUser) {
|
||||
// If this is called and not visible, it must be refreshed later
|
||||
doRefresh = true;
|
||||
}
|
||||
return visibleToUser;
|
||||
}
|
||||
|
@ -7,21 +7,29 @@ class MainWindow;
|
||||
|
||||
class CutterDockWidget : public QDockWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CutterDockWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~CutterDockWidget();
|
||||
~CutterDockWidget() override;
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void toggleDockWidget(bool show);
|
||||
|
||||
|
||||
private:
|
||||
QAction *action;
|
||||
|
||||
/**
|
||||
* @brief doRefresh tells if the widget must refresh its content.
|
||||
*/
|
||||
bool doRefresh = false;
|
||||
void refreshIfNeeded();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
bool isVisibleToUser();
|
||||
virtual void refreshContent() = 0;
|
||||
};
|
||||
|
||||
#endif // CUTTERWIDGET_H
|
||||
|
@ -25,6 +25,8 @@ private slots:
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::Dashboard> ui;
|
||||
|
||||
void refreshContent() override { };
|
||||
};
|
||||
|
||||
#endif // DASHBOARD_H
|
||||
|
@ -268,6 +268,11 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
mDisasTextEdit->horizontalScrollBar()->setValue(horizontalScrollValue);
|
||||
}
|
||||
|
||||
void DisassemblyWidget::refreshContent()
|
||||
{
|
||||
refreshDisasm();
|
||||
}
|
||||
|
||||
|
||||
void DisassemblyWidget::scrollInstructions(int count)
|
||||
{
|
||||
@ -576,7 +581,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
|
||||
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport())
|
||||
/*if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport())
|
||||
&& event->type() == QEvent::MouseButtonDblClick) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
|
||||
@ -599,8 +604,8 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return QDockWidget::eventFilter(obj, event);
|
||||
}*/
|
||||
return CutterDockWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void DisassemblyWidget::on_seekChanged(RVA offset)
|
||||
|
@ -24,7 +24,6 @@ public:
|
||||
public slots:
|
||||
void highlightCurrentLine();
|
||||
void showDisasContextMenu(const QPoint &pt);
|
||||
void refreshDisasm(RVA offset = RVA_INVALID);
|
||||
void fontsUpdatedSlot();
|
||||
void colorsUpdatedSlot();
|
||||
void seekPrev();
|
||||
@ -32,6 +31,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void on_seekChanged(RVA offset);
|
||||
void refreshDisasm(RVA offset = RVA_INVALID);
|
||||
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
|
||||
|
||||
void scrollInstructions(int count);
|
||||
@ -59,10 +59,12 @@ private:
|
||||
|
||||
RVA readCurrentDisassemblyOffset();
|
||||
RVA readDisassemblyOffset(QTextCursor tc);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
QList<RVA> breakpoints;
|
||||
|
||||
void refreshContent() override;
|
||||
|
||||
void setupFonts();
|
||||
void setupColors();
|
||||
|
||||
|
@ -137,6 +137,8 @@ private:
|
||||
CutterTreeWidget *tree;
|
||||
|
||||
void setScrollMode();
|
||||
|
||||
void refreshContent() override { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -39,3 +39,8 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
}
|
||||
|
||||
GraphWidget::~GraphWidget() {}
|
||||
|
||||
void GraphWidget::refreshContent()
|
||||
{
|
||||
graphView->refreshView();
|
||||
}
|
||||
|
@ -12,11 +12,13 @@ class GraphWidget : public CutterDockWidget
|
||||
|
||||
public:
|
||||
explicit GraphWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~GraphWidget();
|
||||
~GraphWidget() override;
|
||||
|
||||
private:
|
||||
DisassemblerGraphView *graphView;
|
||||
|
||||
void refreshContent() override;
|
||||
|
||||
};
|
||||
|
||||
#endif // GRAPHWIDGET_H
|
||||
|
@ -116,7 +116,7 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, this,
|
||||
&HexdumpWidget::selectionChanged);
|
||||
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::on_seekChanged);
|
||||
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::onSeekChanged);
|
||||
connect(&rangeDialog, &QDialog::accepted, this, &HexdumpWidget::on_rangeDialogAccepted);
|
||||
|
||||
format = Format::Hex;
|
||||
@ -208,13 +208,15 @@ void HexdumpWidget::setupScrollSync()
|
||||
asciiHexFunc);
|
||||
}
|
||||
|
||||
void HexdumpWidget::on_seekChanged(RVA addr)
|
||||
void HexdumpWidget::onSeekChanged(RVA addr)
|
||||
{
|
||||
if (sent_seek) {
|
||||
sent_seek = false;
|
||||
return;
|
||||
}
|
||||
refresh(addr);
|
||||
if (isVisibleToUser()) {
|
||||
refreshContent();
|
||||
}
|
||||
}
|
||||
|
||||
void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
||||
|
@ -72,6 +72,7 @@ private:
|
||||
RVA last_loaded_address = RVA_INVALID;
|
||||
|
||||
void refresh(RVA addr = RVA_INVALID);
|
||||
void refreshContent() override { refresh(); }
|
||||
void selectHexPreview();
|
||||
void updateHeaders();
|
||||
|
||||
@ -110,7 +111,7 @@ private:
|
||||
CutterSeekable *seekable;
|
||||
|
||||
private slots:
|
||||
void on_seekChanged(RVA addr);
|
||||
void onSeekChanged(RVA addr);
|
||||
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
|
||||
|
||||
// Currently unused/untested
|
||||
|
@ -31,7 +31,7 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
|
||||
});
|
||||
|
||||
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
|
||||
refresh(Core()->getOffset());
|
||||
doRefresh(Core()->getOffset());
|
||||
});
|
||||
|
||||
if (Core()->getR2DecAvailable()) {
|
||||
@ -42,13 +42,13 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
|
||||
ui->decompilerComboBox->setCurrentIndex(DecompilerCBPdc);
|
||||
}
|
||||
|
||||
refresh(RVA_INVALID);
|
||||
doRefresh(RVA_INVALID);
|
||||
}
|
||||
|
||||
PseudocodeWidget::~PseudocodeWidget() {}
|
||||
|
||||
|
||||
void PseudocodeWidget::refresh(RVA addr)
|
||||
void PseudocodeWidget::doRefresh(RVA addr)
|
||||
{
|
||||
if (addr == RVA_INVALID) {
|
||||
ui->textEdit->setText(tr("Click Refresh to generate Pseudocode from current offset."));
|
||||
@ -78,7 +78,7 @@ void PseudocodeWidget::refresh(RVA addr)
|
||||
|
||||
void PseudocodeWidget::refreshPseudocode()
|
||||
{
|
||||
refresh(Core()->getOffset());
|
||||
doRefresh(Core()->getOffset());
|
||||
}
|
||||
|
||||
void PseudocodeWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
||||
|
@ -33,7 +33,7 @@ private:
|
||||
|
||||
SyntaxHighlighter *syntaxHighLighter;
|
||||
|
||||
void refresh(RVA addr);
|
||||
void doRefresh(RVA addr);
|
||||
void setupFonts();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user