2017-03-29 10:18:37 +00:00
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "ui_mainwindow.h"
|
|
|
|
#include "createnewdialog.h"
|
|
|
|
#include "dialogs/commentsdialog.h"
|
|
|
|
#include "dialogs/aboutdialog.h"
|
|
|
|
#include "dialogs/renamedialog.h"
|
|
|
|
|
|
|
|
#include <qfont.h>
|
|
|
|
#include <qsettings.h>
|
|
|
|
#include <qlabel.h>
|
|
|
|
#include <qfile.h>
|
|
|
|
#include <qmessagebox.h>
|
|
|
|
#include <qfontdialog.h>
|
|
|
|
#include <qcompleter.h>
|
|
|
|
#include <qstringlistmodel.h>
|
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QPropertyAnimation>
|
|
|
|
#include <QStyledItemDelegate>
|
2017-03-31 00:40:27 +00:00
|
|
|
#include <QProcess>
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QToolTip>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QTextCursor>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QStyleFactory>
|
|
|
|
|
|
|
|
// graphics
|
|
|
|
#include <QGraphicsEllipseItem>
|
|
|
|
#include <QGraphicsScene>
|
|
|
|
#include <QGraphicsView>
|
|
|
|
|
2017-04-05 08:56:59 +00:00
|
|
|
#include <cassert>
|
|
|
|
|
2017-04-09 17:09:35 +00:00
|
|
|
static void registerCustomFonts()
|
2017-04-05 08:56:59 +00:00
|
|
|
{
|
2017-04-09 17:09:35 +00:00
|
|
|
int ret = QFontDatabase::addApplicationFont(":/new/prefix1/fonts/Anonymous Pro.ttf");
|
|
|
|
assert(-1 != ret && "unable to register Anonymous Pro.ttf");
|
2017-04-05 08:56:59 +00:00
|
|
|
|
2017-04-09 17:09:35 +00:00
|
|
|
ret = QFontDatabase::addApplicationFont(":/new/prefix1/fonts/Inconsolata-Regular.ttf");
|
|
|
|
assert(-1 != ret && "unable to register Inconsolata-Regular.ttf");
|
2017-04-05 08:56:59 +00:00
|
|
|
|
2017-04-09 17:09:35 +00:00
|
|
|
// do not issue a warning in release
|
|
|
|
Q_UNUSED(ret)
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-04-03 21:02:47 +00:00
|
|
|
MainWindow::MainWindow(QWidget *parent, QRCore *kore) :
|
2017-03-29 10:18:37 +00:00
|
|
|
QMainWindow(parent),
|
2017-04-03 21:02:47 +00:00
|
|
|
core(kore),
|
2017-04-01 01:56:35 +00:00
|
|
|
ui(new Ui::MainWindow),
|
|
|
|
webserverThread(core, this)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-04-03 21:02:47 +00:00
|
|
|
this->start_web_server();
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->setupUi(this);
|
2017-04-01 01:56:35 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
doLock = false;
|
|
|
|
|
2017-04-05 08:56:59 +00:00
|
|
|
registerCustomFonts();
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Toolbar
|
|
|
|
*/
|
|
|
|
// Hide central tab widget tabs
|
|
|
|
QTabBar *centralbar = ui->centralTabWidget->tabBar();
|
|
|
|
centralbar->setVisible(false);
|
|
|
|
// Adjust console lineedit
|
|
|
|
ui->consoleInputLineEdit->setTextMargins(10, 0, 0, 0);
|
|
|
|
/*
|
|
|
|
ui->consoleOutputTextEdit->setFont(QFont("Monospace", 8));
|
|
|
|
ui->consoleOutputTextEdit->setStyleSheet("background-color:black;color:gray;");
|
|
|
|
ui->consoleInputLineEdit->setStyleSheet("background-color:black;color:gray;");
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Adjust text margins of consoleOutputTextEdit
|
|
|
|
QTextDocument *console_docu = ui->consoleOutputTextEdit->document();
|
|
|
|
console_docu->setDocumentMargin(10);
|
|
|
|
|
|
|
|
// Sepparator between back/forward and undo/redo buttons
|
2017-04-09 19:55:06 +00:00
|
|
|
QWidget *spacer4 = new QWidget();
|
2017-03-29 10:18:37 +00:00
|
|
|
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(":/new/prefix1/img/icons/arrow_left.png"));
|
|
|
|
//backButton->setPopupMode(QToolButton::DelayedPopup);
|
|
|
|
ui->mainToolBar->insertWidget(ui->actionForward, backButton);
|
2017-04-01 12:43:57 +00:00
|
|
|
connect(backButton, SIGNAL(clicked()), this, SLOT(on_backButton_clicked()));
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
// Sepparator between undo/redo and goto lineEdit
|
2017-04-09 19:55:06 +00:00
|
|
|
QWidget *spacer3 = new QWidget();
|
2017-03-29 10:18:37 +00:00
|
|
|
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 sepparators to the toolbar that expand to separate groups of elements
|
2017-04-09 19:55:06 +00:00
|
|
|
QWidget *spacer2 = new QWidget();
|
2017-03-29 10:18:37 +00:00
|
|
|
spacer2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
spacer2->setMinimumSize(10, 10);
|
|
|
|
spacer2->setMaximumWidth(300);
|
|
|
|
ui->mainToolBar->insertWidget(ui->actionShow_Hide_mainsidebar, spacer2);
|
|
|
|
|
|
|
|
// Sepparator between back/forward and undo/redo buttons
|
2017-04-09 19:55:06 +00:00
|
|
|
QWidget *spacer = new QWidget();
|
2017-03-29 10:18:37 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
// Fix output panel font
|
2017-04-05 08:56:59 +00:00
|
|
|
qhelpers::normalizeFont(ui->consoleOutputTextEdit);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Dock Widgets
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Add Memory DockWidget
|
|
|
|
this->memoryDock = new MemoryWidget(this);
|
|
|
|
this->dockList << this->memoryDock;
|
|
|
|
// To use in the future when we handle more than one memory views
|
|
|
|
// this->memoryDock->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
// this->add_debug_output( QString::number(this->dockList.length()) );
|
|
|
|
|
|
|
|
// Add Sections dock panel
|
|
|
|
this->sectionsWidget = new SectionsWidget(this);
|
|
|
|
this->sectionsDock = new QDockWidget("Sections");
|
|
|
|
this->sectionsDock->setObjectName("sectionsDock");
|
|
|
|
this->sectionsDock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
|
|
|
this->sectionsDock->setWidget(this->sectionsWidget);
|
2017-04-09 19:55:06 +00:00
|
|
|
this->sectionsWidget->setContentsMargins(0, 0, 0, 5);
|
2017-03-29 10:18:37 +00:00
|
|
|
this->sectionsDock->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
|
|
this->sectionsDock->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(this->sectionsDock, SIGNAL(customContextMenuRequested(const QPoint &)),
|
|
|
|
this, SLOT(showSectionsContextMenu(const QPoint &)));
|
|
|
|
|
|
|
|
// Add functions DockWidget
|
|
|
|
this->functionsDock = new FunctionsWidget(this);
|
|
|
|
|
|
|
|
// Add imports DockWidget
|
|
|
|
this->importsDock = new ImportsWidget(this);
|
|
|
|
|
|
|
|
// Add symbols DockWidget
|
|
|
|
this->symbolsDock = new SymbolsWidget(this);
|
|
|
|
|
|
|
|
// Add relocs DockWidget
|
|
|
|
this->relocsDock = new RelocsWidget(this);
|
|
|
|
|
|
|
|
// Add comments DockWidget
|
|
|
|
this->commentsDock = new CommentsWidget(this);
|
|
|
|
|
|
|
|
// Add strings DockWidget
|
|
|
|
this->stringsDock = new StringsWidget(this);
|
|
|
|
|
|
|
|
// Add flags DockWidget
|
|
|
|
this->flagsDock = new FlagsWidget(this);
|
|
|
|
|
|
|
|
// Add Notepad Dock panel
|
|
|
|
this->notepadDock = new Notepad(this);
|
|
|
|
|
|
|
|
//Add Dashboard Dock panel
|
|
|
|
this->dashboardDock = new Dashboard(this);
|
|
|
|
|
|
|
|
// 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);
|
2017-03-29 10:18:37 +00:00
|
|
|
//setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
|
2017-04-09 19:55:06 +00:00
|
|
|
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
2017-03-29 10:18:37 +00:00
|
|
|
//setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
|
|
|
|
|
|
|
|
this->flagsDock->flagsTreeWidget->clear();
|
|
|
|
|
|
|
|
// Set omnibar completer for flags
|
|
|
|
this->omnibar->setupCompleter();
|
|
|
|
|
|
|
|
// Set console output context menu
|
|
|
|
ui->consoleOutputTextEdit->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(ui->consoleOutputTextEdit, SIGNAL(customContextMenuRequested(const QPoint &)),
|
|
|
|
this, SLOT(showConsoleContextMenu(const QPoint &)));
|
|
|
|
|
|
|
|
// Hide dummy columns so we can reorder the rest
|
|
|
|
hideDummyColumns();
|
|
|
|
|
|
|
|
// 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);
|
2017-03-29 10:18:37 +00:00
|
|
|
connect(cmd_shortcut, SIGNAL(activated()), ui->consoleInputLineEdit, SLOT(setFocus()));
|
|
|
|
|
|
|
|
// 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);
|
2017-03-29 10:18:37 +00:00
|
|
|
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);
|
2017-03-29 10:18:37 +00:00
|
|
|
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);
|
2017-03-29 10:18:37 +00:00
|
|
|
connect(commands_shortcut, SIGNAL(activated()), this->omnibar, SLOT(showCommands()));
|
|
|
|
|
2017-04-01 01:56:35 +00:00
|
|
|
connect(&webserverThread, SIGNAL(finished()), this, SLOT(webserverThreadFinished()));
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
delete ui;
|
|
|
|
delete core;
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::start_web_server()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// Start web server
|
2017-04-01 01:56:35 +00:00
|
|
|
webserverThread.startServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::webserverThreadFinished()
|
|
|
|
{
|
2017-04-09 17:12:36 +00:00
|
|
|
core->core()->http_up = webserverThread.isStarted() ? R_TRUE : R_FALSE;
|
2017-04-01 01:56:35 +00:00
|
|
|
|
|
|
|
// this is not true anymore, cause the webserver might have been stopped
|
|
|
|
//if (core->core->http_up == R_FALSE) {
|
|
|
|
// eprintf("FAILED TO LAUNCH\n");
|
|
|
|
//}
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::adjustColumns(QTreeWidget *tw)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
int count = tw->columnCount();
|
2017-04-09 19:55:06 +00:00
|
|
|
for (int i = 0; i != count; ++i)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
tw->resizeColumnToContents(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
|
2017-04-09 19:55:06 +00:00
|
|
|
const QString &str3, const QString &str4, const QString &str5)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
|
|
|
// Fill dummy hidden column
|
2017-04-09 19:55:06 +00:00
|
|
|
tempItem->setText(0, "0");
|
|
|
|
tempItem->setText(1, str);
|
|
|
|
if (str2 != NULL)
|
2017-03-29 10:18:37 +00:00
|
|
|
tempItem->setText(2, str2);
|
2017-04-09 19:55:06 +00:00
|
|
|
if (str3 != NULL)
|
2017-03-29 10:18:37 +00:00
|
|
|
tempItem->setText(3, str3);
|
2017-04-09 19:55:06 +00:00
|
|
|
if (str4 != NULL)
|
2017-03-29 10:18:37 +00:00
|
|
|
tempItem->setText(4, str4);
|
2017-04-09 19:55:06 +00:00
|
|
|
if (str5 != NULL)
|
2017-03-29 10:18:37 +00:00
|
|
|
tempItem->setText(5, str5);
|
|
|
|
tw->insertTopLevelItem(0, tempItem);
|
|
|
|
}
|
|
|
|
|
2017-04-01 01:56:35 +00:00
|
|
|
void MainWindow::setWebServerState(bool start)
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (start)
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
webserverThread.startServer();
|
|
|
|
|
|
|
|
// Open web interface on default browser
|
|
|
|
// ballessay: well isn't this possible with =H&
|
|
|
|
//QString link = "http://localhost:9090/";
|
|
|
|
//QDesktopServices::openUrl(QUrl(link));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
webserverThread.stopServer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::hideDummyColumns()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// UGLY, should be a loop over all treewidgets...
|
|
|
|
this->functionsDock->functionsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->importsDock->importsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->symbolsDock->symbolsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->relocsDock->relocsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->stringsDock->stringsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->flagsDock->flagsTreeWidget->setColumnHidden(0, true);
|
|
|
|
this->commentsDock->commentsTreeWidget->setColumnHidden(0, true);
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::setFilename(QString fn)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
// Add file name to window title
|
|
|
|
this->filename = fn;
|
|
|
|
this->setWindowTitle("Iaito - " + fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showConsoleContextMenu(const QPoint &pt)
|
|
|
|
{
|
|
|
|
// Set console output popup menu
|
|
|
|
QMenu *menu = ui->consoleOutputTextEdit->createStandardContextMenu();
|
|
|
|
menu->clear();
|
|
|
|
menu->addAction(ui->actionClear_ConsoleOutput);
|
|
|
|
menu->addAction(ui->actionConsoleSync_with_core);
|
|
|
|
ui->actionConsoleSync_with_core->setChecked(true);
|
|
|
|
ui->consoleOutputTextEdit->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
|
|
|
|
menu->exec(ui->consoleOutputTextEdit->mapToGlobal(pt));
|
|
|
|
delete menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
|
|
{
|
|
|
|
QMessageBox::StandardButton ret = QMessageBox::question(this, "Iaito",
|
2017-04-09 19:55:06 +00:00
|
|
|
"Do you really want to exit?\nSave your project before closing!",
|
|
|
|
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
2017-03-29 10:18:37 +00:00
|
|
|
//qDebug() << ret;
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ret == QMessageBox::Save)
|
|
|
|
{
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
settings.setValue("geometry", saveGeometry());
|
|
|
|
settings.setValue("size", size());
|
|
|
|
settings.setValue("pos", pos());
|
|
|
|
settings.setValue("state", saveState());
|
2017-03-31 10:13:33 +00:00
|
|
|
core->cmd("Ps " + QFileInfo(this->filename).fileName());
|
|
|
|
QString notes = this->notepadDock->notesTextEdit->toPlainText().toUtf8().toBase64();
|
|
|
|
//this->add_debug_output(notes);
|
|
|
|
this->core->cmd("Pnj " + notes);
|
2017-03-29 10:18:37 +00:00
|
|
|
QMainWindow::closeEvent(event);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (ret == QMessageBox::Discard)
|
|
|
|
{
|
2017-04-03 00:18:09 +00:00
|
|
|
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
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::readSettings()
|
|
|
|
{
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
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())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->dark();
|
|
|
|
}
|
|
|
|
this->responsive = settings.value("responsive").toBool();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::dark()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
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);} ");
|
|
|
|
this->memoryDock->switchTheme(true);
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
settings.setValue("dark", true);
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::def_theme()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
qApp->setStyleSheet("");
|
|
|
|
this->memoryDock->switchTheme(false);
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
settings.setValue("dark", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Refresh widget functions
|
|
|
|
*/
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::refreshFunctions()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->functionsDock->refreshTree();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::refreshComments()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->commentsDock->refreshTree();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::refreshFlagspaces()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
int cur_idx = this->flagsDock->flagspaceCombo->currentIndex();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (cur_idx < 0)cur_idx = 0;
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->flagspaceCombo->clear();
|
|
|
|
this->flagsDock->flagspaceCombo->addItem("(all)");
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto i : core->getList("flagspaces"))
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->flagspaceCombo->addItem(i);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
if (cur_idx > 0)
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->flagspaceCombo->setCurrentIndex(cur_idx);
|
|
|
|
refreshFlags();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::refreshFlags()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QString flagspace = this->flagsDock->flagspaceCombo->currentText();
|
|
|
|
this->omnibar->clearFlags();
|
|
|
|
if (flagspace == "(all)")
|
|
|
|
flagspace = "";
|
|
|
|
|
|
|
|
this->flagsDock->flagsTreeWidget->clear();
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto i : core->getList("flags", flagspace))
|
|
|
|
{
|
|
|
|
QStringList a = i.split(",");
|
|
|
|
if (a.length() > 3)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
appendRow(this->flagsDock->flagsTreeWidget, a[1], a[2], a[0], a[3]);
|
|
|
|
this->omnibar->fillFlags(a[0]);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
else if (a.length() > 2)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
appendRow(this->flagsDock->flagsTreeWidget, a[1], a[2], a[0], "");
|
|
|
|
this->omnibar->fillFlags(a[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
adjustColumns(this->flagsDock->flagsTreeWidget);
|
|
|
|
// Set omnibar completer for flags and commands
|
|
|
|
this->omnibar->setupCompleter();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::updateFrames()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
if (core == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
static bool first_time = true;
|
2017-04-09 19:55:06 +00:00
|
|
|
if (first_time)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
setup_mem();
|
|
|
|
this->add_output(" > Adding binary information to notepad");
|
|
|
|
notepadDock->setText("# Binary information\n\n" + core->cmd("i") +
|
|
|
|
"\n" + core->cmd("ie") + "\n" + core->cmd("iM") + "\n");
|
|
|
|
//first_time = false;
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
refreshMem("");
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshFlagspaces();
|
|
|
|
|
|
|
|
auto spi = QAbstractItemView::ScrollPerItem;
|
|
|
|
auto spp = QAbstractItemView::ScrollPerPixel;
|
|
|
|
|
|
|
|
// TODO: make this configurable by the user?
|
|
|
|
const bool use_scrollperpixel = true;
|
2017-04-09 19:55:06 +00:00
|
|
|
if (use_scrollperpixel)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->flagsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->symbolsDock->symbolsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->importsDock->importsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->functionsDock->functionsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->stringsDock->stringsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->relocsDock->relocsTreeWidget->setVerticalScrollMode(spp);
|
|
|
|
this->memoryDock->xreFromTreeWidget_2->setVerticalScrollMode(spp);
|
|
|
|
this->memoryDock->xrefToTreeWidget_2->setVerticalScrollMode(spp);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->flagsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->symbolsDock->symbolsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->importsDock->importsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->functionsDock->functionsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->stringsDock->stringsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->relocsDock->relocsTreeWidget->setVerticalScrollMode(spi);
|
|
|
|
this->memoryDock->xreFromTreeWidget_2->setVerticalScrollMode(spi);
|
|
|
|
this->memoryDock->xrefToTreeWidget_2->setVerticalScrollMode(spi);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->functionsDock->fillFunctions();
|
|
|
|
|
|
|
|
this->importsDock->fillImports();
|
|
|
|
|
|
|
|
// FIXME, doesn't work bc it sorts strings, not numbers... sigh
|
|
|
|
/*
|
|
|
|
Use QListWidgetItem::setData() not the constructor to set your value. Then all will work like you expect it to work.
|
|
|
|
|
|
|
|
int yourIntValue = 123456;
|
|
|
|
QListWidgetItem *item = new QListWidgetItem;
|
|
|
|
item->setData(Qt::DisplayRole, yourIntValue);
|
|
|
|
*/
|
|
|
|
//this->importsDock->importsTreeWidget->sortByColumn(1, Qt::DescendingOrder);
|
|
|
|
|
|
|
|
adjustColumns(this->importsDock->importsTreeWidget);
|
|
|
|
|
|
|
|
this->relocsDock->relocsTreeWidget->clear();
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto i : core->getList("bin", "relocs"))
|
|
|
|
{
|
|
|
|
QStringList pieces = i.split(",");
|
|
|
|
if (pieces.length() == 3)
|
2017-03-29 10:18:37 +00:00
|
|
|
appendRow(this->relocsDock->relocsTreeWidget, pieces[0], pieces[1], pieces[2]);
|
|
|
|
}
|
|
|
|
adjustColumns(this->relocsDock->relocsTreeWidget);
|
|
|
|
|
|
|
|
this->symbolsDock->fillSymbols();
|
|
|
|
|
|
|
|
this->stringsDock->stringsTreeWidget->clear();
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto i : core->getList("bin", "strings"))
|
|
|
|
{
|
|
|
|
QStringList pieces = i.split(",");
|
|
|
|
if (pieces.length() == 2)
|
2017-03-29 10:18:37 +00:00
|
|
|
appendRow(this->stringsDock->stringsTreeWidget, pieces[0], pieces[1]);
|
|
|
|
}
|
|
|
|
adjustColumns(this->stringsDock->stringsTreeWidget);
|
|
|
|
|
|
|
|
this->commentsDock->commentsTreeWidget->clear();
|
|
|
|
QList<QList<QString>> comments = this->core->getComments();
|
2017-04-09 19:55:06 +00:00
|
|
|
for (QList<QString> comment : comments)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
/*
|
|
|
|
QString name;
|
|
|
|
//this->add_debug_output("Comment: " + comment[1] + ": " + comment[0]);
|
|
|
|
RAnalFunction *fcn = this->core->functionAt(comment[1].toLongLong(0, 16));
|
|
|
|
if (fcn != NULL) {
|
|
|
|
name = fcn->name;
|
|
|
|
} else {
|
|
|
|
name = "";
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
QString fcn_name = this->core->cmdFunctionAt(comment[1]);
|
|
|
|
appendRow(this->commentsDock->commentsTreeWidget, comment[1], fcn_name, comment[0].remove('"'));
|
|
|
|
}
|
|
|
|
adjustColumns(this->commentsDock->commentsTreeWidget);
|
|
|
|
|
|
|
|
// Add nested comments
|
|
|
|
QMap<QString, QList<QList<QString>>> cmts = this->core->getNestedComments();
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto cmt : cmts.keys())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QTreeWidgetItem *item = new QTreeWidgetItem(this->commentsDock->nestedCommentsTreeWidget);
|
|
|
|
item->setText(0, cmt);
|
|
|
|
QList<QList<QString>> meow = cmts.value(cmt);
|
2017-04-09 19:55:06 +00:00
|
|
|
for (int i = 0; i < meow.size(); ++i)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QList<QString> tmp = meow.at(i);
|
|
|
|
QTreeWidgetItem *it = new QTreeWidgetItem();
|
|
|
|
it->setText(0, tmp[1]);
|
|
|
|
it->setText(1, tmp[0].remove('"'));
|
|
|
|
item->addChild(it);
|
|
|
|
}
|
|
|
|
this->commentsDock->nestedCommentsTreeWidget->addTopLevelItem(item);
|
|
|
|
}
|
|
|
|
adjustColumns(this->commentsDock->nestedCommentsTreeWidget);
|
|
|
|
|
|
|
|
// TODO: FIXME: Remove the check for first_time;
|
2017-04-09 19:55:06 +00:00
|
|
|
if (first_time)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
sectionsWidget->tree->clear();
|
|
|
|
int row = 0;
|
2017-04-09 19:55:06 +00:00
|
|
|
for (auto i : core->getList("bin", "sections"))
|
|
|
|
{
|
|
|
|
QStringList a = i.split(",");
|
|
|
|
if (a.length() > 2)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// Fix to work with ARM bins
|
|
|
|
//if (a[4].startsWith(".")) {
|
2017-04-09 19:55:06 +00:00
|
|
|
if (a[4].contains("."))
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QString addr = a[1];
|
2017-04-09 19:55:06 +00:00
|
|
|
QString addr_end = "0x0" + core->itoa(core->math(a[1] + "+" + a[2]));
|
2017-03-29 10:18:37 +00:00
|
|
|
QString size = QString::number(core->math(a[2]));
|
|
|
|
QString name = a[4];
|
|
|
|
this->sectionsWidget->fillSections(row, name, size, addr, addr_end);
|
|
|
|
|
|
|
|
// Used to select a color for the sections graph
|
2017-04-09 19:55:06 +00:00
|
|
|
if (row == 10)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
row = 0;
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//adjustColumns(sectionsWidget->tree);
|
|
|
|
sectionsWidget->adjustColumns();
|
|
|
|
|
|
|
|
first_time = false;
|
|
|
|
|
|
|
|
this->dashboardDock->updateContents();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* End of refresh widget functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
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-03-29 10:18:37 +00:00
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
|
|
|
{
|
|
|
|
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::lockUnlock_Docks(bool what)
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (what)
|
|
|
|
{
|
|
|
|
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionLockUnlock_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->actionLockUnlock->isChecked())
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
ui->actionLockUnlock->setIcon(QIcon(":/new/prefix1/lock"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
ui->actionLockUnlock->setIcon(QIcon(":/new/prefix1/unlock"));
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionTabs_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->centralTabWidget->tabPosition() == QTabWidget::South)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->centralTabWidget->setTabPosition(QTabWidget::North);
|
|
|
|
this->memoryDock->memTabWidget->setTabPosition(QTabWidget::North);
|
|
|
|
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->centralTabWidget->setTabPosition(QTabWidget::South);
|
|
|
|
this->memoryDock->memTabWidget->setTabPosition(QTabWidget::South);
|
|
|
|
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionMem_triggered()
|
|
|
|
{
|
|
|
|
//this->memoryDock->show();
|
|
|
|
//this->memoryDock->raise();
|
2017-04-09 19:55:06 +00:00
|
|
|
MemoryWidget *newMemDock = new MemoryWidget(this);
|
2017-03-29 10:18:37 +00:00
|
|
|
this->dockList << newMemDock;
|
|
|
|
newMemDock->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
this->tabifyDockWidget(this->memoryDock, newMemDock);
|
|
|
|
newMemDock->refreshDisasm("");
|
|
|
|
newMemDock->refreshHexdump("");
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionFunctions_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->functionsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->functionsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->functionsDock->show();
|
|
|
|
this->functionsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionImports_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->importsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->importsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->importsDock->show();
|
|
|
|
this->importsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSymbols_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->symbolsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->symbolsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->symbolsDock->show();
|
|
|
|
this->symbolsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionReloc_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->relocsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->relocsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->relocsDock->show();
|
|
|
|
this->relocsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionStrings_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->stringsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->stringsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->stringsDock->show();
|
|
|
|
this->stringsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSections_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->sectionsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->sectionsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->sectionsDock->show();
|
|
|
|
this->sectionsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionFlags_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->flagsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->flagsDock->show();
|
|
|
|
this->flagsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionComents_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->commentsDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->commentsDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->commentsDock->show();
|
|
|
|
this->commentsDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionNotepad_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->notepadDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->notepadDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->notepadDock->show();
|
|
|
|
this->notepadDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionAbout_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
AboutDialog *a = new AboutDialog(this);
|
2017-03-29 10:18:37 +00:00
|
|
|
a->open();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_consoleInputLineEdit_returnPressed()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->core)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QString input = ui->consoleInputLineEdit->text();
|
|
|
|
ui->consoleOutputTextEdit->appendPlainText(this->core->cmd(input));
|
2017-03-29 16:04:58 +00:00
|
|
|
ui->consoleOutputTextEdit->verticalScrollBar()->setValue(ui->consoleOutputTextEdit->verticalScrollBar()->maximum());
|
2017-03-29 10:18:37 +00:00
|
|
|
// Add new command to history
|
|
|
|
QCompleter *completer = ui->consoleInputLineEdit->completer();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (completer != NULL)
|
|
|
|
{
|
|
|
|
QStringListModel *completerModel = (QStringListModel *)(completer->model());
|
|
|
|
if (completerModel != NULL)
|
|
|
|
completerModel->setStringList(completerModel->stringList() << input);
|
2017-04-09 17:09:35 +00:00
|
|
|
}
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->consoleInputLineEdit->setText("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_showHistoToolButton_clicked()
|
|
|
|
{
|
2017-04-09 17:09:35 +00:00
|
|
|
QCompleter *completer = ui->consoleInputLineEdit->completer();
|
|
|
|
if (completer == NULL)
|
2017-04-09 19:55:06 +00:00
|
|
|
return;
|
2017-04-09 17:09:35 +00:00
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->showHistoToolButton->isChecked())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
2017-04-09 17:09:35 +00:00
|
|
|
// Uhm... shouldn't it be called always?
|
2017-03-29 10:18:37 +00:00
|
|
|
completer->complete();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
completer->setCompletionMode(QCompleter::PopupCompletion);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionClear_ConsoleOutput_triggered()
|
|
|
|
{
|
|
|
|
ui->consoleOutputTextEdit->setPlainText("");
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionRefresh_Panels_triggered()
|
|
|
|
{
|
|
|
|
this->updateFrames();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::seek(const QString &offset, const QString &name)
|
|
|
|
{
|
|
|
|
if (offset.length() == 0)
|
2017-03-29 10:18:37 +00:00
|
|
|
return;
|
|
|
|
if (name != NULL)
|
|
|
|
this->memoryDock->setWindowTitle(name);
|
|
|
|
this->hexdumpTopOffset = 0;
|
|
|
|
this->hexdumpBottomOffset = 0;
|
2017-04-09 19:55:06 +00:00
|
|
|
core->seek(offset);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
refreshMem(offset);
|
2017-04-05 10:10:22 +00:00
|
|
|
this->memoryDock->disasTextEdit->setFocus();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::setup_mem()
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QString off = this->core->cmd("afo entry0").trimmed();
|
|
|
|
//graphicsBar->refreshColorBar();
|
|
|
|
graphicsBar->fillData();
|
|
|
|
this->memoryDock->refreshDisasm(off);
|
|
|
|
this->memoryDock->refreshHexdump(off);
|
|
|
|
this->memoryDock->create_graph(off);
|
|
|
|
this->memoryDock->get_refs_data(off);
|
|
|
|
this->memoryDock->setFcnName(off);
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::refreshMem(QString off)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
//add_debug_output("Refreshing to: " + off);
|
|
|
|
//graphicsBar->refreshColorBar();
|
|
|
|
this->memoryDock->refreshDisasm(off);
|
|
|
|
this->memoryDock->refreshHexdump(off);
|
|
|
|
this->memoryDock->create_graph(off);
|
|
|
|
this->memoryDock->get_refs_data(off);
|
|
|
|
this->memoryDock->setFcnName(off);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_backButton_clicked()
|
|
|
|
{
|
|
|
|
this->core->cmd("s-");
|
|
|
|
QString back_offset = this->core->cmd("s=").split(" > ").last().trimmed();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (back_offset != "")
|
|
|
|
{
|
2017-04-06 10:14:28 +00:00
|
|
|
QString fcn = this->core->cmdFunctionAt(back_offset);
|
|
|
|
this->seek(this->memoryDock->normalizeAddr(back_offset), fcn);
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionCalculator_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (!this->sideBar->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->on_actionShow_Hide_mainsidebar_triggered();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionCreate_File_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
createNewDialog *n = new createNewDialog(this);
|
2017-03-29 10:18:37 +00:00
|
|
|
n->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionAssembler_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (!this->sideBar->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->on_actionShow_Hide_mainsidebar_triggered();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_consoleExecButton_clicked()
|
|
|
|
{
|
|
|
|
on_consoleInputLineEdit_returnPressed();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionStart_Web_Server_triggered()
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
setWebServerState(ui->actionStart_Web_Server->isChecked());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionConsoleSync_with_core_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->actionConsoleSync_with_core->isChecked())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
//Enable core syncronization
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// Disable core sync
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDisasAdd_comment_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
CommentsDialog *c = new CommentsDialog(this);
|
2017-03-29 10:18:37 +00:00
|
|
|
c->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::restoreDocks()
|
|
|
|
{
|
|
|
|
addDockWidget(Qt::RightDockWidgetArea, sectionsDock);
|
|
|
|
addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock);
|
|
|
|
this->tabifyDockWidget(sectionsDock, this->commentsDock);
|
|
|
|
this->tabifyDockWidget(this->dashboardDock, this->memoryDock);
|
|
|
|
this->tabifyDockWidget(this->dashboardDock, this->functionsDock);
|
|
|
|
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->symbolsDock);
|
|
|
|
this->tabifyDockWidget(this->dashboardDock, this->notepadDock);
|
|
|
|
this->dashboardDock->raise();
|
|
|
|
sectionsDock->raise();
|
|
|
|
this->functionsDock->raise();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDefaut_triggered()
|
|
|
|
{
|
|
|
|
hideAllDocks();
|
|
|
|
restoreDocks();
|
|
|
|
showDefaultDocks();
|
|
|
|
this->dashboardDock->raise();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::hideAllDocks()
|
|
|
|
{
|
|
|
|
sectionsDock->hide();
|
|
|
|
this->functionsDock->hide();
|
|
|
|
this->memoryDock->hide();
|
|
|
|
this->commentsDock->hide();
|
|
|
|
this->flagsDock->hide();
|
|
|
|
this->stringsDock->hide();
|
|
|
|
this->relocsDock->hide();
|
|
|
|
this->importsDock->hide();
|
|
|
|
this->symbolsDock->hide();
|
|
|
|
this->notepadDock->hide();
|
|
|
|
this->dashboardDock->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showDefaultDocks()
|
|
|
|
{
|
|
|
|
sectionsDock->show();
|
|
|
|
this->functionsDock->show();
|
|
|
|
this->memoryDock->show();
|
|
|
|
this->commentsDock->show();
|
|
|
|
this->stringsDock->show();
|
|
|
|
this->importsDock->show();
|
|
|
|
this->symbolsDock->show();
|
|
|
|
this->notepadDock->show();
|
|
|
|
this->dashboardDock->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionhide_bottomPannel_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->centralWidget->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->centralWidget->hide();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->centralWidget->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::send_to_notepad(QString txt)
|
|
|
|
{
|
|
|
|
this->notepadDock->notesTextEdit->appendPlainText("```\n" + txt + "\n```");
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionFunctionsRename_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
RenameDialog *r = new RenameDialog(this);
|
2017-03-29 10:18:37 +00:00
|
|
|
// Get function based on click position
|
|
|
|
//r->setFunctionName(fcn_name);
|
|
|
|
r->open();
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::get_refs(const QString &offset)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
this->memoryDock->get_refs_data(offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::add_output(QString msg)
|
|
|
|
{
|
|
|
|
ui->consoleOutputTextEdit->appendPlainText(msg);
|
2017-03-29 16:04:58 +00:00
|
|
|
ui->consoleOutputTextEdit->verticalScrollBar()->setValue(ui->consoleOutputTextEdit->verticalScrollBar()->maximum());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::add_debug_output(QString msg)
|
|
|
|
{
|
|
|
|
ui->consoleOutputTextEdit->appendHtml("<font color=\"red\"> [DEBUG]:\t" + msg + "</font>");
|
2017-03-29 16:04:58 +00:00
|
|
|
ui->consoleOutputTextEdit->verticalScrollBar()->setValue(ui->consoleOutputTextEdit->verticalScrollBar()->maximum());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionNew_triggered()
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
close();
|
2017-03-31 00:40:27 +00:00
|
|
|
on_actionLoad_triggered();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSave_triggered()
|
|
|
|
{
|
|
|
|
core->cmd("Ps " + QFileInfo(this->filename).fileName());
|
|
|
|
QString notes = this->notepadDock->notesTextEdit->toPlainText().toUtf8().toBase64();
|
|
|
|
//this->add_debug_output(notes);
|
|
|
|
this->core->cmd("Pnj " + notes);
|
|
|
|
this->add_output("Project saved");
|
|
|
|
}
|
|
|
|
|
|
|
|
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, "Select radare2 script");
|
|
|
|
|
|
|
|
qDebug() << "Meow: " + fileName;
|
|
|
|
this->core->cmd(". " + fileName);
|
|
|
|
this->refreshMem("");
|
|
|
|
}
|
|
|
|
|
|
|
|
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->memoryDock, this->sdbDock);
|
|
|
|
this->sdbDock->setFloating(true);
|
|
|
|
this->sdbDock->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionLoad_triggered()
|
|
|
|
{
|
2017-04-01 01:56:35 +00:00
|
|
|
QProcess process(this);
|
|
|
|
process.setEnvironment(QProcess::systemEnvironment());
|
|
|
|
process.startDetached(qApp->applicationFilePath());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionShow_Hide_mainsidebar_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->sideToolBar->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->sideToolBar->hide();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->sideToolBar->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDashboard_triggered()
|
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->dashboardDock->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->dashboardDock->close();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->dashboardDock->show();
|
|
|
|
this->dashboardDock->raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showSectionsContextMenu(const QPoint &pt)
|
|
|
|
{
|
|
|
|
// Set functions popup menu
|
|
|
|
QMenu *menu = new QMenu(this->sectionsDock);
|
|
|
|
menu->clear();
|
|
|
|
menu->addAction(ui->actionSectionsHorizontal);
|
|
|
|
menu->addAction(ui->actionSectionsVertical);
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
if (this->sectionsWidget->orientation() == 1)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->actionSectionsHorizontal->setChecked(true);
|
|
|
|
ui->actionSectionsVertical->setChecked(false);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->actionSectionsVertical->setChecked(true);
|
|
|
|
ui->actionSectionsHorizontal->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->sectionsDock->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
menu->exec(this->sectionsDock->mapToGlobal(pt));
|
|
|
|
delete menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSectionsHorizontal_triggered()
|
|
|
|
{
|
|
|
|
this->sectionsWidget->setOrientation(Qt::Horizontal);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSectionsVertical_triggered()
|
|
|
|
{
|
|
|
|
this->sectionsWidget->setOrientation(Qt::Vertical);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionForward_triggered()
|
|
|
|
{
|
|
|
|
this->core->cmd("s+");
|
|
|
|
QString offset = this->core->cmd("s=").split(" > ").last().trimmed();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (offset != "")
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->add_debug_output(offset);
|
|
|
|
this->seek(offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
void MainWindow::toggleResponsive(bool maybe)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
this->responsive = maybe;
|
|
|
|
// Save options in settings
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
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 = QMessageBox::question(this, "Iaito",
|
2017-04-09 19:55:06 +00:00
|
|
|
"Do you really want to clear all settings?",
|
|
|
|
QMessageBox::Ok | QMessageBox::Cancel);
|
|
|
|
if (ret == QMessageBox::Ok)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// Save options in settings
|
2017-04-03 00:18:09 +00:00
|
|
|
QSettings settings;
|
2017-03-29 10:18:37 +00:00
|
|
|
settings.clear();
|
|
|
|
}
|
|
|
|
}
|
2017-03-31 21:54:06 +00:00
|
|
|
|
|
|
|
void MainWindow::on_actionQuit_triggered()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|