mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +00:00
Vane11ope/fix layout (#1308)
Refactoring and Fixes for the default layout.
This commit is contained in:
parent
f23ff9d8c5
commit
96f6e062fc
@ -123,9 +123,49 @@ void MainWindow::initUI()
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
initToolBar();
|
||||
initDocks();
|
||||
initLayout();
|
||||
|
||||
/*
|
||||
* Toolbar
|
||||
* Some global shortcuts
|
||||
*/
|
||||
// Period goes to command entry
|
||||
QShortcut *cmd_shortcut = new QShortcut(QKeySequence(Qt::Key_Period), this);
|
||||
connect(cmd_shortcut, SIGNAL(activated()), consoleDock, SLOT(focusInputLineEdit()));
|
||||
|
||||
// G and S goes to goto entry
|
||||
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
|
||||
connect(goto_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
|
||||
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
|
||||
connect(seek_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
|
||||
|
||||
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
|
||||
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshAll()));
|
||||
|
||||
connect(core, SIGNAL(projectSaved(bool, const QString &)), this, SLOT(projectSaved(bool,
|
||||
const QString &)));
|
||||
|
||||
connect(core, &CutterCore::changeDebugView, this, &MainWindow::changeDebugView);
|
||||
connect(core, &CutterCore::changeDefinedView, this, &MainWindow::changeDefinedView);
|
||||
|
||||
connect(core, SIGNAL(newMessage(const QString &)),
|
||||
this->consoleDock, SLOT(addOutput(const QString &)));
|
||||
connect(core, SIGNAL(newDebugMessage(const QString &)),
|
||||
this->consoleDock, SLOT(addDebugOutput(const QString &)));
|
||||
|
||||
updateTasksIndicator();
|
||||
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
|
||||
&MainWindow::updateTasksIndicator);
|
||||
|
||||
/* Setup plugins interfaces */
|
||||
for (auto plugin : Plugins()->getPlugins()) {
|
||||
plugin->setupInterface(this);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::initToolBar()
|
||||
{
|
||||
// Sepparator between undo/redo and goto lineEdit
|
||||
QWidget *spacer3 = new QWidget();
|
||||
spacer3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
@ -186,18 +226,15 @@ void MainWindow::initUI()
|
||||
QObject::connect(configuration, &Configuration::colorsUpdated, [this]() {
|
||||
this->visualNavbar->updateGraphicsScene();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Dock Widgets
|
||||
*/
|
||||
void MainWindow::initDocks()
|
||||
{
|
||||
dockWidgets.reserve(20);
|
||||
|
||||
disassemblyDock = new DisassemblyWidget(this, ui->actionDisassembly);
|
||||
hexdumpDock = new HexdumpWidget(this, ui->actionHexdump);
|
||||
pseudocodeDock = new PseudocodeWidget(this, ui->actionPseudocode);
|
||||
consoleDock = new ConsoleWidget(this, ui->actionConsole);
|
||||
|
||||
// Add graph view as dockable
|
||||
overviewDock = new OverviewWidget(this, ui->actionOverview);
|
||||
overviewDock->hide();
|
||||
graphDock = new GraphWidget(this, ui->actionGraph);
|
||||
@ -242,57 +279,18 @@ void MainWindow::initUI()
|
||||
classesDock = new ClassesWidget(this, ui->actionClasses);
|
||||
resourcesDock = new ResourcesWidget(this, ui->actionResources);
|
||||
vTablesDock = new VTablesWidget(this, ui->actionVTables);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::initLayout()
|
||||
{
|
||||
// Set up dock widgets default layout
|
||||
resetToDefaultLayout();
|
||||
enableDebugWidgetsMenu(false);
|
||||
|
||||
// Restore saved settings
|
||||
this->readSettings();
|
||||
readSettingsOrDefault();
|
||||
// TODO: Allow the user to select this option visually in the GUI settings
|
||||
// Adjust the DockWidget areas
|
||||
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
|
||||
//setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
|
||||
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||
//setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
|
||||
|
||||
|
||||
/*
|
||||
* Some global shortcuts
|
||||
*/
|
||||
// Period goes to command entry
|
||||
QShortcut *cmd_shortcut = new QShortcut(QKeySequence(Qt::Key_Period), this);
|
||||
connect(cmd_shortcut, SIGNAL(activated()), consoleDock, SLOT(focusInputLineEdit()));
|
||||
|
||||
// G and S goes to goto entry
|
||||
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
|
||||
connect(goto_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
|
||||
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
|
||||
connect(seek_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
|
||||
|
||||
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
|
||||
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshAll()));
|
||||
|
||||
connect(core, SIGNAL(projectSaved(bool, const QString &)), this, SLOT(projectSaved(bool,
|
||||
const QString &)));
|
||||
|
||||
connect(core, &CutterCore::changeDebugView, this, &MainWindow::changeDebugView);
|
||||
connect(core, &CutterCore::changeDefinedView, this, &MainWindow::changeDefinedView);
|
||||
|
||||
connect(core, SIGNAL(newMessage(const QString &)),
|
||||
this->consoleDock, SLOT(addOutput(const QString &)));
|
||||
connect(core, SIGNAL(newDebugMessage(const QString &)),
|
||||
this->consoleDock, SLOT(addDebugOutput(const QString &)));
|
||||
|
||||
updateTasksIndicator();
|
||||
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
|
||||
&MainWindow::updateTasksIndicator);
|
||||
|
||||
/* Setup plugins interfaces */
|
||||
for (auto plugin : Plugins()->getPlugins()) {
|
||||
plugin->setupInterface(this);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
|
||||
@ -327,13 +325,17 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
|
||||
|
||||
void MainWindow::disconnectOverview()
|
||||
{
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(viewRefreshed()), this, SLOT(forceUpdateOverview()));
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
|
||||
disconnect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
disconnect(overviewDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
|
||||
disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview);
|
||||
disconnect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview()));
|
||||
if (targetGraphDock) {
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(viewRefreshed()), this, SLOT(updateOverview()));
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
|
||||
}
|
||||
if (overviewDock) {
|
||||
disconnect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
disconnect(overviewDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
|
||||
disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview);
|
||||
disconnect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview()));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setOverviewData()
|
||||
@ -616,14 +618,37 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::readSettings()
|
||||
void MainWindow::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QMainWindow::paintEvent(event);
|
||||
/*
|
||||
* Dirty hack
|
||||
* Just to adjust the width of Functions Widget to fixed size
|
||||
* After everything is drawn, safely make it Preferred size policy
|
||||
* So that user can change the widget size with the mouse
|
||||
*/
|
||||
if (functionsDock) {
|
||||
functionsDock->changeSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::readSettingsOrDefault()
|
||||
{
|
||||
QSettings settings;
|
||||
QByteArray geo = settings.value("geometry", QByteArray()).toByteArray();
|
||||
restoreGeometry(geo);
|
||||
QByteArray state = settings.value("state", QByteArray()).toByteArray();
|
||||
/*
|
||||
* Check if saved settings exist
|
||||
* If not, then read the default layout
|
||||
*/
|
||||
if (!geo.length() && !state.length()) {
|
||||
resetToDefaultLayout();
|
||||
return;
|
||||
}
|
||||
hideAllDocks();
|
||||
restoreGeometry(geo);
|
||||
restoreState(state);
|
||||
this->responsive = settings.value("responsive").toBool();
|
||||
responsive = settings.value("responsive").toBool();
|
||||
panelLock = settings.value("panelLock").toBool();
|
||||
setPanelLock();
|
||||
tabsOnTop = settings.value("tabsOnTop").toBool();
|
||||
@ -778,8 +803,6 @@ void MainWindow::hideAllDocks()
|
||||
for (auto w : dockWidgets) {
|
||||
removeDockWidget(w);
|
||||
}
|
||||
|
||||
updateDockActionsChecked();
|
||||
}
|
||||
|
||||
void MainWindow::updateDockActionsChecked()
|
||||
@ -855,16 +878,6 @@ void MainWindow::resetToDefaultLayout()
|
||||
restoreDocks();
|
||||
showZenDocks();
|
||||
dashboardDock->raise();
|
||||
|
||||
// Ugly workaround to set the default widths of functions docks
|
||||
// if anyone finds a way to do this cleaner that also works, feel free to change it!
|
||||
auto restoreFunctionDock = qhelpers::forceWidth(functionsDock->widget(), 200);
|
||||
auto restoreOverviewDock = qhelpers::forceWidth(overviewDock->widget(), 200);
|
||||
qApp->processEvents();
|
||||
restoreFunctionDock.restoreWidth(functionsDock->widget());
|
||||
restoreOverviewDock.restoreWidth(overviewDock->widget());
|
||||
|
||||
core->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
|
||||
}
|
||||
|
||||
void MainWindow::resetToDebugLayout()
|
||||
@ -927,6 +940,7 @@ void MainWindow::on_actionFunctionsRename_triggered()
|
||||
|
||||
void MainWindow::on_actionDefault_triggered()
|
||||
{
|
||||
disconnectOverview();
|
||||
if (core->currentlyDebugging) {
|
||||
resetToDebugLayout();
|
||||
} else {
|
||||
@ -1203,7 +1217,7 @@ void MainWindow::changeDefinedView()
|
||||
CutterCore::MemoryWidgetType memType = core->getMemoryWidgetPriority();
|
||||
hideAllDocks();
|
||||
restoreDocks();
|
||||
readSettings();
|
||||
readSettingsOrDefault();
|
||||
enableDebugWidgetsMenu(false);
|
||||
core->raisePrioritizedMemoryWidget(memType);
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ public:
|
||||
bool saveProjectAs(bool quit = false);
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void readSettings();
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void readSettingsOrDefault();
|
||||
void saveSettings();
|
||||
void readDebugSettings();
|
||||
void saveDebugSettings();
|
||||
@ -254,6 +255,9 @@ private:
|
||||
JupyterWidget *jupyterDock = nullptr;
|
||||
#endif
|
||||
|
||||
void initToolBar();
|
||||
void initDocks();
|
||||
void initLayout();
|
||||
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false);
|
||||
|
||||
void resetToDefaultLayout();
|
||||
|
@ -8,8 +8,8 @@ CutterDockWidget::CutterDockWidget(MainWindow *parent, QAction *action) :
|
||||
QDockWidget(parent),
|
||||
action(action)
|
||||
{
|
||||
parent->addToDockWidgetList(this);
|
||||
if (action) {
|
||||
parent->addToDockWidgetList(this);
|
||||
parent->addDockWidgetAction(this, action);
|
||||
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
|
||||
}
|
||||
|
@ -42,6 +42,18 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
||||
, seekable(new CutterSeekable(this))
|
||||
{
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Disassembly";
|
||||
if (!action) {
|
||||
name = "Extra Disassembly";
|
||||
}
|
||||
setObjectName(name);
|
||||
|
||||
topOffset = bottomOffset = RVA_INVALID;
|
||||
cursorLineOffset = 0;
|
||||
seekFromCursor = false;
|
||||
@ -57,7 +69,6 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
setWidget(mDisasScrollArea);
|
||||
|
||||
setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
setObjectName("DisassemblyWidget");
|
||||
|
||||
setupFonts();
|
||||
setupColors();
|
||||
|
@ -566,6 +566,11 @@ void FunctionsWidget::refreshTree()
|
||||
Core()->getAsyncTaskManager()->start(task);
|
||||
}
|
||||
|
||||
void FunctionsWidget::changeSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver)
|
||||
{
|
||||
ui->dockWidgetContents->setSizePolicy(hor, ver);
|
||||
}
|
||||
|
||||
void FunctionsWidget::onFunctionsDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
@ -101,21 +101,18 @@ class FunctionsWidget : public CutterDockWidget
|
||||
public:
|
||||
explicit FunctionsWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~FunctionsWidget();
|
||||
void changeSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver);
|
||||
|
||||
private slots:
|
||||
void onFunctionsDoubleClicked(const QModelIndex &index);
|
||||
void showFunctionsContextMenu(const QPoint &pt);
|
||||
|
||||
void on_actionDisasAdd_comment_triggered();
|
||||
void on_actionFunctionsRename_triggered();
|
||||
void on_action_References_triggered();
|
||||
void on_actionFunctionsUndefine_triggered();
|
||||
|
||||
void on_actionHorizontal_triggered();
|
||||
void on_actionVertical_triggered();
|
||||
|
||||
void showTitleContextMenu(const QPoint &pt);
|
||||
|
||||
void refreshTree();
|
||||
|
||||
protected:
|
||||
@ -124,18 +121,13 @@ protected:
|
||||
private:
|
||||
std::unique_ptr<Ui::FunctionsWidget> ui;
|
||||
MainWindow *main;
|
||||
|
||||
QSharedPointer<FunctionsTask> task;
|
||||
|
||||
QList<FunctionDescription> functions;
|
||||
QSet<RVA> importAddresses;
|
||||
ut64 mainAdress;
|
||||
|
||||
FunctionModel *functionModel;
|
||||
FunctionSortFilterProxyModel *functionProxyModel;
|
||||
|
||||
CutterTreeWidget *tree;
|
||||
|
||||
void setScrollMode();
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
@ -6,10 +6,20 @@
|
||||
GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action)
|
||||
{
|
||||
this->setObjectName("Graph");
|
||||
this->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
this->graphView = new DisassemblerGraphView(this);
|
||||
this->setWidget(graphView);
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Graph";
|
||||
if (!action) {
|
||||
name = "Extra Graph";
|
||||
}
|
||||
setObjectName(name);
|
||||
setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
graphView = new DisassemblerGraphView(this);
|
||||
setWidget(graphView);
|
||||
|
||||
// getting the name of the class is implementation defined, and cannot be
|
||||
// used reliably across different compilers.
|
||||
@ -24,8 +34,8 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
main->toggleOverview(visibility, this);
|
||||
if (visibility) {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
|
||||
this->graphView->refreshView();
|
||||
this->graphView->onSeekChanged(Core()->getOffset());
|
||||
graphView->refreshView();
|
||||
graphView->onSeekChanged(Core()->getOffset());
|
||||
}
|
||||
});
|
||||
|
||||
@ -37,8 +47,8 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
this, [ = ](CutterCore::MemoryWidgetType type) {
|
||||
bool emptyGraph = (type == CutterCore::MemoryWidgetType::Graph && Core()->isGraphEmpty());
|
||||
if (type == CutterCore::MemoryWidgetType::Graph && !emptyGraph) {
|
||||
this->raise();
|
||||
this->graphView->setFocus();
|
||||
raise();
|
||||
graphView->setFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -21,6 +21,18 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
/*
|
||||
* Ugly hack just for the layout issue
|
||||
* QSettings saves the state with the object names
|
||||
* By doing this hack,
|
||||
* you can at least avoid some mess by dismissing all the Extra Widgets
|
||||
*/
|
||||
QString name = "Hexdump";
|
||||
if (!action) {
|
||||
name = "Extra Hexdump";
|
||||
}
|
||||
setObjectName(name);
|
||||
|
||||
// Setup hex highlight
|
||||
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine()));
|
||||
//highlightHexCurrentLine();
|
||||
|
@ -5,11 +5,11 @@
|
||||
OverviewWidget::OverviewWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action)
|
||||
{
|
||||
this->setWindowTitle("Graph Overview");
|
||||
this->setObjectName("Graph Overview");
|
||||
this->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
this->graphView = new OverviewView(this);
|
||||
this->setWidget(graphView);
|
||||
setWindowTitle("Graph Overview");
|
||||
setObjectName("Graph Overview");
|
||||
setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
graphView = new OverviewView(this);
|
||||
setWidget(graphView);
|
||||
refreshDeferrer = createRefreshDeferrer([this]() {
|
||||
updateContents();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user