cutter/src/MainWindow.cpp

973 lines
26 KiB
C++
Raw Normal View History

2017-10-01 19:09:42 +00:00
#include "MainWindow.h"
#include "ui_MainWindow.h"
2017-10-02 09:41:28 +00:00
#include "dialogs/CreateNewDialog.h"
2017-10-01 19:09:42 +00:00
#include "dialogs/CommentsDialog.h"
#include "dialogs/AboutDialog.h"
#include "dialogs/RenameDialog.h"
#include "dialogs/AsmOptionsDialog.h"
#include "utils/Helpers.h"
#include <QComboBox>
#include <QCompleter>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QDockWidget>
#include <QFile>
#include <QFileDialog>
#include <QFont>
#include <QFontDialog>
#include <QLabel>
#include <QLineEdit>
#include <QList>
#include <QMessageBox>
#include <QProcess>
#include <QPropertyAnimation>
#include <QScrollBar>
#include <QSettings>
#include <QShortcut>
#include <QStringListModel>
#include <QStyledItemDelegate>
#include <QStyleFactory>
#include <QTextCursor>
#include <QtGlobal>
#include <QToolButton>
#include <QToolTip>
#include <QTreeWidgetItem>
2017-10-01 19:09:42 +00:00
#include "utils/Highlighter.h"
#include "utils/HexAsciiHighlighter.h"
#include "utils/Helpers.h"
2017-10-02 09:41:28 +00:00
#include "dialogs/NewFileDialog.h"
#include "widgets/PreviewWidget.h"
#include "widgets/FunctionsWidget.h"
#include "widgets/SectionsWidget.h"
#include "widgets/CommentsWidget.h"
#include "widgets/ImportsWidget.h"
#include "widgets/ExportsWidget.h"
#include "widgets/SymbolsWidget.h"
#include "widgets/StringsWidget.h"
#include "widgets/SectionsDock.h"
#include "widgets/RelocsWidget.h"
#include "widgets/FlagsWidget.h"
#include "widgets/CodeGraphic.h"
#include "widgets/Dashboard.h"
#include "widgets/Notepad.h"
#include "widgets/Sidebar.h"
#include "widgets/SdbDock.h"
#include "widgets/Omnibar.h"
#include "widgets/ConsoleWidget.h"
2017-10-01 19:09:42 +00:00
#include "dialogs/OptionsDialog.h"
#include "widgets/EntrypointWidget.h"
#include "widgets/DisassemblerGraphView.h"
// graphics
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <cassert>
static void registerCustomFonts()
{
int ret = QFontDatabase::addApplicationFont(":/fonts/Anonymous Pro.ttf");
assert(-1 != ret && "unable to register Anonymous Pro.ttf");
ret = QFontDatabase::addApplicationFont(":/fonts/Inconsolata-Regular.ttf");
assert(-1 != ret && "unable to register Inconsolata-Regular.ttf");
// do not issue a warning in release
Q_UNUSED(ret)
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
2017-10-09 18:08:35 +00:00
core(CutterCore::getInstance()),
previewDock(nullptr),
notepadDock(nullptr),
asmDock(nullptr),
calcDock(nullptr),
omnibar(nullptr),
sideBar(nullptr),
ui(new Ui::MainWindow),
highlighter(nullptr),
hex_highlighter(nullptr),
graphicsBar(nullptr),
entrypointDock(nullptr),
functionsDock(nullptr),
importsDock(nullptr),
exportsDock(nullptr),
symbolsDock(nullptr),
relocsDock(nullptr),
commentsDock(nullptr),
stringsDock(nullptr),
flagsDock(nullptr),
dashboardDock(nullptr),
gotoEntry(nullptr),
sdbDock(nullptr),
sidebar_action(nullptr),
sectionsDock(nullptr),
2017-10-14 09:45:11 +00:00
consoleWidget(nullptr)
{
doLock = false;
configuration = new Configuration();
}
MainWindow::~MainWindow()
{
delete core;
}
void MainWindow::initUI()
{
ui->setupUi(this);
registerCustomFonts();
/*
* Toolbar
*/
// Hide central tab widget tabs
QTabBar *centralbar = ui->centralTabWidget->tabBar();
centralbar->setVisible(false);
2017-10-09 18:08:35 +00:00
consoleWidget = new ConsoleWidget(this);
ui->tabVerticalLayout->addWidget(consoleWidget);
// Sepparator between back/forward and undo/redo buttons
2017-04-09 19:55:06 +00:00
QWidget *spacer4 = new QWidget();
spacer4->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
spacer4->setMinimumSize(10, 10);
ui->mainToolBar->insertWidget(ui->actionForward, spacer4);
// Popup menu on theme toolbar button
QToolButton *backButton = new QToolButton(this);
backButton->setIcon(QIcon(":/img/icons/arrow_left.svg"));
//backButton->setPopupMode(QToolButton::DelayedPopup);
ui->mainToolBar->insertWidget(ui->actionForward, backButton);
2017-09-02 08:46:48 +00:00
connect(backButton, SIGNAL(clicked()), this, SLOT(backButton_clicked()));
// Sepparator between undo/redo and goto lineEdit
2017-04-09 19:55:06 +00:00
QWidget *spacer3 = new QWidget();
spacer3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
spacer3->setMinimumSize(20, 20);
spacer3->setMaximumWidth(300);
ui->mainToolBar->insertWidget(ui->actionShow_Hide_mainsidebar, spacer3);
// Omnibar LineEdit
this->omnibar = new Omnibar(this);
ui->mainToolBar->insertWidget(ui->actionShow_Hide_mainsidebar, this->omnibar);
// Add special separators to the toolbar that expand to separate groups of elements
2017-04-09 19:55:06 +00:00
QWidget *spacer2 = new QWidget();
spacer2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
spacer2->setMinimumSize(10, 10);
spacer2->setMaximumWidth(300);
ui->mainToolBar->insertWidget(ui->actionShow_Hide_mainsidebar, spacer2);
// Separator between back/forward and undo/redo buttons
2017-04-09 19:55:06 +00:00
QWidget *spacer = new QWidget();
spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
spacer->setMinimumSize(20, 20);
ui->mainToolBar->addWidget(spacer);
// codeGraphics tool bar
this->graphicsBar = new GraphicsBar(this);
this->graphicsBar->setMovable(false);
addToolBarBreak(Qt::TopToolBarArea);
addToolBar(graphicsBar);
/*
* Dock Widgets
*/
dockWidgets.reserve(14);
// Add Memory DockWidget
this->previewDock = new PreviewWidget(tr("Preview"), this);
dockWidgets.push_back(previewDock);
// To use in the future when we handle more than one memory views
// this->previewDock->setAttribute(Qt::WA_DeleteOnClose);
// this->add_debug_output( QString::number(this->dockList.length()) );
// Add disassembly view (dockable)
this->disassemblyDock = new DisassemblyWidget(tr("Disassembly"), this);
dockWidgets.push_back(disassemblyDock);
sidebarDock = new SidebarWidget(tr("Sidebar"), this);
dockWidgets.push_back(sidebarDock);
hexdumpDock = new HexdumpWidget(tr("Hexdump"), this);
dockWidgets.push_back(hexdumpDock);
// Add graph view as dockable
graphDock = new QDockWidget(tr("Graph"), this);
graphDock->setObjectName("Graph");
graphDock->setAllowedAreas(Qt::AllDockWidgetAreas);
DisassemblerGraphView *gv = new DisassemblerGraphView(graphDock);
graphDock->setWidget(gv);
dockWidgets.push_back(graphDock);
// Add Sections dock panel
this->sectionsDock = new SectionsDock(this);
dockWidgets.push_back(sectionsDock);
// Add entrypoint DockWidget
this->entrypointDock = new EntrypointWidget(this);
dockWidgets.push_back(entrypointDock);
// Add functions DockWidget
this->functionsDock = new FunctionsWidget(this);
dockWidgets.push_back(functionsDock);
// Add imports DockWidget
this->importsDock = new ImportsWidget(this);
dockWidgets.push_back(importsDock);
// Add exports DockWidget
this->exportsDock = new ExportsWidget(this);
dockWidgets.push_back(exportsDock);
// Add symbols DockWidget
this->symbolsDock = new SymbolsWidget(this);
dockWidgets.push_back(symbolsDock);
// Add relocs DockWidget
this->relocsDock = new RelocsWidget(this);
dockWidgets.push_back(relocsDock);
// Add comments DockWidget
this->commentsDock = new CommentsWidget(this);
dockWidgets.push_back(commentsDock);
// Add strings DockWidget
this->stringsDock = new StringsWidget(this);
dockWidgets.push_back(stringsDock);
// Add flags DockWidget
this->flagsDock = new FlagsWidget(this);
dockWidgets.push_back(flagsDock);
// Add Notepad Dock panel
this->notepadDock = new Notepad(this);
dockWidgets.push_back(notepadDock);
connect(previewDock, SIGNAL(fontChanged(QFont)), notepadDock, SLOT(setFonts(QFont)));
//Add Dashboard Dock panel
this->dashboardDock = new Dashboard(this);
dockWidgets.push_back(dashboardDock);
// Set up dock widgets default layout
restoreDocks();
hideAllDocks();
showDefaultDocks();
// Restore saved settings
this->readSettings();
// TODO: Allow the user to select this option visually in the GUI settings
// Adjust the DockWidget areas
2017-04-09 19:55:06 +00:00
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
//setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
2017-04-09 19:55:06 +00:00
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
//setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
// Setup and hide sidebar by default
this->sideBar = new SideBar(this);
this->sidebar_action = ui->sideToolBar->addWidget(this->sideBar);
ui->sideToolBar->hide();
// Show dashboard by default
this->dashboardDock->raise();
//qDebug() << "FOLDER: " << QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
/*
* Some global shortcuts
*/
// Period goes to command entry
2017-04-09 19:55:06 +00:00
QShortcut *cmd_shortcut = new QShortcut(QKeySequence(Qt::Key_Period), this);
connect(cmd_shortcut, SIGNAL(activated()), consoleWidget, SLOT(focusInputLineEdit()));
// G and S goes to goto entry
2017-04-09 19:55:06 +00:00
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
connect(goto_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
2017-04-09 19:55:06 +00:00
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
connect(seek_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus()));
// : goes to goto entry
2017-04-09 19:55:06 +00:00
QShortcut *commands_shortcut = new QShortcut(QKeySequence(Qt::Key_Colon), this);
connect(commands_shortcut, SIGNAL(activated()), this->omnibar, SLOT(showCommands()));
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshVisibleDockWidgets()));
}
void MainWindow::openFile(const QString &fn, int anal_level, QList<QString> advanced)
2017-04-09 19:55:06 +00:00
{
QString project_name = qhelpers::uniqueProjectName(fn);
2017-06-03 12:27:23 +00:00
if (core->getProjectNames().contains(project_name))
openProject(project_name);
else
openNewFile(fn, anal_level, advanced);
}
void MainWindow::openNewFile(const QString &fn, int anal_level, QList<QString> advanced)
{
setFilename(fn);
OptionsDialog *o = new OptionsDialog(this);
o->setAttribute(Qt::WA_DeleteOnClose);
o->show();
2017-06-03 12:27:23 +00:00
if (anal_level >= 0)
o->setupAndStartAnalysis(anal_level, advanced);
}
void MainWindow::openProject(const QString &project_name)
{
QString filename = core->cmd("Pi " + project_name);
setFilename(filename.trimmed());
core->cmd("Po " + project_name);
initUI();
finalizeOpen();
}
void MainWindow::finalizeOpen()
{
core->getOpcodes();
// Set settings to override any incorrect saved in the project
core->setSettings();
addOutput(tr(" > Populating UI"));
// FIXME: initialization order frakup. the next line is needed so that the
// comments widget displays the function names.
core->cmd("fs sections");
updateFrames();
// Restore project notes
QString notes = this->core->cmd("Pnj");
//qDebug() << "Notes:" << notes;
if (notes != "")
{
QByteArray ba;
ba.append(notes);
notepadDock->setText(QByteArray::fromBase64(ba));
}
else
{
addOutput(tr(" > Adding binary information to notepad"));
notepadDock->setText(tr("# Binary information\n\n") + core->cmd("i") +
2017-06-03 12:27:23 +00:00
"\n" + core->cmd("ie") + "\n" + core->cmd("iM") + "\n");
}
//Get binary beginning/end addresses
this->core->binStart = this->core->cmd("?v $M");
this->core->binEnd = this->core->cmd("?v $M+$s");
addOutput(tr(" > Finished, happy reversing :)"));
// Add fortune message
addOutput("\n" + core->cmd("fo"));
//previewDock->setWindowTitle("entry0");
showMaximized();
// Initialize syntax highlighters
notepadDock->highlightPreview();
}
void MainWindow::saveProject()
{
QString project_name = qhelpers::uniqueProjectName(filename);
core->cmd("Ps " + project_name);
QString notes = this->notepadDock->textToBase64();
//this->add_debug_output(notes);
this->core->cmd("Pnj " + notes);
this->addOutput(tr("Project saved: ") + project_name);
}
void MainWindow::toggleSideBarTheme()
2017-04-09 19:55:06 +00:00
{
sideBar->themesButtonToggle();
}
void MainWindow::refreshOmniBar(const QStringList &flags)
{
omnibar->refresh(flags);
}
void MainWindow::setFilename(const QString &fn)
{
// Add file name to window title
this->filename = fn;
2017-09-25 12:55:41 +00:00
this->setWindowTitle(APPNAME" - " + fn);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
2017-09-25 12:55:41 +00:00
QMessageBox::StandardButton ret = QMessageBox::question(this, APPNAME,
tr("Do you really want to exit?\nSave your project before closing!"),
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
//qDebug() << ret;
2017-04-09 19:55:06 +00:00
if (ret == QMessageBox::Save)
{
QSettings settings;
settings.setValue("geometry", saveGeometry());
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.setValue("state", saveState());
saveProject();
QMainWindow::closeEvent(event);
2017-04-09 19:55:06 +00:00
}
else if (ret == QMessageBox::Discard)
{
QSettings settings;
2017-03-31 10:13:33 +00:00
settings.setValue("geometry", saveGeometry());
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.setValue("state", saveState());
2017-04-09 19:55:06 +00:00
}
else
{
event->ignore();
}
}
void MainWindow::readSettings()
{
QSettings settings;
QByteArray geo = settings.value("geometry", QByteArray()).toByteArray();
restoreGeometry(geo);
QByteArray state = settings.value("state", QByteArray()).toByteArray();
restoreState(state);
2017-04-09 19:55:06 +00:00
if (settings.value("dark").toBool())
{
this->dark();
}
this->responsive = settings.value("responsive").toBool();
}
2017-04-09 19:55:06 +00:00
void MainWindow::dark()
{
qApp->setStyleSheet("QPlainTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} QTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} ");
QSettings settings;
settings.setValue("dark", true);
// TODO: emit a signal for theme
}
2017-04-09 19:55:06 +00:00
void MainWindow::def_theme()
{
qApp->setStyleSheet("");
QSettings settings;
settings.setValue("dark", false);
// TODO: emit a signal for theme
}
/*
* Refresh widget functions
*/
2017-04-09 19:55:06 +00:00
void MainWindow::refreshFunctions()
{
functionsDock->refresh();
}
2017-04-09 19:55:06 +00:00
void MainWindow::refreshComments()
{
commentsDock->refresh();
}
2017-04-09 19:55:06 +00:00
void MainWindow::updateFrames()
{
/* TODO Widgets are independants and responsible to update their own
2017-10-11 21:57:06 +00:00
* content right? Just send a signal.*/
if (core == NULL)
return;
static bool first_time = true;
//TODO Send signal rather than that
disassemblyDock->refreshDisasm();
2017-04-09 19:55:06 +00:00
if (first_time)
{
2017-10-11 21:57:06 +00:00
for (auto W : dockWidgets)
{
2017-10-13 13:53:23 +00:00
// Temporary hack
2017-10-11 21:57:06 +00:00
DockWidget* w = dynamic_cast<DockWidget*>(W);
if (w) {
w->setup();
}
}
first_time = false;
2017-04-09 19:55:06 +00:00
}
else
{
2017-10-11 21:57:06 +00:00
for (auto W : dockWidgets)
2017-04-09 19:55:06 +00:00
{
2017-10-13 13:53:23 +00:00
// Temporary hack
2017-10-11 21:57:06 +00:00
DockWidget* w = dynamic_cast<DockWidget*>(W);
if (w) {
w->refresh();
}
}
}
// graphicsBar->refreshColorBar();
graphicsBar->fillData();
}
void MainWindow::on_actionLock_triggered()
{
doLock = !doLock;
2017-04-09 19:55:06 +00:00
if (doLock)
{
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
}
}
2017-04-09 19:55:06 +00:00
else
{
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
}
}
}
void MainWindow::lockUnlock_Docks(bool what)
{
2017-04-09 19:55:06 +00:00
if (what)
{
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
}
2017-04-09 19:55:06 +00:00
}
else
{
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
}
}
}
void MainWindow::on_actionLockUnlock_triggered()
{
2017-04-09 19:55:06 +00:00
if (ui->actionLockUnlock->isChecked())
{
2017-04-09 19:55:06 +00:00
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
}
ui->actionLockUnlock->setIcon(QIcon(":/lock"));
2017-04-09 19:55:06 +00:00
}
else
{
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
{
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
}
ui->actionLockUnlock->setIcon(QIcon(":/unlock"));
}
}
void MainWindow::on_actionTabs_triggered()
{
2017-04-09 19:55:06 +00:00
if (ui->centralTabWidget->tabPosition() == QTabWidget::South)
{
ui->centralTabWidget->setTabPosition(QTabWidget::North);
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
2017-04-09 19:55:06 +00:00
}
else
{
ui->centralTabWidget->setTabPosition(QTabWidget::South);
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
}
}
void MainWindow::on_actionMem_triggered()
{
//this->previewDock->show();
//this->previewDock->raise();
PreviewWidget *newMemDock = new PreviewWidget();
this->dockWidgets << newMemDock;
newMemDock->setAttribute(Qt::WA_DeleteOnClose);
this->tabifyDockWidget(this->previewDock, newMemDock);
//newMemDock->refreshDisasm();
}
void MainWindow::on_actionEntry_points_triggered()
{
toggleDockWidget(entrypointDock);
}
void MainWindow::on_actionFunctions_triggered()
{
toggleDockWidget(functionsDock);
}
void MainWindow::on_actionImports_triggered()
{
toggleDockWidget(importsDock);
}
void MainWindow::on_actionExports_triggered()
{
toggleDockWidget(exportsDock);
}
void MainWindow::on_actionSymbols_triggered()
{
toggleDockWidget(symbolsDock);
}
void MainWindow::on_actionReloc_triggered()
{
toggleDockWidget(relocsDock);
}
void MainWindow::on_actionStrings_triggered()
{
toggleDockWidget(stringsDock);
}
void MainWindow::on_actionSections_triggered()
{
toggleDockWidget(sectionsDock);
}
void MainWindow::on_actionFlags_triggered()
{
toggleDockWidget(flagsDock);
}
void MainWindow::on_actionComents_triggered()
{
toggleDockWidget(commentsDock);
}
void MainWindow::on_actionNotepad_triggered()
{
toggleDockWidget(notepadDock);
}
void MainWindow::on_actionAbout_triggered()
{
2017-04-09 19:55:06 +00:00
AboutDialog *a = new AboutDialog(this);
a->open();
}
void MainWindow::on_actionRefresh_Panels_triggered()
{
this->updateFrames();
}
void MainWindow::toggleDockWidget(DockWidget *dock_widget)
{
if (dock_widget->isVisible())
{
dock_widget->close();
}
else
{
dock_widget->show();
dock_widget->raise();
}
}
2017-10-03 18:38:34 +00:00
void MainWindow::setCursorAddress(RVA addr)
2017-04-09 19:55:06 +00:00
{
2017-10-03 18:38:34 +00:00
this->cursorAddress = addr;
emit cursorAddressChanged(core->getOffset());
}
2017-09-02 08:46:48 +00:00
void MainWindow::backButton_clicked()
{
2017-10-16 19:00:47 +00:00
core->seekPrev();
2017-10-13 13:53:23 +00:00
}
void MainWindow::on_actionForward_triggered()
{
2017-10-16 19:00:47 +00:00
core->seekNext();
}
void MainWindow::on_actionCalculator_triggered()
{
2017-04-09 19:55:06 +00:00
if (!this->sideBar->isVisible())
{
this->on_actionShow_Hide_mainsidebar_triggered();
}
}
void MainWindow::on_actionCreate_File_triggered()
{
2017-10-02 09:41:28 +00:00
CreateNewDialog *n = new CreateNewDialog(this);
n->exec();
}
void MainWindow::on_actionAssembler_triggered()
{
2017-04-09 19:55:06 +00:00
if (!this->sideBar->isVisible())
{
this->on_actionShow_Hide_mainsidebar_triggered();
}
}
void MainWindow::on_actionDisasAdd_comment_triggered()
{
2017-04-09 19:55:06 +00:00
CommentsDialog *c = new CommentsDialog(this);
c->exec();
}
void MainWindow::restoreDocks()
{
addDockWidget(Qt::RightDockWidgetArea, this->sectionsDock);
addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock);
this->tabifyDockWidget(this->sectionsDock, this->commentsDock);
this->tabifyDockWidget(this->dashboardDock, this->disassemblyDock);
this->tabifyDockWidget(this->dashboardDock, this->graphDock);
2017-10-13 13:53:23 +00:00
this->tabifyDockWidget(this->dashboardDock, this->hexdumpDock);
this->tabifyDockWidget(this->dashboardDock, this->previewDock);
2017-10-13 13:53:23 +00:00
this->tabifyDockWidget(this->dashboardDock, this->sidebarDock);
this->tabifyDockWidget(this->dashboardDock, this->functionsDock);
this->tabifyDockWidget(this->dashboardDock, this->entrypointDock);
this->tabifyDockWidget(this->dashboardDock, this->flagsDock);
this->tabifyDockWidget(this->dashboardDock, this->stringsDock);
this->tabifyDockWidget(this->dashboardDock, this->relocsDock);
this->tabifyDockWidget(this->dashboardDock, this->importsDock);
this->tabifyDockWidget(this->dashboardDock, this->exportsDock);
this->tabifyDockWidget(this->dashboardDock, this->symbolsDock);
this->tabifyDockWidget(this->dashboardDock, this->notepadDock);
this->dashboardDock->raise();
this->sectionsDock->raise();
}
2017-10-13 13:53:23 +00:00
void MainWindow::on_actionDefaut_triggered()
{
hideAllDocks();
restoreDocks();
showDefaultDocks();
this->dashboardDock->raise();
}
void MainWindow::hideAllDocks()
{
for (auto w : dockWidgets)
{
w->hide();
}
}
void MainWindow::showDefaultDocks()
{
const QList<QDockWidget *> defaultDocks = { sectionsDock,
entrypointDock,
2017-04-13 15:51:58 +00:00
functionsDock,
previewDock,
2017-04-13 15:51:58 +00:00
commentsDock,
stringsDock,
importsDock,
symbolsDock,
notepadDock,
graphDock,
disassemblyDock,
sidebarDock,
hexdumpDock,
2017-04-13 15:51:58 +00:00
dashboardDock
};
for (auto w : dockWidgets)
{
if (defaultDocks.contains(w))
{
w->show();
}
}
}
void MainWindow::on_actionhide_bottomPannel_triggered()
{
2017-04-09 19:55:06 +00:00
if (ui->centralWidget->isVisible())
{
ui->centralWidget->hide();
2017-04-09 19:55:06 +00:00
}
else
{
ui->centralWidget->show();
}
}
void MainWindow::sendToNotepad(const QString &txt)
{
this->notepadDock->appendPlainText("```\n" + txt + "\n```");
}
void MainWindow::on_actionFunctionsRename_triggered()
{
2017-04-09 19:55:06 +00:00
RenameDialog *r = new RenameDialog(this);
// Get function based on click position
//r->setFunctionName(fcn_name);
r->open();
}
void MainWindow::addOutput(const QString &msg)
{
consoleWidget->addOutput(msg);
}
void MainWindow::addDebugOutput(const QString &msg)
{
printf("debug output: %s\n", msg.toLocal8Bit().constData());
consoleWidget->addDebugOutput(msg);
}
void MainWindow::on_actionNew_triggered()
{
2017-04-13 15:51:58 +00:00
if (close())
2017-04-09 20:36:17 +00:00
on_actionLoad_triggered();
}
void MainWindow::on_actionSave_triggered()
{
saveProject();
}
void MainWindow::on_actionRun_Script_triggered()
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setViewMode(QFileDialog::Detail);
dialog.setDirectory(QDir::home());
QString fileName;
fileName = dialog.getOpenFileName(this, tr("Select radare2 script"));
2017-04-13 15:51:58 +00:00
if (!fileName.length()) //cancel was pressed
2017-04-09 20:36:17 +00:00
return;
this->core->cmd(". " + fileName);
}
void MainWindow::on_actionDark_Theme_triggered()
{
this->dark();
}
void MainWindow::on_actionWhite_Theme_triggered()
{
this->def_theme();
}
void MainWindow::on_actionSDB_browser_triggered()
{
this->sdbDock = new SdbDock(this);
this->tabifyDockWidget(this->previewDock, this->sdbDock);
this->sdbDock->setFloating(true);
this->sdbDock->show();
}
void MainWindow::on_actionLoad_triggered()
{
QProcess process(this);
process.setEnvironment(QProcess::systemEnvironment());
process.startDetached(qApp->applicationFilePath());
}
void MainWindow::on_actionShow_Hide_mainsidebar_triggered()
{
2017-04-09 19:55:06 +00:00
if (ui->sideToolBar->isVisible())
{
ui->sideToolBar->hide();
2017-04-09 19:55:06 +00:00
}
else
{
ui->sideToolBar->show();
}
}
void MainWindow::on_actionDashboard_triggered()
{
2017-04-09 19:55:06 +00:00
if (this->dashboardDock->isVisible())
{
this->dashboardDock->close();
2017-04-09 19:55:06 +00:00
}
else
{
this->dashboardDock->show();
this->dashboardDock->raise();
}
}
2017-04-09 19:55:06 +00:00
void MainWindow::toggleResponsive(bool maybe)
{
this->responsive = maybe;
// Save options in settings
QSettings settings;
settings.setValue("responsive", this->responsive);
}
void MainWindow::on_actionTabs_on_Top_triggered()
{
this->on_actionTabs_triggered();
}
void MainWindow::on_actionReset_settings_triggered()
{
QMessageBox::StandardButton ret =
2017-09-25 12:55:41 +00:00
(QMessageBox::StandardButton)QMessageBox::question(this, APPNAME,
tr("Do you really want to clear all settings?"),
2017-06-03 12:27:23 +00:00
QMessageBox::Ok | QMessageBox::Cancel);
2017-04-09 19:55:06 +00:00
if (ret == QMessageBox::Ok)
{
// Save options in settings
QSettings settings;
settings.clear();
}
}
void MainWindow::on_actionQuit_triggered()
{
close();
}
void MainWindow::refreshVisibleDockWidgets()
{
2017-10-13 13:53:23 +00:00
/* TODO Just send a signal no? */
// There seems to be no convenience function to check if a QDockWidget
// is really visible or hidden in a tabbed dock. So:
2017-04-13 15:51:58 +00:00
auto isDockVisible = [](const QDockWidget * const pWidget)
{
return pWidget != nullptr && !pWidget->visibleRegion().isEmpty();
};
2017-10-13 13:53:23 +00:00
for (auto W : dockWidgets)
{
2017-10-13 13:53:23 +00:00
if (isDockVisible(W))
{
2017-10-13 13:53:23 +00:00
// Temporary hack
DockWidget* w = dynamic_cast<DockWidget*>(W);
if (w) {
w->setup();
}
}
}
}
void MainWindow::on_actionRefresh_contents_triggered()
{
refreshVisibleDockWidgets();
}
2017-08-31 17:43:46 +00:00
void MainWindow::on_actionAsmOptions_triggered()
2017-08-31 17:43:46 +00:00
{
auto dialog = new AsmOptionsDialog(this);
dialog->show();
2017-09-02 08:17:48 +00:00
}