mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-23 06:54:49 +00:00
Apply clang-format
This commit is contained in:
parent
a62f138e2f
commit
48ae2150a9
@ -21,13 +21,13 @@
|
|||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <QtNetwork/QtNetwork>
|
# include <QtNetwork/QtNetwork>
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#if CUTTER_RZGHIDRA_STATIC
|
#if CUTTER_RZGHIDRA_STATIC
|
||||||
#include <RzGhidraDecompiler.h>
|
# include <RzGhidraDecompiler.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
|
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
|
||||||
@ -38,7 +38,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
setAttribute(Qt::AA_UseHighDpiPixmaps);
|
setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
setLayoutDirection(Qt::LeftToRight);
|
setLayoutDirection(Qt::LeftToRight);
|
||||||
|
|
||||||
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First
|
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run
|
||||||
|
// First
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
// Hack to force Cutter load internet connection related DLL's
|
// Hack to force Cutter load internet connection related DLL's
|
||||||
@ -62,10 +63,9 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
qWarning() << "Cannot load Incosolata-Regular font.";
|
qWarning() << "Cannot load Incosolata-Regular font.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set QString codec to UTF-8
|
// Set QString codec to UTF-8
|
||||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||||
#endif
|
#endif
|
||||||
@ -82,9 +82,10 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
msg.setIcon(QMessageBox::Critical);
|
msg.setIcon(QMessageBox::Critical);
|
||||||
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||||
msg.setWindowTitle(QObject::tr("Version mismatch!"));
|
msg.setWindowTitle(QObject::tr("Version mismatch!"));
|
||||||
msg.setText(QString(
|
msg.setText(QString(QObject::tr("The version used to compile Cutter (%1) does not match "
|
||||||
QObject::tr("The version used to compile Cutter (%1) does not match the binary version of rizin (%2). This could result in unexpected behaviour. Are you sure you want to continue?")).arg(
|
"the binary version of rizin (%2). This could result in "
|
||||||
localVersion, rzversion));
|
"unexpected behaviour. Are you sure you want to continue?"))
|
||||||
|
.arg(localVersion, rzversion));
|
||||||
if (msg.exec() == QMessageBox::No) {
|
if (msg.exec() == QMessageBox::No) {
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
@ -134,7 +135,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
|
|
||||||
if (clOptions.args.empty()) {
|
if (clOptions.args.empty()) {
|
||||||
// check if this is the first execution of Cutter in this computer
|
// check if this is the first execution of Cutter in this computer
|
||||||
// Note: the execution after the preferences been reset, will be considered as first-execution
|
// Note: the execution after the preferences been reset, will be considered as
|
||||||
|
// first-execution
|
||||||
if (Config()->isFirstExecution()) {
|
if (Config()->isFirstExecution()) {
|
||||||
mainWindow->displayWelcomeDialog();
|
mainWindow->displayWelcomeDialog();
|
||||||
}
|
}
|
||||||
@ -144,14 +146,14 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions);
|
mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef APPIMAGE
|
#ifdef APPIMAGE
|
||||||
{
|
{
|
||||||
auto appdir = QDir(QCoreApplication::applicationDirPath()); // appdir/bin
|
auto appdir = QDir(QCoreApplication::applicationDirPath()); // appdir/bin
|
||||||
appdir.cdUp(); // appdir
|
appdir.cdUp(); // appdir
|
||||||
|
|
||||||
auto sleighHome = appdir;
|
auto sleighHome = appdir;
|
||||||
sleighHome.cd("share/rizin/plugins/rz_ghidra_sleigh"); // appdir/share/rizin/plugins/rz_ghidra_sleigh
|
sleighHome.cd(
|
||||||
|
"share/rizin/plugins/rz_ghidra_sleigh"); // appdir/share/rizin/plugins/rz_ghidra_sleigh
|
||||||
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
|
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
|
||||||
|
|
||||||
auto jsdecHome = appdir;
|
auto jsdecHome = appdir;
|
||||||
@ -167,11 +169,13 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
rzprefix.cd("Resources"); // Contents/Resources/rz
|
rzprefix.cd("Resources"); // Contents/Resources/rz
|
||||||
|
|
||||||
auto sleighHome = rzprefix;
|
auto sleighHome = rzprefix;
|
||||||
sleighHome.cd("share/rizin/plugins/rz_ghidra_sleigh"); // Contents/Resources/rz/share/rizin/plugins/rz_ghidra_sleigh
|
sleighHome.cd(
|
||||||
|
"share/rizin/plugins/rz_ghidra_sleigh"); // Contents/Resources/rz/share/rizin/plugins/rz_ghidra_sleigh
|
||||||
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
|
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
|
||||||
|
|
||||||
auto jsdecHome = rzprefix;
|
auto jsdecHome = rzprefix;
|
||||||
jsdecHome.cd("share/rizin/plugins/jsdec"); // Contents/Resources/rz/share/rizin/plugins/jsdec
|
jsdecHome.cd(
|
||||||
|
"share/rizin/plugins/jsdec"); // Contents/Resources/rz/share/rizin/plugins/jsdec
|
||||||
qputenv("JSDEC_HOME", jsdecHome.absolutePath().toLocal8Bit());
|
qputenv("JSDEC_HOME", jsdecHome.absolutePath().toLocal8Bit());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -221,7 +225,7 @@ bool CutterApplication::event(QEvent *e)
|
|||||||
// We already dropped a file in macOS, let's spawn another instance
|
// We already dropped a file in macOS, let's spawn another instance
|
||||||
// (Like the File -> Open)
|
// (Like the File -> Open)
|
||||||
QString fileName = openEvent->file();
|
QString fileName = openEvent->file();
|
||||||
launchNewInstance({fileName});
|
launchNewInstance({ fileName });
|
||||||
} else {
|
} else {
|
||||||
QString fileName = openEvent->file();
|
QString fileName = openEvent->file();
|
||||||
m_FileAlreadyDropped = true;
|
m_FileAlreadyDropped = true;
|
||||||
@ -241,8 +245,8 @@ bool CutterApplication::loadTranslations()
|
|||||||
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
|
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
const auto &allLocales =
|
||||||
QLocale::AnyCountry);
|
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||||
|
|
||||||
bool cutterTrLoaded = false;
|
bool cutterTrLoaded = false;
|
||||||
|
|
||||||
@ -259,7 +263,8 @@ bool CutterApplication::loadTranslations()
|
|||||||
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
|
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
|
||||||
|
|
||||||
for (const auto &trPath : cutterTrPaths) {
|
for (const auto &trPath : cutterTrPaths) {
|
||||||
if (trCutter && trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) {
|
if (trCutter
|
||||||
|
&& trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) {
|
||||||
installTranslator(trCutter);
|
installTranslator(trCutter);
|
||||||
cutterTrLoaded = true;
|
cutterTrLoaded = true;
|
||||||
trCutter = nullptr;
|
trCutter = nullptr;
|
||||||
@ -304,47 +309,45 @@ bool CutterApplication::parseCommandLineOptions()
|
|||||||
cmd_parser.addVersionOption();
|
cmd_parser.addVersionOption();
|
||||||
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
||||||
|
|
||||||
QCommandLineOption analOption({"A", "analysis"},
|
QCommandLineOption analOption(
|
||||||
|
{ "A", "analysis" },
|
||||||
QObject::tr("Automatically open file and optionally start analysis. "
|
QObject::tr("Automatically open file and optionally start analysis. "
|
||||||
"Needs filename to be specified. May be a value between 0 and 2:"
|
"Needs filename to be specified. May be a value between 0 and 2:"
|
||||||
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
|
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
|
||||||
QObject::tr("level"));
|
QObject::tr("level"));
|
||||||
cmd_parser.addOption(analOption);
|
cmd_parser.addOption(analOption);
|
||||||
|
|
||||||
QCommandLineOption formatOption({"F", "format"},
|
QCommandLineOption formatOption({ "F", "format" },
|
||||||
QObject::tr("Force using a specific file format (bin plugin)"),
|
QObject::tr("Force using a specific file format (bin plugin)"),
|
||||||
QObject::tr("name"));
|
QObject::tr("name"));
|
||||||
cmd_parser.addOption(formatOption);
|
cmd_parser.addOption(formatOption);
|
||||||
|
|
||||||
QCommandLineOption baddrOption({"B", "base"},
|
QCommandLineOption baddrOption({ "B", "base" },
|
||||||
QObject::tr("Load binary at a specific base address"),
|
QObject::tr("Load binary at a specific base address"),
|
||||||
QObject::tr("base address"));
|
QObject::tr("base address"));
|
||||||
cmd_parser.addOption(baddrOption);
|
cmd_parser.addOption(baddrOption);
|
||||||
|
|
||||||
QCommandLineOption scriptOption("i",
|
QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
|
||||||
QObject::tr("Run script file"),
|
|
||||||
QObject::tr("file"));
|
|
||||||
cmd_parser.addOption(scriptOption);
|
cmd_parser.addOption(scriptOption);
|
||||||
|
|
||||||
QCommandLineOption writeModeOption({"w", "writemode"},
|
QCommandLineOption writeModeOption({ "w", "writemode" },
|
||||||
QObject::tr("Open file in write mode"));
|
QObject::tr("Open file in write mode"));
|
||||||
cmd_parser.addOption(writeModeOption);
|
cmd_parser.addOption(writeModeOption);
|
||||||
|
|
||||||
|
QCommandLineOption pythonHomeOption(
|
||||||
QCommandLineOption pythonHomeOption("pythonhome",
|
"pythonhome", QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
||||||
QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
|
||||||
"PYTHONHOME");
|
"PYTHONHOME");
|
||||||
cmd_parser.addOption(pythonHomeOption);
|
cmd_parser.addOption(pythonHomeOption);
|
||||||
|
|
||||||
QCommandLineOption disableRedirectOption("no-output-redirect",
|
QCommandLineOption disableRedirectOption(
|
||||||
|
"no-output-redirect",
|
||||||
QObject::tr("Disable output redirection."
|
QObject::tr("Disable output redirection."
|
||||||
" Some of the output in console widget will not be visible."
|
" Some of the output in console widget will not be visible."
|
||||||
" Use this option when debuging a crash or freeze and output "
|
" Use this option when debuging a crash or freeze and output "
|
||||||
" redirection is causing some messages to be lost."));
|
" redirection is causing some messages to be lost."));
|
||||||
cmd_parser.addOption(disableRedirectOption);
|
cmd_parser.addOption(disableRedirectOption);
|
||||||
|
|
||||||
QCommandLineOption disablePlugins("no-plugins",
|
QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
|
||||||
QObject::tr("Do not load plugins"));
|
|
||||||
cmd_parser.addOption(disablePlugins);
|
cmd_parser.addOption(disablePlugins);
|
||||||
|
|
||||||
QCommandLineOption disableCutterPlugins("no-cutter-plugins",
|
QCommandLineOption disableCutterPlugins("no-cutter-plugins",
|
||||||
@ -366,7 +369,9 @@ bool CutterApplication::parseCommandLineOptions()
|
|||||||
|
|
||||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
|
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
|
||||||
fprintf(stderr, "%s\n",
|
fprintf(stderr, "%s\n",
|
||||||
QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData());
|
QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.")
|
||||||
|
.toLocal8Bit()
|
||||||
|
.constData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (analLevel) {
|
switch (analLevel) {
|
||||||
@ -384,7 +389,9 @@ bool CutterApplication::parseCommandLineOptions()
|
|||||||
|
|
||||||
if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) {
|
if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) {
|
||||||
fprintf(stderr, "%s\n",
|
fprintf(stderr, "%s\n",
|
||||||
QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
QObject::tr("Filename must be specified to start analysis automatically.")
|
||||||
|
.toLocal8Bit()
|
||||||
|
.constData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,10 +413,10 @@ bool CutterApplication::parseCommandLineOptions()
|
|||||||
opts.fileOpenOptions.analCmd = {};
|
opts.fileOpenOptions.analCmd = {};
|
||||||
break;
|
break;
|
||||||
case AutomaticAnalysisLevel::AAA:
|
case AutomaticAnalysisLevel::AAA:
|
||||||
opts.fileOpenOptions.analCmd = { {"aaa", "Auto analysis"} };
|
opts.fileOpenOptions.analCmd = { { "aaa", "Auto analysis" } };
|
||||||
break;
|
break;
|
||||||
case AutomaticAnalysisLevel::AAAA:
|
case AutomaticAnalysisLevel::AAAA:
|
||||||
opts.fileOpenOptions.analCmd = { {"aaaa", "Auto analysis (experimental)"} };
|
opts.fileOpenOptions.analCmd = { { "aaaa", "Auto analysis (experimental)" } };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
opts.fileOpenOptions.script = cmd_parser.value(scriptOption);
|
opts.fileOpenOptions.script = cmd_parser.value(scriptOption);
|
||||||
@ -439,7 +446,6 @@ bool CutterApplication::parseCommandLineOptions()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CutterProxyStyle::polish(QWidget *widget)
|
void CutterProxyStyle::polish(QWidget *widget)
|
||||||
{
|
{
|
||||||
QProxyStyle::polish(widget);
|
QProxyStyle::polish(widget);
|
||||||
|
@ -8,11 +8,10 @@
|
|||||||
|
|
||||||
#include "core/MainWindow.h"
|
#include "core/MainWindow.h"
|
||||||
|
|
||||||
enum class AutomaticAnalysisLevel {
|
enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA };
|
||||||
Ask, None, AAA, AAAA
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CutterCommandLineOptions {
|
struct CutterCommandLineOptions
|
||||||
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask;
|
AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask;
|
||||||
InitialOptions fileOpenOptions;
|
InitialOptions fileOpenOptions;
|
||||||
@ -30,12 +29,10 @@ public:
|
|||||||
CutterApplication(int &argc, char **argv);
|
CutterApplication(int &argc, char **argv);
|
||||||
~CutterApplication();
|
~CutterApplication();
|
||||||
|
|
||||||
MainWindow *getMainWindow()
|
MainWindow *getMainWindow() { return mainWindow; }
|
||||||
{
|
|
||||||
return mainWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
void launchNewInstance(const QStringList &args = {});
|
void launchNewInstance(const QStringList &args = {});
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event(QEvent *e);
|
bool event(QEvent *e);
|
||||||
|
|
||||||
@ -50,13 +47,13 @@ private:
|
|||||||
* @return false if options have error
|
* @return false if options have error
|
||||||
*/
|
*/
|
||||||
bool parseCommandLineOptions();
|
bool parseCommandLineOptions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_FileAlreadyDropped;
|
bool m_FileAlreadyDropped;
|
||||||
MainWindow *mainWindow;
|
MainWindow *mainWindow;
|
||||||
CutterCommandLineOptions clOptions;
|
CutterCommandLineOptions clOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CutterProxyStyle is used to force shortcuts displaying in context menu
|
* @brief CutterProxyStyle is used to force shortcuts displaying in context menu
|
||||||
*/
|
*/
|
||||||
|
17
src/Main.cpp
17
src/Main.cpp
@ -10,7 +10,6 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Attempt to connect to a parent console and configure outputs.
|
* @brief Attempt to connect to a parent console and configure outputs.
|
||||||
*
|
*
|
||||||
@ -51,7 +50,6 @@ static void connectToConsole()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#ifdef CUTTER_ENABLE_CRASH_REPORTS
|
#ifdef CUTTER_ENABLE_CRASH_REPORTS
|
||||||
@ -77,12 +75,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Cutter::initializeSettings();
|
Cutter::initializeSettings();
|
||||||
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
|
QCoreApplication::setAttribute(
|
||||||
|
Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||||
#endif
|
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CutterApplication a(argc, argv);
|
CutterApplication a(argc, argv);
|
||||||
@ -93,8 +93,9 @@ int main(int argc, char *argv[])
|
|||||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
UpdateWorker *updateWorker = new UpdateWorker;
|
UpdateWorker *updateWorker = new UpdateWorker;
|
||||||
QObject::connect(updateWorker, &UpdateWorker::checkComplete,
|
QObject::connect(updateWorker, &UpdateWorker::checkComplete,
|
||||||
[=](const QVersionNumber &version, const QString & error) {
|
[=](const QVersionNumber &version, const QString &error) {
|
||||||
if (error.isEmpty() && version > UpdateWorker::currentVersionNumber()) {
|
if (error.isEmpty()
|
||||||
|
&& version > UpdateWorker::currentVersionNumber()) {
|
||||||
updateWorker->showUpdateDialog(true);
|
updateWorker->showUpdateDialog(true);
|
||||||
}
|
}
|
||||||
updateWorker->deleteLater();
|
updateWorker->deleteLater();
|
||||||
|
@ -11,4 +11,4 @@
|
|||||||
#include "../plugins/CutterPlugin.h"
|
#include "../plugins/CutterPlugin.h"
|
||||||
#include "../menus/AddressableItemContextMenu.h"
|
#include "../menus/AddressableItemContextMenu.h"
|
||||||
|
|
||||||
#endif //CUTTER_BINDINGS_H
|
#endif // CUTTER_BINDINGS_H
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
|
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
|
||||||
QObject *parent) :
|
QObject *parent)
|
||||||
AddressableItemModel<QSortFilterProxyModel>(parent)
|
: AddressableItemModel<QSortFilterProxyModel>(parent)
|
||||||
{
|
{
|
||||||
setSourceModel(sourceModel);
|
setSourceModel(sourceModel);
|
||||||
addressableSourceModel = sourceModel;
|
addressableSourceModel = sourceModel;
|
||||||
|
@ -17,15 +17,20 @@ public:
|
|||||||
* @param index item intex
|
* @param index item intex
|
||||||
* @return Item name or empty QString if item doesn't have short descriptive name.
|
* @return Item name or empty QString if item doesn't have short descriptive name.
|
||||||
*/
|
*/
|
||||||
virtual QString name(const QModelIndex &index) const { Q_UNUSED(index) return QString(); }
|
virtual QString name(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(index)
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
virtual QAbstractItemModel *asItemModel() = 0;
|
virtual QAbstractItemModel *asItemModel() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ParentModel = QAbstractItemModel>
|
template<class ParentModel = QAbstractItemModel>
|
||||||
class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
||||||
{
|
{
|
||||||
static_assert (std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
static_assert(std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
||||||
"ParentModel needs to inherit from QAbstractItemModel");
|
"ParentModel needs to inherit from QAbstractItemModel");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
|
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
|
||||||
virtual ~AddressableItemModel() {}
|
virtual ~AddressableItemModel() {}
|
||||||
@ -35,12 +40,14 @@ public:
|
|||||||
class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
|
class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
|
||||||
{
|
{
|
||||||
using ParentClass = AddressableItemModel<QSortFilterProxyModel>;
|
using ParentClass = AddressableItemModel<QSortFilterProxyModel>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent);
|
AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent);
|
||||||
|
|
||||||
RVA address(const QModelIndex &index) const override;
|
RVA address(const QModelIndex &index) const override;
|
||||||
QString name(const QModelIndex &) const override;
|
QString name(const QModelIndex &) const override;
|
||||||
void setSourceModel(AddressableItemModelI *sourceModel);
|
void setSourceModel(AddressableItemModelI *sourceModel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly
|
void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly
|
||||||
AddressableItemModelI *addressableSourceModel;
|
AddressableItemModelI *addressableSourceModel;
|
||||||
|
@ -6,14 +6,9 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
|
||||||
AnalTask::AnalTask() :
|
AnalTask::AnalTask() : AsyncTask() {}
|
||||||
AsyncTask()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AnalTask::~AnalTask()
|
AnalTask::~AnalTask() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnalTask::interrupt()
|
void AnalTask::interrupt()
|
||||||
{
|
{
|
||||||
@ -21,7 +16,8 @@ void AnalTask::interrupt()
|
|||||||
rz_cons_singleton()->context->breaked = true;
|
rz_cons_singleton()->context->breaked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AnalTask::getTitle() {
|
QString AnalTask::getTitle()
|
||||||
|
{
|
||||||
// If no file is loaded we consider it's Initial Analysis
|
// If no file is loaded we consider it's Initial Analysis
|
||||||
QJsonArray openedFiles = Core()->getOpenedFiles();
|
QJsonArray openedFiles = Core()->getOpenedFiles();
|
||||||
if (!openedFiles.size()) {
|
if (!openedFiles.size()) {
|
||||||
@ -36,7 +32,6 @@ void AnalTask::runTask()
|
|||||||
if (options.writeEnabled) {
|
if (options.writeEnabled) {
|
||||||
perms |= RZ_PERM_W;
|
perms |= RZ_PERM_W;
|
||||||
emit Core()->ioModeChanged();
|
emit Core()->ioModeChanged();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demangle (must be before file Core()->loadFile)
|
// Demangle (must be before file Core()->loadFile)
|
||||||
@ -47,13 +42,9 @@ void AnalTask::runTask()
|
|||||||
if (!openedFiles.size() && options.filename.length()) {
|
if (!openedFiles.size() && options.filename.length()) {
|
||||||
log(tr("Loading the file..."));
|
log(tr("Loading the file..."));
|
||||||
openFailed = false;
|
openFailed = false;
|
||||||
bool fileLoaded = Core()->loadFile(options.filename,
|
bool fileLoaded =
|
||||||
options.binLoadAddr,
|
Core()->loadFile(options.filename, options.binLoadAddr, options.mapAddr, perms,
|
||||||
options.mapAddr,
|
options.useVA, options.loadBinInfo, options.forceBinPlugin);
|
||||||
perms,
|
|
||||||
options.useVA,
|
|
||||||
options.loadBinInfo,
|
|
||||||
options.forceBinPlugin);
|
|
||||||
if (!fileLoaded) {
|
if (!fileLoaded) {
|
||||||
// Something wrong happened, fallback to open dialog
|
// Something wrong happened, fallback to open dialog
|
||||||
openFailed = true;
|
openFailed = true;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
|
|
||||||
#include "AsyncTask.h"
|
#include "AsyncTask.h"
|
||||||
|
|
||||||
AsyncTask::AsyncTask()
|
AsyncTask::AsyncTask() : QObject(nullptr), QRunnable()
|
||||||
: QObject(nullptr),
|
|
||||||
QRunnable()
|
|
||||||
{
|
{
|
||||||
setAutoDelete(false);
|
setAutoDelete(false);
|
||||||
running = false;
|
running = false;
|
||||||
@ -64,15 +62,12 @@ void AsyncTask::log(QString s)
|
|||||||
emit logChanged(logBuffer);
|
emit logChanged(logBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncTaskManager::AsyncTaskManager(QObject *parent)
|
AsyncTaskManager::AsyncTaskManager(QObject *parent) : QObject(parent)
|
||||||
: QObject(parent)
|
|
||||||
{
|
{
|
||||||
threadPool = new QThreadPool(this);
|
threadPool = new QThreadPool(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncTaskManager::~AsyncTaskManager()
|
AsyncTaskManager::~AsyncTaskManager() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncTaskManager::start(AsyncTask::Ptr task)
|
void AsyncTaskManager::start(AsyncTask::Ptr task)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
virtual QString getTitle() { return QString(); }
|
virtual QString getTitle() { return QString(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void runTask() =0;
|
virtual void runTask() = 0;
|
||||||
|
|
||||||
void log(QString s);
|
void log(QString s);
|
||||||
|
|
||||||
@ -78,5 +78,4 @@ signals:
|
|||||||
void tasksChanged();
|
void tasksChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // ASYNCTASK_H
|
||||||
#endif //ASYNCTASK_H
|
|
@ -1,8 +1,6 @@
|
|||||||
#include "BasicBlockHighlighter.h"
|
#include "BasicBlockHighlighter.h"
|
||||||
|
|
||||||
BasicBlockHighlighter::BasicBlockHighlighter()
|
BasicBlockHighlighter::BasicBlockHighlighter() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicBlockHighlighter::~BasicBlockHighlighter()
|
BasicBlockHighlighter::~BasicBlockHighlighter()
|
||||||
{
|
{
|
||||||
|
@ -6,12 +6,13 @@ class BasicBlockHighlighter;
|
|||||||
#include "Cutter.h"
|
#include "Cutter.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
struct BasicBlock {
|
struct BasicBlock
|
||||||
|
{
|
||||||
RVA address;
|
RVA address;
|
||||||
QColor color;
|
QColor color;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<RVA, BasicBlock*>::iterator BasicBlockIt;
|
typedef std::map<RVA, BasicBlock *>::iterator BasicBlockIt;
|
||||||
|
|
||||||
class BasicBlockHighlighter
|
class BasicBlockHighlighter
|
||||||
{
|
{
|
||||||
@ -24,7 +25,7 @@ public:
|
|||||||
BasicBlock *getBasicBlock(RVA address);
|
BasicBlock *getBasicBlock(RVA address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<RVA, BasicBlock*> bbMap;
|
std::map<RVA, BasicBlock *> bbMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BASICBLOCKHIGHLIGHTER_H
|
#endif // BASICBLOCKHIGHLIGHTER_H
|
||||||
|
@ -24,13 +24,13 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
|
|||||||
if (!addrs.empty()) {
|
if (!addrs.empty()) {
|
||||||
const BasicInstruction &prev = biMap[addrs.front()];
|
const BasicInstruction &prev = biMap[addrs.front()];
|
||||||
if (prev.address < address && prev.address + prev.size > address) {
|
if (prev.address < address && prev.address + prev.size > address) {
|
||||||
newInstructions.push_back({prev.address, address - prev.address, prev.color});
|
newInstructions.push_back({ prev.address, address - prev.address, prev.color });
|
||||||
}
|
}
|
||||||
|
|
||||||
const BasicInstruction &next = biMap[addrs.back()];
|
const BasicInstruction &next = biMap[addrs.back()];
|
||||||
if (next.address < address + size && next.address + next.size > address + size) {
|
if (next.address < address + size && next.address + next.size > address + size) {
|
||||||
const RVA offset = address + size - next.address;
|
const RVA offset = address + size - next.address;
|
||||||
newInstructions.push_back({next.address + offset, next.size - offset, next.color});
|
newInstructions.push_back({ next.address + offset, next.size - offset, next.color });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( BasicInstruction newInstr : newInstructions) {
|
for (BasicInstruction newInstr : newInstructions) {
|
||||||
biMap[newInstr.address] = newInstr;
|
biMap[newInstr.address] = newInstr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
|
|||||||
void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color)
|
void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color)
|
||||||
{
|
{
|
||||||
clear(address, size);
|
clear(address, size);
|
||||||
biMap[address] = {address, size, color};
|
biMap[address] = { address, size, color };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
struct BasicInstruction {
|
struct BasicInstruction
|
||||||
|
{
|
||||||
RVA address;
|
RVA address;
|
||||||
RVA size;
|
RVA size;
|
||||||
QColor color;
|
QColor color;
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not really a segment tree for storing segments as referred in academic literature. Can be considered a
|
* Not really a segment tree for storing segments as referred in academic literature. Can be
|
||||||
* full, almost perfect, augmented binary tree. In the context of competitive programming often called segment tree.
|
* considered a full, almost perfect, augmented binary tree. In the context of competitive
|
||||||
|
* programming often called segment tree.
|
||||||
*
|
*
|
||||||
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left, NodeType& right)
|
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left,
|
||||||
* method which calculates inner node values from children nodes.
|
* NodeType& right) method which calculates inner node values from children nodes.
|
||||||
*
|
*
|
||||||
* \tparam NodeTypeT type of each tree element
|
* \tparam NodeTypeT type of each tree element
|
||||||
* \tparam FinalType final child class used for curiously recurring template pattern
|
* \tparam FinalType final child class used for curiously recurring template pattern
|
||||||
@ -33,11 +33,7 @@ public:
|
|||||||
* @brief Create tree with \a size leaves.
|
* @brief Create tree with \a size leaves.
|
||||||
* @param size number of leaves in the tree
|
* @param size number of leaves in the tree
|
||||||
*/
|
*/
|
||||||
explicit SegmentTreeBase(size_t size)
|
explicit SegmentTreeBase(size_t size) : size(size), nodeCount(2 * size), nodes(nodeCount) {}
|
||||||
: size(size)
|
|
||||||
, nodeCount(2 * size)
|
|
||||||
, nodes(nodeCount)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a tree with given size and initial value.
|
* @brief Create a tree with given size and initial value.
|
||||||
@ -46,38 +42,23 @@ public:
|
|||||||
* @param size number of leaves
|
* @param size number of leaves
|
||||||
* @param initialValue initial leave value
|
* @param initialValue initial leave value
|
||||||
*/
|
*/
|
||||||
SegmentTreeBase(size_t size, const NodeType &initialValue)
|
SegmentTreeBase(size_t size, const NodeType &initialValue) : SegmentTreeBase(size)
|
||||||
: SegmentTreeBase(size)
|
|
||||||
{
|
{
|
||||||
init(initialValue);
|
init(initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Curiously recurring template pattern
|
// Curiously recurring template pattern
|
||||||
FinalType &This()
|
FinalType &This() { return static_cast<FinalType &>(*this); }
|
||||||
{
|
|
||||||
return static_cast<FinalType &>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Curiously recurring template pattern
|
// Curiously recurring template pattern
|
||||||
const FinalType &This() const
|
const FinalType &This() const { return static_cast<const FinalType &>(*this); }
|
||||||
{
|
|
||||||
return static_cast<const FinalType &>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t leavePositionToIndex(NodePosition pos) const
|
size_t leavePositionToIndex(NodePosition pos) const { return pos - size; }
|
||||||
{
|
|
||||||
return pos - size;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodePosition leaveIndexToPosition(size_t index) const
|
NodePosition leaveIndexToPosition(size_t index) const { return index + size; }
|
||||||
{
|
|
||||||
return index + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLeave(NodePosition position) const
|
bool isLeave(NodePosition position) const { return position >= size; }
|
||||||
{
|
|
||||||
return position >= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate inner node values from leaves.
|
* @brief Calculate inner node values from leaves.
|
||||||
@ -111,6 +92,7 @@ template<class NodeType, class FinalType>
|
|||||||
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
|
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
|
||||||
{
|
{
|
||||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using BaseType::BaseType;
|
using BaseType::BaseType;
|
||||||
|
|
||||||
@ -125,7 +107,8 @@ public:
|
|||||||
this->nodes[pos] = value;
|
this->nodes[pos] = value;
|
||||||
while (pos > 1) {
|
while (pos > 1) {
|
||||||
auto parrent = pos >> 1;
|
auto parrent = pos >> 1;
|
||||||
this->This().updateFromChildren(this->nodes[parrent], this->nodes[pos], this->nodes[pos ^ 1]);
|
this->This().updateFromChildren(this->nodes[parrent], this->nodes[pos],
|
||||||
|
this->nodes[pos ^ 1]);
|
||||||
pos = parrent;
|
pos = parrent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,6 +124,7 @@ public:
|
|||||||
class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree>
|
class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree>
|
||||||
{
|
{
|
||||||
using BaseType = PointSetSegmentTree<int, PointSetMinTree>;
|
using BaseType = PointSetSegmentTree<int, PointSetMinTree>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using NodeType = int;
|
using NodeType = int;
|
||||||
|
|
||||||
@ -159,16 +143,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
int rightMostLessThan(size_t position, int value)
|
int rightMostLessThan(size_t position, int value)
|
||||||
{
|
{
|
||||||
auto isGood = [&](size_t pos) {
|
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||||
return nodes[pos] < value;
|
|
||||||
};
|
|
||||||
// right side exclusive range [l;r)
|
// right side exclusive range [l;r)
|
||||||
size_t goodSubtree = 0;
|
size_t goodSubtree = 0;
|
||||||
for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r;
|
for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r;
|
||||||
l >>= 1, r >>= 1) {
|
l >>= 1, r >>= 1) {
|
||||||
if (l & 1) {
|
if (l & 1) {
|
||||||
if (isGood(l)) {
|
if (isGood(l)) {
|
||||||
// mark subtree as good but don't stop yet, there might be something good further to the right
|
// mark subtree as good but don't stop yet, there might be something good
|
||||||
|
// further to the right
|
||||||
goodSubtree = l;
|
goodSubtree = l;
|
||||||
}
|
}
|
||||||
++l;
|
++l;
|
||||||
@ -202,9 +185,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
int leftMostLessThan(size_t position, int value)
|
int leftMostLessThan(size_t position, int value)
|
||||||
{
|
{
|
||||||
auto isGood = [&](size_t pos) {
|
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||||
return nodes[pos] < value;
|
|
||||||
};
|
|
||||||
// right side exclusive range [l;r)
|
// right side exclusive range [l;r)
|
||||||
size_t goodSubtree = 0;
|
size_t goodSubtree = 0;
|
||||||
for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r;
|
for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r;
|
||||||
@ -220,7 +201,8 @@ public:
|
|||||||
--r;
|
--r;
|
||||||
if (isGood(r)) {
|
if (isGood(r)) {
|
||||||
goodSubtree = r;
|
goodSubtree = r;
|
||||||
// mark subtree as good but don't stop yet, there might be something good further to the left
|
// mark subtree as good but don't stop yet, there might be something good
|
||||||
|
// further to the left
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,28 +223,28 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Tree that supports lazily applying an operation to range.
|
* \brief Tree that supports lazily applying an operation to range.
|
||||||
*
|
*
|
||||||
* Each inner node has a promise value describing an operation that needs to be applied to corresponding subtree.
|
* Each inner node has a promise value describing an operation that needs to be applied to
|
||||||
|
* corresponding subtree.
|
||||||
*
|
*
|
||||||
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies the applies the
|
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies
|
||||||
* operation stored in \a promise for nodePosition to the direct children nodes.
|
* the applies the operation stored in \a promise for nodePosition to the direct children nodes.
|
||||||
*
|
*
|
||||||
* \tparam NodeType type of tree nodes
|
* \tparam NodeType type of tree nodes
|
||||||
* \tparam PromiseType type describing operation that needs to be applied to subtree
|
* \tparam PromiseType type describing operation that needs to be applied to subtree
|
||||||
* \tparam FinalType child class type for CRTP. See SegmentTreeBase
|
* \tparam FinalType child class type for CRTP. See SegmentTreeBase
|
||||||
*/
|
*/
|
||||||
template <class NodeType, class PromiseType, class FinalType>
|
template<class NodeType, class PromiseType, class FinalType>
|
||||||
class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType>
|
class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType>
|
||||||
{
|
{
|
||||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param size Number of tree leaves.
|
* @param size Number of tree leaves.
|
||||||
* @param neutralPromise Promise value that doesn't modify tree nodes.
|
* @param neutralPromise Promise value that doesn't modify tree nodes.
|
||||||
*/
|
*/
|
||||||
LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise)
|
LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise)
|
||||||
: BaseType(size)
|
: BaseType(size), neutralPromiseElement(neutralPromise), promise(size, neutralPromise)
|
||||||
, neutralPromiseElement(neutralPromise)
|
|
||||||
, promise(size, neutralPromise)
|
|
||||||
{
|
{
|
||||||
h = 0;
|
h = 0;
|
||||||
size_t v = size;
|
size_t v = size;
|
||||||
@ -324,7 +306,8 @@ protected:
|
|||||||
while (p > 1) {
|
while (p > 1) {
|
||||||
auto parent = p >> 1;
|
auto parent = p >> 1;
|
||||||
if (promise[parent] == neutralPromiseElement) {
|
if (promise[parent] == neutralPromiseElement) {
|
||||||
This().updateFromChildren(this->nodes[parent], this->nodes[p & ~size_t(1)], this->nodes[p | 1]);
|
This().updateFromChildren(this->nodes[parent], this->nodes[p & ~size_t(1)],
|
||||||
|
this->nodes[p | 1]);
|
||||||
}
|
}
|
||||||
p = parent;
|
p = parent;
|
||||||
}
|
}
|
||||||
@ -337,19 +320,16 @@ protected:
|
|||||||
std::vector<PromiseType> promise;
|
std::vector<PromiseType> promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure supporting range assignment and range maximum operations.
|
* @brief Structure supporting range assignment and range maximum operations.
|
||||||
*/
|
*/
|
||||||
class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>
|
class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>
|
||||||
{
|
{
|
||||||
using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>;
|
using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using ValueType = int;
|
using ValueType = int;
|
||||||
RangeAssignMaxTree(size_t size, ValueType initialValue)
|
RangeAssignMaxTree(size_t size, ValueType initialValue) : BaseType(size, initialValue, 0) {}
|
||||||
: BaseType(size, initialValue, 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
|
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
|
||||||
{
|
{
|
||||||
|
@ -9,11 +9,9 @@
|
|||||||
void openIssue()
|
void openIssue()
|
||||||
{
|
{
|
||||||
QString url, osInfo, format, arch, type;
|
QString url, osInfo, format, arch, type;
|
||||||
//Pull in info needed for git issue
|
// Pull in info needed for git issue
|
||||||
osInfo = QSysInfo::productType() + " " +
|
osInfo = QSysInfo::productType() + " "
|
||||||
(QSysInfo::productVersion() == "unknown"
|
+ (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
|
||||||
? ""
|
|
||||||
: QSysInfo::productVersion());
|
|
||||||
QJsonDocument docu = Core()->getFileInfo();
|
QJsonDocument docu = Core()->getFileInfo();
|
||||||
QJsonObject coreObj = docu.object()["core"].toObject();
|
QJsonObject coreObj = docu.object()["core"].toObject();
|
||||||
QJsonObject binObj = docu.object()["bin"].toObject();
|
QJsonObject binObj = docu.object()["bin"].toObject();
|
||||||
@ -30,12 +28,14 @@ void openIssue()
|
|||||||
arch = "N/A";
|
arch = "N/A";
|
||||||
type = "N/A";
|
type = "N/A";
|
||||||
}
|
}
|
||||||
url =
|
url = "https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* "
|
||||||
"https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* Operating System: "
|
"Operating System: "
|
||||||
+ osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL +
|
+ osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL + "\n* File format: " + format
|
||||||
"\n* File format: " + format + "\n * Arch: " + arch + "\n * Type: " + type +
|
+ "\n * Arch: " + arch + "\n * Type: " + type
|
||||||
"\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\n"
|
+ "\n\n**Describe the bug**\nA clear and concise description of what the bug "
|
||||||
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n"
|
"is.\n\n**To Reproduce**\n"
|
||||||
|
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll "
|
||||||
|
"down to '....'\n"
|
||||||
"4. See error\n\n**Expected behavior**\n"
|
"4. See error\n\n**Expected behavior**\n"
|
||||||
"A clear and concise description of what you expected to happen.\n\n"
|
"A clear and concise description of what you expected to happen.\n\n"
|
||||||
"**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n"
|
"**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n"
|
||||||
|
@ -11,8 +11,7 @@ template<typename T>
|
|||||||
class CachedFontMetrics
|
class CachedFontMetrics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CachedFontMetrics(const QFont &font)
|
explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font)
|
||||||
: mFontMetrics(font)
|
|
||||||
{
|
{
|
||||||
memset(mWidths, 0, sizeof(mWidths));
|
memset(mWidths, 0, sizeof(mWidths));
|
||||||
mHeight = mFontMetrics.height();
|
mHeight = mFontMetrics.height();
|
||||||
@ -20,7 +19,7 @@ public:
|
|||||||
|
|
||||||
T width(const QChar &ch)
|
T width(const QChar &ch)
|
||||||
{
|
{
|
||||||
//return mFontMetrics.width(ch);
|
// return mFontMetrics.width(ch);
|
||||||
auto unicode = ch.unicode();
|
auto unicode = ch.unicode();
|
||||||
if (unicode >= 0xD800) {
|
if (unicode >= 0xD800) {
|
||||||
if (unicode >= 0xE000)
|
if (unicode >= 0xE000)
|
||||||
@ -49,10 +48,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
T height()
|
T height() { return mHeight; }
|
||||||
{
|
|
||||||
return mHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
T position(const QString &text, T offset)
|
T position(const QString &text, T offset)
|
||||||
{
|
{
|
||||||
@ -84,7 +80,7 @@ private:
|
|||||||
|
|
||||||
T fetchWidth(QChar c)
|
T fetchWidth(QChar c)
|
||||||
{
|
{
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5,11,0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||||
return mFontMetrics.width(c);
|
return mFontMetrics.width(c);
|
||||||
#else
|
#else
|
||||||
return mFontMetrics.horizontalAdvance(c);
|
return mFontMetrics.horizontalAdvance(c);
|
||||||
@ -93,7 +89,7 @@ private:
|
|||||||
|
|
||||||
T fetchWidth(const QString &s)
|
T fetchWidth(const QString &s)
|
||||||
{
|
{
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5,11,0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||||
return mFontMetrics.width(s);
|
return mFontMetrics.width(s);
|
||||||
#else
|
#else
|
||||||
return mFontMetrics.horizontalAdvance(s);
|
return mFontMetrics.horizontalAdvance(s);
|
||||||
|
@ -10,80 +10,46 @@
|
|||||||
#include "common/Configuration.h"
|
#include "common/Configuration.h"
|
||||||
|
|
||||||
const QStringList ColorThemeWorker::cutterSpecificOptions = {
|
const QStringList ColorThemeWorker::cutterSpecificOptions = {
|
||||||
"wordHighlight",
|
"wordHighlight", "lineHighlight", "gui.main",
|
||||||
"lineHighlight",
|
"gui.imports", "highlightPC", "gui.navbar.err",
|
||||||
"gui.main",
|
"gui.navbar.seek", "gui.navbar.pc", "gui.navbar.sym",
|
||||||
"gui.imports",
|
"gui.dataoffset", "gui.navbar.code", "gui.navbar.empty",
|
||||||
"highlightPC",
|
"angui.navbar.str", "gui.disass_selected", "gui.breakpoint_background",
|
||||||
"gui.navbar.err",
|
"gui.overview.node", "gui.overview.fill", "gui.overview.border",
|
||||||
"gui.navbar.seek",
|
"gui.border", "gui.background", "gui.alt_background",
|
||||||
"gui.navbar.pc",
|
|
||||||
"gui.navbar.sym",
|
|
||||||
"gui.dataoffset",
|
|
||||||
"gui.navbar.code",
|
|
||||||
"gui.navbar.empty",
|
|
||||||
"angui.navbar.str",
|
|
||||||
"gui.disass_selected",
|
|
||||||
"gui.breakpoint_background",
|
|
||||||
"gui.overview.node",
|
|
||||||
"gui.overview.fill",
|
|
||||||
"gui.overview.border",
|
|
||||||
"gui.border",
|
|
||||||
"gui.background",
|
|
||||||
"gui.alt_background",
|
|
||||||
"gui.disass_selected"
|
"gui.disass_selected"
|
||||||
};
|
};
|
||||||
|
|
||||||
const QStringList ColorThemeWorker::rizinUnusedOptions = {
|
const QStringList ColorThemeWorker::rizinUnusedOptions = {
|
||||||
"linehl",
|
"linehl", "wordhl", "graph.box", "graph.box2", "graph.box3",
|
||||||
"wordhl",
|
"graph.box4", "graph.current", "graph.box2", "widget_sel", "widget_bg",
|
||||||
"graph.box",
|
"label", "ai.write", "invalid", "ai.seq", "args",
|
||||||
"graph.box2",
|
"ai.read", "ai.exec", "ai.ascii", "prompt", "graph.traced"
|
||||||
"graph.box3",
|
|
||||||
"graph.box4",
|
|
||||||
"graph.current",
|
|
||||||
"graph.box2",
|
|
||||||
"widget_sel",
|
|
||||||
"widget_bg",
|
|
||||||
"label",
|
|
||||||
"ai.write",
|
|
||||||
"invalid",
|
|
||||||
"ai.seq",
|
|
||||||
"args",
|
|
||||||
"ai.read",
|
|
||||||
"ai.exec",
|
|
||||||
"ai.ascii",
|
|
||||||
"prompt",
|
|
||||||
"graph.traced"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject (parent)
|
ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
char* szThemes = rz_str_home(RZ_HOME_THEMES);
|
char *szThemes = rz_str_home(RZ_HOME_THEMES);
|
||||||
customRzThemesLocationPath = szThemes;
|
customRzThemesLocationPath = szThemes;
|
||||||
rz_mem_free(szThemes);
|
rz_mem_free(szThemes);
|
||||||
if (!QDir(customRzThemesLocationPath).exists()) {
|
if (!QDir(customRzThemesLocationPath).exists()) {
|
||||||
QDir().mkpath(customRzThemesLocationPath);
|
QDir().mkpath(customRzThemesLocationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir currDir { QStringLiteral("%1%2%3")
|
QDir currDir {
|
||||||
.arg(rz_sys_prefix(nullptr))
|
QStringLiteral("%1%2%3").arg(rz_sys_prefix(nullptr)).arg(RZ_SYS_DIR).arg(RZ_THEMES)
|
||||||
.arg(RZ_SYS_DIR)
|
|
||||||
.arg(RZ_THEMES)
|
|
||||||
};
|
};
|
||||||
if (currDir.exists()) {
|
if (currDir.exists()) {
|
||||||
standardRzThemesLocationPath = currDir.absolutePath();
|
standardRzThemesLocationPath = currDir.absolutePath();
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(nullptr,
|
QMessageBox::critical(nullptr, tr("Standard themes not found"),
|
||||||
tr("Standard themes not found"),
|
|
||||||
tr("The Rizin standard themes could not be found in '%1'. "
|
tr("The Rizin standard themes could not be found in '%1'. "
|
||||||
"Most likely, Rizin is not properly installed.")
|
"Most likely, Rizin is not properly installed.")
|
||||||
.arg(currDir.path())
|
.arg(currDir.path()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) const
|
QColor ColorThemeWorker::mergeColors(const QColor &upper, const QColor &lower) const
|
||||||
{
|
{
|
||||||
qreal r1, g1, b1, a1;
|
qreal r1, g1, b1, a1;
|
||||||
qreal r2, g2, b2, a2;
|
qreal r2, g2, b2, a2;
|
||||||
@ -102,12 +68,10 @@ QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) c
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ColorThemeWorker::copy(const QString &srcThemeName,
|
QString ColorThemeWorker::copy(const QString &srcThemeName, const QString ©ThemeName) const
|
||||||
const QString ©ThemeName) const
|
|
||||||
{
|
{
|
||||||
if (!isThemeExist(srcThemeName)) {
|
if (!isThemeExist(srcThemeName)) {
|
||||||
return tr("Theme <b>%1</b> does not exist.")
|
return tr("Theme <b>%1</b> does not exist.").arg(srcThemeName);
|
||||||
.arg(srcThemeName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return save(getTheme(srcThemeName), copyThemeName);
|
return save(getTheme(srcThemeName), copyThemeName);
|
||||||
@ -117,8 +81,7 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
|
|||||||
{
|
{
|
||||||
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
|
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
|
||||||
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
|
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||||
return tr("The file <b>%1</b> cannot be opened.")
|
return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
|
||||||
.arg(QFileInfo(fOut).filePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject obj = theme.object();
|
QJsonObject obj = theme.object();
|
||||||
@ -161,7 +124,7 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
|
|||||||
return themes.contains(name);
|
return themes.contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
|
||||||
{
|
{
|
||||||
int r, g, b, a;
|
int r, g, b, a;
|
||||||
QVariantMap theme;
|
QVariantMap theme;
|
||||||
@ -178,7 +141,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
|||||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
for (auto it = theme.begin(); it != theme.end(); it++) {
|
||||||
auto arr = it.value().toList();
|
auto arr = it.value().toList();
|
||||||
QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt()).getRgb(&r, &g, &b, &a);
|
QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt()).getRgb(&r, &g, &b, &a);
|
||||||
theme[it.key()] = QJsonArray({r, g, b, a});
|
theme[it.key()] = QJsonArray({ r, g, b, a });
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorFlags colorFlags = ColorFlags::DarkFlag;
|
ColorFlags colorFlags = ColorFlags::DarkFlag;
|
||||||
@ -186,9 +149,9 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
|||||||
colorFlags = Configuration::relevantThemes[themeName];
|
colorFlags = Configuration::relevantThemes[themeName];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : cutterSpecificOptions) {
|
for (auto &it : cutterSpecificOptions) {
|
||||||
Configuration::cutterOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a);
|
Configuration::cutterOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a);
|
||||||
theme.insert(it, QJsonArray{r, g, b, a});
|
theme.insert(it, QJsonArray { r, g, b, a });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCustomTheme(themeName)) {
|
if (isCustomTheme(themeName)) {
|
||||||
@ -198,12 +161,14 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
|||||||
}
|
}
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
|
for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
|
||||||
sl = line.replace("#~", "ec ").replace("rgb:", "#").split(' ', CUTTER_QT_SKIP_EMPTY_PARTS);
|
sl = line.replace("#~", "ec ")
|
||||||
|
.replace("rgb:", "#")
|
||||||
|
.split(' ', CUTTER_QT_SKIP_EMPTY_PARTS);
|
||||||
if (sl.size() != 3 || sl[0][0] == '#') {
|
if (sl.size() != 3 || sl[0][0] == '#') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QColor(sl[2]).getRgb(&r, &g, &b, &a);
|
QColor(sl[2]).getRgb(&r, &g, &b, &a);
|
||||||
theme.insert(sl[1], QJsonArray({r, g, b, a}));
|
theme.insert(sl[1], QJsonArray({ r, g, b, a }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +178,8 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
|||||||
|
|
||||||
// manualy converting instead of using QJsonObject::fromVariantMap because
|
// manualy converting instead of using QJsonObject::fromVariantMap because
|
||||||
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
|
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
|
||||||
// QJson values like QJsonArray. https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
|
// QJson values like QJsonArray.
|
||||||
|
// https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
for (auto it = theme.begin(); it != theme.end(); it++) {
|
||||||
auto &value = it.value();
|
auto &value = it.value();
|
||||||
@ -222,7 +188,6 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
|||||||
} else {
|
} else {
|
||||||
obj[it.key()] = QJsonValue::fromVariant(value);
|
obj[it.key()] = QJsonValue::fromVariant(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QJsonDocument(obj);
|
return QJsonDocument(obj);
|
||||||
@ -239,21 +204,18 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const
|
|||||||
|
|
||||||
QFile file(QDir(customRzThemesLocationPath).filePath(themeName));
|
QFile file(QDir(customRzThemesLocationPath).filePath(themeName));
|
||||||
if (file.isWritable()) {
|
if (file.isWritable()) {
|
||||||
return tr("You have no permission to write to <b>%1</b>")
|
return tr("You have no permission to write to <b>%1</b>").arg(QFileInfo(file).filePath());
|
||||||
.arg(QFileInfo(file).filePath());
|
|
||||||
}
|
}
|
||||||
if (!file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
return tr("File <b>%1</b> can not be opened.")
|
return tr("File <b>%1</b> can not be opened.").arg(QFileInfo(file).filePath());
|
||||||
.arg(QFileInfo(file).filePath());
|
|
||||||
}
|
}
|
||||||
if (!file.remove()) {
|
if (!file.remove()) {
|
||||||
return tr("File <b>%1</b> can not be removed.")
|
return tr("File <b>%1</b> can not be removed.").arg(QFileInfo(file).filePath());
|
||||||
.arg(QFileInfo(file).filePath());
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ColorThemeWorker::importTheme(const QString& file) const
|
QString ColorThemeWorker::importTheme(const QString &file) const
|
||||||
{
|
{
|
||||||
QFileInfo src(file);
|
QFileInfo src(file);
|
||||||
if (!src.exists()) {
|
if (!src.exists()) {
|
||||||
@ -285,7 +247,7 @@ QString ColorThemeWorker::importTheme(const QString& file) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ColorThemeWorker::renameTheme(const QString& themeName, const QString& newName) const
|
QString ColorThemeWorker::renameTheme(const QString &themeName, const QString &newName) const
|
||||||
{
|
{
|
||||||
if (isThemeExist(newName)) {
|
if (isThemeExist(newName)) {
|
||||||
return tr("A color theme named <b>\"%1\"</b> already exists.").arg(newName);
|
return tr("A color theme named <b>\"%1\"</b> already exists.").arg(newName);
|
||||||
@ -299,12 +261,13 @@ QString ColorThemeWorker::renameTheme(const QString& themeName, const QString& n
|
|||||||
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return tr("Something went wrong during renaming. "
|
return tr("Something went wrong during renaming. "
|
||||||
"Please make sure you have access to the directory <b>\"%1\"</b>.").arg(dir.path());
|
"Please make sure you have access to the directory <b>\"%1\"</b>.")
|
||||||
|
.arg(dir.path());
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
|
||||||
{
|
{
|
||||||
QFile f(filePath);
|
QFile f(filePath);
|
||||||
if (!f.open(QFile::ReadOnly)) {
|
if (!f.open(QFile::ReadOnly)) {
|
||||||
@ -317,7 +280,9 @@ bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
|||||||
.join('|')
|
.join('|')
|
||||||
.replace(".", "\\.");
|
.replace(".", "\\.");
|
||||||
|
|
||||||
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options).arg(colors);
|
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
|
||||||
|
.arg(options)
|
||||||
|
.arg(colors);
|
||||||
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
|
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
|
||||||
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
|
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ public:
|
|||||||
|
|
||||||
virtual ~ColorThemeWorker() {}
|
virtual ~ColorThemeWorker() {}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies @a srcThemeName with name @a copyThemeName.
|
* @brief Copies @a srcThemeName with name @a copyThemeName.
|
||||||
* @param srcThemeName
|
* @param srcThemeName
|
||||||
@ -59,10 +58,11 @@ public:
|
|||||||
* Name of theme to save.
|
* Name of theme to save.
|
||||||
* @return "" on success or error message.
|
* @return "" on success or error message.
|
||||||
*/
|
*/
|
||||||
QString save(const QJsonDocument& theme, const QString &themeName) const;
|
QString save(const QJsonDocument &theme, const QString &themeName) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or not.
|
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or
|
||||||
|
* not.
|
||||||
* @param themeName
|
* @param themeName
|
||||||
* Name of theme to check.
|
* Name of theme to check.
|
||||||
*/
|
*/
|
||||||
@ -75,7 +75,8 @@ public:
|
|||||||
bool isThemeExist(const QString &name) const;
|
bool isThemeExist(const QString &name) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red, Green, Blue).
|
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red,
|
||||||
|
* Green, Blue).
|
||||||
* @param themeName
|
* @param themeName
|
||||||
* Theme to get.
|
* Theme to get.
|
||||||
*/
|
*/
|
||||||
@ -93,13 +94,13 @@ public:
|
|||||||
* @brief Imports theme from @a file.
|
* @brief Imports theme from @a file.
|
||||||
* @return "" on success or error message.
|
* @return "" on success or error message.
|
||||||
*/
|
*/
|
||||||
QString importTheme(const QString& file) const;
|
QString importTheme(const QString &file) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Renames theme from @a themeName to @a newName.
|
* @brief Renames theme from @a themeName to @a newName.
|
||||||
* @return "" on success or error message.
|
* @return "" on success or error message.
|
||||||
*/
|
*/
|
||||||
QString renameTheme(const QString& themeName, const QString& newName) const;
|
QString renameTheme(const QString &themeName, const QString &newName) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns whether or not file at @a filePath is a color theme.
|
* @brief Returns whether or not file at @a filePath is a color theme.
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
#include "Colors.h"
|
#include "Colors.h"
|
||||||
#include "common/Configuration.h"
|
#include "common/Configuration.h"
|
||||||
|
|
||||||
Colors::Colors()
|
Colors::Colors() {}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
|
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
|
||||||
{
|
{
|
||||||
@ -101,4 +97,3 @@ QString Colors::getColor(ut64 type)
|
|||||||
return "invalid";
|
return "invalid";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ CommandTask::CommandTask(const QString &cmd, ColorMode colorMode, bool outFormat
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandTask::runTask() {
|
void CommandTask::runTask()
|
||||||
|
{
|
||||||
TempConfig tempConfig;
|
TempConfig tempConfig;
|
||||||
tempConfig.set("scr.color", colorMode);
|
tempConfig.set("scr.color", colorMode);
|
||||||
auto res = Core()->cmdTask(cmd);
|
auto res = Core()->cmdTask(cmd);
|
||||||
|
@ -7,12 +7,18 @@
|
|||||||
|
|
||||||
class CUTTER_EXPORT CommandTask : public AsyncTask
|
class CUTTER_EXPORT CommandTask : public AsyncTask
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum ColorMode {DISABLED=COLOR_MODE_DISABLED, MODE_16=COLOR_MODE_16, MODE_256=COLOR_MODE_256, MODE_16M=COLOR_MODE_16M};
|
enum ColorMode {
|
||||||
|
DISABLED = COLOR_MODE_DISABLED,
|
||||||
|
MODE_16 = COLOR_MODE_16,
|
||||||
|
MODE_256 = COLOR_MODE_256,
|
||||||
|
MODE_16M = COLOR_MODE_16M
|
||||||
|
};
|
||||||
|
|
||||||
CommandTask(const QString &cmd, ColorMode colorMode=ColorMode::DISABLED, bool outFormatHtml=false);
|
CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED,
|
||||||
|
bool outFormatHtml = false);
|
||||||
|
|
||||||
QString getTitle() override { return tr("Running Command"); }
|
QString getTitle() override { return tr("Running Command"); }
|
||||||
|
|
||||||
@ -28,4 +34,4 @@ private:
|
|||||||
bool outFormatHtml;
|
bool outFormatHtml;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //COMMANDTASK_H
|
#endif // COMMANDTASK_H
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||||
#include <KSyntaxHighlighting/repository.h>
|
# include <KSyntaxHighlighting/repository.h>
|
||||||
#include <KSyntaxHighlighting/theme.h>
|
# include <KSyntaxHighlighting/theme.h>
|
||||||
#include <KSyntaxHighlighting/definition.h>
|
# include <KSyntaxHighlighting/definition.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/ColorThemeWorker.h"
|
#include "common/ColorThemeWorker.h"
|
||||||
@ -21,75 +21,71 @@
|
|||||||
* and for light - only light ones.
|
* and for light - only light ones.
|
||||||
*/
|
*/
|
||||||
const QHash<QString, ColorFlags> Configuration::relevantThemes = {
|
const QHash<QString, ColorFlags> Configuration::relevantThemes = {
|
||||||
{ "ayu", DarkFlag },
|
{ "ayu", DarkFlag }, { "consonance", DarkFlag }, { "darkda", DarkFlag },
|
||||||
{ "consonance", DarkFlag },
|
{ "onedark", DarkFlag }, { "solarized", DarkFlag }, { "zenburn", DarkFlag },
|
||||||
{ "darkda", DarkFlag },
|
{ "cutter", LightFlag }, { "dark", LightFlag }, { "matrix", LightFlag },
|
||||||
{ "onedark", DarkFlag },
|
{ "tango", LightFlag }, { "white", LightFlag }
|
||||||
{ "solarized", DarkFlag },
|
|
||||||
{ "zenburn", DarkFlag },
|
|
||||||
{ "cutter", LightFlag },
|
|
||||||
{ "dark", LightFlag },
|
|
||||||
{ "matrix", LightFlag },
|
|
||||||
{ "tango", LightFlag },
|
|
||||||
{ "white", LightFlag }
|
|
||||||
};
|
};
|
||||||
static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter";
|
static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter";
|
||||||
static const QString DEFAULT_DARK_COLOR_THEME = "ayu";
|
static const QString DEFAULT_DARK_COLOR_THEME = "ayu";
|
||||||
|
|
||||||
|
|
||||||
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
|
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
|
||||||
{ "gui.cflow", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
{ "gui.cflow",
|
||||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
{ { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
|
||||||
{ "gui.dataoffset", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
{ "gui.dataoffset",
|
||||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
{ { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
|
||||||
{ "gui.imports", { { DarkFlag, QColor(0x32, 0x8c, 0xff) },
|
{ "gui.imports",
|
||||||
{ LightFlag, QColor(0x32, 0x8c, 0xff) }} },
|
{ { DarkFlag, QColor(0x32, 0x8c, 0xff) }, { LightFlag, QColor(0x32, 0x8c, 0xff) } } },
|
||||||
{ "gui.item_invalid", { { DarkFlag, QColor(0x9b, 0x9b, 0x9b) },
|
{ "gui.item_invalid",
|
||||||
{ LightFlag, QColor(0x9b, 0x9b, 0x9b) }} },
|
{ { DarkFlag, QColor(0x9b, 0x9b, 0x9b) }, { LightFlag, QColor(0x9b, 0x9b, 0x9b) } } },
|
||||||
{ "gui.main", { { DarkFlag, QColor(0x00, 0x80, 0x00) },
|
{ "gui.main",
|
||||||
{ LightFlag, QColor(0x00, 0x80, 0x00) }} },
|
{ { DarkFlag, QColor(0x00, 0x80, 0x00) }, { LightFlag, QColor(0x00, 0x80, 0x00) } } },
|
||||||
{ "gui.item_unsafe", { { DarkFlag, QColor(0xff, 0x81, 0x7b) },
|
{ "gui.item_unsafe",
|
||||||
{ LightFlag, QColor(0xff, 0x81, 0x7b) }} },
|
{ { DarkFlag, QColor(0xff, 0x81, 0x7b) }, { LightFlag, QColor(0xff, 0x81, 0x7b) } } },
|
||||||
{ "gui.navbar.seek", { { DarkFlag, QColor(0xe9, 0x56, 0x56) },
|
{ "gui.navbar.seek",
|
||||||
{ LightFlag, QColor(0xff, 0x00, 0x00) }} },
|
{ { DarkFlag, QColor(0xe9, 0x56, 0x56) }, { LightFlag, QColor(0xff, 0x00, 0x00) } } },
|
||||||
{ "gui.navbar.pc", { { DarkFlag, QColor(0x42, 0xee, 0xf4) },
|
{ "gui.navbar.pc",
|
||||||
{ LightFlag, QColor(0x42, 0xee, 0xf4) }} },
|
{ { DarkFlag, QColor(0x42, 0xee, 0xf4) }, { LightFlag, QColor(0x42, 0xee, 0xf4) } } },
|
||||||
{ "gui.navbar.code", { { DarkFlag, QColor(0x82, 0xc8, 0x6f) },
|
{ "gui.navbar.code",
|
||||||
{ LightFlag, QColor(0x68, 0xe5, 0x45) }} },
|
{ { DarkFlag, QColor(0x82, 0xc8, 0x6f) }, { LightFlag, QColor(0x68, 0xe5, 0x45) } } },
|
||||||
{ "gui.navbar.str", { { DarkFlag, QColor(0x6f, 0x86, 0xd8) },
|
{ "gui.navbar.str",
|
||||||
{ LightFlag, QColor(0x45, 0x68, 0xe5) }} },
|
{ { DarkFlag, QColor(0x6f, 0x86, 0xd8) }, { LightFlag, QColor(0x45, 0x68, 0xe5) } } },
|
||||||
{ "gui.navbar.sym", { { DarkFlag, QColor(0xdd, 0xa3, 0x68) },
|
{ "gui.navbar.sym",
|
||||||
{ LightFlag, QColor(0xe5, 0x96, 0x45) }} },
|
{ { DarkFlag, QColor(0xdd, 0xa3, 0x68) }, { LightFlag, QColor(0xe5, 0x96, 0x45) } } },
|
||||||
{ "gui.navbar.empty", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
{ "gui.navbar.empty",
|
||||||
{ LightFlag, QColor(0xdc, 0xec, 0xf5) }} },
|
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xdc, 0xec, 0xf5) } } },
|
||||||
{ "gui.breakpoint_background", { { DarkFlag, QColor(0x8c, 0x4c, 0x4c) },
|
{ "gui.breakpoint_background",
|
||||||
{ LightFlag, QColor(0xe9, 0x8f, 0x8f) }} },
|
{ { DarkFlag, QColor(0x8c, 0x4c, 0x4c) }, { LightFlag, QColor(0xe9, 0x8f, 0x8f) } } },
|
||||||
{ "gui.overview.node", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
{ "gui.overview.node",
|
||||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
|
||||||
{ "gui.tooltip.background", { { DarkFlag, QColor(0x2a, 0x2c, 0x2e) },
|
{ "gui.tooltip.background",
|
||||||
{ LightFlag, QColor(0xfa, 0xfc, 0xfe) }} },
|
{ { DarkFlag, QColor(0x2a, 0x2c, 0x2e) }, { LightFlag, QColor(0xfa, 0xfc, 0xfe) } } },
|
||||||
{ "gui.tooltip.foreground", { { DarkFlag, QColor(0xfa, 0xfc, 0xfe) },
|
{ "gui.tooltip.foreground",
|
||||||
{ LightFlag, QColor(0x2a, 0x2c, 0x2e) }} },
|
{ { DarkFlag, QColor(0xfa, 0xfc, 0xfe) }, { LightFlag, QColor(0x2a, 0x2c, 0x2e) } } },
|
||||||
{ "gui.border", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
{ "gui.border",
|
||||||
{ LightFlag, QColor(0x91, 0xc8, 0xfa) }} },
|
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0x91, 0xc8, 0xfa) } } },
|
||||||
{ "gui.background", { { DarkFlag, QColor(0x25, 0x28, 0x2b) },
|
{ "gui.background",
|
||||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
{ { DarkFlag, QColor(0x25, 0x28, 0x2b) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
|
||||||
{ "gui.alt_background", { { DarkFlag, QColor(0x1c, 0x1f, 0x24) },
|
{ "gui.alt_background",
|
||||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
{ { DarkFlag, QColor(0x1c, 0x1f, 0x24) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
|
||||||
{ "gui.disass_selected", { { DarkFlag, QColor(0x1f, 0x22, 0x28) },
|
{ "gui.disass_selected",
|
||||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
{ { DarkFlag, QColor(0x1f, 0x22, 0x28) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
|
||||||
{ "lineHighlight", { { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
{ "lineHighlight",
|
||||||
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) }} },
|
{ { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
||||||
{ "wordHighlight", { { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
|
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } },
|
||||||
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) }} },
|
{ "wordHighlight",
|
||||||
{ "highlightPC", { { DarkFlag, QColor(0x57, 0x1a, 0x07) },
|
{ { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
|
||||||
{ LightFlag, QColor(0xd6, 0xff, 0xd2) }} },
|
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) } } },
|
||||||
{ "gui.overview.fill", { { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
|
{ "highlightPC",
|
||||||
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) }} },
|
{ { DarkFlag, QColor(0x57, 0x1a, 0x07) }, { LightFlag, QColor(0xd6, 0xff, 0xd2) } } },
|
||||||
{ "gui.overview.border", { { DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32) },
|
{ "gui.overview.fill",
|
||||||
{ LightFlag, QColor(0x63, 0xda, 0xe8, 0x32) }} },
|
{ { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
|
||||||
{ "gui.navbar.err", { { DarkFlag, QColor(0x03, 0xaa, 0xf5) },
|
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) } } },
|
||||||
{ LightFlag, QColor(0x03, 0xaa, 0xf5) }} }
|
{ "gui.overview.border",
|
||||||
|
{ { DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32) },
|
||||||
|
{ LightFlag, QColor(0x63, 0xda, 0xe8, 0x32) } } },
|
||||||
|
{ "gui.navbar.err",
|
||||||
|
{ { DarkFlag, QColor(0x03, 0xaa, 0xf5) }, { LightFlag, QColor(0x03, 0xaa, 0xf5) } } }
|
||||||
};
|
};
|
||||||
|
|
||||||
Configuration *Configuration::mPtr = nullptr;
|
Configuration *Configuration::mPtr = nullptr;
|
||||||
@ -97,8 +93,7 @@ Configuration *Configuration::mPtr = nullptr;
|
|||||||
/**
|
/**
|
||||||
* @brief All asm.* options saved as settings. Values are the default values.
|
* @brief All asm.* options saved as settings. Values are the default values.
|
||||||
*/
|
*/
|
||||||
static const QHash<QString, QVariant> asmOptions = {
|
static const QHash<QString, QVariant> asmOptions = { { "asm.esil", false },
|
||||||
{ "asm.esil", false },
|
|
||||||
{ "asm.pseudo", false },
|
{ "asm.pseudo", false },
|
||||||
{ "asm.offset", true },
|
{ "asm.offset", true },
|
||||||
{ "asm.xrefs", false },
|
{ "asm.xrefs", false },
|
||||||
@ -109,7 +104,7 @@ static const QHash<QString, QVariant> asmOptions = {
|
|||||||
{ "asm.lines.fcn", true },
|
{ "asm.lines.fcn", true },
|
||||||
{ "asm.flags.offset", false },
|
{ "asm.flags.offset", false },
|
||||||
{ "asm.emu", false },
|
{ "asm.emu", false },
|
||||||
{ "emu.str", false},
|
{ "emu.str", false },
|
||||||
{ "asm.cmt.right", true },
|
{ "asm.cmt.right", true },
|
||||||
{ "asm.cmt.col", 35 },
|
{ "asm.cmt.col", 35 },
|
||||||
{ "asm.var.summary", false },
|
{ "asm.var.summary", false },
|
||||||
@ -131,20 +126,17 @@ static const QHash<QString, QVariant> asmOptions = {
|
|||||||
{ "asm.flags.real", true },
|
{ "asm.flags.real", true },
|
||||||
{ "asm.reloff", false },
|
{ "asm.reloff", false },
|
||||||
{ "asm.reloff.flags", false },
|
{ "asm.reloff.flags", false },
|
||||||
{ "esil.breakoninvalid",true },
|
{ "esil.breakoninvalid", true },
|
||||||
{ "graph.offset", false}
|
{ "graph.offset", false } };
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
|
Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
|
||||||
{
|
{
|
||||||
mPtr = this;
|
mPtr = this;
|
||||||
if (!s.isWritable()) {
|
if (!s.isWritable()) {
|
||||||
QMessageBox::critical(nullptr,
|
QMessageBox::critical(
|
||||||
tr("Critical!"),
|
nullptr, tr("Critical!"),
|
||||||
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
|
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
|
||||||
.arg(s.fileName())
|
.arg(s.fileName()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||||
kSyntaxHighlightingRepository = nullptr;
|
kSyntaxHighlightingRepository = nullptr;
|
||||||
@ -200,7 +192,7 @@ void Configuration::resetAll()
|
|||||||
{
|
{
|
||||||
// Don't reset all rizin vars, that currently breaks a bunch of stuff.
|
// Don't reset all rizin vars, that currently breaks a bunch of stuff.
|
||||||
// settingsFile.remove()+loadInitials() should reset all settings configurable using Cutter GUI.
|
// settingsFile.remove()+loadInitials() should reset all settings configurable using Cutter GUI.
|
||||||
//Core()->cmdRaw("e-");
|
// Core()->cmdRaw("e-");
|
||||||
|
|
||||||
Core()->setSettings();
|
Core()->setSettings();
|
||||||
// Delete the file so no extra configuration is in it.
|
// Delete the file so no extra configuration is in it.
|
||||||
@ -247,8 +239,8 @@ void Configuration::setLocale(const QLocale &l)
|
|||||||
*/
|
*/
|
||||||
bool Configuration::setLocaleByName(const QString &language)
|
bool Configuration::setLocaleByName(const QString &language)
|
||||||
{
|
{
|
||||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
const auto &allLocales =
|
||||||
QLocale::AnyCountry);
|
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||||
|
|
||||||
for (auto &it : allLocales) {
|
for (auto &it : allLocales) {
|
||||||
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
||||||
@ -391,26 +383,26 @@ void Configuration::refreshFont()
|
|||||||
emit fontsUpdated();
|
emit fontsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Configuration::getZoomFactor() const {
|
qreal Configuration::getZoomFactor() const
|
||||||
|
{
|
||||||
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
||||||
return qMax(fontZoom, 0.1);
|
return qMax(fontZoom, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::setZoomFactor(qreal zoom) {
|
void Configuration::setZoomFactor(qreal zoom)
|
||||||
|
{
|
||||||
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
||||||
emit fontsUpdated();
|
emit fontsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Configuration::getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const
|
QString Configuration::getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const
|
||||||
{
|
{
|
||||||
return s.value("lastThemeOf." + currInterfaceTheme.name,
|
return s.value("lastThemeOf." + currInterfaceTheme.name, Config()->getColorTheme()).toString();
|
||||||
Config()->getColorTheme()).toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::setInterfaceTheme(int theme)
|
void Configuration::setInterfaceTheme(int theme)
|
||||||
{
|
{
|
||||||
if (theme >= cutterInterfaceThemesList().size() ||
|
if (theme >= cutterInterfaceThemesList().size() || theme < 0) {
|
||||||
theme < 0) {
|
|
||||||
theme = 0;
|
theme = 0;
|
||||||
}
|
}
|
||||||
s.setValue("ColorPalette", theme);
|
s.setValue("ColorPalette", theme);
|
||||||
@ -464,8 +456,7 @@ KSyntaxHighlighting::Theme Configuration::getKSyntaxHighlightingTheme()
|
|||||||
if (!repo) {
|
if (!repo) {
|
||||||
return KSyntaxHighlighting::Theme();
|
return KSyntaxHighlighting::Theme();
|
||||||
}
|
}
|
||||||
return repo->defaultTheme(
|
return repo->defaultTheme(getCurrentTheme()->flag & DarkFlag
|
||||||
getCurrentTheme()->flag & DarkFlag
|
|
||||||
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
||||||
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
||||||
}
|
}
|
||||||
@ -487,8 +478,7 @@ QSyntaxHighlighter *Configuration::createSyntaxHighlighter(QTextDocument *docume
|
|||||||
|
|
||||||
QString Configuration::getLogoFile()
|
QString Configuration::getLogoFile()
|
||||||
{
|
{
|
||||||
return windowColorIsDark()
|
return windowColorIsDark() ? QString(":/img/cutter_white_plain.svg")
|
||||||
? QString(":/img/cutter_white_plain.svg")
|
|
||||||
: QString(":/img/cutter_plain.svg");
|
: QString(":/img/cutter_plain.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +492,8 @@ void Configuration::setColor(const QString &name, const QColor &color)
|
|||||||
s.setValue("colors." + name, color);
|
s.setValue("colors." + name, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme)
|
void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme,
|
||||||
|
const QString &theme)
|
||||||
{
|
{
|
||||||
s.setValue("lastThemeOf." + currInterfaceTheme.name, theme);
|
s.setValue("lastThemeOf." + currInterfaceTheme.name, theme);
|
||||||
}
|
}
|
||||||
@ -572,7 +563,7 @@ void Configuration::applySavedAsmOptions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<CutterInterfaceTheme>& Configuration::cutterInterfaceThemesList()
|
const QList<CutterInterfaceTheme> &Configuration::cutterInterfaceThemesList()
|
||||||
{
|
{
|
||||||
static const QList<CutterInterfaceTheme> list = {
|
static const QList<CutterInterfaceTheme> list = {
|
||||||
{ "Native", Configuration::nativeWindowIsDark() ? DarkFlag : LightFlag },
|
{ "Native", Configuration::nativeWindowIsDark() ? DarkFlag : LightFlag },
|
||||||
@ -599,7 +590,6 @@ QVariant Configuration::getConfigVar(const QString &key)
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Configuration::getConfigBool(const QString &key)
|
bool Configuration::getConfigBool(const QString &key)
|
||||||
{
|
{
|
||||||
return getConfigVar(key).toBool();
|
return getConfigVar(key).toBool();
|
||||||
@ -644,8 +634,8 @@ QStringList Configuration::getAvailableTranslations()
|
|||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const QStringList &currTrFileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files,
|
const QStringList &currTrFileNames =
|
||||||
QDir::Name);
|
dir.entryList(QStringList("cutter_*.qm"), QDir::Files, QDir::Name);
|
||||||
for (const auto &trFile : currTrFileNames) {
|
for (const auto &trFile : currTrFileNames) {
|
||||||
fileNamesSet << trFile;
|
fileNamesSet << trFile;
|
||||||
}
|
}
|
||||||
@ -655,16 +645,16 @@ QStringList Configuration::getAvailableTranslations()
|
|||||||
std::sort(fileNames.begin(), fileNames.end());
|
std::sort(fileNames.begin(), fileNames.end());
|
||||||
QStringList languages;
|
QStringList languages;
|
||||||
QString currLanguageName;
|
QString currLanguageName;
|
||||||
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
auto allLocales =
|
||||||
QLocale::AnyCountry);
|
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||||
|
|
||||||
for (auto i : fileNames) {
|
for (auto i : fileNames) {
|
||||||
QString localeName = i.mid(sizeof("cutter_") - 1, 2);
|
QString localeName = i.mid(sizeof("cutter_") - 1, 2);
|
||||||
for (auto j : allLocales) {
|
for (auto j : allLocales) {
|
||||||
if (j.name().startsWith(localeName)) {
|
if (j.name().startsWith(localeName)) {
|
||||||
currLanguageName = j.nativeLanguageName();
|
currLanguageName = j.nativeLanguageName();
|
||||||
currLanguageName = currLanguageName.at(0).toUpper() +
|
currLanguageName = currLanguageName.at(0).toUpper()
|
||||||
currLanguageName.right(currLanguageName.length() - 1);
|
+ currLanguageName.right(currLanguageName.length() - 1);
|
||||||
languages << currLanguageName;
|
languages << currLanguageName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,26 +10,25 @@
|
|||||||
|
|
||||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||||
namespace KSyntaxHighlighting {
|
namespace KSyntaxHighlighting {
|
||||||
class Repository;
|
class Repository;
|
||||||
class Theme;
|
class Theme;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class QSyntaxHighlighter;
|
class QSyntaxHighlighter;
|
||||||
class QTextDocument;
|
class QTextDocument;
|
||||||
|
|
||||||
|
|
||||||
enum ColorFlags {
|
enum ColorFlags {
|
||||||
LightFlag = 1,
|
LightFlag = 1,
|
||||||
DarkFlag = 2,
|
DarkFlag = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CutterInterfaceTheme {
|
struct CutterInterfaceTheme
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
ColorFlags flag;
|
ColorFlags flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CUTTER_EXPORT Configuration : public QObject
|
class CUTTER_EXPORT Configuration : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -56,7 +55,7 @@ private:
|
|||||||
void applySavedAsmOptions();
|
void applySavedAsmOptions();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const QList<CutterInterfaceTheme>& cutterInterfaceThemesList();
|
static const QList<CutterInterfaceTheme> &cutterInterfaceThemesList();
|
||||||
static const QHash<QString, ColorFlags> relevantThemes;
|
static const QHash<QString, ColorFlags> relevantThemes;
|
||||||
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
||||||
|
|
||||||
@ -101,10 +100,7 @@ public:
|
|||||||
void setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme);
|
void setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme);
|
||||||
QString getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const;
|
QString getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const;
|
||||||
void setInterfaceTheme(int theme);
|
void setInterfaceTheme(int theme);
|
||||||
int getInterfaceTheme()
|
int getInterfaceTheme() { return s.value("ColorPalette", 0).toInt(); }
|
||||||
{
|
|
||||||
return s.value("ColorPalette", 0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
const CutterInterfaceTheme *getCurrentTheme();
|
const CutterInterfaceTheme *getCurrentTheme();
|
||||||
|
|
||||||
@ -164,27 +160,16 @@ public:
|
|||||||
bool isDecompilerAnnotationHighlighterEnabled();
|
bool isDecompilerAnnotationHighlighterEnabled();
|
||||||
|
|
||||||
// Graph
|
// Graph
|
||||||
int getGraphBlockMaxChars() const
|
int getGraphBlockMaxChars() const { return s.value("graph.maxcols", 100).toInt(); }
|
||||||
{
|
void setGraphBlockMaxChars(int ch) { s.setValue("graph.maxcols", ch); }
|
||||||
return s.value("graph.maxcols", 100).toInt();
|
|
||||||
}
|
|
||||||
void setGraphBlockMaxChars(int ch)
|
|
||||||
{
|
|
||||||
s.setValue("graph.maxcols", ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getGraphMinFontSize() const
|
int getGraphMinFontSize() const { return s.value("graph.minfontsize", 4).toInt(); }
|
||||||
{
|
|
||||||
return s.value("graph.minfontsize", 4).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setGraphMinFontSize(int sz)
|
void setGraphMinFontSize(int sz) { s.setValue("graph.minfontsize", sz); }
|
||||||
{
|
|
||||||
s.setValue("graph.minfontsize", sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Getters and setters for the transaparent option state and scale factor for bitmap graph exports.
|
* @brief Getters and setters for the transaparent option state and scale factor for bitmap
|
||||||
|
* graph exports.
|
||||||
*/
|
*/
|
||||||
bool getBitmapTransparentState();
|
bool getBitmapTransparentState();
|
||||||
double getBitmapExportScaleFactor();
|
double getBitmapExportScaleFactor();
|
||||||
@ -202,7 +187,8 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable or disable the displaying of the entry offset in each graph block
|
* @brief Enable or disable the displaying of the entry offset in each graph block
|
||||||
* @param enabled set this to true for displaying the entry offset in each graph block, false otherwise
|
* @param enabled set this to true for displaying the entry offset in each graph block, false
|
||||||
|
* otherwise
|
||||||
*/
|
*/
|
||||||
void setGraphBlockEntryOffset(bool enabled);
|
void setGraphBlockEntryOffset(bool enabled);
|
||||||
|
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
#if defined (Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
#include "client/linux/handler/exception_handler.h"
|
# include "client/linux/handler/exception_handler.h"
|
||||||
#elif defined (Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
#include "client/windows/handler/exception_handler.h"
|
# include "client/windows/handler/exception_handler.h"
|
||||||
#elif defined (Q_OS_MACOS)
|
#elif defined(Q_OS_MACOS)
|
||||||
#include "client/mac/handler/exception_handler.h"
|
# include "client/mac/handler/exception_handler.h"
|
||||||
#endif // Q_OS
|
#endif // Q_OS
|
||||||
|
|
||||||
static google_breakpad::ExceptionHandler *exceptionHandler = nullptr;
|
static google_breakpad::ExceptionHandler *exceptionHandler = nullptr;
|
||||||
@ -32,11 +32,8 @@ static void finishCrashHandler()
|
|||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
// Called if crash dump was successfully created
|
// Called if crash dump was successfully created
|
||||||
// Saves path to file
|
// Saves path to file
|
||||||
bool callback(const wchar_t *_dump_dir,
|
bool callback(const wchar_t *_dump_dir, const wchar_t *_minidump_id, void *context,
|
||||||
const wchar_t *_minidump_id,
|
EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool success)
|
||||||
void *context, EXCEPTION_POINTERS *exinfo,
|
|
||||||
MDRawAssertionInfo *assertion,
|
|
||||||
bool success)
|
|
||||||
{
|
{
|
||||||
const QDir dir = QString::fromWCharArray(_dump_dir);
|
const QDir dir = QString::fromWCharArray(_dump_dir);
|
||||||
const QString id = QString::fromWCharArray(_minidump_id);
|
const QString id = QString::fromWCharArray(_minidump_id);
|
||||||
@ -45,7 +42,7 @@ bool callback(const wchar_t *_dump_dir,
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined (Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
// Called if crash dump was successfully created
|
// Called if crash dump was successfully created
|
||||||
// Saves path to file
|
// Saves path to file
|
||||||
bool callback(const google_breakpad::MinidumpDescriptor &md, void *context, bool b)
|
bool callback(const google_breakpad::MinidumpDescriptor &md, void *context, bool b)
|
||||||
@ -55,7 +52,7 @@ bool callback(const google_breakpad::MinidumpDescriptor &md, void *context, bool
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined (Q_OS_MACOS)
|
#elif defined(Q_OS_MACOS)
|
||||||
// Called if crash dump was successfully created
|
// Called if crash dump was successfully created
|
||||||
// Saves path to file
|
// Saves path to file
|
||||||
bool callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded)
|
bool callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded)
|
||||||
@ -77,28 +74,21 @@ void initCrashHandler()
|
|||||||
// Here will be placed crash dump at the first place
|
// Here will be placed crash dump at the first place
|
||||||
// and then moved if needed
|
// and then moved if needed
|
||||||
|
|
||||||
#if defined (Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
static std::string tmpLocation =
|
||||||
exceptionHandler = new google_breakpad::ExceptionHandler(google_breakpad::MinidumpDescriptor(tmpLocation),
|
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||||
nullptr,
|
exceptionHandler = new google_breakpad::ExceptionHandler(
|
||||||
callback,
|
google_breakpad::MinidumpDescriptor(tmpLocation), nullptr, callback, nullptr, true, -1);
|
||||||
nullptr,
|
#elif defined(Q_OS_MACOS)
|
||||||
true,
|
static std::string tmpLocation =
|
||||||
-1);
|
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||||
#elif defined (Q_OS_MACOS)
|
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback,
|
||||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
nullptr, true, nullptr);
|
||||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
|
||||||
nullptr,
|
|
||||||
callback,
|
|
||||||
nullptr,
|
|
||||||
true,
|
|
||||||
nullptr);
|
|
||||||
#else
|
#else
|
||||||
static std::wstring tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
static std::wstring tmpLocation =
|
||||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
||||||
nullptr,
|
exceptionHandler =
|
||||||
callback,
|
new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback, nullptr,
|
||||||
nullptr,
|
|
||||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||||
#endif
|
#endif
|
||||||
atexit(finishCrashHandler);
|
atexit(finishCrashHandler);
|
||||||
@ -125,11 +115,10 @@ void showCrashDialog(const QString &dumpFile)
|
|||||||
if (placementFailCounter == 4) {
|
if (placementFailCounter == 4) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dumpSaveFileName = QFileDialog::getSaveFileName(nullptr,
|
dumpSaveFileName = QFileDialog::getSaveFileName(
|
||||||
QObject::tr("Choose a directory to save the crash dump in"),
|
nullptr, QObject::tr("Choose a directory to save the crash dump in"),
|
||||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
|
QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
|
||||||
QDir::separator() +
|
+ QDir::separator() + "Cutter_crash_dump_"
|
||||||
"Cutter_crash_dump_"
|
|
||||||
+ QDate::currentDate().toString("dd.MM.yy") + "_"
|
+ QDate::currentDate().toString("dd.MM.yy") + "_"
|
||||||
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
||||||
QObject::tr("Minidump (*.dmp)"));
|
QObject::tr("Minidump (*.dmp)"));
|
||||||
@ -141,11 +130,11 @@ void showCrashDialog(const QString &dumpFile)
|
|||||||
ok = true;
|
ok = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
QMessageBox::critical(nullptr,
|
QMessageBox::critical(nullptr, QObject::tr("Save Crash Dump"),
|
||||||
QObject::tr("Save Crash Dump"),
|
|
||||||
QObject::tr("Failed to write to %1.<br/>"
|
QObject::tr("Failed to write to %1.<br/>"
|
||||||
"Please make sure you have access to that directory "
|
"Please make sure you have access to that directory "
|
||||||
"and try again.").arg(QFileInfo(dumpSaveFileName).dir().path()));
|
"and try again.")
|
||||||
|
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@ -164,8 +153,7 @@ void showCrashDialog(const QString &dumpFile)
|
|||||||
openIssue();
|
openIssue();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(nullptr,
|
QMessageBox::critical(nullptr, QObject::tr("Error"),
|
||||||
QObject::tr("Error"),
|
|
||||||
QObject::tr("Error occurred during crash dump creation."));
|
QObject::tr("Error occurred during crash dump creation."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* If CUTTER_ENABLE_CRASH_REPORTS is true, initializes
|
* If CUTTER_ENABLE_CRASH_REPORTS is true, initializes
|
||||||
* crash handling and reporting, otherwise does nothing.
|
* crash handling and reporting, otherwise does nothing.
|
||||||
*/
|
*/
|
||||||
void initCrashHandler();
|
void initCrashHandler();
|
||||||
|
|
||||||
void showCrashDialog(const QString &dumpFile);
|
void showCrashDialog(const QString &dumpFile);
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
namespace Cutter
|
namespace Cutter {
|
||||||
{
|
|
||||||
|
|
||||||
struct CutterLayout
|
struct CutterLayout
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,7 @@
|
|||||||
|
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
CutterSeekable::CutterSeekable(QObject *parent) : QObject(parent)
|
||||||
CutterSeekable::CutterSeekable(QObject *parent)
|
|
||||||
:
|
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged);
|
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged);
|
||||||
}
|
}
|
||||||
@ -38,7 +35,6 @@ void CutterSeekable::updateSeek(RVA addr, bool localOnly)
|
|||||||
emit seekableSeekChanged(addr);
|
emit seekableSeekChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CutterSeekable::seekPrev()
|
void CutterSeekable::seekPrev()
|
||||||
{
|
{
|
||||||
if (synchronized) {
|
if (synchronized) {
|
||||||
@ -65,8 +61,7 @@ bool CutterSeekable::isSynchronized()
|
|||||||
|
|
||||||
void CutterSeekable::seekToReference(RVA offset)
|
void CutterSeekable::seekToReference(RVA offset)
|
||||||
{
|
{
|
||||||
if (offset == RVA_INVALID)
|
if (offset == RVA_INVALID) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ public:
|
|||||||
bool isSynchronized();
|
bool isSynchronized();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief seekToReference will seek to the function or the object which is referenced in a given offset
|
* @brief seekToReference will seek to the function or the object which is referenced in a given
|
||||||
|
* offset
|
||||||
* @param offset - an address that contains a reference to jump to
|
* @param offset - an address that contains a reference to jump to
|
||||||
*/
|
*/
|
||||||
void seekToReference(RVA offset);
|
void seekToReference(RVA offset);
|
||||||
|
@ -6,19 +6,17 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
|
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent), id(id), name(name)
|
||||||
id(id),
|
|
||||||
name(name)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage){
|
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
|
||||||
|
{
|
||||||
std::string temporary = warningMessage.toStdString();
|
std::string temporary = warningMessage.toStdString();
|
||||||
return rz_annotated_code_new(strdup(temporary.c_str()));
|
return rz_annotated_code_new(strdup(temporary.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
JSDecDecompiler::JSDecDecompiler(QObject *parent)
|
JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", parent)
|
||||||
: Decompiler("jsdec", "jsdec", parent)
|
|
||||||
{
|
{
|
||||||
task = nullptr;
|
task = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
/**
|
/**
|
||||||
* Implements a decompiler that can be registered using CutterCore::registerDecompiler()
|
* Implements a decompiler that can be registered using CutterCore::registerDecompiler()
|
||||||
*/
|
*/
|
||||||
class CUTTER_EXPORT Decompiler: public QObject
|
class CUTTER_EXPORT Decompiler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -30,14 +30,14 @@ public:
|
|||||||
virtual bool isRunning() { return false; }
|
virtual bool isRunning() { return false; }
|
||||||
virtual bool isCancelable() { return false; }
|
virtual bool isCancelable() { return false; }
|
||||||
|
|
||||||
virtual void decompileAt(RVA addr) =0;
|
virtual void decompileAt(RVA addr) = 0;
|
||||||
virtual void cancel() {}
|
virtual void cancel() {}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished(RzAnnotatedCode *codeDecompiled);
|
void finished(RzAnnotatedCode *codeDecompiled);
|
||||||
};
|
};
|
||||||
|
|
||||||
class JSDecDecompiler: public Decompiler
|
class JSDecDecompiler : public Decompiler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -53,4 +53,4 @@ public:
|
|||||||
static bool isAvailable();
|
static bool isAvailable();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //DECOMPILER_H
|
#endif // DECOMPILER_H
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent)
|
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||||
: QSyntaxHighlighter(parent)
|
|
||||||
{
|
{
|
||||||
setupTheme();
|
setupTheme();
|
||||||
connect(Config(), &Configuration::colorsUpdated, this, [this]() {
|
connect(Config(), &Configuration::colorsUpdated, this, [this]() {
|
||||||
@ -21,18 +20,19 @@ void DecompilerHighlighter::setAnnotations(RzAnnotatedCode *code)
|
|||||||
|
|
||||||
void DecompilerHighlighter::setupTheme()
|
void DecompilerHighlighter::setupTheme()
|
||||||
{
|
{
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
RSyntaxHighlightType type;
|
RSyntaxHighlightType type;
|
||||||
QString name;
|
QString name;
|
||||||
} mapping[] = {
|
} mapping[] = {
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD, "pop"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD, "pop" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT, "comment"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT, "comment" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE, "func_var_type"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE, "func_var_type" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME, "fname"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME, "fname" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER, "args"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER, "args" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE, "func_var"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE, "func_var" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE, "num"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE, "num" },
|
||||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE, "flag"},
|
{ RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE, "flag" },
|
||||||
};
|
};
|
||||||
for (const auto &pair : mapping) {
|
for (const auto &pair : mapping) {
|
||||||
assert(pair.type < format.size());
|
assert(pair.type < format.size());
|
||||||
@ -49,10 +49,12 @@ void DecompilerHighlighter::highlightBlock(const QString &)
|
|||||||
size_t start = block.position();
|
size_t start = block.position();
|
||||||
size_t end = block.position() + block.length();
|
size_t end = block.position() + block.length();
|
||||||
|
|
||||||
std::unique_ptr<RzPVector, decltype(&rz_pvector_free)> annotations(rz_annotated_code_annotations_range(code, start, end), &rz_pvector_free);
|
std::unique_ptr<RzPVector, decltype(&rz_pvector_free)> annotations(
|
||||||
|
rz_annotated_code_annotations_range(code, start, end), &rz_pvector_free);
|
||||||
void **iter;
|
void **iter;
|
||||||
rz_pvector_foreach(annotations.get(), iter) {
|
rz_pvector_foreach(annotations.get(), iter)
|
||||||
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation*>(*iter);
|
{
|
||||||
|
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation *>(*iter);
|
||||||
if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
|
if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ public:
|
|||||||
* @param code
|
* @param code
|
||||||
*/
|
*/
|
||||||
void setAnnotations(RzAnnotatedCode *code);
|
void setAnnotations(RzAnnotatedCode *code);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text) override;
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupTheme();
|
void setupTheme();
|
||||||
|
|
||||||
|
@ -10,11 +10,9 @@ void DirectionalComboBox::showPopup()
|
|||||||
QComboBox::showPopup();
|
QComboBox::showPopup();
|
||||||
QWidget *popup = this->findChild<QFrame *>();
|
QWidget *popup = this->findChild<QFrame *>();
|
||||||
if (popupUpwards) {
|
if (popupUpwards) {
|
||||||
popup->move(popup->x(),
|
popup->move(popup->x(), mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
||||||
mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
|
||||||
} else {
|
} else {
|
||||||
popup->move(popup->x(),
|
popup->move(popup->x(), mapToGlobal(this->rect().topLeft()).y());
|
||||||
mapToGlobal(this->rect().topLeft()).y());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,4 +20,3 @@ private:
|
|||||||
|
|
||||||
void showPopup();
|
void showPopup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class FunctionsTask : public AsyncTask
|
class FunctionsTask : public AsyncTask
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString getTitle() override { return tr("Fetching Functions"); }
|
QString getTitle() override { return tr("Fetching Functions"); }
|
||||||
@ -23,4 +23,4 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FUNCTIONSTASK_H
|
#endif // FUNCTIONSTASK_H
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
static QAbstractItemView::ScrollMode scrollMode()
|
static QAbstractItemView::ScrollMode scrollMode()
|
||||||
{
|
{
|
||||||
const bool use_scrollperpixel = true;
|
const bool use_scrollperpixel = true;
|
||||||
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel : QAbstractItemView::ScrollPerItem;
|
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
|
||||||
|
: QAbstractItemView::ScrollPerItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace qhelpers {
|
namespace qhelpers {
|
||||||
|
|
||||||
QString formatBytecount(const uint64_t bytecount)
|
QString formatBytecount(const uint64_t bytecount)
|
||||||
@ -31,12 +31,12 @@ QString formatBytecount(const uint64_t bytecount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int exp = log(bytecount) / log(1024);
|
const int exp = log(bytecount) / log(1024);
|
||||||
constexpr char suffixes[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E'};
|
constexpr char suffixes[] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E' };
|
||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
QTextStream stream(&str);
|
QTextStream stream(&str);
|
||||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp)
|
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) << ' ' << suffixes[exp]
|
||||||
<< ' ' << suffixes[exp] << 'B';
|
<< 'B';
|
||||||
return stream.readAll();
|
return stream.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,8 +161,7 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
|||||||
{
|
{
|
||||||
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||||
return (textEdit->height()
|
return (textEdit->height()
|
||||||
- (textEdit->contentsMargins().top()
|
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
|
||||||
+ textEdit->contentsMargins().bottom()
|
|
||||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||||
/ fontMetrics.lineSpacing();
|
/ fontMetrics.lineSpacing();
|
||||||
}
|
}
|
||||||
@ -171,15 +170,15 @@ int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
|||||||
{
|
{
|
||||||
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||||
return (plainTextEdit->height()
|
return (plainTextEdit->height()
|
||||||
- (plainTextEdit->contentsMargins().top()
|
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
|
||||||
+ plainTextEdit->contentsMargins().bottom()
|
|
||||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||||
/ fontMetrics.lineSpacing();
|
/ fontMetrics.lineSpacing();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||||
{
|
{
|
||||||
static const QRegularExpression styleRegExp("(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
static const QRegularExpression styleRegExp(
|
||||||
|
"(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
||||||
|
|
||||||
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
||||||
int replaceStrLen = replaceStr.length();
|
int replaceStrLen = replaceStr.length();
|
||||||
@ -194,7 +193,8 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int captureIndex = match.captured(1).isNull() ? 2 : 1;
|
int captureIndex = match.captured(1).isNull() ? 2 : 1;
|
||||||
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex), replaceStr);
|
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex),
|
||||||
|
replaceStr);
|
||||||
offset = match.capturedStart(captureIndex) + replaceStrLen;
|
offset = match.capturedStart(captureIndex) + replaceStrLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,11 +210,12 @@ QByteArray applyColorToSvg(const QString &filename, QColor color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an object which has to be used
|
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an
|
||||||
* and loaded icon
|
* object which has to be used and loaded icon
|
||||||
* @param supportedIconsNames list of <object ptr, icon name>
|
* @param supportedIconsNames list of <object ptr, icon name>
|
||||||
* @param setter functor which has to be called
|
* @param setter functor which has to be called
|
||||||
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon &icon) { static_cast<QAction*>(o)->setIcon(icon); }
|
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon
|
||||||
|
* &icon) { static_cast<QAction*>(o)->setIcon(icon); }
|
||||||
*/
|
*/
|
||||||
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
||||||
std::function<void(void *, const QIcon &)> setter)
|
std::function<void(void *, const QIcon &)> setter)
|
||||||
@ -272,11 +273,8 @@ void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex)
|
|||||||
void emitColumnChanged(QAbstractItemModel *model, int column)
|
void emitColumnChanged(QAbstractItemModel *model, int column)
|
||||||
{
|
{
|
||||||
if (model && model->rowCount()) {
|
if (model && model->rowCount()) {
|
||||||
emit model->dataChanged(
|
emit model->dataChanged(model->index(0, column),
|
||||||
model->index(0, column),
|
model->index(model->rowCount() - 1, column), { Qt::DisplayRole });
|
||||||
model->index(model->rowCount() - 1, column),
|
|
||||||
{ Qt::DisplayRole }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ class QPaintDevice;
|
|||||||
class QComboBox;
|
class QComboBox;
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
#define CUTTER_QT_SKIP_EMPTY_PARTS QString::SkipEmptyParts
|
# define CUTTER_QT_SKIP_EMPTY_PARTS QString::SkipEmptyParts
|
||||||
#else
|
#else
|
||||||
#define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
|
# define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace qhelpers {
|
namespace qhelpers {
|
||||||
@ -35,15 +35,18 @@ CUTTER_EXPORT QString formatBytecount(const uint64_t bytecount);
|
|||||||
CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
||||||
CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
|
CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
|
||||||
CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
|
CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
|
||||||
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str,
|
||||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
const QString &str2 = QString(),
|
||||||
|
const QString &str3 = QString(),
|
||||||
|
const QString &str4 = QString(),
|
||||||
|
const QString &str5 = QString());
|
||||||
|
|
||||||
CUTTER_EXPORT void setVerticalScrollMode(QAbstractItemView *tw);
|
CUTTER_EXPORT void setVerticalScrollMode(QAbstractItemView *tw);
|
||||||
|
|
||||||
CUTTER_EXPORT void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
CUTTER_EXPORT void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
||||||
|
|
||||||
|
struct CUTTER_EXPORT SizePolicyMinMax
|
||||||
struct CUTTER_EXPORT SizePolicyMinMax {
|
{
|
||||||
QSizePolicy sizePolicy;
|
QSizePolicy sizePolicy;
|
||||||
int min;
|
int min;
|
||||||
int max;
|
int max;
|
||||||
@ -61,7 +64,8 @@ CUTTER_EXPORT int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
|
|||||||
CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color);
|
CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color);
|
||||||
CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color);
|
CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color);
|
||||||
|
|
||||||
CUTTER_EXPORT void setThemeIcons(QList<QPair<void*, QString>> supportedIconsNames, std::function<void(void *, const QIcon &)> setter);
|
CUTTER_EXPORT void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
||||||
|
std::function<void(void *, const QIcon &)> setter);
|
||||||
|
|
||||||
CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu);
|
CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu);
|
||||||
CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
|
CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
|
||||||
|
@ -16,8 +16,8 @@ static qreal GetDevicePixelRatio(qreal devicePixelRatio)
|
|||||||
}
|
}
|
||||||
|
|
||||||
HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio)
|
HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio)
|
||||||
: QPixmap(int(width * GetDevicePixelRatio(devicePixelRatio)),
|
: QPixmap(int(width *GetDevicePixelRatio(devicePixelRatio)),
|
||||||
int(height * GetDevicePixelRatio(devicePixelRatio)))
|
int(height *GetDevicePixelRatio(devicePixelRatio)))
|
||||||
{
|
{
|
||||||
setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio));
|
setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio));
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
Highlighter::Highlighter(QTextDocument *parent) :
|
Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||||
QSyntaxHighlighter(parent)
|
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
HighlightingRule rule;
|
||||||
|
|
||||||
@ -28,7 +27,6 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
|||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
singleLineCommentFormat.setFontWeight(QFont::Bold);
|
singleLineCommentFormat.setFontWeight(QFont::Bold);
|
||||||
singleLineCommentFormat.setForeground(QColor(63, 195, 128));
|
singleLineCommentFormat.setForeground(QColor(63, 195, 128));
|
||||||
rule.pattern.setPattern(";[^\n]*");
|
rule.pattern.setPattern(";[^\n]*");
|
||||||
@ -57,17 +55,19 @@ void Highlighter::highlightBlock(const QString &text)
|
|||||||
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
|
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
|
||||||
|
|
||||||
while (startIndex >= 0) {
|
while (startIndex >= 0) {
|
||||||
QRegularExpressionMatch commentEndMatch = QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
QRegularExpressionMatch commentEndMatch =
|
||||||
|
QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
||||||
int endIndex = commentEndMatch.capturedStart();
|
int endIndex = commentEndMatch.capturedStart();
|
||||||
int commentLength;
|
int commentLength;
|
||||||
if (endIndex == -1) {
|
if (endIndex == -1) {
|
||||||
setCurrentBlockState(1);
|
setCurrentBlockState(1);
|
||||||
commentLength = text.length() - startIndex;
|
commentLength = text.length() - startIndex;
|
||||||
} else {
|
} else {
|
||||||
commentLength = endIndex - startIndex
|
commentLength = endIndex - startIndex + commentEndMatch.capturedLength();
|
||||||
+ commentEndMatch.capturedLength();
|
|
||||||
}
|
}
|
||||||
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||||
startIndex = QRegularExpression(commentStartRegularExpression).match(text.mid(startIndex + commentLength)).capturedStart();
|
startIndex = QRegularExpression(commentStartRegularExpression)
|
||||||
|
.match(text.mid(startIndex + commentLength))
|
||||||
|
.capturedStart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
CutterCore *core;
|
CutterCore *core;
|
||||||
|
|
||||||
struct HighlightingRule {
|
struct HighlightingRule
|
||||||
|
{
|
||||||
QRegularExpression pattern;
|
QRegularExpression pattern;
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
};
|
};
|
||||||
|
@ -51,17 +51,17 @@ bool IOModesController::prepareForWriting()
|
|||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||||
msgBox.setWindowTitle(QObject::tr("Write error"));
|
msgBox.setWindowTitle(QObject::tr("Write error"));
|
||||||
msgBox.setText(
|
msgBox.setText(QObject::tr(
|
||||||
QObject::tr("Your file is opened in read-only mode. "
|
"Your file is opened in read-only mode. "
|
||||||
"Editing is only available when the file is opened in either Write or Cache modes.\n\n"
|
"Editing is only available when the file is opened in either Write or Cache modes.\n\n"
|
||||||
"WARNING: In Write mode, any changes will be committed to the file on disk. "
|
"WARNING: In Write mode, any changes will be committed to the file on disk. "
|
||||||
"For safety, please consider using Cache mode and then commit the changes manually "
|
"For safety, please consider using Cache mode and then commit the changes manually "
|
||||||
"via File -> Commit modifications to disk."));
|
"via File -> Commit modifications to disk."));
|
||||||
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
|
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
|
||||||
QAbstractButton *reopenButton = msgBox.addButton(QObject::tr("Reopen in Write mode"),
|
QAbstractButton *reopenButton =
|
||||||
QMessageBox::YesRole);
|
msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole);
|
||||||
QAbstractButton *iocacheButton = msgBox.addButton(QObject::tr("Enable Cache mode"),
|
QAbstractButton *iocacheButton =
|
||||||
QMessageBox::YesRole);
|
msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole);
|
||||||
|
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
@ -95,10 +95,13 @@ bool IOModesController::askCommitUnsavedChanges()
|
|||||||
{
|
{
|
||||||
// Check if there are uncommitted changes
|
// Check if there are uncommitted changes
|
||||||
if (!allChangesComitted()) {
|
if (!allChangesComitted()) {
|
||||||
QMessageBox::StandardButton ret = QMessageBox::question(NULL, QObject::tr("Uncomitted changes"),
|
QMessageBox::StandardButton ret = QMessageBox::question(
|
||||||
QObject::tr("It seems that you have changes or patches that are not committed to the file.\n"
|
NULL, QObject::tr("Uncomitted changes"),
|
||||||
|
QObject::tr("It seems that you have changes or patches that are not committed to "
|
||||||
|
"the file.\n"
|
||||||
"Do you want to commit them now?"),
|
"Do you want to commit them now?"),
|
||||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
|
||||||
|
| QMessageBox::Cancel));
|
||||||
if (ret == QMessageBox::Save) {
|
if (ret == QMessageBox::Save) {
|
||||||
Core()->commitWriteCache();
|
Core()->commitWriteCache();
|
||||||
} else if (ret == QMessageBox::Discard) {
|
} else if (ret == QMessageBox::Discard) {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
/**
|
/**
|
||||||
* @brief The CommandDescription struct is a pair of a Rizin command and its description
|
* @brief The CommandDescription struct is a pair of a Rizin command and its description
|
||||||
*/
|
*/
|
||||||
struct CommandDescription {
|
struct CommandDescription
|
||||||
|
{
|
||||||
QString command;
|
QString command;
|
||||||
QString description;
|
QString description;
|
||||||
};
|
};
|
||||||
@ -38,9 +39,9 @@ struct InitialOptions
|
|||||||
QString pdbFile;
|
QString pdbFile;
|
||||||
QString script;
|
QString script;
|
||||||
|
|
||||||
QList<CommandDescription> analCmd = { {"aaa", "Auto analysis"} };
|
QList<CommandDescription> analCmd = { { "aaa", "Auto analysis" } };
|
||||||
|
|
||||||
QString shellcode;
|
QString shellcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CUTTER_INITIALOPTIONS_H
|
#endif // CUTTER_INITIALOPTIONS_H
|
||||||
|
@ -16,4 +16,4 @@ static inline RVA JsonValueGetRVA(const QJsonValue &value, RVA defaultValue = RV
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //CUTTER_JSON_H
|
#endif // CUTTER_JSON_H
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "JsonModel.h"
|
#include "JsonModel.h"
|
||||||
|
|
||||||
JsonModel::JsonModel(QObject *parent) :
|
JsonModel::JsonModel(QObject *parent) : QAbstractItemModel(parent)
|
||||||
QAbstractItemModel(parent)
|
|
||||||
{
|
{
|
||||||
mRootItem = new JsonTreeItem;
|
mRootItem = new JsonTreeItem;
|
||||||
mHeaders.append("key");
|
mHeaders.append("key");
|
||||||
@ -42,10 +41,8 @@ QVariant JsonModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
|
|
||||||
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
|
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
|
||||||
|
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
|
|
||||||
if (index.column() == 0)
|
if (index.column() == 0)
|
||||||
@ -122,4 +119,3 @@ int JsonModel::columnCount(const QModelIndex &parent) const
|
|||||||
Q_UNUSED(parent)
|
Q_UNUSED(parent)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
~JsonModel();
|
~JsonModel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonTreeItem *mRootItem;
|
JsonTreeItem *mRootItem;
|
||||||
QJsonDocument mDocument;
|
QJsonDocument mDocument;
|
||||||
|
@ -73,9 +73,9 @@ JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
|||||||
JsonTreeItem *rootItem = new JsonTreeItem(parent);
|
JsonTreeItem *rootItem = new JsonTreeItem(parent);
|
||||||
rootItem->setKey("root");
|
rootItem->setKey("root");
|
||||||
|
|
||||||
if ( value.isObject()) {
|
if (value.isObject()) {
|
||||||
|
|
||||||
//Get all QJsonValue childs
|
// Get all QJsonValue childs
|
||||||
for (const QString &key : value.toObject().keys()) {
|
for (const QString &key : value.toObject().keys()) {
|
||||||
QJsonValue v = value.toObject().value(key);
|
QJsonValue v = value.toObject().value(key);
|
||||||
JsonTreeItem *child = load(v, rootItem);
|
JsonTreeItem *child = load(v, rootItem);
|
||||||
@ -84,8 +84,8 @@ JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
|||||||
rootItem->appendChild(child);
|
rootItem->appendChild(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( value.isArray()) {
|
} else if (value.isArray()) {
|
||||||
//Get all QJsonValue childs
|
// Get all QJsonValue childs
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (const QJsonValue &v : value.toArray()) {
|
for (const QJsonValue &v : value.toArray()) {
|
||||||
|
|
||||||
|
@ -8,20 +8,23 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Pool of singly linked lists.
|
* @brief Pool of singly linked lists.
|
||||||
*
|
*
|
||||||
* Should not be used as general purpose container. Use only for algorithms that require linked lists ability
|
* Should not be used as general purpose container. Use only for algorithms that require linked
|
||||||
* to split and concatenate them. All the data is owned by LinkedListPool.
|
* lists ability to split and concatenate them. All the data is owned by LinkedListPool.
|
||||||
*
|
*
|
||||||
* In contrast to std::list and std::forward_list doesn't allocate each node separately. LinkedListPool can reserve
|
* In contrast to std::list and std::forward_list doesn't allocate each node separately.
|
||||||
* all the memory for multiple lists during construction. Uses std::vector as backing container.
|
* LinkedListPool can reserve all the memory for multiple lists during construction. Uses
|
||||||
|
* std::vector as backing container.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
class LinkedListPool
|
class LinkedListPool
|
||||||
{
|
{
|
||||||
using IndexType = size_t;
|
using IndexType = size_t;
|
||||||
struct Item {
|
struct Item
|
||||||
|
{
|
||||||
IndexType next;
|
IndexType next;
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief List iterator.
|
* @brief List iterator.
|
||||||
@ -32,27 +35,19 @@ public:
|
|||||||
{
|
{
|
||||||
IndexType index = 0;
|
IndexType index = 0;
|
||||||
LinkedListPool<T> *pool = nullptr;
|
LinkedListPool<T> *pool = nullptr;
|
||||||
ListIterator(IndexType index, LinkedListPool<T> *pool)
|
ListIterator(IndexType index, LinkedListPool<T> *pool) : index(index), pool(pool) {}
|
||||||
: index(index)
|
|
||||||
, pool(pool)
|
|
||||||
{}
|
|
||||||
|
|
||||||
friend class LinkedListPool<T>;
|
friend class LinkedListPool<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator_category = std::forward_iterator_tag;
|
using iterator_category = std::forward_iterator_tag;
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using difference_type = size_t;
|
using difference_type = size_t;
|
||||||
using pointer = T*;
|
using pointer = T *;
|
||||||
using reference = T&;
|
using reference = T &;
|
||||||
ListIterator() = default;
|
ListIterator() = default;
|
||||||
reference operator*()
|
reference operator*() { return pool->data[index].value; }
|
||||||
{
|
pointer operator->() { return &pool->data[index].value; }
|
||||||
return pool->data[index].value;
|
|
||||||
}
|
|
||||||
pointer operator->()
|
|
||||||
{
|
|
||||||
return &pool->data[index].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListIterator &operator++()
|
ListIterator &operator++()
|
||||||
{
|
{
|
||||||
@ -65,24 +60,18 @@ public:
|
|||||||
operator++();
|
operator++();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
bool operator!=(const ListIterator &b) const
|
bool operator!=(const ListIterator &b) const { return index != b.index || pool != b.pool; };
|
||||||
{
|
|
||||||
return index != b.index || pool != b.pool;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* @brief Test if iterator points to valid value.
|
* @brief Test if iterator points to valid value.
|
||||||
*/
|
*/
|
||||||
explicit operator bool() const
|
explicit operator bool() const { return index; }
|
||||||
{
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Single list within LinkedListPool.
|
* @brief Single list within LinkedListPool.
|
||||||
*
|
*
|
||||||
* List only refers to chain of elements. Copying it doesn't copy any element. Item data is owned by
|
* List only refers to chain of elements. Copying it doesn't copy any element. Item data is
|
||||||
* LinkedListPool.
|
* owned by LinkedListPool.
|
||||||
*
|
*
|
||||||
* Use LinkedListPool::makeList to create non-empty list.
|
* Use LinkedListPool::makeList to create non-empty list.
|
||||||
*/
|
*/
|
||||||
@ -91,28 +80,22 @@ public:
|
|||||||
IndexType head = 0;
|
IndexType head = 0;
|
||||||
IndexType tail = 0;
|
IndexType tail = 0;
|
||||||
friend class LinkedListPool;
|
friend class LinkedListPool;
|
||||||
List(IndexType head, IndexType tail)
|
List(IndexType head, IndexType tail) : head(head), tail(tail) {}
|
||||||
: head(head)
|
|
||||||
, tail(tail)
|
|
||||||
{}
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Create an empty list
|
* @brief Create an empty list
|
||||||
*/
|
*/
|
||||||
List() = default;
|
List() = default;
|
||||||
|
|
||||||
bool isEmpty() const
|
bool isEmpty() const { return head == 0; }
|
||||||
{
|
|
||||||
return head == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a linked list pool with capacity for \a initialCapacity list items.
|
* @brief Create a linked list pool with capacity for \a initialCapacity list items.
|
||||||
* @param initialCapacity number of elements to preallocate.
|
* @param initialCapacity number of elements to preallocate.
|
||||||
*/
|
*/
|
||||||
LinkedListPool(size_t initialCapacity)
|
LinkedListPool(size_t initialCapacity) : data(1)
|
||||||
: data(1)
|
|
||||||
{
|
{
|
||||||
data.reserve(initialCapacity + 1); // [0] element reserved
|
data.reserve(initialCapacity + 1); // [0] element reserved
|
||||||
}
|
}
|
||||||
@ -120,22 +103,23 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Create a list containing single item.
|
* @brief Create a list containing single item.
|
||||||
*
|
*
|
||||||
* Does not invalidate any iterators, but may cause item relocation when initialCapacity is exceeded.
|
* Does not invalidate any iterators, but may cause item relocation when initialCapacity is
|
||||||
|
* exceeded.
|
||||||
* @param value value of element that will be inserted in the created list
|
* @param value value of element that will be inserted in the created list
|
||||||
* @return List containing single value \a value .
|
* @return List containing single value \a value .
|
||||||
*/
|
*/
|
||||||
List makeList(const T &value)
|
List makeList(const T &value)
|
||||||
{
|
{
|
||||||
size_t position = data.size();
|
size_t position = data.size();
|
||||||
data.push_back(Item{0, value});
|
data.push_back(Item { 0, value });
|
||||||
return {position, position};
|
return { position, position };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Split list and return second half.
|
* @brief Split list and return second half.
|
||||||
*
|
*
|
||||||
* After performing the operation, list passed as argument and return list point to the same items. Modifying them
|
* After performing the operation, list passed as argument and return list point to the same
|
||||||
* will affect both lists.
|
* items. Modifying them will affect both lists.
|
||||||
*
|
*
|
||||||
* @param list The list that needs to be split.
|
* @param list The list that needs to be split.
|
||||||
* @param head Iterator to the first item in new list. Needs to be within \a list .
|
* @param head Iterator to the first item in new list. Needs to be within \a list .
|
||||||
@ -143,14 +127,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
List splitTail(const List &list, const ListIterator &head)
|
List splitTail(const List &list, const ListIterator &head)
|
||||||
{
|
{
|
||||||
return List {head.index, list.tail};
|
return List { head.index, list.tail };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Split list and return first half.
|
* @brief Split list and return first half.
|
||||||
*
|
*
|
||||||
* @param list The list that needs to be split.
|
* @param list The list that needs to be split.
|
||||||
* @param end Iterator to the first item that should not be included in returned list. Needs to be within \a list .
|
* @param end Iterator to the first item that should not be included in returned list. Needs to
|
||||||
|
* be within \a list .
|
||||||
* @return Returns prefix of \a list.
|
* @return Returns prefix of \a list.
|
||||||
*/
|
*/
|
||||||
List splitHead(const List &list, const ListIterator &end)
|
List splitHead(const List &list, const ListIterator &end)
|
||||||
@ -166,7 +151,7 @@ public:
|
|||||||
last = data[last].next;
|
last = data[last].next;
|
||||||
}
|
}
|
||||||
data[last].next = 0;
|
data[last].next = 0;
|
||||||
return List {list.head, last};
|
return List { list.head, last };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,15 +159,9 @@ public:
|
|||||||
* @param list
|
* @param list
|
||||||
* @return Iterator pointing to the first item in the list.
|
* @return Iterator pointing to the first item in the list.
|
||||||
*/
|
*/
|
||||||
ListIterator head(const List &list)
|
ListIterator head(const List &list) { return iteratorFromIndex(list.head); }
|
||||||
{
|
|
||||||
return iteratorFromIndex(list.head);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListIterator end(const List &list)
|
ListIterator end(const List &list) { return std::next(iteratorFromIndex(list.tail)); }
|
||||||
{
|
|
||||||
return std::next(iteratorFromIndex(list.tail));
|
|
||||||
}
|
|
||||||
|
|
||||||
List append(const List &head, const List &tail)
|
List append(const List &head, const List &tail)
|
||||||
{
|
{
|
||||||
@ -192,18 +171,15 @@ public:
|
|||||||
if (tail.isEmpty()) {
|
if (tail.isEmpty()) {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
List result{head.head, tail.tail};
|
List result { head.head, tail.tail };
|
||||||
data[head.tail].next = tail.head;
|
data[head.tail].next = tail.head;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListIterator iteratorFromIndex(IndexType index)
|
ListIterator iteratorFromIndex(IndexType index) { return ListIterator { index, this }; }
|
||||||
{
|
|
||||||
return ListIterator{ index, this };
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Item> data;
|
std::vector<Item> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // LINKED_LIST_POOL
|
#endif // LINKED_LIST_POOL
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
#include "common/MdHighlighter.h"
|
#include "common/MdHighlighter.h"
|
||||||
|
|
||||||
MdHighlighter::MdHighlighter(QTextDocument *parent)
|
MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||||
: QSyntaxHighlighter(parent)
|
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
HighlightingRule rule;
|
||||||
|
|
||||||
@ -11,8 +10,10 @@ MdHighlighter::MdHighlighter(QTextDocument *parent)
|
|||||||
keywordFormat.setFontWeight(QFont::Bold);
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
|
|
||||||
QStringList keywordPatterns;
|
QStringList keywordPatterns;
|
||||||
keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b" << "\\*\\*([^\\\\]+)\\*\\*"
|
keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b"
|
||||||
<< "\\*([^\\\\]+)\\*" << "\\_([^\\\\]+)\\_"
|
<< "\\*\\*([^\\\\]+)\\*\\*"
|
||||||
|
<< "\\*([^\\\\]+)\\*"
|
||||||
|
<< "\\_([^\\\\]+)\\_"
|
||||||
<< "\\_\\_([^\\\\]+)\\_\\_";
|
<< "\\_\\_([^\\\\]+)\\_\\_";
|
||||||
|
|
||||||
for (const QString &pattern : keywordPatterns) {
|
for (const QString &pattern : keywordPatterns) {
|
||||||
|
@ -20,7 +20,8 @@ protected:
|
|||||||
void highlightBlock(const QString &text);
|
void highlightBlock(const QString &text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct HighlightingRule {
|
struct HighlightingRule
|
||||||
|
{
|
||||||
QRegularExpression pattern;
|
QRegularExpression pattern;
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
};
|
};
|
||||||
|
@ -9,18 +9,23 @@ class QRectF;
|
|||||||
class QFontMetrics;
|
class QFontMetrics;
|
||||||
class QFontMetricsF;
|
class QFontMetricsF;
|
||||||
|
|
||||||
template<typename T> struct Metrics {};
|
template<typename T>
|
||||||
|
struct Metrics
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template<> struct Metrics<int>
|
template<>
|
||||||
|
struct Metrics<int>
|
||||||
{
|
{
|
||||||
using Rect = QRect;
|
using Rect = QRect;
|
||||||
using FontMetrics = QFontMetrics;
|
using FontMetrics = QFontMetrics;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct Metrics<qreal>
|
template<>
|
||||||
|
struct Metrics<qreal>
|
||||||
{
|
{
|
||||||
using Rect = QRectF;
|
using Rect = QRectF;
|
||||||
using FontMetrics = QFontMetricsF;
|
using FontMetrics = QFontMetricsF;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //METRICS_H
|
#endif // METRICS_H
|
||||||
|
@ -9,15 +9,12 @@ static const int paddingInner = 8;
|
|||||||
static const int arms = 12;
|
static const int arms = 12;
|
||||||
static const int timerInterval = 50;
|
static const int timerInterval = 50;
|
||||||
|
|
||||||
ProgressIndicator::ProgressIndicator(QWidget *parent)
|
ProgressIndicator::ProgressIndicator(QWidget *parent) : QWidget(parent)
|
||||||
: QWidget(parent)
|
|
||||||
{
|
{
|
||||||
updateAnimationTimer();
|
updateAnimationTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressIndicator::~ProgressIndicator()
|
ProgressIndicator::~ProgressIndicator() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProgressIndicator::setProgressIndicatorVisible(bool visible)
|
void ProgressIndicator::setProgressIndicatorVisible(bool visible)
|
||||||
{
|
{
|
||||||
@ -77,13 +74,9 @@ void ProgressIndicator::paintEvent(QPaintEvent *)
|
|||||||
QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0);
|
QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0);
|
||||||
|
|
||||||
qreal angle = 360.0 / arms;
|
qreal angle = 360.0 / arms;
|
||||||
for (int i=0; i<arms; i++) {
|
for (int i = 0; i < arms; i++) {
|
||||||
int state = (i + (arms - animationState)) % arms;
|
int state = (i + (arms - animationState)) % arms;
|
||||||
painter.setOpacity((float)state / arms);
|
painter.setOpacity((float)state / arms);
|
||||||
painter.drawLine(line * QTransform()
|
painter.drawLine(line * QTransform().translate(origin.x(), origin.y()).rotate(angle * i));
|
||||||
.translate(origin.x(), origin.y())
|
|
||||||
.rotate(angle * i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class ProgressIndicator: public QWidget
|
class ProgressIndicator : public QWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProgressIndicator(QWidget *parent = nullptr);
|
ProgressIndicator(QWidget *parent = nullptr);
|
||||||
@ -33,5 +33,4 @@ private:
|
|||||||
void updateAnimationTimer();
|
void updateAnimationTimer();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // PROGRESSINDICATOR_H
|
||||||
#endif //PROGRESSINDICATOR_H
|
|
||||||
|
@ -16,7 +16,7 @@ PyObject *api_cmd(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(self);
|
Q_UNUSED(self);
|
||||||
char *command;
|
char *command;
|
||||||
char *result = (char *) "";
|
char *result = (char *)"";
|
||||||
QString cmdRes;
|
QString cmdRes;
|
||||||
QByteArray cmdBytes;
|
QByteArray cmdBytes;
|
||||||
if (PyArg_ParseTuple(args, "s:command", &command)) {
|
if (PyArg_ParseTuple(args, "s:command", &command)) {
|
||||||
@ -41,9 +41,8 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
char *message;
|
char *message;
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
static const char *kwlist[] = { "", "debug", NULL };
|
static const char *kwlist[] = { "", "debug", NULL };
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", const_cast<char **>(kwlist), &message,
|
||||||
const_cast<char**>(kwlist),
|
&debug)) {
|
||||||
&message, &debug)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Core()->message(QString(message), debug);
|
Core()->message(QString(message), debug);
|
||||||
@ -52,28 +51,16 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyMethodDef CutterMethods[] = {
|
PyMethodDef CutterMethods[] = {
|
||||||
{
|
{ "version", api_version, METH_NOARGS, "Returns Cutter current version" },
|
||||||
"version", api_version, METH_NOARGS,
|
{ "cmd", api_cmd, METH_VARARGS, "Execute a command inside Cutter" },
|
||||||
"Returns Cutter current version"
|
{ "refresh", api_refresh, METH_NOARGS, "Refresh Cutter widgets" },
|
||||||
},
|
{ "message", (PyCFunction)(void *)/* don't remove this double cast! */ api_message,
|
||||||
{
|
METH_VARARGS | METH_KEYWORDS, "Print message" },
|
||||||
"cmd", api_cmd, METH_VARARGS,
|
{ NULL, NULL, 0, NULL }
|
||||||
"Execute a command inside Cutter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"refresh", api_refresh, METH_NOARGS,
|
|
||||||
"Refresh Cutter widgets"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"message", (PyCFunction)(void *)/* don't remove this double cast! */api_message, METH_VARARGS | METH_KEYWORDS,
|
|
||||||
"Print message"
|
|
||||||
},
|
|
||||||
{NULL, NULL, 0, NULL}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PyModuleDef CutterModule = {
|
PyModuleDef CutterModule = {
|
||||||
PyModuleDef_HEAD_INIT, "_cutter", NULL, -1, CutterMethods,
|
PyModuleDef_HEAD_INIT, "_cutter", NULL, -1, CutterMethods, NULL, NULL, NULL, NULL
|
||||||
NULL, NULL, NULL, NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *PyInit_api()
|
PyObject *PyInit_api()
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||||
#include <shiboken.h>
|
# include <shiboken.h>
|
||||||
#include <pyside.h>
|
# include <pyside.h>
|
||||||
#include <signalmanager.h>
|
# include <signalmanager.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "QtResImporter.h"
|
#include "QtResImporter.h"
|
||||||
@ -28,13 +28,9 @@ PythonManager *PythonManager::getInstance()
|
|||||||
return uniqueInstance;
|
return uniqueInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonManager::PythonManager()
|
PythonManager::PythonManager() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PythonManager::~PythonManager()
|
PythonManager::~PythonManager() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void PythonManager::initPythonHome()
|
void PythonManager::initPythonHome()
|
||||||
{
|
{
|
||||||
@ -48,8 +44,8 @@ void PythonManager::initPythonHome()
|
|||||||
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED
|
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED
|
||||||
// @executable_path/../Frameworks/Python.framework/Versions/Current
|
// @executable_path/../Frameworks/Python.framework/Versions/Current
|
||||||
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
|
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
|
||||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() <<
|
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath()
|
||||||
" for macOS Application Bundle.";
|
<< " for macOS Application Bundle.";
|
||||||
# endif
|
# endif
|
||||||
customPythonHome = pythonHomeDir.absolutePath();
|
customPythonHome = pythonHomeDir.absolutePath();
|
||||||
}
|
}
|
||||||
@ -85,11 +81,11 @@ void PythonManager::initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||||
static void pySideDestructionVisitor(SbkObject* pyObj, void* data)
|
static void pySideDestructionVisitor(SbkObject *pyObj, void *data)
|
||||||
{
|
{
|
||||||
void **realData = reinterpret_cast<void**>(data);
|
void **realData = reinterpret_cast<void **>(data);
|
||||||
auto pyQApp = reinterpret_cast<SbkObject*>(realData[0]);
|
auto pyQApp = reinterpret_cast<SbkObject *>(realData[0]);
|
||||||
auto pyQObjectType = reinterpret_cast<PyTypeObject*>(realData[1]);
|
auto pyQObjectType = reinterpret_cast<PyTypeObject *>(realData[1]);
|
||||||
|
|
||||||
if (pyObj == pyQApp || !PyObject_TypeCheck(pyObj, pyQObjectType)) {
|
if (pyObj == pyQApp || !PyObject_TypeCheck(pyObj, pyQObjectType)) {
|
||||||
return;
|
return;
|
||||||
@ -112,8 +108,8 @@ static void pySideDestructionVisitor(SbkObject* pyObj, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Shiboken::Object::setValidCpp(pyObj, false);
|
Shiboken::Object::setValidCpp(pyObj, false);
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS Shiboken::callCppDestructor<QObject>(
|
||||||
Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, pyQObjectType));
|
Shiboken::Object::cppPointer(pyObj, pyQObjectType));
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -125,15 +121,16 @@ void PythonManager::shutdown()
|
|||||||
restoreThread();
|
restoreThread();
|
||||||
|
|
||||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||||
// This is necessary to prevent a segfault when the CutterCore instance is deleted after the Shiboken::BindingManager
|
// This is necessary to prevent a segfault when the CutterCore instance is deleted after the
|
||||||
|
// Shiboken::BindingManager
|
||||||
Core()->setProperty("_PySideInvalidatePtr", QVariant());
|
Core()->setProperty("_PySideInvalidatePtr", QVariant());
|
||||||
|
|
||||||
// see PySide::destroyQCoreApplication()
|
// see PySide::destroyQCoreApplication()
|
||||||
PySide::SignalManager::instance().clear();
|
PySide::SignalManager::instance().clear();
|
||||||
Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
|
Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
|
||||||
SbkObject* pyQApp = bm.retrieveWrapper(QCoreApplication::instance());
|
SbkObject *pyQApp = bm.retrieveWrapper(QCoreApplication::instance());
|
||||||
PyTypeObject* pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
|
PyTypeObject *pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
|
||||||
void* data[2] = {pyQApp, pyQObjectType};
|
void *data[2] = { pyQApp, pyQObjectType };
|
||||||
bm.visitAllPyObjects(&pySideDestructionVisitor, &data);
|
bm.visitAllPyObjects(&pySideDestructionVisitor, &data);
|
||||||
|
|
||||||
PySide::runCleanupFunctions();
|
PySide::runCleanupFunctions();
|
||||||
@ -146,7 +143,8 @@ void PythonManager::shutdown()
|
|||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonManager::addPythonPath(char *path) {
|
void PythonManager::addPythonPath(char *path)
|
||||||
|
{
|
||||||
restoreThread();
|
restoreThread();
|
||||||
|
|
||||||
PyObject *sysModule = PyImport_ImportModule("sys");
|
PyObject *sysModule = PyImport_ImportModule("sys");
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#ifdef CUTTER_ENABLE_PYTHON
|
#ifdef CUTTER_ENABLE_PYTHON
|
||||||
|
|
||||||
#include <QObject>
|
# include <QObject>
|
||||||
|
|
||||||
typedef struct _ts PyThreadState;
|
typedef struct _ts PyThreadState;
|
||||||
typedef struct _object PyObject;
|
typedef struct _object PyObject;
|
||||||
|
|
||||||
class PythonManager: public QObject
|
class PythonManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ private:
|
|||||||
int pyThreadStateCounter = 0;
|
int pyThreadStateCounter = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Python() (PythonManager::getInstance())
|
# define Python() (PythonManager::getInstance())
|
||||||
|
|
||||||
#endif // CUTTER_ENABLE_PYTHON
|
#endif // CUTTER_ENABLE_PYTHON
|
||||||
|
|
||||||
|
@ -23,9 +23,8 @@ PyObject *QtResGetCode(const char *name)
|
|||||||
QByteArray data = moduleFile.readAll();
|
QByteArray data = moduleFile.readAll();
|
||||||
moduleFile.close();
|
moduleFile.close();
|
||||||
|
|
||||||
PyObject *codeObject = Py_CompileString(data.constData(),
|
PyObject *codeObject = Py_CompileString(
|
||||||
moduleFile.fileName().toLocal8Bit().constData(),
|
data.constData(), moduleFile.fileName().toLocal8Bit().constData(), Py_file_input);
|
||||||
Py_file_input);
|
|
||||||
if (!codeObject) {
|
if (!codeObject) {
|
||||||
qWarning() << "Couldn't compile " << moduleFile.fileName();
|
qWarning() << "Couldn't compile " << moduleFile.fileName();
|
||||||
}
|
}
|
||||||
@ -68,15 +67,12 @@ PyObject *qtres_get_code(PyObject *self, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyMethodDef QtResMethods[] = {
|
PyMethodDef QtResMethods[] = { { "exists", qtres_exists, METH_VARARGS, NULL },
|
||||||
{ "exists", qtres_exists, METH_VARARGS, NULL },
|
|
||||||
{ "get_code", qtres_get_code, METH_VARARGS, NULL },
|
{ "get_code", qtres_get_code, METH_VARARGS, NULL },
|
||||||
{NULL, NULL, 0, NULL}
|
{ NULL, NULL, 0, NULL } };
|
||||||
};
|
|
||||||
|
|
||||||
PyModuleDef QtResModule = {
|
PyModuleDef QtResModule = {
|
||||||
PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods,
|
PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods, NULL, NULL, NULL, NULL
|
||||||
NULL, NULL, NULL, NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *PyInit_qtres()
|
PyObject *PyInit_qtres()
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#include "RefreshDeferrer.h"
|
#include "RefreshDeferrer.h"
|
||||||
#include "widgets/CutterDockWidget.h"
|
#include "widgets/CutterDockWidget.h"
|
||||||
|
|
||||||
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent) : QObject(parent),
|
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent)
|
||||||
acc(acc)
|
: QObject(parent), acc(acc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,4 +41,3 @@ void RefreshDeferrer::registerFor(CutterDockWidget *dockWidget)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,33 +24,33 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* @brief Add a new param to the accumulator
|
* @brief Add a new param to the accumulator
|
||||||
*/
|
*/
|
||||||
virtual void accumulate(RefreshDeferrerParams params) =0;
|
virtual void accumulate(RefreshDeferrerParams params) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ignore the incoming params. Useful for freeing if necessary.
|
* @brief Ignore the incoming params. Useful for freeing if necessary.
|
||||||
*/
|
*/
|
||||||
virtual void ignoreParams(RefreshDeferrerParams params) =0;
|
virtual void ignoreParams(RefreshDeferrerParams params) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clear the current accumulator
|
* @brief Clear the current accumulator
|
||||||
*/
|
*/
|
||||||
virtual void clear() =0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the final result of the accumulation
|
* @brief Return the final result of the accumulation
|
||||||
*/
|
*/
|
||||||
virtual RefreshDeferrerParamsResult result() =0;
|
virtual RefreshDeferrerParamsResult result() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accumulator which simply replaces the current value by an incoming new one
|
* @brief Accumulator which simply replaces the current value by an incoming new one
|
||||||
* @tparam T The type of the param to store
|
* @tparam T The type of the param to store
|
||||||
*
|
*
|
||||||
* This accumulator takes the ownership of all params passed to it and deletes them automatically if not needed anymore!
|
* This accumulator takes the ownership of all params passed to it and deletes them automatically if
|
||||||
|
* not needed anymore!
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
class ReplacingRefreshDeferrerAccumulator : public RefreshDeferrerAccumulator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
T *value = nullptr;
|
T *value = nullptr;
|
||||||
@ -58,16 +58,16 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \param Determines whether, if nullptr is passed, the current value should be replaced or kept.
|
* \param Determines whether, if nullptr is passed, the current value should be replaced or
|
||||||
|
* kept.
|
||||||
*/
|
*/
|
||||||
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
|
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
|
||||||
: replaceIfNull(replaceIfNull) {}
|
: replaceIfNull(replaceIfNull)
|
||||||
|
|
||||||
~ReplacingRefreshDeferrerAccumulator() override
|
|
||||||
{
|
{
|
||||||
delete value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~ReplacingRefreshDeferrerAccumulator() override { delete value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void accumulate(RefreshDeferrerParams params) override
|
void accumulate(RefreshDeferrerParams params) override
|
||||||
{
|
{
|
||||||
@ -78,10 +78,7 @@ protected:
|
|||||||
value = static_cast<T *>(params);
|
value = static_cast<T *>(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ignoreParams(RefreshDeferrerParams params) override
|
void ignoreParams(RefreshDeferrerParams params) override { delete static_cast<T *>(params); }
|
||||||
{
|
|
||||||
delete static_cast<T *>(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() override
|
void clear() override
|
||||||
{
|
{
|
||||||
@ -89,25 +86,22 @@ protected:
|
|||||||
value = nullptr;
|
value = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual RefreshDeferrerParamsResult result() override
|
virtual RefreshDeferrerParamsResult result() override { return value; }
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper class for deferred refreshing in Widgets
|
* @brief Helper class for deferred refreshing in Widgets
|
||||||
*
|
*
|
||||||
* This class can handle the logic necessary to defer the refreshing of widgets when they are not visible.
|
* This class can handle the logic necessary to defer the refreshing of widgets when they are not
|
||||||
* It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate incoming events while
|
* visible. It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate
|
||||||
* refreshing is deferred.
|
* incoming events while refreshing is deferred.
|
||||||
*
|
*
|
||||||
* Example (don't write it like this in practice, use the convenience methods in CutterDockWidget):
|
* Example (don't write it like this in practice, use the convenience methods in CutterDockWidget):
|
||||||
* ```
|
* ```
|
||||||
* // in the constructor of a widget
|
* // in the constructor of a widget
|
||||||
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false), this);
|
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false),
|
||||||
* this->refreshDeferrer->registerFor(this);
|
* this); this->refreshDeferrer->registerFor(this); connect(this->refreshDeferrer,
|
||||||
* connect(this->refreshDeferrer, &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
|
* &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
|
||||||
* // We attempted a refresh some time before, but it got deferred.
|
* // We attempted a refresh some time before, but it got deferred.
|
||||||
* // Now the RefreshDeferrer tells us to do the refresh and gives us the accumulated param.
|
* // Now the RefreshDeferrer tells us to do the refresh and gives us the accumulated param.
|
||||||
* this->doRefresh(*param);
|
* this->doRefresh(*param);
|
||||||
@ -151,4 +145,4 @@ signals:
|
|||||||
void refreshNow(const RefreshDeferrerParamsResult paramsResult);
|
void refreshNow(const RefreshDeferrerParamsResult paramsResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //REFRESHDEFERRER_H
|
#endif // REFRESHDEFERRER_H
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
#ifdef APPIMAGE
|
#ifdef APPIMAGE
|
||||||
static QDir appimageRoot()
|
static QDir appimageRoot()
|
||||||
{
|
{
|
||||||
@ -37,7 +36,8 @@ static QStringList substitutePaths(const QStringList &paths)
|
|||||||
QStringList result;
|
QStringList result;
|
||||||
result.reserve(paths.size());
|
result.reserve(paths.size());
|
||||||
for (auto &path : paths) {
|
for (auto &path : paths) {
|
||||||
// consider ignoring some of system folders for portable packages here or standardLocations if it depends on path type
|
// consider ignoring some of system folders for portable packages here or standardLocations
|
||||||
|
// if it depends on path type
|
||||||
result.push_back(substitutePath(path));
|
result.push_back(substitutePath(path));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -46,8 +46,8 @@ static QStringList substitutePaths(const QStringList &paths)
|
|||||||
QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
|
QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
|
||||||
QStandardPaths::LocateOptions options)
|
QStandardPaths::LocateOptions options)
|
||||||
{
|
{
|
||||||
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs to be done
|
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs
|
||||||
// after substitutions
|
// to be done after substitutions
|
||||||
QStringList result;
|
QStringList result;
|
||||||
for (auto path : standardLocations(type)) {
|
for (auto path : standardLocations(type)) {
|
||||||
QString filePath = path + QLatin1Char('/') + fileName;
|
QString filePath = path + QLatin1Char('/') + fileName;
|
||||||
@ -81,4 +81,3 @@ QStringList Cutter::getTranslationsDirectories()
|
|||||||
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,14 +11,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Cutter {
|
namespace Cutter {
|
||||||
QStringList locateAll(
|
QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
|
||||||
QStandardPaths::StandardLocation type,
|
|
||||||
const QString &fileName,
|
|
||||||
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
|
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
|
||||||
QStringList standardLocations(QStandardPaths::StandardLocation type);
|
QStringList standardLocations(QStandardPaths::StandardLocation type);
|
||||||
QString writableLocation(QStandardPaths::StandardLocation type);
|
QString writableLocation(QStandardPaths::StandardLocation type);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get list of available translation directories (depends on configuration and OS)
|
* @brief Get list of available translation directories (depends on configuration and OS)
|
||||||
* @return list of directories
|
* @return list of directories
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
#include <QTextFragment>
|
#include <QTextFragment>
|
||||||
|
|
||||||
//TODO: fix performance (possibly use QTextLayout?)
|
// TODO: fix performance (possibly use QTextLayout?)
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
|
void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
|
||||||
@ -21,24 +20,24 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
|
|||||||
T backgroundWidth = textWidth;
|
T backgroundWidth = textWidth;
|
||||||
if (backgroundWidth + xinc > w)
|
if (backgroundWidth + xinc > w)
|
||||||
backgroundWidth = w - xinc;
|
backgroundWidth = w - xinc;
|
||||||
if (backgroundWidth <= 0) //stop drawing when going outside the specified width
|
if (backgroundWidth <= 0) // stop drawing when going outside the specified width
|
||||||
break;
|
break;
|
||||||
switch (curRichText.flags) {
|
switch (curRichText.flags) {
|
||||||
case FlagNone: //defaults
|
case FlagNone: // defaults
|
||||||
pen.setColor(ConfigColor("btext").name());
|
pen.setColor(ConfigColor("btext").name());
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
break;
|
break;
|
||||||
case FlagColor: //color only
|
case FlagColor: // color only
|
||||||
pen.setColor(curRichText.textColor);
|
pen.setColor(curRichText.textColor);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
break;
|
break;
|
||||||
case FlagBackground: //background only
|
case FlagBackground: // background only
|
||||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||||
brush.setColor(curRichText.textBackground);
|
brush.setColor(curRichText.textBackground);
|
||||||
painter->fillRect(QRectF(x + xinc, y, backgroundWidth, h), brush);
|
painter->fillRect(QRectF(x + xinc, y, backgroundWidth, h), brush);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FlagAll: //color+background
|
case FlagAll: // color+background
|
||||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||||
brush.setColor(curRichText.textBackground);
|
brush.setColor(curRichText.textBackground);
|
||||||
painter->fillRect(QRectF(x + xinc, y, backgroundWidth, h), brush);
|
painter->fillRect(QRectF(x + xinc, y, backgroundWidth, h), brush);
|
||||||
@ -52,67 +51,74 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
|
|||||||
flags = Qt::TextBypassShaping;
|
flags = Qt::TextBypassShaping;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
painter->drawText(typename Metrics<T>::Rect(x + xinc, y, w - xinc, h), flags, curRichText.text);
|
painter->drawText(typename Metrics<T>::Rect(x + xinc, y, w - xinc, h), flags,
|
||||||
|
curRichText.text);
|
||||||
if (curRichText.highlight && curRichText.highlightColor.alpha()) {
|
if (curRichText.highlight && curRichText.highlightColor.alpha()) {
|
||||||
highlightPen.setColor(curRichText.highlightColor);
|
highlightPen.setColor(curRichText.highlightColor);
|
||||||
highlightPen.setWidth(curRichText.highlightWidth);
|
highlightPen.setWidth(curRichText.highlightWidth);
|
||||||
painter->setPen(highlightPen);
|
painter->setPen(highlightPen);
|
||||||
T highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1;
|
T highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1;
|
||||||
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1, x + xinc + backgroundWidth - 1,
|
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1,
|
||||||
y + h - 1);
|
x + xinc + backgroundWidth - 1, y + h - 1);
|
||||||
}
|
}
|
||||||
xinc += textWidth;
|
xinc += textWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template
|
template void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w,
|
||||||
void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w, qreal h, qreal xinc,
|
qreal h, qreal xinc, const List &richText,
|
||||||
const List &richText, CachedFontMetrics<qreal> *fontMetrics);
|
CachedFontMetrics<qreal> *fontMetrics);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other applications
|
* @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other
|
||||||
|
* applications
|
||||||
* @param richText The rich text to be converted to HTML format
|
* @param richText The rich text to be converted to HTML format
|
||||||
* @param textHtml The HTML source. Any previous content will be preserved and new content will be appended at the end.
|
* @param textHtml The HTML source. Any previous content will be preserved and new content will be
|
||||||
* @param textPlain The plain text. Any previous content will be preserved and new content will be appended at the end.
|
* appended at the end.
|
||||||
|
* @param textPlain The plain text. Any previous content will be preserved and new content will be
|
||||||
|
* appended at the end.
|
||||||
*/
|
*/
|
||||||
void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain)
|
void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain)
|
||||||
{
|
{
|
||||||
for (const CustomRichText_t &curRichText : richText) {
|
for (const CustomRichText_t &curRichText : richText) {
|
||||||
if (curRichText.text == " ") { //blank
|
if (curRichText.text == " ") { // blank
|
||||||
textHtml += " ";
|
textHtml += " ";
|
||||||
textPlain += " ";
|
textPlain += " ";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (curRichText.flags) {
|
switch (curRichText.flags) {
|
||||||
case FlagNone: //defaults
|
case FlagNone: // defaults
|
||||||
textHtml += "<span>";
|
textHtml += "<span>";
|
||||||
break;
|
break;
|
||||||
case FlagColor: //color only
|
case FlagColor: // color only
|
||||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||||
break;
|
break;
|
||||||
case FlagBackground: //background only
|
case FlagBackground: // background only
|
||||||
if (curRichText.textBackground !=
|
if (curRichText.textBackground
|
||||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
!= Qt::transparent) // QColor::name() returns "#000000" for transparent color.
|
||||||
textHtml += QString("<span style=\"background-color:%1\">").arg(curRichText.textBackground.name());
|
// That's not desired. Leave it blank.
|
||||||
|
textHtml += QString("<span style=\"background-color:%1\">")
|
||||||
|
.arg(curRichText.textBackground.name());
|
||||||
else
|
else
|
||||||
textHtml += QString("<span>");
|
textHtml += QString("<span>");
|
||||||
break;
|
break;
|
||||||
case FlagAll: //color+background
|
case FlagAll: // color+background
|
||||||
if (curRichText.textBackground !=
|
if (curRichText.textBackground
|
||||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
!= Qt::transparent) // QColor::name() returns "#000000" for transparent color.
|
||||||
textHtml += QString("<span style=\"color:%1; background-color:%2\">").arg(
|
// That's not desired. Leave it blank.
|
||||||
curRichText.textColor.name(), curRichText.textBackground.name());
|
textHtml += QString("<span style=\"color:%1; background-color:%2\">")
|
||||||
|
.arg(curRichText.textColor.name(),
|
||||||
|
curRichText.textBackground.name());
|
||||||
else
|
else
|
||||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (curRichText.highlight) //Underline highlighted token
|
if (curRichText.highlight) // Underline highlighted token
|
||||||
textHtml += "<u>";
|
textHtml += "<u>";
|
||||||
textHtml += curRichText.text.toHtmlEscaped();
|
textHtml += curRichText.text.toHtmlEscaped();
|
||||||
if (curRichText.highlight)
|
if (curRichText.highlight)
|
||||||
textHtml += "</u>";
|
textHtml += "</u>";
|
||||||
textHtml += "</span>"; //Close the tag
|
textHtml += "</span>"; // Close the tag
|
||||||
textPlain += curRichText.text;
|
textPlain += curRichText.text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,7 +191,8 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
|
|||||||
auto &text = r.back();
|
auto &text = r.back();
|
||||||
|
|
||||||
if (text.text.length() >= indicatorCropLength) {
|
if (text.text.length() >= indicatorCropLength) {
|
||||||
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength, indicator);
|
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength,
|
||||||
|
indicator);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,21 +10,18 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class QFontMetricsF;
|
class QFontMetricsF;
|
||||||
template<typename T> class CachedFontMetrics;
|
template<typename T>
|
||||||
|
class CachedFontMetrics;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
|
|
||||||
class RichTextPainter
|
class RichTextPainter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//structures
|
// structures
|
||||||
enum CustomRichTextFlags {
|
enum CustomRichTextFlags { FlagNone, FlagColor, FlagBackground, FlagAll };
|
||||||
FlagNone,
|
|
||||||
FlagColor,
|
|
||||||
FlagBackground,
|
|
||||||
FlagAll
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CustomRichText_t {
|
struct CustomRichText_t
|
||||||
|
{
|
||||||
QString text;
|
QString text;
|
||||||
QColor textColor;
|
QColor textColor;
|
||||||
QColor textBackground;
|
QColor textBackground;
|
||||||
@ -37,10 +34,10 @@ public:
|
|||||||
|
|
||||||
typedef std::vector<CustomRichText_t> List;
|
typedef std::vector<CustomRichText_t> List;
|
||||||
|
|
||||||
//functions
|
// functions
|
||||||
template<typename T = qreal>
|
template<typename T = qreal>
|
||||||
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
|
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText,
|
||||||
const List &richText, CachedFontMetrics<T> *fontMetrics);
|
CachedFontMetrics<T> *fontMetrics);
|
||||||
static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
|
static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
|
||||||
|
|
||||||
static List fromTextDocument(const QTextDocument &doc);
|
static List fromTextDocument(const QTextDocument &doc);
|
||||||
|
@ -33,10 +33,9 @@ void RizinTask::taskFinished()
|
|||||||
|
|
||||||
RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient)
|
RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient)
|
||||||
{
|
{
|
||||||
task = rz_core_cmd_task_new(Core()->core(),
|
task = rz_core_cmd_task_new(
|
||||||
cmd.toLocal8Bit().constData(),
|
Core()->core(), cmd.toLocal8Bit().constData(),
|
||||||
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback),
|
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback), this);
|
||||||
this);
|
|
||||||
task->transient = transient;
|
task->transient = transient;
|
||||||
rz_core_task_incref(task);
|
rz_core_task_incref(task);
|
||||||
}
|
}
|
||||||
@ -74,9 +73,8 @@ const char *RizinCmdTask::getResultRaw()
|
|||||||
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
|
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
|
||||||
: fcn(fcn), res(nullptr)
|
: fcn(fcn), res(nullptr)
|
||||||
{
|
{
|
||||||
task = rz_core_function_task_new(Core()->core(),
|
task = rz_core_function_task_new(
|
||||||
static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner),
|
Core()->core(), static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner), this);
|
||||||
this);
|
|
||||||
task->transient = transient;
|
task->transient = transient;
|
||||||
rz_core_task_incref(task);
|
rz_core_task_incref(task);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
|
|
||||||
class CUTTER_EXPORT RizinTask: public QObject
|
class CUTTER_EXPORT RizinTask : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ signals:
|
|||||||
void finished();
|
void finished();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CUTTER_EXPORT RizinCmdTask: public RizinTask
|
class CUTTER_EXPORT RizinCmdTask : public RizinTask
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ public:
|
|||||||
const char *getResultRaw();
|
const char *getResultRaw();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CUTTER_EXPORT RizinFunctionTask: public RizinTask
|
class CUTTER_EXPORT RizinFunctionTask : public RizinTask
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -2,14 +2,9 @@
|
|||||||
#include "common/RunScriptTask.h"
|
#include "common/RunScriptTask.h"
|
||||||
#include "core/MainWindow.h"
|
#include "core/MainWindow.h"
|
||||||
|
|
||||||
RunScriptTask::RunScriptTask() :
|
RunScriptTask::RunScriptTask() : AsyncTask() {}
|
||||||
AsyncTask()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunScriptTask::~RunScriptTask()
|
RunScriptTask::~RunScriptTask() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunScriptTask::interrupt()
|
void RunScriptTask::interrupt()
|
||||||
{
|
{
|
||||||
|
@ -12,13 +12,9 @@ public:
|
|||||||
explicit RunScriptTask();
|
explicit RunScriptTask();
|
||||||
~RunScriptTask();
|
~RunScriptTask();
|
||||||
|
|
||||||
QString getTitle() override {
|
QString getTitle() override { return tr("Run Script"); }
|
||||||
return tr("Run Script");
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFileName(const QString &fileName) {
|
void setFileName(const QString &fileName) { this->fileName = fileName; }
|
||||||
this->fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word)
|
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
|
||||||
|
const QString &word)
|
||||||
{
|
{
|
||||||
QList<QTextEdit::ExtraSelection> selections;
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
QTextEdit::ExtraSelection highlightSelection;
|
QTextEdit::ExtraSelection highlightSelection;
|
||||||
@ -23,8 +24,8 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
|
|||||||
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||||
|
|
||||||
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
|
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
|
||||||
highlightSelection.cursor = document->find(word, highlightSelection.cursor,
|
highlightSelection.cursor =
|
||||||
QTextDocument::FindWholeWords);
|
document->find(word, highlightSelection.cursor, QTextDocument::FindWholeWords);
|
||||||
|
|
||||||
if (!highlightSelection.cursor.isNull()) {
|
if (!highlightSelection.cursor.isNull()) {
|
||||||
highlightSelection.format.setBackground(highlightWordColor);
|
highlightSelection.format.setBackground(highlightWordColor);
|
||||||
@ -35,7 +36,6 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
|
|||||||
return selections;
|
return selections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor)
|
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor)
|
||||||
{
|
{
|
||||||
QTextEdit::ExtraSelection highlightSelection;
|
QTextEdit::ExtraSelection highlightSelection;
|
||||||
@ -52,7 +52,6 @@ QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor
|
|||||||
return createLineHighlight(cursor, highlightColor);
|
return createLineHighlight(cursor, highlightColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
|
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
|
||||||
{
|
{
|
||||||
QColor highlightColor = ConfigColor("highlightPC");
|
QColor highlightColor = ConfigColor("highlightPC");
|
||||||
|
@ -12,12 +12,14 @@ class QString;
|
|||||||
* @param word
|
* @param word
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word);
|
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
|
||||||
|
const QString &word);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief createLineHighlight
|
* @brief createLineHighlight
|
||||||
* @param cursor - a Cursor object represents the line to be highlighted
|
* @param cursor - a Cursor object represents the line to be highlighted
|
||||||
* @param highlightColor - the color to be used for highlighting. The color is decided by the callee for different usages (BP, PC, Current line, ...)
|
* @param highlightColor - the color to be used for highlighting. The color is decided by the callee
|
||||||
|
* for different usages (BP, PC, Current line, ...)
|
||||||
* @return ExtraSelection with highlighted line
|
* @return ExtraSelection with highlighted line
|
||||||
*/
|
*/
|
||||||
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);
|
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);
|
||||||
@ -43,4 +45,4 @@ QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor);
|
|||||||
*/
|
*/
|
||||||
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor);
|
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor);
|
||||||
|
|
||||||
#endif //CUTTER_SELECTIONHIGHLIGHT_H
|
#endif // CUTTER_SELECTIONHIGHLIGHT_H
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
static bool migrateSettingsPre18(QSettings &newSettings)
|
static bool migrateSettingsPre18(QSettings &newSettings)
|
||||||
{
|
{
|
||||||
if(newSettings.value("settings_migrated", false).toBool()) {
|
if (newSettings.value("settings_migrated", false).toBool()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QSettings oldSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, "Cutter", "Cutter");
|
QSettings oldSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, "Cutter", "Cutter");
|
||||||
@ -40,28 +40,30 @@ static bool migrateSettingsPre18(QSettings &newSettings)
|
|||||||
* This function takes care of migrating from EXACTLY version X-1 to X.
|
* This function takes care of migrating from EXACTLY version X-1 to X.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void migrateSettingsTo1(QSettings &settings) {
|
static void migrateSettingsTo1(QSettings &settings)
|
||||||
|
{
|
||||||
settings.remove("settings_migrated"); // now handled by version
|
settings.remove("settings_migrated"); // now handled by version
|
||||||
settings.remove("updated_custom_themes"); // now handled by theme_version
|
settings.remove("updated_custom_themes"); // now handled by theme_version
|
||||||
}
|
}
|
||||||
|
|
||||||
static void migrateSettingsTo2(QSettings &settings) {
|
static void migrateSettingsTo2(QSettings &settings)
|
||||||
|
{
|
||||||
QStringList docks = settings.value("docks").toStringList(); // get current list of docks
|
QStringList docks = settings.value("docks").toStringList(); // get current list of docks
|
||||||
// replace occurences of "PseudocodeWidget" with "DecompilerWidget"
|
// replace occurences of "PseudocodeWidget" with "DecompilerWidget"
|
||||||
settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget"));
|
settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void migrateSettingsTo3(QSettings &settings) {
|
static void migrateSettingsTo3(QSettings &settings)
|
||||||
|
{
|
||||||
auto defaultGeometry = settings.value("geometry").toByteArray();
|
auto defaultGeometry = settings.value("geometry").toByteArray();
|
||||||
auto defaultState = settings.value("state").toByteArray();
|
auto defaultState = settings.value("state").toByteArray();
|
||||||
|
|
||||||
auto debugGeometry = settings.value("debug.geometry").toByteArray();
|
auto debugGeometry = settings.value("debug.geometry").toByteArray();
|
||||||
auto debugState = settings.value("debug.state").toByteArray();
|
auto debugState = settings.value("debug.state").toByteArray();
|
||||||
|
|
||||||
|
|
||||||
const auto docks = settings.value("docks", QStringList()).toStringList();
|
const auto docks = settings.value("docks", QStringList()).toStringList();
|
||||||
auto unsyncList = settings.value("unsync", QStringList()).toStringList();
|
auto unsyncList = settings.value("unsync", QStringList()).toStringList();
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
QSet<QString> unsyncDocks = unsyncList.toSet();
|
QSet<QString> unsyncDocks = unsyncList.toSet();
|
||||||
#else
|
#else
|
||||||
QSet<QString> unsyncDocks(unsyncList.begin(), unsyncList.end());
|
QSet<QString> unsyncDocks(unsyncList.begin(), unsyncList.end());
|
||||||
@ -134,29 +136,35 @@ void Cutter::initializeSettings()
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt();
|
int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt();
|
||||||
if(settingsVersion == 0) {
|
if (settingsVersion == 0) {
|
||||||
migrateSettingsPre18(settings);
|
migrateSettingsPre18(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(settings.allKeys().length() > 0) {
|
if (settings.allKeys().length() > 0) {
|
||||||
if (settingsVersion > CUTTER_SETTINGS_VERSION_CURRENT) {
|
if (settingsVersion > CUTTER_SETTINGS_VERSION_CURRENT) {
|
||||||
qWarning() << "Settings have a higher version than current! Skipping migration.";
|
qWarning() << "Settings have a higher version than current! Skipping migration.";
|
||||||
} else if(settingsVersion >= 0) {
|
} else if (settingsVersion >= 0) {
|
||||||
for (int v = settingsVersion + 1; v <= CUTTER_SETTINGS_VERSION_CURRENT; v++) {
|
for (int v = settingsVersion + 1; v <= CUTTER_SETTINGS_VERSION_CURRENT; v++) {
|
||||||
qInfo() << "Migrating Settings to Version" << v;
|
qInfo() << "Migrating Settings to Version" << v;
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case 1:
|
case 1:
|
||||||
migrateSettingsTo1(settings); break;
|
migrateSettingsTo1(settings);
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
migrateSettingsTo2(settings); break;
|
migrateSettingsTo2(settings);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
migrateSettingsTo3(settings); break;
|
migrateSettingsTo3(settings);
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
migrateSettingsTo4(settings); break;
|
migrateSettingsTo4(settings);
|
||||||
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
migrateSettingsTo5(settings); break;
|
migrateSettingsTo5(settings);
|
||||||
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
migrateSettingsTo6(settings); break;
|
migrateSettingsTo6(settings);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -169,7 +177,8 @@ void Cutter::initializeSettings()
|
|||||||
#define THEME_VERSION_CURRENT 1
|
#define THEME_VERSION_CURRENT 1
|
||||||
#define THEME_VERSION_KEY "theme_version"
|
#define THEME_VERSION_KEY "theme_version"
|
||||||
|
|
||||||
static void removeObsoleteOptionsFromCustomThemes() {
|
static void removeObsoleteOptionsFromCustomThemes()
|
||||||
|
{
|
||||||
const QStringList options = Core()->cmdj("ecj").object().keys()
|
const QStringList options = Core()->cmdj("ecj").object().keys()
|
||||||
<< ColorThemeWorker::cutterSpecificOptions;
|
<< ColorThemeWorker::cutterSpecificOptions;
|
||||||
for (auto theme : Core()->cmdList("eco*")) {
|
for (auto theme : Core()->cmdList("eco*")) {
|
||||||
@ -179,7 +188,7 @@ static void removeObsoleteOptionsFromCustomThemes() {
|
|||||||
}
|
}
|
||||||
QJsonObject updatedTheme;
|
QJsonObject updatedTheme;
|
||||||
auto sch = ThemeWorker().getTheme(theme).object();
|
auto sch = ThemeWorker().getTheme(theme).object();
|
||||||
for (const auto& key : sch.keys()) {
|
for (const auto &key : sch.keys()) {
|
||||||
if (options.contains(key)) {
|
if (options.contains(key)) {
|
||||||
updatedTheme.insert(key, sch[key]);
|
updatedTheme.insert(key, sch[key]);
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include <core/Cutter.h>
|
#include <core/Cutter.h>
|
||||||
|
|
||||||
namespace Cutter {
|
namespace Cutter {
|
||||||
void initializeSettings();
|
void initializeSettings();
|
||||||
void migrateThemes();
|
void migrateThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMMON_SETTINGS_UPGRADE_H
|
#endif // COMMON_SETTINGS_UPGRADE_H
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class StringsTask : public AsyncTask
|
class StringsTask : public AsyncTask
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString getTitle() override { return tr("Searching for Strings"); }
|
QString getTitle() override { return tr("Searching for Strings"); }
|
||||||
@ -23,4 +23,4 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //STRINGSASYNCTASK_H
|
#endif // STRINGSASYNCTASK_H
|
||||||
|
@ -14,7 +14,8 @@ SvgIconEngine::SvgIconEngine(const QString &filename)
|
|||||||
this->svgData = file.readAll();
|
this->svgData = file.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor) : SvgIconEngine(filename)
|
SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor)
|
||||||
|
: SvgIconEngine(filename)
|
||||||
{
|
{
|
||||||
this->svgData = qhelpers::applyColorToSvg(svgData, tintColor);
|
this->svgData = qhelpers::applyColorToSvg(svgData, tintColor);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <QIconEngine>
|
#include <QIconEngine>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
|
|
||||||
class SvgIconEngine: public QIconEngine
|
class SvgIconEngine : public QIconEngine
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
QByteArray svgData;
|
QByteArray svgData;
|
||||||
@ -19,7 +19,6 @@ public:
|
|||||||
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
|
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
|
||||||
QIconEngine *clone() const override;
|
QIconEngine *clone() const override;
|
||||||
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override;
|
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SVGICONENGINE_H
|
#endif // SVGICONENGINE_H
|
||||||
|
@ -3,13 +3,15 @@
|
|||||||
|
|
||||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||||
|
|
||||||
#include "Configuration.h"
|
# include "Configuration.h"
|
||||||
|
|
||||||
#include <KSyntaxHighlighting/theme.h>
|
# include <KSyntaxHighlighting/theme.h>
|
||||||
|
|
||||||
SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document) : KSyntaxHighlighting::SyntaxHighlighter(document)
|
SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document)
|
||||||
|
: KSyntaxHighlighting::SyntaxHighlighter(document)
|
||||||
{
|
{
|
||||||
connect(Config(), &Configuration::kSyntaxHighlightingThemeChanged, this, &SyntaxHighlighter::updateTheme);
|
connect(Config(), &Configuration::kSyntaxHighlightingThemeChanged, this,
|
||||||
|
&SyntaxHighlighter::updateTheme);
|
||||||
updateTheme();
|
updateTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,38 +23,56 @@ void SyntaxHighlighter::updateTheme()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
||||||
: QSyntaxHighlighter(parent)
|
: QSyntaxHighlighter(parent), commentStartExpression("/\\*"), commentEndExpression("\\*/")
|
||||||
, commentStartExpression("/\\*")
|
|
||||||
, commentEndExpression("\\*/")
|
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
HighlightingRule rule;
|
||||||
QStringList keywordPatterns;
|
QStringList keywordPatterns;
|
||||||
|
|
||||||
//C language keywords
|
// C language keywords
|
||||||
keywordPatterns << "\\bauto\\b" << "\\bdouble\\b" << "\\bint\\b"
|
keywordPatterns << "\\bauto\\b"
|
||||||
<< "\\bstruct\\b" << "\\bbreak\\b" << "\\belse\\b"
|
<< "\\bdouble\\b"
|
||||||
<< "\\blong\\b" << "\\switch\\b" << "\\bcase\\b"
|
<< "\\bint\\b"
|
||||||
<< "\\benum\\b" << "\\bregister\\b" << "\\btypedef\\b"
|
<< "\\bstruct\\b"
|
||||||
<< "\\bchar\\b" << "\\bextern\\b" << "\\breturn\\b"
|
<< "\\bbreak\\b"
|
||||||
<< "\\bunion\\b" << "\\bconst\\b" << "\\bfloat\\b"
|
<< "\\belse\\b"
|
||||||
<< "\\bshort\\b" << "\\bunsigned\\b" << "\\bcontinue\\b"
|
<< "\\blong\\b"
|
||||||
<< "\\bfor\\b" << "\\bsigned\\b" << "\\bvoid\\b"
|
<< "\\switch\\b"
|
||||||
<< "\\bdefault\\b" << "\\bgoto\\b" << "\\bsizeof\\b"
|
<< "\\bcase\\b"
|
||||||
<< "\\bvolatile\\b" << "\\bdo\\b" << "\\bif\\b"
|
<< "\\benum\\b"
|
||||||
<< "\\static\\b" << "\\while\\b";
|
<< "\\bregister\\b"
|
||||||
|
<< "\\btypedef\\b"
|
||||||
|
<< "\\bchar\\b"
|
||||||
|
<< "\\bextern\\b"
|
||||||
|
<< "\\breturn\\b"
|
||||||
|
<< "\\bunion\\b"
|
||||||
|
<< "\\bconst\\b"
|
||||||
|
<< "\\bfloat\\b"
|
||||||
|
<< "\\bshort\\b"
|
||||||
|
<< "\\bunsigned\\b"
|
||||||
|
<< "\\bcontinue\\b"
|
||||||
|
<< "\\bfor\\b"
|
||||||
|
<< "\\bsigned\\b"
|
||||||
|
<< "\\bvoid\\b"
|
||||||
|
<< "\\bdefault\\b"
|
||||||
|
<< "\\bgoto\\b"
|
||||||
|
<< "\\bsizeof\\b"
|
||||||
|
<< "\\bvolatile\\b"
|
||||||
|
<< "\\bdo\\b"
|
||||||
|
<< "\\bif\\b"
|
||||||
|
<< "\\static\\b"
|
||||||
|
<< "\\while\\b";
|
||||||
|
|
||||||
QTextCharFormat keywordFormat;
|
QTextCharFormat keywordFormat;
|
||||||
keywordFormat.setForeground(QColor(80, 200, 215));
|
keywordFormat.setForeground(QColor(80, 200, 215));
|
||||||
|
|
||||||
for ( const auto &pattern : keywordPatterns ) {
|
for (const auto &pattern : keywordPatterns) {
|
||||||
rule.pattern.setPattern(pattern);
|
rule.pattern.setPattern(pattern);
|
||||||
rule.format = keywordFormat;
|
rule.format = keywordFormat;
|
||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Functions
|
// Functions
|
||||||
rule.pattern.setPattern("\\b[A-Za-z0-9_]+(?=\\()");
|
rule.pattern.setPattern("\\b[A-Za-z0-9_]+(?=\\()");
|
||||||
rule.format.clearBackground();
|
rule.format.clearBackground();
|
||||||
rule.format.clearForeground();
|
rule.format.clearForeground();
|
||||||
@ -60,14 +80,14 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
|||||||
rule.format.setForeground(Qt::darkCyan);
|
rule.format.setForeground(Qt::darkCyan);
|
||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
//single-line comment
|
// single-line comment
|
||||||
rule.pattern.setPattern("//[^\n]*");
|
rule.pattern.setPattern("//[^\n]*");
|
||||||
rule.format.clearBackground();
|
rule.format.clearBackground();
|
||||||
rule.format.clearForeground();
|
rule.format.clearForeground();
|
||||||
rule.format.setForeground(Qt::gray);
|
rule.format.setForeground(Qt::gray);
|
||||||
highlightingRules.append(rule);
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
//quotation
|
// quotation
|
||||||
rule.pattern.setPattern("\".*\"");
|
rule.pattern.setPattern("\".*\"");
|
||||||
rule.format.clearBackground();
|
rule.format.clearBackground();
|
||||||
rule.format.clearForeground();
|
rule.format.clearForeground();
|
||||||
@ -79,7 +99,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
|||||||
|
|
||||||
void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
|
void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
|
||||||
{
|
{
|
||||||
for ( const auto &it : highlightingRules ) {
|
for (const auto &it : highlightingRules) {
|
||||||
auto matchIterator = it.pattern.globalMatch(text);
|
auto matchIterator = it.pattern.globalMatch(text);
|
||||||
while (matchIterator.hasNext()) {
|
while (matchIterator.hasNext()) {
|
||||||
const auto match = matchIterator.next();
|
const auto match = matchIterator.next();
|
||||||
@ -103,8 +123,7 @@ void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
|
|||||||
setCurrentBlockState(1);
|
setCurrentBlockState(1);
|
||||||
commentLength = text.length() - startIndex;
|
commentLength = text.length() - startIndex;
|
||||||
} else {
|
} else {
|
||||||
commentLength = endIndex - startIndex
|
commentLength = endIndex - startIndex + match.capturedLength();
|
||||||
+ match.capturedLength();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||||
|
|
||||||
#include <KSyntaxHighlighting/syntaxhighlighter.h>
|
# include <KSyntaxHighlighting/syntaxhighlighter.h>
|
||||||
|
|
||||||
class SyntaxHighlighter : public KSyntaxHighlighting::SyntaxHighlighter
|
class SyntaxHighlighter : public KSyntaxHighlighting::SyntaxHighlighter
|
||||||
{
|
{
|
||||||
@ -40,7 +40,8 @@ protected:
|
|||||||
void highlightBlock(const QString &text) override;
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct HighlightingRule {
|
struct HighlightingRule
|
||||||
|
{
|
||||||
QRegularExpression pattern;
|
QRegularExpression pattern;
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
};
|
};
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Class for temporary modifying Rizin `e` configuration.
|
* @brief Class for temporary modifying Rizin `e` configuration.
|
||||||
*
|
*
|
||||||
* Modified values will be restored at the end of scope. This is useful when using a Rizin command that can only
|
* Modified values will be restored at the end of scope. This is useful when using a Rizin command
|
||||||
* be configured using `e` configuration and doesn't accept arguments. TempConfig::set calls can be chained.
|
* that can only be configured using `e` configuration and doesn't accept arguments. TempConfig::set
|
||||||
* If a command or Rizin method accepts arguments directly it is preferred to use those instead of temporary modifying
|
* calls can be chained. If a command or Rizin method accepts arguments directly it is preferred to
|
||||||
* global configuration.
|
* use those instead of temporary modifying global configuration.
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* {
|
* {
|
||||||
@ -36,9 +36,9 @@ public:
|
|||||||
TempConfig &set(const QString &key, bool value);
|
TempConfig &set(const QString &key, bool value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TempConfig(const TempConfig&) = delete;
|
TempConfig(const TempConfig &) = delete;
|
||||||
TempConfig &operator=(const TempConfig&) = delete;
|
TempConfig &operator=(const TempConfig &) = delete;
|
||||||
QMap<QString, QVariant> resetValues;
|
QMap<QString, QVariant> resetValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //TEMPCONFIG_H
|
#endif // TEMPCONFIG_H
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
#include "UpdateWorker.h"
|
#include "UpdateWorker.h"
|
||||||
|
|
||||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
#include <QUrl>
|
# include <QUrl>
|
||||||
#include <QFile>
|
# include <QFile>
|
||||||
#include <QTimer>
|
# include <QTimer>
|
||||||
#include <QEventLoop>
|
# include <QEventLoop>
|
||||||
#include <QDataStream>
|
# include <QDataStream>
|
||||||
#include <QJsonObject>
|
# include <QJsonObject>
|
||||||
#include <QApplication>
|
# include <QApplication>
|
||||||
#include <QJsonDocument>
|
# include <QJsonDocument>
|
||||||
#include <QDesktopServices>
|
# include <QDesktopServices>
|
||||||
#include <QtNetwork/QNetworkReply>
|
# include <QtNetwork/QNetworkReply>
|
||||||
#include <QtNetwork/QNetworkRequest>
|
# include <QtNetwork/QNetworkRequest>
|
||||||
|
|
||||||
#include <QProgressDialog>
|
# include <QProgressDialog>
|
||||||
#include <QPushButton>
|
# include <QPushButton>
|
||||||
#include <QFileDialog>
|
# include <QFileDialog>
|
||||||
#include <QMessageBox>
|
# include <QMessageBox>
|
||||||
#include "common/Configuration.h"
|
# include "common/Configuration.h"
|
||||||
#include "CutterConfig.h"
|
# include "CutterConfig.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
UpdateWorker::UpdateWorker(QObject *parent) :
|
UpdateWorker::UpdateWorker(QObject *parent) : QObject(parent), pending(false)
|
||||||
QObject(parent), pending(false)
|
|
||||||
{
|
{
|
||||||
connect(&t, &QTimer::timeout, this, [this]() {
|
connect(&t, &QTimer::timeout, this, [this]() {
|
||||||
if (pending) {
|
if (pending) {
|
||||||
disconnect(checkReply, nullptr, this, nullptr);
|
disconnect(checkReply, nullptr, this, nullptr);
|
||||||
checkReply->close();
|
checkReply->close();
|
||||||
checkReply->deleteLater();
|
checkReply->deleteLater();
|
||||||
emit checkComplete(QVersionNumber(), tr("Time limit exceeded during version check. Please check your "
|
emit checkComplete(QVersionNumber(),
|
||||||
|
tr("Time limit exceeded during version check. Please check your "
|
||||||
"internet connection and try again."));
|
"internet connection and try again."));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -47,8 +47,7 @@ void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
|
|||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
checkReply = nm.get(request);
|
checkReply = nm.get(request);
|
||||||
connect(checkReply, &QNetworkReply::finished,
|
connect(checkReply, &QNetworkReply::finished, this, &UpdateWorker::serveVersionCheckReply);
|
||||||
this, &UpdateWorker::serveVersionCheckReply);
|
|
||||||
pending = true;
|
pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,26 +59,27 @@ void UpdateWorker::download(QString filename, QString version)
|
|||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
QUrl url(QString("https://github.com/rizinorg/cutter/releases/"
|
QUrl url(QString("https://github.com/rizinorg/cutter/releases/"
|
||||||
"download/v%1/%2").arg(version).arg(getRepositoryFileName()));
|
"download/v%1/%2")
|
||||||
|
.arg(version)
|
||||||
|
.arg(getRepositoryFileName()));
|
||||||
request.setUrl(url);
|
request.setUrl(url);
|
||||||
|
|
||||||
downloadReply = nm.get(request);
|
downloadReply = nm.get(request);
|
||||||
connect(downloadReply, &QNetworkReply::downloadProgress,
|
connect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
|
||||||
this, &UpdateWorker::process);
|
connect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
|
||||||
connect(downloadReply, &QNetworkReply::finished,
|
|
||||||
this, &UpdateWorker::serveDownloadFinish);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
||||||
{
|
{
|
||||||
QMessageBox mb;
|
QMessageBox mb;
|
||||||
mb.setWindowTitle(tr("Version control"));
|
mb.setWindowTitle(tr("Version control"));
|
||||||
mb.setText(tr("There is an update available for Cutter.<br/>")
|
mb.setText(tr("There is an update available for Cutter.<br/>") + "<b>" + tr("Current version:")
|
||||||
+ "<b>" + tr("Current version:") + "</b> " CUTTER_VERSION_FULL "<br/>"
|
+ "</b> " CUTTER_VERSION_FULL "<br/>" + "<b>" + tr("Latest version:") + "</b> "
|
||||||
+ "<b>" + tr("Latest version:") + "</b> " + latestVersion.toString() + "<br/><br/>"
|
+ latestVersion.toString() + "<br/><br/>"
|
||||||
+ tr("For update, please check the link:<br/>")
|
+ tr("For update, please check the link:<br/>")
|
||||||
+ QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">"
|
+ QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">"
|
||||||
"https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>").arg(latestVersion.toString())
|
"https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>")
|
||||||
|
.arg(latestVersion.toString())
|
||||||
+ tr("or click \"Download\" to download latest version of Cutter."));
|
+ tr("or click \"Download\" to download latest version of Cutter."));
|
||||||
if (showDontCheckForUpdatesButton) {
|
if (showDontCheckForUpdatesButton) {
|
||||||
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok);
|
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok);
|
||||||
@ -93,31 +93,23 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
|||||||
if (ret == QMessageBox::Reset) {
|
if (ret == QMessageBox::Reset) {
|
||||||
Config()->setAutoUpdateEnabled(false);
|
Config()->setAutoUpdateEnabled(false);
|
||||||
} else if (ret == QMessageBox::Save) {
|
} else if (ret == QMessageBox::Save) {
|
||||||
QString fullFileName =
|
QString fullFileName = QFileDialog::getSaveFileName(
|
||||||
QFileDialog::getSaveFileName(nullptr,
|
nullptr, tr("Choose directory for downloading"),
|
||||||
tr("Choose directory for downloading"),
|
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator()
|
||||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
|
+ getRepositoryFileName(),
|
||||||
QDir::separator() + getRepositoryFileName(),
|
|
||||||
QString("%1 (*.%1)").arg(getRepositeryExt()));
|
QString("%1 (*.%1)").arg(getRepositeryExt()));
|
||||||
if (!fullFileName.isEmpty()) {
|
if (!fullFileName.isEmpty()) {
|
||||||
QProgressDialog progressDial(tr("Downloading update..."),
|
QProgressDialog progressDial(tr("Downloading update..."), tr("Cancel"), 0, 100);
|
||||||
tr("Cancel"),
|
|
||||||
0, 100);
|
|
||||||
connect(this, &UpdateWorker::downloadProcess, &progressDial,
|
connect(this, &UpdateWorker::downloadProcess, &progressDial,
|
||||||
[&progressDial](size_t curr, size_t total) {
|
[&progressDial](size_t curr, size_t total) {
|
||||||
progressDial.setValue(100.0f * curr / total);
|
progressDial.setValue(100.0f * curr / total);
|
||||||
});
|
});
|
||||||
connect(&progressDial, &QProgressDialog::canceled,
|
connect(&progressDial, &QProgressDialog::canceled, this, &UpdateWorker::abortDownload);
|
||||||
this, &UpdateWorker::abortDownload);
|
connect(this, &UpdateWorker::downloadFinished, &progressDial, &QProgressDialog::cancel);
|
||||||
connect(this, &UpdateWorker::downloadFinished,
|
connect(this, &UpdateWorker::downloadFinished, this, [](QString filePath) {
|
||||||
&progressDial, &QProgressDialog::cancel);
|
QMessageBox info(QMessageBox::Information, tr("Download finished!"),
|
||||||
connect(this, &UpdateWorker::downloadFinished, this,
|
|
||||||
[](QString filePath){
|
|
||||||
QMessageBox info(QMessageBox::Information,
|
|
||||||
tr("Download finished!"),
|
|
||||||
tr("Latest version of Cutter was succesfully downloaded!"),
|
tr("Latest version of Cutter was succesfully downloaded!"),
|
||||||
QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok,
|
QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok, nullptr);
|
||||||
nullptr);
|
|
||||||
info.button(QMessageBox::Open)->setText(tr("Open file"));
|
info.button(QMessageBox::Open)->setText(tr("Open file"));
|
||||||
info.button(QMessageBox::Yes)->setText(tr("Open download folder"));
|
info.button(QMessageBox::Yes)->setText(tr("Open download folder"));
|
||||||
int r = info.exec();
|
int r = info.exec();
|
||||||
@ -140,10 +132,8 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
|||||||
|
|
||||||
void UpdateWorker::abortDownload()
|
void UpdateWorker::abortDownload()
|
||||||
{
|
{
|
||||||
disconnect(downloadReply, &QNetworkReply::finished,
|
disconnect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
|
||||||
this, &UpdateWorker::serveDownloadFinish);
|
disconnect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
|
||||||
disconnect(downloadReply, &QNetworkReply::downloadProgress,
|
|
||||||
this, &UpdateWorker::process);
|
|
||||||
downloadReply->close();
|
downloadReply->close();
|
||||||
downloadReply->deleteLater();
|
downloadReply->deleteLater();
|
||||||
downloadFile.remove();
|
downloadFile.remove();
|
||||||
@ -157,7 +147,10 @@ void UpdateWorker::serveVersionCheckReply()
|
|||||||
if (checkReply->error()) {
|
if (checkReply->error()) {
|
||||||
errStr = checkReply->errorString();
|
errStr = checkReply->errorString();
|
||||||
} else {
|
} else {
|
||||||
versionReplyStr = QJsonDocument::fromJson(checkReply->readAll()).object().value("tag_name").toString();
|
versionReplyStr = QJsonDocument::fromJson(checkReply->readAll())
|
||||||
|
.object()
|
||||||
|
.value("tag_name")
|
||||||
|
.toString();
|
||||||
versionReplyStr.remove('v');
|
versionReplyStr.remove('v');
|
||||||
}
|
}
|
||||||
QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
|
QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
|
||||||
@ -188,30 +181,28 @@ void UpdateWorker::process(size_t bytesReceived, size_t bytesTotal)
|
|||||||
|
|
||||||
QString UpdateWorker::getRepositeryExt() const
|
QString UpdateWorker::getRepositeryExt() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
# ifdef Q_OS_LINUX
|
||||||
return "AppImage";
|
return "AppImage";
|
||||||
#elif defined (Q_OS_WIN64) || defined (Q_OS_WIN32)
|
# elif defined(Q_OS_WIN64) || defined(Q_OS_WIN32)
|
||||||
return "zip";
|
return "zip";
|
||||||
#elif defined (Q_OS_MACOS)
|
# elif defined(Q_OS_MACOS)
|
||||||
return "dmg";
|
return "dmg";
|
||||||
#endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UpdateWorker::getRepositoryFileName() const
|
QString UpdateWorker::getRepositoryFileName() const
|
||||||
{
|
{
|
||||||
QString downloadFileName;
|
QString downloadFileName;
|
||||||
#ifdef Q_OS_LINUX
|
# ifdef Q_OS_LINUX
|
||||||
downloadFileName = "Cutter-v%1-x%2.Linux.AppImage";
|
downloadFileName = "Cutter-v%1-x%2.Linux.AppImage";
|
||||||
#elif defined (Q_OS_WIN64) || defined (Q_OS_WIN32)
|
# elif defined(Q_OS_WIN64) || defined(Q_OS_WIN32)
|
||||||
downloadFileName = "Cutter-v%1-x%2.Windows.zip";
|
downloadFileName = "Cutter-v%1-x%2.Windows.zip";
|
||||||
#elif defined (Q_OS_MACOS)
|
# elif defined(Q_OS_MACOS)
|
||||||
downloadFileName = "Cutter-v%1-x%2.macOS.dmg";
|
downloadFileName = "Cutter-v%1-x%2.macOS.dmg";
|
||||||
#endif
|
# endif
|
||||||
downloadFileName = downloadFileName
|
downloadFileName =
|
||||||
.arg(latestVersion.toString())
|
downloadFileName.arg(latestVersion.toString())
|
||||||
.arg(QSysInfo::buildAbi().split('-').at(2).contains("64")
|
.arg(QSysInfo::buildAbi().split('-').at(2).contains("64") ? "64" : "32");
|
||||||
? "64"
|
|
||||||
: "32");
|
|
||||||
|
|
||||||
return downloadFileName;
|
return downloadFileName;
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||||
#define CUTTER_UPDATE_WORKER_AVAILABLE 1
|
# define CUTTER_UPDATE_WORKER_AVAILABLE 1
|
||||||
#else
|
#else
|
||||||
#define CUTTER_UPDATE_WORKER_AVAILABLE 0
|
# define CUTTER_UPDATE_WORKER_AVAILABLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
#include <QDir>
|
# include <QDir>
|
||||||
#include <QTimer>
|
# include <QTimer>
|
||||||
#include <QObject>
|
# include <QObject>
|
||||||
#include <QtNetwork/QNetworkAccessManager>
|
# include <QtNetwork/QNetworkAccessManager>
|
||||||
|
|
||||||
#include <QVersionNumber>
|
# include <QVersionNumber>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
@ -68,7 +68,8 @@ public:
|
|||||||
void showUpdateDialog(bool showDontCheckForUpdatesButton);
|
void showUpdateDialog(bool showDontCheckForUpdatesButton);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the version of this Cutter binary, derived from CUTTER_VERSION_MAJOR, CUTTER_VERSION_MINOR and CUTTER_VERSION_PATCH.
|
* @return the version of this Cutter binary, derived from CUTTER_VERSION_MAJOR,
|
||||||
|
* CUTTER_VERSION_MINOR and CUTTER_VERSION_PATCH.
|
||||||
*/
|
*/
|
||||||
static QVersionNumber currentVersionNumber();
|
static QVersionNumber currentVersionNumber();
|
||||||
|
|
||||||
@ -102,7 +103,6 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void downloadProcess(size_t bytesReceived, size_t bytesTotal);
|
void downloadProcess(size_t bytesReceived, size_t bytesTotal);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fn UpdateWorker::downloadFinished(QString filename)
|
* @fn UpdateWorker::downloadFinished(QString filename)
|
||||||
*
|
*
|
||||||
@ -138,5 +138,5 @@ private:
|
|||||||
QNetworkReply *checkReply;
|
QNetworkReply *checkReply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CUTTER_UPDATE_WORKER_AVAILABLE
|
#endif // CUTTER_UPDATE_WORKER_AVAILABLE
|
||||||
#endif // UPDATEWORKER_H
|
#endif // UPDATEWORKER_H
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@ class RizinTaskDialog;
|
|||||||
|
|
||||||
class RzCoreLocked;
|
class RzCoreLocked;
|
||||||
|
|
||||||
class CUTTER_EXPORT CutterCore: public QObject
|
class CUTTER_EXPORT CutterCore : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -75,12 +75,17 @@ public:
|
|||||||
* If you want to seek to an address, you should use CutterCore::seek.
|
* If you want to seek to an address, you should use CutterCore::seek.
|
||||||
*/
|
*/
|
||||||
bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task);
|
bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task);
|
||||||
bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task) { return asyncCmd(str.toUtf8().constData(), task); }
|
bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task)
|
||||||
|
{
|
||||||
|
return asyncCmd(str.toUtf8().constData(), task);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a Rizin command \a cmd. By nature, the API
|
* @brief Execute a Rizin command \a cmd. By nature, the API
|
||||||
* is executing raw commands, and thus ignores multiple commands and overcome command injections.
|
* is executing raw commands, and thus ignores multiple commands and overcome command
|
||||||
* @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf") will result in them treated as arguments to first command.
|
* injections.
|
||||||
|
* @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf")
|
||||||
|
* will result in them treated as arguments to first command.
|
||||||
* @return the output of the command
|
* @return the output of the command
|
||||||
*/
|
*/
|
||||||
QString cmdRaw(const char *cmd);
|
QString cmdRaw(const char *cmd);
|
||||||
@ -91,12 +96,12 @@ public:
|
|||||||
QString cmdRaw(const QString &cmd) { return cmdRaw(cmd.toUtf8().constData()); };
|
QString cmdRaw(const QString &cmd) { return cmdRaw(cmd.toUtf8().constData()); };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a Rizin command \a cmd at \a address. The function will preform a silent seek to the address
|
* @brief Execute a Rizin command \a cmd at \a address. The function will preform a silent seek
|
||||||
* without triggering the seekChanged event nor adding new entries to the seek history. By nature, the
|
* to the address without triggering the seekChanged event nor adding new entries to the seek
|
||||||
* API is executing a single command without going through Rizin shell, and thus ignores multiple commands
|
* history. By nature, the API is executing a single command without going through Rizin shell,
|
||||||
* and tries to overcome command injections.
|
* and thus ignores multiple commands and tries to overcome command injections.
|
||||||
* @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then
|
* @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7
|
||||||
* only the first command will be executed.
|
* && pdf") then only the first command will be executed.
|
||||||
* @param address - an address to which Cutter will temporarily seek.
|
* @param address - an address to which Cutter will temporarily seek.
|
||||||
* @return the output of the command
|
* @return the output of the command
|
||||||
*/
|
*/
|
||||||
@ -105,12 +110,18 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief a wrapper around cmdRawAt(const char *cmd, RVA address).
|
* @brief a wrapper around cmdRawAt(const char *cmd, RVA address).
|
||||||
*/
|
*/
|
||||||
QString cmdRawAt(const QString &str, RVA address) { return cmdRawAt(str.toUtf8().constData(), address); }
|
QString cmdRawAt(const QString &str, RVA address)
|
||||||
|
{
|
||||||
|
return cmdRawAt(str.toUtf8().constData(), address);
|
||||||
|
}
|
||||||
|
|
||||||
QJsonDocument cmdj(const char *str);
|
QJsonDocument cmdj(const char *str);
|
||||||
QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
||||||
QJsonDocument cmdjAt(const char *str, RVA address);
|
QJsonDocument cmdjAt(const char *str, RVA address);
|
||||||
QStringList cmdList(const char *str) { return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS); }
|
QStringList cmdList(const char *str)
|
||||||
|
{
|
||||||
|
return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS);
|
||||||
|
}
|
||||||
QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); }
|
QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); }
|
||||||
QString cmdTask(const QString &str);
|
QString cmdTask(const QString &str);
|
||||||
QJsonDocument cmdjTask(const QString &str);
|
QJsonDocument cmdjTask(const QString &str);
|
||||||
@ -132,7 +143,10 @@ public:
|
|||||||
* If you want to seek to an address, you should use CutterCore::seek.
|
* If you want to seek to an address, you should use CutterCore::seek.
|
||||||
*/
|
*/
|
||||||
bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task);
|
bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task);
|
||||||
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task) { return asyncCmdEsil(command.toUtf8().constData(), task); }
|
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task)
|
||||||
|
{
|
||||||
|
return asyncCmdEsil(command.toUtf8().constData(), task);
|
||||||
|
}
|
||||||
QString getVersionInformation();
|
QString getVersionInformation();
|
||||||
|
|
||||||
QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
|
QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
|
||||||
@ -253,7 +267,8 @@ public:
|
|||||||
void renameClass(const QString &oldName, const QString &newName);
|
void renameClass(const QString &oldName, const QString &newName);
|
||||||
void deleteClass(const QString &cls);
|
void deleteClass(const QString &cls);
|
||||||
bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc);
|
bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc);
|
||||||
void renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName);
|
void renameAnalMethod(const QString &className, const QString &oldMethodName,
|
||||||
|
const QString &newMethodName);
|
||||||
void setAnalMethod(const QString &cls, const AnalMethodDescription &meth);
|
void setAnalMethod(const QString &cls, const AnalMethodDescription &meth);
|
||||||
|
|
||||||
/* File related methods */
|
/* File related methods */
|
||||||
@ -445,7 +460,8 @@ public:
|
|||||||
* Register a new decompiler
|
* Register a new decompiler
|
||||||
*
|
*
|
||||||
* The decompiler must have a unique id, otherwise this method will fail.
|
* The decompiler must have a unique id, otherwise this method will fail.
|
||||||
* The decompiler's parent will be set to this CutterCore instance, so it will automatically be freed later.
|
* The decompiler's parent will be set to this CutterCore instance, so it will automatically be
|
||||||
|
* freed later.
|
||||||
*
|
*
|
||||||
* @return whether the decompiler was registered successfully
|
* @return whether the decompiler was registered successfully
|
||||||
*/
|
*/
|
||||||
@ -536,7 +552,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
QString getTypeAsC(QString name, QString category);
|
QString getTypeAsC(QString name, QString category);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds new types
|
* @brief Adds new types
|
||||||
* It first uses the rz_parse_c_string() function from Rizin API to parse the
|
* It first uses the rz_parse_c_string() function from Rizin API to parse the
|
||||||
@ -572,11 +587,12 @@ public:
|
|||||||
* @brief Fetches all the writes or reads to the specified local variable 'variableName'
|
* @brief Fetches all the writes or reads to the specified local variable 'variableName'
|
||||||
* in the function in which the specified offset is a part of.
|
* in the function in which the specified offset is a part of.
|
||||||
* @param variableName Name of the local variable.
|
* @param variableName Name of the local variable.
|
||||||
* @param findWrites If this is true, then locations at which modification happen to the specified
|
* @param findWrites If this is true, then locations at which modification happen to the
|
||||||
* local variable is fetched. Else, the locations at which the local is variable is read is fetched.
|
* specified local variable is fetched. Else, the locations at which the local is variable is
|
||||||
|
* read is fetched.
|
||||||
* @param offset An offset in the function in which the specified local variable exist.
|
* @param offset An offset in the function in which the specified local variable exist.
|
||||||
* @return A list of XrefDescriptions that contains details of all the writes or reads that happen to the
|
* @return A list of XrefDescriptions that contains details of all the writes or reads that
|
||||||
* variable 'variableName'.
|
* happen to the variable 'variableName'.
|
||||||
*/
|
*/
|
||||||
QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset);
|
QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset);
|
||||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
|
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
|
||||||
@ -622,9 +638,9 @@ public:
|
|||||||
void commitWriteCache();
|
void commitWriteCache();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it will be immediately
|
* @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it
|
||||||
* committed to the file on disk, thus modify the file. This function wrap Rizin function which re-open the file with
|
* will be immediately committed to the file on disk, thus modify the file. This function wrap
|
||||||
* the desired permissions.
|
* Rizin function which re-open the file with the desired permissions.
|
||||||
* @param enabled
|
* @param enabled
|
||||||
*/
|
*/
|
||||||
void setWriteMode(bool enabled);
|
void setWriteMode(bool enabled);
|
||||||
@ -732,7 +748,7 @@ private:
|
|||||||
|
|
||||||
class CUTTER_EXPORT RzCoreLocked
|
class CUTTER_EXPORT RzCoreLocked
|
||||||
{
|
{
|
||||||
CutterCore * const core;
|
CutterCore *const core;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RzCoreLocked(CutterCore *core);
|
explicit RzCoreLocked(CutterCore *core);
|
||||||
|
@ -10,17 +10,20 @@
|
|||||||
|
|
||||||
// Workaround for compile errors on Windows
|
// Workaround for compile errors on Windows
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#undef min
|
# undef min
|
||||||
#undef max
|
# undef max
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
// Rizin list iteration macros
|
// Rizin list iteration macros
|
||||||
#define CutterRListForeach(list, it, type, x) \
|
#define CutterRListForeach(list, it, type, x) \
|
||||||
if (list) for (it = list->head; it && ((x=static_cast<type*>(it->data))); it = it->n)
|
if (list) \
|
||||||
|
for (it = list->head; it && ((x = static_cast<type *>(it->data))); it = it->n)
|
||||||
|
|
||||||
#define CutterRVectorForeach(vec, it, type) \
|
#define CutterRVectorForeach(vec, it, type) \
|
||||||
if ((vec) && (vec)->a) \
|
if ((vec) && (vec)->a) \
|
||||||
for (it = (type *)(vec)->a; (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); it = (type *)((char *)it + (vec)->elem_size))
|
for (it = (type *)(vec)->a; \
|
||||||
|
(char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); \
|
||||||
|
it = (type *)((char *)it + (vec)->elem_size))
|
||||||
|
|
||||||
// Global information for Cutter
|
// Global information for Cutter
|
||||||
#define APPNAME "Cutter"
|
#define APPNAME "Cutter"
|
||||||
@ -31,7 +34,8 @@
|
|||||||
typedef ut64 RVA;
|
typedef ut64 RVA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum value of RVA. Do NOT use this for specifying invalid values, use RVA_INVALID instead.
|
* @brief Maximum value of RVA. Do NOT use this for specifying invalid values, use RVA_INVALID
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
#define RVA_MAX UT64_MAX
|
#define RVA_MAX UT64_MAX
|
||||||
|
|
||||||
@ -56,20 +60,18 @@ inline QString RHexString(RVA size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CUTTER_SOURCE_BUILD
|
#ifdef CUTTER_SOURCE_BUILD
|
||||||
#define CUTTER_EXPORT Q_DECL_EXPORT
|
# define CUTTER_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
#define CUTTER_EXPORT Q_DECL_IMPORT
|
# define CUTTER_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(__has_cpp_attribute)
|
#if defined(__has_cpp_attribute)
|
||||||
#if __has_cpp_attribute(deprecated)
|
# if __has_cpp_attribute(deprecated)
|
||||||
#define CUTTER_DEPRECATED(msg) [[deprecated(msg)]]
|
# define CUTTER_DEPRECATED(msg) [[deprecated(msg)]]
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CUTTER_DEPRECATED)
|
#if !defined(CUTTER_DEPRECATED)
|
||||||
#define CUTTER_DEPRECATED(msg)
|
# define CUTTER_DEPRECATED(msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // CUTTERCORE_H
|
#endif // CUTTERCORE_H
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include "core/CutterCommon.h"
|
#include "core/CutterCommon.h"
|
||||||
|
|
||||||
struct FunctionDescription {
|
struct FunctionDescription
|
||||||
|
{
|
||||||
RVA offset;
|
RVA offset;
|
||||||
RVA linearSize;
|
RVA linearSize;
|
||||||
RVA nargs;
|
RVA nargs;
|
||||||
@ -31,7 +32,8 @@ struct FunctionDescription {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImportDescription {
|
struct ImportDescription
|
||||||
|
{
|
||||||
RVA plt;
|
RVA plt;
|
||||||
int ordinal;
|
int ordinal;
|
||||||
QString bind;
|
QString bind;
|
||||||
@ -40,7 +42,8 @@ struct ImportDescription {
|
|||||||
QString libname;
|
QString libname;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExportDescription {
|
struct ExportDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
RVA paddr;
|
RVA paddr;
|
||||||
RVA size;
|
RVA size;
|
||||||
@ -69,40 +72,46 @@ struct ZignatureDescription
|
|||||||
QStringList refs;
|
QStringList refs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeDescription {
|
struct TypeDescription
|
||||||
|
{
|
||||||
QString type;
|
QString type;
|
||||||
int size;
|
int size;
|
||||||
QString format;
|
QString format;
|
||||||
QString category;
|
QString category;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchDescription {
|
struct SearchDescription
|
||||||
|
{
|
||||||
RVA offset;
|
RVA offset;
|
||||||
int size;
|
int size;
|
||||||
QString code;
|
QString code;
|
||||||
QString data;
|
QString data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SymbolDescription {
|
struct SymbolDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
QString bind;
|
QString bind;
|
||||||
QString type;
|
QString type;
|
||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommentDescription {
|
struct CommentDescription
|
||||||
|
{
|
||||||
RVA offset;
|
RVA offset;
|
||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RelocDescription {
|
struct RelocDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
RVA paddr;
|
RVA paddr;
|
||||||
QString type;
|
QString type;
|
||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringDescription {
|
struct StringDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
QString string;
|
QString string;
|
||||||
QString type;
|
QString type;
|
||||||
@ -111,18 +120,21 @@ struct StringDescription {
|
|||||||
ut32 size;
|
ut32 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlagspaceDescription {
|
struct FlagspaceDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlagDescription {
|
struct FlagDescription
|
||||||
|
{
|
||||||
RVA offset;
|
RVA offset;
|
||||||
RVA size;
|
RVA size;
|
||||||
QString name;
|
QString name;
|
||||||
QString realname;
|
QString realname;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SectionDescription {
|
struct SectionDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
RVA paddr;
|
RVA paddr;
|
||||||
RVA size;
|
RVA size;
|
||||||
@ -132,7 +144,8 @@ struct SectionDescription {
|
|||||||
QString entropy;
|
QString entropy;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SegmentDescription {
|
struct SegmentDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
RVA paddr;
|
RVA paddr;
|
||||||
RVA size;
|
RVA size;
|
||||||
@ -141,7 +154,8 @@ struct SegmentDescription {
|
|||||||
QString perm;
|
QString perm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntrypointDescription {
|
struct EntrypointDescription
|
||||||
|
{
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
RVA paddr;
|
RVA paddr;
|
||||||
RVA baddr;
|
RVA baddr;
|
||||||
@ -150,7 +164,8 @@ struct EntrypointDescription {
|
|||||||
QString type;
|
QString type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XrefDescription {
|
struct XrefDescription
|
||||||
|
{
|
||||||
RVA from;
|
RVA from;
|
||||||
QString from_str;
|
QString from_str;
|
||||||
RVA to;
|
RVA to;
|
||||||
@ -158,14 +173,16 @@ struct XrefDescription {
|
|||||||
QString type;
|
QString type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RzBinPluginDescription {
|
struct RzBinPluginDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
QString license;
|
QString license;
|
||||||
QString type;
|
QString type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RzIOPluginDescription {
|
struct RzIOPluginDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
QString license;
|
QString license;
|
||||||
@ -173,12 +190,14 @@ struct RzIOPluginDescription {
|
|||||||
QList<QString> uris;
|
QList<QString> uris;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RzCorePluginDescription {
|
struct RzCorePluginDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RzAsmPluginDescription {
|
struct RzAsmPluginDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString architecture;
|
QString architecture;
|
||||||
QString author;
|
QString author;
|
||||||
@ -188,29 +207,34 @@ struct RzAsmPluginDescription {
|
|||||||
QString license;
|
QString license;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisassemblyLine {
|
struct DisassemblyLine
|
||||||
|
{
|
||||||
RVA offset;
|
RVA offset;
|
||||||
QString text;
|
QString text;
|
||||||
RVA arrow;
|
RVA arrow;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinClassBaseClassDescription {
|
struct BinClassBaseClassDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA offset;
|
RVA offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinClassMethodDescription {
|
struct BinClassMethodDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA addr = RVA_INVALID;
|
RVA addr = RVA_INVALID;
|
||||||
st64 vtableOffset = -1;
|
st64 vtableOffset = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinClassFieldDescription {
|
struct BinClassFieldDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA addr = RVA_INVALID;
|
RVA addr = RVA_INVALID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinClassDescription {
|
struct BinClassDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA addr = RVA_INVALID;
|
RVA addr = RVA_INVALID;
|
||||||
RVA vtableAddr = RVA_INVALID;
|
RVA vtableAddr = RVA_INVALID;
|
||||||
@ -220,25 +244,29 @@ struct BinClassDescription {
|
|||||||
QList<BinClassFieldDescription> fields;
|
QList<BinClassFieldDescription> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnalMethodDescription {
|
struct AnalMethodDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA addr;
|
RVA addr;
|
||||||
st64 vtableOffset;
|
st64 vtableOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnalBaseClassDescription {
|
struct AnalBaseClassDescription
|
||||||
|
{
|
||||||
QString id;
|
QString id;
|
||||||
RVA offset;
|
RVA offset;
|
||||||
QString className;
|
QString className;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnalVTableDescription {
|
struct AnalVTableDescription
|
||||||
|
{
|
||||||
QString id;
|
QString id;
|
||||||
ut64 offset;
|
ut64 offset;
|
||||||
ut64 addr;
|
ut64 addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourcesDescription {
|
struct ResourcesDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
RVA vaddr;
|
RVA vaddr;
|
||||||
ut64 index;
|
ut64 index;
|
||||||
@ -247,12 +275,14 @@ struct ResourcesDescription {
|
|||||||
QString lang;
|
QString lang;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VTableDescription {
|
struct VTableDescription
|
||||||
|
{
|
||||||
RVA addr;
|
RVA addr;
|
||||||
QList<BinClassMethodDescription> methods;
|
QList<BinClassMethodDescription> methods;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockDescription {
|
struct BlockDescription
|
||||||
|
{
|
||||||
RVA addr;
|
RVA addr;
|
||||||
RVA size;
|
RVA size;
|
||||||
int flags;
|
int flags;
|
||||||
@ -264,14 +294,16 @@ struct BlockDescription {
|
|||||||
ut8 rwx;
|
ut8 rwx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockStatistics {
|
struct BlockStatistics
|
||||||
|
{
|
||||||
RVA from;
|
RVA from;
|
||||||
RVA to;
|
RVA to;
|
||||||
RVA blocksize;
|
RVA blocksize;
|
||||||
QList<BlockDescription> blocks;
|
QList<BlockDescription> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemoryMapDescription {
|
struct MemoryMapDescription
|
||||||
|
{
|
||||||
RVA addrStart;
|
RVA addrStart;
|
||||||
RVA addrEnd;
|
RVA addrEnd;
|
||||||
QString name;
|
QString name;
|
||||||
@ -280,7 +312,8 @@ struct MemoryMapDescription {
|
|||||||
QString permission;
|
QString permission;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BreakpointDescription {
|
struct BreakpointDescription
|
||||||
|
{
|
||||||
enum PositionType {
|
enum PositionType {
|
||||||
Address,
|
Address,
|
||||||
Named,
|
Named,
|
||||||
@ -302,26 +335,30 @@ struct BreakpointDescription {
|
|||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProcessDescription {
|
struct ProcessDescription
|
||||||
|
{
|
||||||
int pid;
|
int pid;
|
||||||
int uid;
|
int uid;
|
||||||
QString status;
|
QString status;
|
||||||
QString path;
|
QString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RefDescription {
|
struct RefDescription
|
||||||
|
{
|
||||||
QString ref;
|
QString ref;
|
||||||
QColor refColor;
|
QColor refColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariableDescription {
|
struct VariableDescription
|
||||||
|
{
|
||||||
enum class RefType { SP, BP, Reg };
|
enum class RefType { SP, BP, Reg };
|
||||||
RefType refType;
|
RefType refType;
|
||||||
QString name;
|
QString name;
|
||||||
QString type;
|
QString type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegisterRefValueDescription {
|
struct RegisterRefValueDescription
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString value;
|
QString value;
|
||||||
QString ref;
|
QString ref;
|
||||||
|
@ -117,14 +117,14 @@
|
|||||||
#define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)")
|
#define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)")
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T *getNewInstance(MainWindow *m) { return new T(m); }
|
T *getNewInstance(MainWindow *m)
|
||||||
|
{
|
||||||
|
return new T(m);
|
||||||
|
}
|
||||||
|
|
||||||
using namespace Cutter;
|
using namespace Cutter;
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow)
|
||||||
QMainWindow(parent),
|
|
||||||
core(Core()),
|
|
||||||
ui(new Ui::MainWindow)
|
|
||||||
{
|
{
|
||||||
tabsOnTop = false;
|
tabsOnTop = false;
|
||||||
configuration = Config();
|
configuration = Config();
|
||||||
@ -132,9 +132,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
initUI();
|
initUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::initUI()
|
void MainWindow::initUI()
|
||||||
{
|
{
|
||||||
@ -146,18 +144,19 @@ void MainWindow::initUI()
|
|||||||
|
|
||||||
connect(ui->actionExtraDecompiler, &QAction::triggered, this, &MainWindow::addExtraDecompiler);
|
connect(ui->actionExtraDecompiler, &QAction::triggered, this, &MainWindow::addExtraDecompiler);
|
||||||
connect(ui->actionExtraGraph, &QAction::triggered, this, &MainWindow::addExtraGraph);
|
connect(ui->actionExtraGraph, &QAction::triggered, this, &MainWindow::addExtraGraph);
|
||||||
connect(ui->actionExtraDisassembly, &QAction::triggered, this, &MainWindow::addExtraDisassembly);
|
connect(ui->actionExtraDisassembly, &QAction::triggered, this,
|
||||||
|
&MainWindow::addExtraDisassembly);
|
||||||
connect(ui->actionExtraHexdump, &QAction::triggered, this, &MainWindow::addExtraHexdump);
|
connect(ui->actionExtraHexdump, &QAction::triggered, this, &MainWindow::addExtraHexdump);
|
||||||
connect(ui->actionCommitChanges, &QAction::triggered, this, [this]() {
|
connect(ui->actionCommitChanges, &QAction::triggered, this,
|
||||||
Core()->commitWriteCache();
|
[this]() { Core()->commitWriteCache(); });
|
||||||
});
|
|
||||||
ui->actionCommitChanges->setEnabled(false);
|
ui->actionCommitChanges->setEnabled(false);
|
||||||
connect(Core(), &CutterCore::ioCacheChanged, ui->actionCommitChanges, &QAction::setEnabled);
|
connect(Core(), &CutterCore::ioCacheChanged, ui->actionCommitChanges, &QAction::setEnabled);
|
||||||
|
|
||||||
widgetTypeToConstructorMap.insert(GraphWidget::getWidgetType(), getNewInstance<GraphWidget>);
|
widgetTypeToConstructorMap.insert(GraphWidget::getWidgetType(), getNewInstance<GraphWidget>);
|
||||||
widgetTypeToConstructorMap.insert(DisassemblyWidget::getWidgetType(),
|
widgetTypeToConstructorMap.insert(DisassemblyWidget::getWidgetType(),
|
||||||
getNewInstance<DisassemblyWidget>);
|
getNewInstance<DisassemblyWidget>);
|
||||||
widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(), getNewInstance<HexdumpWidget>);
|
widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(),
|
||||||
|
getNewInstance<HexdumpWidget>);
|
||||||
widgetTypeToConstructorMap.insert(DecompilerWidget::getWidgetType(),
|
widgetTypeToConstructorMap.insert(DecompilerWidget::getWidgetType(),
|
||||||
getNewInstance<DecompilerWidget>);
|
getNewInstance<DecompilerWidget>);
|
||||||
|
|
||||||
@ -175,13 +174,17 @@ void MainWindow::initUI()
|
|||||||
|
|
||||||
// G and S goes to goto entry
|
// G and S goes to goto entry
|
||||||
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
|
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
|
||||||
connect(goto_shortcut, &QShortcut::activated, this->omnibar, [this](){ this->omnibar->setFocus(); });
|
connect(goto_shortcut, &QShortcut::activated, this->omnibar,
|
||||||
|
[this]() { this->omnibar->setFocus(); });
|
||||||
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
|
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
|
||||||
connect(seek_shortcut, &QShortcut::activated, this->omnibar, [this](){ this->omnibar->setFocus(); });
|
connect(seek_shortcut, &QShortcut::activated, this->omnibar,
|
||||||
|
[this]() { this->omnibar->setFocus(); });
|
||||||
QShortcut *seek_to_func_end_shortcut = new QShortcut(QKeySequence(Qt::Key_Dollar), this);
|
QShortcut *seek_to_func_end_shortcut = new QShortcut(QKeySequence(Qt::Key_Dollar), this);
|
||||||
connect(seek_to_func_end_shortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionLastInstruction);
|
connect(seek_to_func_end_shortcut, &QShortcut::activated, this,
|
||||||
|
&MainWindow::seekToFunctionLastInstruction);
|
||||||
QShortcut *seek_to_func_start_shortcut = new QShortcut(QKeySequence(Qt::Key_AsciiCircum), this);
|
QShortcut *seek_to_func_start_shortcut = new QShortcut(QKeySequence(Qt::Key_AsciiCircum), this);
|
||||||
connect(seek_to_func_start_shortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionStart);
|
connect(seek_to_func_start_shortcut, &QShortcut::activated, this,
|
||||||
|
&MainWindow::seekToFunctionStart);
|
||||||
|
|
||||||
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
|
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
|
||||||
connect(refresh_shortcut, &QShortcut::activated, this, &MainWindow::refreshAll);
|
connect(refresh_shortcut, &QShortcut::activated, this, &MainWindow::refreshAll);
|
||||||
@ -192,13 +195,11 @@ void MainWindow::initUI()
|
|||||||
|
|
||||||
connect(core, &CutterCore::toggleDebugView, this, &MainWindow::toggleDebugView);
|
connect(core, &CutterCore::toggleDebugView, this, &MainWindow::toggleDebugView);
|
||||||
|
|
||||||
connect(core, &CutterCore::newMessage,
|
connect(core, &CutterCore::newMessage, this->consoleDock, &ConsoleWidget::addOutput);
|
||||||
this->consoleDock, &ConsoleWidget::addOutput);
|
connect(core, &CutterCore::newDebugMessage, this->consoleDock, &ConsoleWidget::addDebugOutput);
|
||||||
connect(core, &CutterCore::newDebugMessage,
|
|
||||||
this->consoleDock, &ConsoleWidget::addDebugOutput);
|
|
||||||
|
|
||||||
connect(core, &CutterCore::showMemoryWidgetRequested,
|
connect(core, &CutterCore::showMemoryWidgetRequested, this,
|
||||||
this, static_cast<void(MainWindow::*)()>(&MainWindow::showMemoryWidget));
|
static_cast<void (MainWindow::*)()>(&MainWindow::showMemoryWidget));
|
||||||
|
|
||||||
updateTasksIndicator();
|
updateTasksIndicator();
|
||||||
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
|
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
|
||||||
@ -247,7 +248,8 @@ void MainWindow::initUI()
|
|||||||
ui->menuWindows->setToolTipsVisible(true);
|
ui->menuWindows->setToolTipsVisible(true);
|
||||||
if (plugins.empty()) {
|
if (plugins.empty()) {
|
||||||
ui->menuPlugins->menuAction()->setToolTip(
|
ui->menuPlugins->menuAction()->setToolTip(
|
||||||
tr("No plugins are installed. Check the plugins section on Cutter documentation to learn more."));
|
tr("No plugins are installed. Check the plugins section on Cutter documentation to "
|
||||||
|
"learn more."));
|
||||||
ui->menuPlugins->setEnabled(false);
|
ui->menuPlugins->setEnabled(false);
|
||||||
} else if (ui->menuPlugins->isEmpty()) {
|
} else if (ui->menuPlugins->isEmpty()) {
|
||||||
ui->menuPlugins->menuAction()->setToolTip(
|
ui->menuPlugins->menuAction()->setToolTip(
|
||||||
@ -255,7 +257,7 @@ void MainWindow::initUI()
|
|||||||
ui->menuPlugins->setEnabled(false);
|
ui->menuPlugins->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->actionUnlock, &QAction::toggled, this, [this](bool unlock){ lockDocks(!unlock); });
|
connect(ui->actionUnlock, &QAction::toggled, this, [this](bool unlock) { lockDocks(!unlock); });
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
ui->actionGrouped_dock_dragging->setVisible(false);
|
ui->actionGrouped_dock_dragging->setVisible(false);
|
||||||
@ -342,10 +344,10 @@ void MainWindow::initToolBar()
|
|||||||
this->visualNavbar->setMovable(false);
|
this->visualNavbar->setMovable(false);
|
||||||
addToolBarBreak(Qt::TopToolBarArea);
|
addToolBarBreak(Qt::TopToolBarArea);
|
||||||
addToolBar(visualNavbar);
|
addToolBar(visualNavbar);
|
||||||
QObject::connect(configuration, &Configuration::colorsUpdated, this, [this]() {
|
QObject::connect(configuration, &Configuration::colorsUpdated, this,
|
||||||
this->visualNavbar->updateGraphicsScene();
|
[this]() { this->visualNavbar->updateGraphicsScene(); });
|
||||||
});
|
QObject::connect(configuration, &Configuration::interfaceThemeChanged, this,
|
||||||
QObject::connect(configuration, &Configuration::interfaceThemeChanged, this, &MainWindow::chooseThemeIcons);
|
&MainWindow::chooseThemeIcons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initDocks()
|
void MainWindow::initDocks()
|
||||||
@ -356,9 +358,8 @@ void MainWindow::initDocks()
|
|||||||
overviewDock = new OverviewWidget(this);
|
overviewDock = new OverviewWidget(this);
|
||||||
overviewDock->hide();
|
overviewDock->hide();
|
||||||
actionOverview = overviewDock->toggleViewAction();
|
actionOverview = overviewDock->toggleViewAction();
|
||||||
connect(overviewDock, &OverviewWidget::isAvailableChanged, this, [this](bool isAvailable) {
|
connect(overviewDock, &OverviewWidget::isAvailableChanged, this,
|
||||||
actionOverview->setEnabled(isAvailable);
|
[this](bool isAvailable) { actionOverview->setEnabled(isAvailable); });
|
||||||
});
|
|
||||||
actionOverview->setEnabled(overviewDock->getIsAvailable());
|
actionOverview->setEnabled(overviewDock->getIsAvailable());
|
||||||
actionOverview->setChecked(overviewDock->getUserOpened());
|
actionOverview->setChecked(overviewDock->getUserOpened());
|
||||||
|
|
||||||
@ -370,14 +371,10 @@ void MainWindow::initDocks()
|
|||||||
stringsDock = new StringsWidget(this);
|
stringsDock = new StringsWidget(this);
|
||||||
|
|
||||||
QList<CutterDockWidget *> debugDocks = {
|
QList<CutterDockWidget *> debugDocks = {
|
||||||
stackDock = new StackWidget(this),
|
stackDock = new StackWidget(this), threadsDock = new ThreadsWidget(this),
|
||||||
threadsDock = new ThreadsWidget(this),
|
processesDock = new ProcessesWidget(this), backtraceDock = new BacktraceWidget(this),
|
||||||
processesDock = new ProcessesWidget(this),
|
registersDock = new RegistersWidget(this), memoryMapDock = new MemoryMapWidget(this),
|
||||||
backtraceDock = new BacktraceWidget(this),
|
breakpointDock = new BreakpointWidget(this), registerRefsDock = new RegisterRefsWidget(this)
|
||||||
registersDock = new RegistersWidget(this),
|
|
||||||
memoryMapDock = new MemoryMapWidget(this),
|
|
||||||
breakpointDock = new BreakpointWidget(this),
|
|
||||||
registerRefsDock = new RegisterRefsWidget(this)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QList<CutterDockWidget *> infoDocks = {
|
QList<CutterDockWidget *> infoDocks = {
|
||||||
@ -415,15 +412,8 @@ void MainWindow::initDocks()
|
|||||||
};
|
};
|
||||||
|
|
||||||
QList<CutterDockWidget *> windowDocks = {
|
QList<CutterDockWidget *> windowDocks = {
|
||||||
dashboardDock,
|
dashboardDock, nullptr, functionsDock, overviewDock, nullptr,
|
||||||
nullptr,
|
searchDock, stringsDock, typesDock, nullptr,
|
||||||
functionsDock,
|
|
||||||
overviewDock,
|
|
||||||
nullptr,
|
|
||||||
searchDock,
|
|
||||||
stringsDock,
|
|
||||||
typesDock,
|
|
||||||
nullptr,
|
|
||||||
};
|
};
|
||||||
ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks));
|
ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks));
|
||||||
QList<CutterDockWidget *> windowDocks2 = {
|
QList<CutterDockWidget *> windowDocks2 = {
|
||||||
@ -556,8 +546,8 @@ void MainWindow::openNewFileFailed()
|
|||||||
mb.setIcon(QMessageBox::Critical);
|
mb.setIcon(QMessageBox::Critical);
|
||||||
mb.setStandardButtons(QMessageBox::Ok);
|
mb.setStandardButtons(QMessageBox::Ok);
|
||||||
mb.setWindowTitle(tr("Cannot open file!"));
|
mb.setWindowTitle(tr("Cannot open file!"));
|
||||||
mb.setText(
|
mb.setText(tr("Could not open the file! Make sure the file exists and that you have the "
|
||||||
tr("Could not open the file! Make sure the file exists and that you have the correct permissions."));
|
"correct permissions."));
|
||||||
mb.exec();
|
mb.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,9 +605,7 @@ bool MainWindow::openProject(const QString &file)
|
|||||||
const char *s = rz_project_err_message(err);
|
const char *s = rz_project_err_message(err);
|
||||||
QString msg = tr("Failed to open project: %1").arg(QString::fromUtf8(s));
|
QString msg = tr("Failed to open project: %1").arg(QString::fromUtf8(s));
|
||||||
RzListIter *it;
|
RzListIter *it;
|
||||||
CutterRListForeach(res, it, const char, s) {
|
CutterRListForeach(res, it, const char, s) { msg += "\n" + QString::fromUtf8(s); }
|
||||||
msg += "\n" + QString::fromUtf8(s);
|
|
||||||
}
|
|
||||||
QMessageBox::critical(this, tr("Open Project"), msg);
|
QMessageBox::critical(this, tr("Open Project"), msg);
|
||||||
rz_list_free(res);
|
rz_list_free(res);
|
||||||
return false;
|
return false;
|
||||||
@ -656,7 +644,6 @@ void MainWindow::finalizeOpen()
|
|||||||
Config()->adjustColorThemeDarkness();
|
Config()->adjustColorThemeDarkness();
|
||||||
setViewLayout(getViewLayout(LAYOUT_DEFAULT));
|
setViewLayout(getViewLayout(LAYOUT_DEFAULT));
|
||||||
|
|
||||||
|
|
||||||
// Set focus to disasm or graph widget
|
// Set focus to disasm or graph widget
|
||||||
// Graph with function in it has focus priority over DisasmWidget.
|
// Graph with function in it has focus priority over DisasmWidget.
|
||||||
// If there are no graph/disasm widgets focus on MainWindow
|
// If there are no graph/disasm widgets focus on MainWindow
|
||||||
@ -730,7 +717,8 @@ void MainWindow::showProjectSaveError(RzProjectErr err)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const char *s = rz_project_err_message(err);
|
const char *s = rz_project_err_message(err);
|
||||||
QMessageBox::critical(this, tr("Save Project"), tr("Failed to save project: %1").arg(QString::fromUtf8(s)));
|
QMessageBox::critical(this, tr("Save Project"),
|
||||||
|
tr("Failed to save project: %1").arg(QString::fromUtf8(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshOmniBar(const QStringList &flags)
|
void MainWindow::refreshOmniBar(const QStringList &flags)
|
||||||
@ -742,7 +730,7 @@ void MainWindow::setFilename(const QString &fn)
|
|||||||
{
|
{
|
||||||
// Add file name to window title
|
// Add file name to window title
|
||||||
this->filename = fn;
|
this->filename = fn;
|
||||||
this->setWindowTitle(APPNAME" – " + fn);
|
this->setWindowTitle(APPNAME " – " + fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent *event)
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
@ -757,9 +745,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||||||
|
|
||||||
activateWindow();
|
activateWindow();
|
||||||
|
|
||||||
QMessageBox::StandardButton ret = QMessageBox::question(this, APPNAME,
|
QMessageBox::StandardButton ret = QMessageBox::question(
|
||||||
tr("Do you really want to exit?\nSave your project before closing!"),
|
this, APPNAME, tr("Do you really want to exit?\nSave your project before closing!"),
|
||||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
|
||||||
|
| QMessageBox::Cancel));
|
||||||
if (ret == QMessageBox::Cancel) {
|
if (ret == QMessageBox::Cancel) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
@ -855,12 +844,10 @@ void MainWindow::lockDocks(bool lock)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (QDockWidget *dockWidget : findChildren<QDockWidget *>()) {
|
for (QDockWidget *dockWidget : findChildren<QDockWidget *>()) {
|
||||||
dockWidget->setFeatures(QDockWidget::DockWidgetClosable |
|
dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable
|
||||||
QDockWidget::DockWidgetMovable |
|
| QDockWidget::DockWidgetFloatable);
|
||||||
QDockWidget::DockWidgetFloatable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::restoreDocks()
|
void MainWindow::restoreDocks()
|
||||||
@ -924,22 +911,15 @@ void MainWindow::restoreDocks()
|
|||||||
|
|
||||||
bool MainWindow::isDebugWidget(QDockWidget *dock) const
|
bool MainWindow::isDebugWidget(QDockWidget *dock) const
|
||||||
{
|
{
|
||||||
return dock == stackDock ||
|
return dock == stackDock || dock == registersDock || dock == backtraceDock
|
||||||
dock == registersDock ||
|
|| dock == threadsDock || dock == memoryMapDock || dock == breakpointDock
|
||||||
dock == backtraceDock ||
|
|| dock == processesDock || dock == registerRefsDock;
|
||||||
dock == threadsDock ||
|
|
||||||
dock == memoryMapDock ||
|
|
||||||
dock == breakpointDock ||
|
|
||||||
dock == processesDock ||
|
|
||||||
dock == registerRefsDock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::isExtraMemoryWidget(QDockWidget *dock) const
|
bool MainWindow::isExtraMemoryWidget(QDockWidget *dock) const
|
||||||
{
|
{
|
||||||
return qobject_cast<GraphWidget*>(dock) ||
|
return qobject_cast<GraphWidget *>(dock) || qobject_cast<HexdumpWidget *>(dock)
|
||||||
qobject_cast<HexdumpWidget*>(dock) ||
|
|| qobject_cast<DisassemblyWidget *>(dock) || qobject_cast<DecompilerWidget *>(dock);
|
||||||
qobject_cast<DisassemblyWidget*>(dock) ||
|
|
||||||
qobject_cast<DecompilerWidget*>(dock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore()
|
MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore()
|
||||||
@ -1005,8 +985,7 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHi
|
|||||||
for (auto &dock : dockWidgets) {
|
for (auto &dock : dockWidgets) {
|
||||||
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
|
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
|
||||||
if (memoryWidget->getType() == MemoryWidgetType::Graph
|
if (memoryWidget->getType() == MemoryWidgetType::Graph
|
||||||
|| memoryWidget->getType() == MemoryWidgetType::Decompiler)
|
|| memoryWidget->getType() == MemoryWidgetType::Decompiler) {
|
||||||
{
|
|
||||||
if (addressType == AddressTypeHint::Data) {
|
if (addressType == AddressTypeHint::Data) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1037,9 +1016,8 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHi
|
|||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) {
|
auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) {
|
||||||
QAction *action = new QAction(label, menu);
|
QAction *action = new QAction(label, menu);
|
||||||
connect(action, &QAction::triggered, this, [this, address, type]() {
|
connect(action, &QAction::triggered, this,
|
||||||
addNewMemoryWidget(type, address, false);
|
[this, address, type]() { addNewMemoryWidget(type, address, false); });
|
||||||
});
|
|
||||||
menu->addAction(action);
|
menu->addAction(action);
|
||||||
};
|
};
|
||||||
createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly);
|
createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly);
|
||||||
@ -1091,7 +1069,7 @@ MemoryDockWidget *MainWindow::addNewMemoryWidget(MemoryWidgetType type, RVA addr
|
|||||||
|
|
||||||
void MainWindow::initBackForwardMenu()
|
void MainWindow::initBackForwardMenu()
|
||||||
{
|
{
|
||||||
auto prepareButtonMenu = [this](QAction *action) -> QMenu* {
|
auto prepareButtonMenu = [this](QAction *action) -> QMenu * {
|
||||||
QToolButton *button = qobject_cast<QToolButton *>(ui->mainToolBar->widgetForAction(action));
|
QToolButton *button = qobject_cast<QToolButton *>(ui->mainToolBar->widgetForAction(action));
|
||||||
if (!button) {
|
if (!button) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1101,9 +1079,7 @@ void MainWindow::initBackForwardMenu()
|
|||||||
button->setPopupMode(QToolButton::DelayedPopup);
|
button->setPopupMode(QToolButton::DelayedPopup);
|
||||||
button->setContextMenuPolicy(Qt::CustomContextMenu);
|
button->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(button, &QWidget::customContextMenuRequested, button,
|
connect(button, &QWidget::customContextMenuRequested, button,
|
||||||
[menu, button] (const QPoint &pos) {
|
[menu, button](const QPoint &pos) { menu->exec(button->mapToGlobal(pos)); });
|
||||||
menu->exec(button->mapToGlobal(pos));
|
|
||||||
});
|
|
||||||
|
|
||||||
QFontMetrics metrics(fontMetrics());
|
QFontMetrics metrics(fontMetrics());
|
||||||
// Roughly 10-16 lines depending on padding size, no need to calculate more precisely
|
// Roughly 10-16 lines depending on padding size, no need to calculate more precisely
|
||||||
@ -1115,15 +1091,12 @@ void MainWindow::initBackForwardMenu()
|
|||||||
|
|
||||||
if (auto menu = prepareButtonMenu(ui->actionBackward)) {
|
if (auto menu = prepareButtonMenu(ui->actionBackward)) {
|
||||||
menu->setObjectName("historyMenu");
|
menu->setObjectName("historyMenu");
|
||||||
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
|
connect(menu, &QMenu::aboutToShow, menu,
|
||||||
updateHistoryMenu(menu, false);
|
[this, menu]() { updateHistoryMenu(menu, false); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (auto menu = prepareButtonMenu(ui->actionForward)) {
|
if (auto menu = prepareButtonMenu(ui->actionForward)) {
|
||||||
menu->setObjectName("forwardHistoryMenu");
|
menu->setObjectName("forwardHistoryMenu");
|
||||||
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
|
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() { updateHistoryMenu(menu, true); });
|
||||||
updateHistoryMenu(menu, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,7 +1120,8 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
|
|||||||
if (history != redo || current) { // Include current in both directions
|
if (history != redo || current) { // Include current in both directions
|
||||||
QString addressString = RAddressString(offset);
|
QString addressString = RAddressString(offset);
|
||||||
|
|
||||||
QString toolTip = QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip
|
QString toolTip =
|
||||||
|
QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip
|
||||||
|
|
||||||
name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function
|
name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function
|
||||||
QString label = QString("%1 (%2)").arg(name, addressString);
|
QString label = QString("%1 (%2)").arg(name, addressString);
|
||||||
@ -1186,7 +1160,6 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
|
|||||||
}
|
}
|
||||||
++steps;
|
++steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateLayoutsMenu()
|
void MainWindow::updateLayoutsMenu()
|
||||||
@ -1198,9 +1171,8 @@ void MainWindow::updateLayoutsMenu()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto action = new QAction(it.key(), ui->menuLayouts);
|
auto action = new QAction(it.key(), ui->menuLayouts);
|
||||||
connect(action, &QAction::triggered, this, [this, name]() {
|
connect(action, &QAction::triggered, this,
|
||||||
setViewLayout(getViewLayout(name));
|
[this, name]() { setViewLayout(getViewLayout(name)); });
|
||||||
});
|
|
||||||
ui->menuLayouts->addAction(action);
|
ui->menuLayouts->addAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1214,9 +1186,11 @@ void MainWindow::saveNamedLayout()
|
|||||||
names.removeAll(LAYOUT_DEFAULT);
|
names.removeAll(LAYOUT_DEFAULT);
|
||||||
while (name.isEmpty() || isBuiltinLayoutName(name)) {
|
while (name.isEmpty() || isBuiltinLayoutName(name)) {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
QMessageBox::warning(this, tr("Save layout error"), tr("'%1' is not a valid name.").arg(name));
|
QMessageBox::warning(this, tr("Save layout error"),
|
||||||
|
tr("'%1' is not a valid name.").arg(name));
|
||||||
}
|
}
|
||||||
name = QInputDialog::getItem(this, tr("Save layout"), tr("Enter name"), names, -1, true, &ok);
|
name = QInputDialog::getItem(this, tr("Save layout"), tr("Enter name"), names, -1, true,
|
||||||
|
&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1261,17 +1235,12 @@ void MainWindow::removeWidget(CutterDockWidget *widget)
|
|||||||
|
|
||||||
void MainWindow::showZenDocks()
|
void MainWindow::showZenDocks()
|
||||||
{
|
{
|
||||||
const QList<QDockWidget *> zenDocks = { functionsDock,
|
const QList<QDockWidget *> zenDocks = { functionsDock, dashboardDock, stringsDock, searchDock,
|
||||||
dashboardDock,
|
importsDock };
|
||||||
stringsDock,
|
|
||||||
searchDock,
|
|
||||||
importsDock
|
|
||||||
};
|
|
||||||
functionDockWidthToRestore = functionsDock->maximumWidth();
|
functionDockWidthToRestore = functionsDock->maximumWidth();
|
||||||
functionsDock->setMaximumWidth(200);
|
functionsDock->setMaximumWidth(200);
|
||||||
for (auto w : dockWidgets) {
|
for (auto w : dockWidgets) {
|
||||||
if (zenDocks.contains(w) ||
|
if (zenDocks.contains(w) || isExtraMemoryWidget(w)) {
|
||||||
isExtraMemoryWidget(w)) {
|
|
||||||
w->show();
|
w->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1280,27 +1249,19 @@ void MainWindow::showZenDocks()
|
|||||||
|
|
||||||
void MainWindow::showDebugDocks()
|
void MainWindow::showDebugDocks()
|
||||||
{
|
{
|
||||||
const QList<QDockWidget *> debugDocks = { functionsDock,
|
const QList<QDockWidget *> debugDocks = { functionsDock, stringsDock, searchDock,
|
||||||
stringsDock,
|
stackDock, registersDock, backtraceDock,
|
||||||
searchDock,
|
threadsDock, memoryMapDock, breakpointDock };
|
||||||
stackDock,
|
|
||||||
registersDock,
|
|
||||||
backtraceDock,
|
|
||||||
threadsDock,
|
|
||||||
memoryMapDock,
|
|
||||||
breakpointDock
|
|
||||||
};
|
|
||||||
functionDockWidthToRestore = functionsDock->maximumWidth();
|
functionDockWidthToRestore = functionsDock->maximumWidth();
|
||||||
functionsDock->setMaximumWidth(200);
|
functionsDock->setMaximumWidth(200);
|
||||||
auto registerWidth = qhelpers::forceWidth(registersDock, std::min(500, this->width() / 4));
|
auto registerWidth = qhelpers::forceWidth(registersDock, std::min(500, this->width() / 4));
|
||||||
auto registerHeight = qhelpers::forceHeight(registersDock, std::max(100, height() / 2));
|
auto registerHeight = qhelpers::forceHeight(registersDock, std::max(100, height() / 2));
|
||||||
QDockWidget *widgetToFocus = nullptr;
|
QDockWidget *widgetToFocus = nullptr;
|
||||||
for (auto w : dockWidgets) {
|
for (auto w : dockWidgets) {
|
||||||
if (debugDocks.contains(w) ||
|
if (debugDocks.contains(w) || isExtraMemoryWidget(w)) {
|
||||||
isExtraMemoryWidget(w)) {
|
|
||||||
w->show();
|
w->show();
|
||||||
}
|
}
|
||||||
if (qobject_cast<DisassemblyWidget*>(w)) {
|
if (qobject_cast<DisassemblyWidget *>(w)) {
|
||||||
widgetToFocus = w;
|
widgetToFocus = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1313,12 +1274,12 @@ void MainWindow::showDebugDocks()
|
|||||||
|
|
||||||
void MainWindow::dockOnMainArea(QDockWidget *widget)
|
void MainWindow::dockOnMainArea(QDockWidget *widget)
|
||||||
{
|
{
|
||||||
QDockWidget* best = nullptr;
|
QDockWidget *best = nullptr;
|
||||||
float bestScore = 1;
|
float bestScore = 1;
|
||||||
// choose best existing area for placing the new widget
|
// choose best existing area for placing the new widget
|
||||||
for (auto dock : dockWidgets) {
|
for (auto dock : dockWidgets) {
|
||||||
if (dock->isHidden() || dock == widget ||
|
if (dock->isHidden() || dock == widget || dock->isFloating()
|
||||||
dock->isFloating() || // tabifying onto floating dock using code doesn't work well
|
|| // tabifying onto floating dock using code doesn't work well
|
||||||
dock->parentWidget() != this) { // floating group isn't considered floating
|
dock->parentWidget() != this) { // floating group isn't considered floating
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1392,19 +1353,16 @@ void MainWindow::setViewLayout(const CutterLayout &layout)
|
|||||||
|
|
||||||
QStringList docksToCreate;
|
QStringList docksToCreate;
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
docksToCreate = QStringList {
|
docksToCreate =
|
||||||
DisassemblyWidget::getWidgetType(),
|
QStringList { DisassemblyWidget::getWidgetType(), GraphWidget::getWidgetType(),
|
||||||
GraphWidget::getWidgetType(),
|
HexdumpWidget::getWidgetType(), DecompilerWidget::getWidgetType() };
|
||||||
HexdumpWidget::getWidgetType(),
|
|
||||||
DecompilerWidget::getWidgetType()
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
docksToCreate = layout.viewProperties.keys();
|
docksToCreate = layout.viewProperties.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &it : docksToCreate) {
|
for (const auto &it : docksToCreate) {
|
||||||
if (std::none_of(dockWidgets.constBegin(), dockWidgets.constEnd(),
|
if (std::none_of(dockWidgets.constBegin(), dockWidgets.constEnd(),
|
||||||
[&it](QDockWidget * w) { return w->objectName() == it; })) {
|
[&it](QDockWidget *w) { return w->objectName() == it; })) {
|
||||||
auto className = it.split(';').at(0);
|
auto className = it.split(';').at(0);
|
||||||
if (widgetTypeToConstructorMap.contains(className)) {
|
if (widgetTypeToConstructorMap.contains(className)) {
|
||||||
auto widget = widgetTypeToConstructorMap[className](this);
|
auto widget = widgetTypeToConstructorMap[className](this);
|
||||||
@ -1490,7 +1448,8 @@ void MainWindow::saveLayouts(QSettings &settings)
|
|||||||
settings.setValue("state", layout.state);
|
settings.setValue("state", layout.state);
|
||||||
settings.setValue("geometry", layout.geometry);
|
settings.setValue("geometry", layout.geometry);
|
||||||
QVariantMap properties;
|
QVariantMap properties;
|
||||||
for (auto it = layout.viewProperties.begin(), end = layout.viewProperties.end(); it != end; ++it) {
|
for (auto it = layout.viewProperties.begin(), end = layout.viewProperties.end(); it != end;
|
||||||
|
++it) {
|
||||||
properties.insert(it.key(), it.value());
|
properties.insert(it.key(), it.value());
|
||||||
}
|
}
|
||||||
settings.setValue("docks", properties);
|
settings.setValue("docks", properties);
|
||||||
@ -1498,7 +1457,6 @@ void MainWindow::saveLayouts(QSettings &settings)
|
|||||||
settings.endArray();
|
settings.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_actionDefault_triggered()
|
void MainWindow::on_actionDefault_triggered()
|
||||||
{
|
{
|
||||||
if (core->currentlyDebugging) {
|
if (core->currentlyDebugging) {
|
||||||
@ -1510,7 +1468,6 @@ void MainWindow::on_actionDefault_triggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MainWindow::on_actionNew_triggered
|
* @brief MainWindow::on_actionNew_triggered
|
||||||
* Open a new Cutter session.
|
* Open a new Cutter session.
|
||||||
@ -1518,7 +1475,7 @@ void MainWindow::on_actionDefault_triggered()
|
|||||||
void MainWindow::on_actionNew_triggered()
|
void MainWindow::on_actionNew_triggered()
|
||||||
{
|
{
|
||||||
// Create a new Cutter process
|
// Create a new Cutter process
|
||||||
static_cast<CutterApplication*>(qApp)->launchNewInstance();
|
static_cast<CutterApplication *>(qApp)->launchNewInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSave_triggered()
|
void MainWindow::on_actionSave_triggered()
|
||||||
@ -1538,8 +1495,8 @@ void MainWindow::on_actionRun_Script_triggered()
|
|||||||
dialog.setViewMode(QFileDialog::Detail);
|
dialog.setViewMode(QFileDialog::Detail);
|
||||||
dialog.setDirectory(QDir::home());
|
dialog.setDirectory(QDir::home());
|
||||||
|
|
||||||
const QString &fileName = QDir::toNativeSeparators(dialog.getOpenFileName(this,
|
const QString &fileName =
|
||||||
tr("Select Rizin script")));
|
QDir::toNativeSeparators(dialog.getOpenFileName(this, tr("Select Rizin script")));
|
||||||
if (fileName.isEmpty()) // Cancel was pressed
|
if (fileName.isEmpty()) // Cancel was pressed
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1581,9 +1538,8 @@ void MainWindow::on_actionTabs_on_Top_triggered()
|
|||||||
|
|
||||||
void MainWindow::on_actionReset_settings_triggered()
|
void MainWindow::on_actionReset_settings_triggered()
|
||||||
{
|
{
|
||||||
QMessageBox::StandardButton ret =
|
QMessageBox::StandardButton ret = (QMessageBox::StandardButton)QMessageBox::question(
|
||||||
(QMessageBox::StandardButton)QMessageBox::question(this, APPNAME,
|
this, APPNAME, tr("Do you really want to clear all settings?"),
|
||||||
tr("Do you really want to clear all settings?"),
|
|
||||||
QMessageBox::Ok | QMessageBox::Cancel);
|
QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
if (ret == QMessageBox::Ok) {
|
if (ret == QMessageBox::Ok) {
|
||||||
Config()->resetAll();
|
Config()->resetAll();
|
||||||
@ -1620,7 +1576,7 @@ void MainWindow::on_actionRefresh_contents_triggered()
|
|||||||
|
|
||||||
void MainWindow::on_actionPreferences_triggered()
|
void MainWindow::on_actionPreferences_triggered()
|
||||||
{
|
{
|
||||||
if (!findChild<PreferencesDialog*>()) {
|
if (!findChild<PreferencesDialog *>()) {
|
||||||
auto dialog = new PreferencesDialog(this);
|
auto dialog = new PreferencesDialog(this);
|
||||||
dialog->show();
|
dialog->show();
|
||||||
}
|
}
|
||||||
@ -1661,7 +1617,7 @@ void MainWindow::on_actionAnalyze_triggered()
|
|||||||
{
|
{
|
||||||
auto *analTask = new AnalTask();
|
auto *analTask = new AnalTask();
|
||||||
InitialOptions options;
|
InitialOptions options;
|
||||||
options.analCmd = { {"aaa", "Auto analysis"} };
|
options.analCmd = { { "aaa", "Auto analysis" } };
|
||||||
analTask->setOptions(options);
|
analTask->setOptions(options);
|
||||||
AsyncTask::Ptr analTaskPtr(analTask);
|
AsyncTask::Ptr analTaskPtr(analTask);
|
||||||
|
|
||||||
@ -1810,13 +1766,13 @@ bool MainWindow::eventFilter(QObject *, QEvent *event)
|
|||||||
|
|
||||||
bool MainWindow::event(QEvent *event)
|
bool MainWindow::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::FontChange
|
if (event->type() == QEvent::FontChange || event->type() == QEvent::StyleChange
|
||||||
|| event->type() == QEvent::StyleChange
|
|
||||||
|| event->type() == QEvent::PaletteChange) {
|
|| event->type() == QEvent::PaletteChange) {
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||||
QMetaObject::invokeMethod(Config(), "refreshFont", Qt::ConnectionType::QueuedConnection);
|
QMetaObject::invokeMethod(Config(), "refreshFont", Qt::ConnectionType::QueuedConnection);
|
||||||
#else
|
#else
|
||||||
QMetaObject::invokeMethod(Config(), &Configuration::refreshFont, Qt::ConnectionType::QueuedConnection);
|
QMetaObject::invokeMethod(Config(), &Configuration::refreshFont,
|
||||||
|
Qt::ConnectionType::QueuedConnection);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return QMainWindow::event(event);
|
return QMainWindow::event(event);
|
||||||
@ -1843,15 +1799,14 @@ void MainWindow::messageBoxWarning(QString title, QString message)
|
|||||||
void MainWindow::chooseThemeIcons()
|
void MainWindow::chooseThemeIcons()
|
||||||
{
|
{
|
||||||
// List of QActions which have alternative icons in different themes
|
// List of QActions which have alternative icons in different themes
|
||||||
const QList<QPair<void*, QString>> kSupportedIconsNames {
|
const QList<QPair<void *, QString>> kSupportedIconsNames {
|
||||||
{ ui->actionForward, QStringLiteral("arrow_right.svg") },
|
{ ui->actionForward, QStringLiteral("arrow_right.svg") },
|
||||||
{ ui->actionBackward, QStringLiteral("arrow_left.svg") },
|
{ ui->actionBackward, QStringLiteral("arrow_left.svg") },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Set the correct icon for the QAction
|
// Set the correct icon for the QAction
|
||||||
qhelpers::setThemeIcons(kSupportedIconsNames, [](void *obj, const QIcon &icon) {
|
qhelpers::setThemeIcons(kSupportedIconsNames, [](void *obj, const QIcon &icon) {
|
||||||
static_cast<QAction*>(obj)->setIcon(icon);
|
static_cast<QAction *>(obj)->setIcon(icon);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +90,14 @@ public:
|
|||||||
void addMemoryDockWidget(MemoryDockWidget *widget);
|
void addMemoryDockWidget(MemoryDockWidget *widget);
|
||||||
void removeWidget(CutterDockWidget *widget);
|
void removeWidget(CutterDockWidget *widget);
|
||||||
void addExtraWidget(CutterDockWidget *extraDock);
|
void addExtraWidget(CutterDockWidget *extraDock);
|
||||||
MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address, bool synchronized = true);
|
MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address,
|
||||||
|
bool synchronized = true);
|
||||||
|
|
||||||
CUTTER_DEPRECATED("Action will be ignored. Use addPluginDockWidget(CutterDockWidget*) instead.")
|
CUTTER_DEPRECATED("Action will be ignored. Use addPluginDockWidget(CutterDockWidget*) instead.")
|
||||||
void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *) { addPluginDockWidget(dockWidget); }
|
void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *)
|
||||||
|
{
|
||||||
|
addPluginDockWidget(dockWidget);
|
||||||
|
}
|
||||||
void addPluginDockWidget(CutterDockWidget *dockWidget);
|
void addPluginDockWidget(CutterDockWidget *dockWidget);
|
||||||
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
|
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
|
||||||
/**
|
/**
|
||||||
@ -104,19 +108,17 @@ public:
|
|||||||
QMenu *getMenuByType(MenuType type);
|
QMenu *getMenuByType(MenuType type);
|
||||||
void addMenuFileAction(QAction *action);
|
void addMenuFileAction(QAction *action);
|
||||||
|
|
||||||
QString getFilename() const
|
QString getFilename() const { return filename; }
|
||||||
{
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
void messageBoxWarning(QString title, QString message);
|
void messageBoxWarning(QString title, QString message);
|
||||||
|
|
||||||
QString getUniqueObjectName(const QString &widgetType) const;
|
QString getUniqueObjectName(const QString &widgetType) const;
|
||||||
void showMemoryWidget();
|
void showMemoryWidget();
|
||||||
void showMemoryWidget(MemoryWidgetType type);
|
void showMemoryWidget(MemoryWidgetType type);
|
||||||
enum class AddressTypeHint { Function, Data, Unknown };
|
enum class AddressTypeHint { Function, Data, Unknown };
|
||||||
QMenu *createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType = AddressTypeHint::Unknown);
|
QMenu *createShowInMenu(QWidget *parent, RVA address,
|
||||||
void setCurrentMemoryWidget(MemoryDockWidget* memoryWidget);
|
AddressTypeHint addressType = AddressTypeHint::Unknown);
|
||||||
MemoryDockWidget* getLastMemoryWidget();
|
void setCurrentMemoryWidget(MemoryDockWidget *memoryWidget);
|
||||||
|
MemoryDockWidget *getLastMemoryWidget();
|
||||||
|
|
||||||
/* Context menu plugins */
|
/* Context menu plugins */
|
||||||
enum class ContextMenuType { Disassembly, Addressable };
|
enum class ContextMenuType { Disassembly, Addressable };
|
||||||
@ -202,6 +204,7 @@ private slots:
|
|||||||
void onZoomReset();
|
void onZoomReset();
|
||||||
|
|
||||||
void setAvailableIOModeOptions();
|
void setAvailableIOModeOptions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CutterCore *core;
|
CutterCore *core;
|
||||||
|
|
||||||
@ -266,7 +269,8 @@ private:
|
|||||||
void initToolBar();
|
void initToolBar();
|
||||||
void initDocks();
|
void initDocks();
|
||||||
void initBackForwardMenu();
|
void initBackForwardMenu();
|
||||||
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false);
|
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(),
|
||||||
|
bool skipOptionsDialog = false);
|
||||||
|
|
||||||
Cutter::CutterLayout getViewLayout();
|
Cutter::CutterLayout getViewLayout();
|
||||||
Cutter::CutterLayout getViewLayout(const QString &name);
|
Cutter::CutterLayout getViewLayout(const QString &name);
|
||||||
@ -275,7 +279,6 @@ private:
|
|||||||
void loadLayouts(QSettings &settings);
|
void loadLayouts(QSettings &settings);
|
||||||
void saveLayouts(QSettings &settings);
|
void saveLayouts(QSettings &settings);
|
||||||
|
|
||||||
|
|
||||||
void updateMemberPointers();
|
void updateMemberPointers();
|
||||||
void restoreDocks();
|
void restoreDocks();
|
||||||
void showZenDocks();
|
void showZenDocks();
|
||||||
@ -309,12 +312,13 @@ private:
|
|||||||
MemoryWidgetType getMemoryWidgetTypeToRestore();
|
MemoryWidgetType getMemoryWidgetTypeToRestore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective contructor of the widget
|
* @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective
|
||||||
|
* contructor of the widget
|
||||||
*/
|
*/
|
||||||
QMap<QString, std::function<CutterDockWidget*(MainWindow*)>> widgetTypeToConstructorMap;
|
QMap<QString, std::function<CutterDockWidget *(MainWindow *)>> widgetTypeToConstructorMap;
|
||||||
|
|
||||||
MemoryDockWidget* lastSyncMemoryWidget = nullptr;
|
MemoryDockWidget *lastSyncMemoryWidget = nullptr;
|
||||||
MemoryDockWidget* lastMemoryWidget = nullptr;
|
MemoryDockWidget *lastMemoryWidget = nullptr;
|
||||||
int functionDockWidthToRestore = 0;
|
int functionDockWidthToRestore = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,26 +18,25 @@
|
|||||||
|
|
||||||
#include "CutterConfig.h"
|
#include "CutterConfig.h"
|
||||||
|
|
||||||
AboutDialog::AboutDialog(QWidget *parent) :
|
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::AboutDialog)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
ui->logoSvgWidget->load(Config()->getLogoFile());
|
ui->logoSvgWidget->load(Config()->getLogoFile());
|
||||||
|
|
||||||
QString aboutString(tr("Version") + " " CUTTER_VERSION_FULL "<br/>"
|
QString aboutString(
|
||||||
+ tr("Using rizin-") + RZ_GITTAP + "<br/>"
|
tr("Version") + " " CUTTER_VERSION_FULL "<br/>" + tr("Using rizin-") + RZ_GITTAP
|
||||||
+ buildQtVersionString()
|
+ "<br/>" + buildQtVersionString() + "<p><b>" + tr("Optional Features:") + "</b><br/>"
|
||||||
+ "<p><b>" + tr("Optional Features:") + "</b><br/>"
|
+ QString("Python: %1<br/>")
|
||||||
+ QString("Python: %1<br/>").arg(
|
.arg(
|
||||||
#ifdef CUTTER_ENABLE_PYTHON
|
#ifdef CUTTER_ENABLE_PYTHON
|
||||||
"ON"
|
"ON"
|
||||||
#else
|
#else
|
||||||
"OFF"
|
"OFF"
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
+ QString("Python Bindings: %2</p>").arg(
|
+ QString("Python Bindings: %2</p>")
|
||||||
|
.arg(
|
||||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||||
"ON"
|
"ON"
|
||||||
#else
|
#else
|
||||||
@ -45,10 +44,13 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
+ "<h2>" + tr("License") + "</h2>"
|
+ "<h2>" + tr("License") + "</h2>"
|
||||||
+ tr("This Software is released under the GNU General Public License v3.0")
|
+ tr("This Software is released under the GNU General Public License v3.0") + "<h2>"
|
||||||
+ "<h2>" + tr("Authors") + "</h2>"
|
+ tr("Authors") + "</h2>"
|
||||||
+ tr("Cutter is developed by the community and maintained by its core and development teams.<br/>")
|
+ tr("Cutter is developed by the community and maintained by its core and development "
|
||||||
+ tr("Check our <a href='https://github.com/rizinorg/cutter/graphs/contributors'>contributors page</a> for the full list of contributors."));
|
"teams.<br/>")
|
||||||
|
+ tr("Check our <a "
|
||||||
|
"href='https://github.com/rizinorg/cutter/graphs/contributors'>contributors "
|
||||||
|
"page</a> for the full list of contributors."));
|
||||||
ui->label->setText(aboutString);
|
ui->label->setText(aboutString);
|
||||||
|
|
||||||
QSignalBlocker s(ui->updatesCheckBox);
|
QSignalBlocker s(ui->updatesCheckBox);
|
||||||
@ -97,12 +99,13 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
|
|||||||
|
|
||||||
connect(&updateWorker, &UpdateWorker::checkComplete, &waitDialog, &QProgressDialog::cancel);
|
connect(&updateWorker, &UpdateWorker::checkComplete, &waitDialog, &QProgressDialog::cancel);
|
||||||
connect(&updateWorker, &UpdateWorker::checkComplete,
|
connect(&updateWorker, &UpdateWorker::checkComplete,
|
||||||
[&updateWorker](const QVersionNumber & version, const QString & error) {
|
[&updateWorker](const QVersionNumber &version, const QString &error) {
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
QMessageBox::critical(nullptr, tr("Error!"), error);
|
QMessageBox::critical(nullptr, tr("Error!"), error);
|
||||||
} else {
|
} else {
|
||||||
if (version <= UpdateWorker::currentVersionNumber()) {
|
if (version <= UpdateWorker::currentVersionNumber()) {
|
||||||
QMessageBox::information(nullptr, tr("Version control"), tr("Cutter is up to date!"));
|
QMessageBox::information(nullptr, tr("Version control"),
|
||||||
|
tr("Cutter is up to date!"));
|
||||||
} else {
|
} else {
|
||||||
updateWorker.showUpdateDialog(false);
|
updateWorker.showUpdateDialog(false);
|
||||||
}
|
}
|
||||||
@ -123,13 +126,13 @@ static QString compilerString()
|
|||||||
{
|
{
|
||||||
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
|
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
|
||||||
QString isAppleString;
|
QString isAppleString;
|
||||||
#if defined(__apple_build_version__) // Apple clang has other version numbers
|
# if defined(__apple_build_version__) // Apple clang has other version numbers
|
||||||
isAppleString = QLatin1String(" (Apple)");
|
isAppleString = QLatin1String(" (Apple)");
|
||||||
#endif
|
# endif
|
||||||
return QLatin1String("Clang " ) + QString::number(__clang_major__) + QLatin1Char('.')
|
return QLatin1String("Clang ") + QString::number(__clang_major__) + QLatin1Char('.')
|
||||||
+ QString::number(__clang_minor__) + isAppleString;
|
+ QString::number(__clang_minor__) + isAppleString;
|
||||||
#elif defined(Q_CC_GNU)
|
#elif defined(Q_CC_GNU)
|
||||||
return QLatin1String("GCC " ) + QLatin1String(__VERSION__);
|
return QLatin1String("GCC ") + QLatin1String(__VERSION__);
|
||||||
#elif defined(Q_CC_MSVC)
|
#elif defined(Q_CC_MSVC)
|
||||||
if (_MSC_VER > 1999)
|
if (_MSC_VER > 1999)
|
||||||
return QLatin1String("MSVC <unknown>");
|
return QLatin1String("MSVC <unknown>");
|
||||||
@ -143,7 +146,6 @@ static QString compilerString()
|
|||||||
|
|
||||||
QString AboutDialog::buildQtVersionString(void)
|
QString AboutDialog::buildQtVersionString(void)
|
||||||
{
|
{
|
||||||
return tr("Based on Qt %1 (%2, %3 bit)").arg(QLatin1String(qVersion()),
|
return tr("Based on Qt %1 (%2, %3 bit)")
|
||||||
compilerString(),
|
.arg(QLatin1String(qVersion()), compilerString(), QString::number(QSysInfo::WordSize));
|
||||||
QString::number(QSysInfo::WordSize));
|
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,8 @@
|
|||||||
|
|
||||||
#include "ui_AsyncTaskDialog.h"
|
#include "ui_AsyncTaskDialog.h"
|
||||||
|
|
||||||
|
|
||||||
AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent), ui(new Ui::AsyncTaskDialog), task(task)
|
||||||
ui(new Ui::AsyncTaskDialog),
|
|
||||||
task(task)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -18,9 +15,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(task.data(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog);
|
connect(task.data(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog);
|
||||||
connect(task.data(), &AsyncTask::finished, this, [this]() {
|
connect(task.data(), &AsyncTask::finished, this, [this]() { close(); });
|
||||||
close();
|
|
||||||
});
|
|
||||||
|
|
||||||
updateLog(task->getLog());
|
updateLog(task->getLog());
|
||||||
|
|
||||||
@ -32,9 +27,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
|||||||
updateProgressTimer();
|
updateProgressTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncTaskDialog::~AsyncTaskDialog()
|
AsyncTaskDialog::~AsyncTaskDialog() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncTaskDialog::updateLog(const QString &log)
|
void AsyncTaskDialog::updateLog(const QString &log)
|
||||||
{
|
{
|
||||||
|
@ -42,4 +42,4 @@ private:
|
|||||||
bool interruptOnClose = false;
|
bool interruptOnClose = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //ASYNCTASKDIALOG_H
|
#endif // ASYNCTASKDIALOG_H
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
// ------------
|
// ------------
|
||||||
// ProcessModel
|
// ProcessModel
|
||||||
// ------------
|
// ------------
|
||||||
ProcessModel::ProcessModel(QObject *parent)
|
ProcessModel::ProcessModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
: QAbstractListModel(parent)
|
|
||||||
{
|
{
|
||||||
updateData();
|
updateData();
|
||||||
}
|
}
|
||||||
@ -125,7 +124,8 @@ QString ProcessBeingAnalysedProxyModel::processPathToFilename(const QString &pat
|
|||||||
bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||||
ProcessDescription item = index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
ProcessDescription item =
|
||||||
|
index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
|
|
||||||
QString procFilename = processPathToFilename(item.path);
|
QString procFilename = processPathToFilename(item.path);
|
||||||
return procFilename == processBeingAnalysedFilename;
|
return procFilename == processBeingAnalysedFilename;
|
||||||
@ -134,10 +134,10 @@ bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex
|
|||||||
bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left,
|
bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left,
|
||||||
const QModelIndex &right) const
|
const QModelIndex &right) const
|
||||||
{
|
{
|
||||||
ProcessDescription leftProc = left.data(
|
ProcessDescription leftProc =
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
ProcessDescription rightProc = right.data(
|
ProcessDescription rightProc =
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
|
|
||||||
return ProcessModel::lessThan(leftProc, rightProc, left.column());
|
return ProcessModel::lessThan(leftProc, rightProc, left.column());
|
||||||
}
|
}
|
||||||
@ -154,16 +154,17 @@ ProcessProxyModel::ProcessProxyModel(ProcessModel *sourceModel, QObject *parent)
|
|||||||
bool ProcessProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
bool ProcessProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||||
ProcessDescription item = index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
ProcessDescription item =
|
||||||
|
index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
return item.path.contains(filterRegExp());
|
return item.path.contains(filterRegExp());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
{
|
{
|
||||||
ProcessDescription leftProc = left.data(
|
ProcessDescription leftProc =
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
ProcessDescription rightProc = right.data(
|
ProcessDescription rightProc =
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||||
|
|
||||||
return ProcessModel::lessThan(leftProc, rightProc, left.column());
|
return ProcessModel::lessThan(leftProc, rightProc, left.column());
|
||||||
}
|
}
|
||||||
@ -171,9 +172,7 @@ bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig
|
|||||||
// ----------------
|
// ----------------
|
||||||
// AttachProcDialog
|
// AttachProcDialog
|
||||||
// ----------------
|
// ----------------
|
||||||
AttachProcDialog::AttachProcDialog(QWidget *parent) :
|
AttachProcDialog::AttachProcDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AttachProcDialog)
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::AttachProcDialog)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
@ -232,13 +231,19 @@ void AttachProcDialog::updateModelData()
|
|||||||
|
|
||||||
if (allViewHadSelection) {
|
if (allViewHadSelection) {
|
||||||
allViewPrevScrollPos = allView->verticalScrollBar()->value();
|
allViewPrevScrollPos = allView->verticalScrollBar()->value();
|
||||||
allViewPrevPID = allView->selectionModel()->currentIndex().data(
|
allViewPrevPID = allView->selectionModel()
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
->currentIndex()
|
||||||
|
.data(ProcessModel::ProcDescriptionRole)
|
||||||
|
.value<ProcessDescription>()
|
||||||
|
.pid;
|
||||||
}
|
}
|
||||||
if (smallViewHadSelection) {
|
if (smallViewHadSelection) {
|
||||||
smallViewPrevScrollPos = smallView->verticalScrollBar()->value();
|
smallViewPrevScrollPos = smallView->verticalScrollBar()->value();
|
||||||
smallViewPrevPID = smallView->selectionModel()->currentIndex().data(
|
smallViewPrevPID = smallView->selectionModel()
|
||||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
->currentIndex()
|
||||||
|
.data(ProcessModel::ProcDescriptionRole)
|
||||||
|
.value<ProcessDescription>()
|
||||||
|
.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the model update
|
// Let the model update
|
||||||
@ -246,16 +251,18 @@ void AttachProcDialog::updateModelData()
|
|||||||
|
|
||||||
// Restore the selection and scroll position
|
// Restore the selection and scroll position
|
||||||
if (allViewHadSelection) {
|
if (allViewHadSelection) {
|
||||||
QModelIndexList idx = allView->model()->match(
|
QModelIndexList idx =
|
||||||
allView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(allViewPrevPID));
|
allView->model()->match(allView->model()->index(0, 0), Qt::DisplayRole,
|
||||||
|
QVariant::fromValue(allViewPrevPID));
|
||||||
if (!idx.isEmpty()) {
|
if (!idx.isEmpty()) {
|
||||||
allView->setCurrentIndex(idx.first());
|
allView->setCurrentIndex(idx.first());
|
||||||
allView->verticalScrollBar()->setValue(allViewPrevScrollPos);
|
allView->verticalScrollBar()->setValue(allViewPrevScrollPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (smallViewHadSelection) {
|
if (smallViewHadSelection) {
|
||||||
QModelIndexList idx = smallView->model()->match(
|
QModelIndexList idx =
|
||||||
smallView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(smallViewPrevPID));
|
smallView->model()->match(smallView->model()->index(0, 0), Qt::DisplayRole,
|
||||||
|
QVariant::fromValue(smallViewPrevPID));
|
||||||
|
|
||||||
if (!idx.isEmpty()) {
|
if (!idx.isEmpty()) {
|
||||||
smallView->setCurrentIndex(idx.first());
|
smallView->setCurrentIndex(idx.first());
|
||||||
@ -265,14 +272,13 @@ void AttachProcDialog::updateModelData()
|
|||||||
|
|
||||||
// Init selection if nothing was ever selected yet, and a new process with the same name
|
// Init selection if nothing was ever selected yet, and a new process with the same name
|
||||||
// as the one being analysed was launched.
|
// as the one being analysed was launched.
|
||||||
if (!allView->selectionModel()->hasSelection() && !smallView->selectionModel()->hasSelection()) {
|
if (!allView->selectionModel()->hasSelection()
|
||||||
|
&& !smallView->selectionModel()->hasSelection()) {
|
||||||
smallView->setCurrentIndex(smallView->model()->index(0, 0));
|
smallView->setCurrentIndex(smallView->model()->index(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachProcDialog::on_buttonBox_accepted()
|
void AttachProcDialog::on_buttonBox_accepted() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttachProcDialog::on_buttonBox_rejected()
|
void AttachProcDialog::on_buttonBox_rejected()
|
||||||
{
|
{
|
||||||
@ -302,12 +308,18 @@ int AttachProcDialog::getPID()
|
|||||||
|
|
||||||
// Here we need to know which table was selected last to get the proper PID
|
// Here we need to know which table was selected last to get the proper PID
|
||||||
if (wasAllProcViewLastPressed && ui->allProcView->selectionModel()->hasSelection()) {
|
if (wasAllProcViewLastPressed && ui->allProcView->selectionModel()->hasSelection()) {
|
||||||
pid = ui->allProcView->selectionModel()->currentIndex().
|
pid = ui->allProcView->selectionModel()
|
||||||
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
->currentIndex()
|
||||||
|
.data(ProcessModel::ProcDescriptionRole)
|
||||||
|
.value<ProcessDescription>()
|
||||||
|
.pid;
|
||||||
} else if (!wasAllProcViewLastPressed
|
} else if (!wasAllProcViewLastPressed
|
||||||
&& ui->procBeingAnalyzedView->selectionModel()->hasSelection()) {
|
&& ui->procBeingAnalyzedView->selectionModel()->hasSelection()) {
|
||||||
pid = ui->procBeingAnalyzedView->selectionModel()->currentIndex().
|
pid = ui->procBeingAnalyzedView->selectionModel()
|
||||||
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
->currentIndex()
|
||||||
|
.data(ProcessModel::ProcDescriptionRole)
|
||||||
|
.value<ProcessDescription>()
|
||||||
|
.pid;
|
||||||
} else {
|
} else {
|
||||||
// Error attaching. No process selected! Happens when you press ENTER but
|
// Error attaching. No process selected! Happens when you press ENTER but
|
||||||
// there was no process with the same name as the one being analyzed.
|
// there was no process with the same name as the one being analyzed.
|
||||||
|
@ -15,8 +15,7 @@ class MainWindow;
|
|||||||
class QTreeWidget;
|
class QTreeWidget;
|
||||||
class QTreeWidgetItem;
|
class QTreeWidgetItem;
|
||||||
|
|
||||||
|
class ProcessModel : public QAbstractListModel
|
||||||
class ProcessModel: public QAbstractListModel
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -34,14 +33,13 @@ public:
|
|||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
static bool lessThan(const ProcessDescription &left, const ProcessDescription &right, int column);
|
static bool lessThan(const ProcessDescription &left, const ProcessDescription &right,
|
||||||
|
int column);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateData();
|
void updateData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessProxyModel : public QSortFilterProxyModel
|
class ProcessProxyModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -54,7 +52,6 @@ protected:
|
|||||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ProcessBeingAnalysedProxyModel : public QSortFilterProxyModel
|
class ProcessBeingAnalysedProxyModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -71,8 +68,6 @@ private:
|
|||||||
QString processPathToFilename(const QString &path) const;
|
QString processPathToFilename(const QString &path) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AttachProcDialog : public QDialog
|
class AttachProcDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -7,15 +7,14 @@
|
|||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
|
||||||
BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::BreakpointsDialog), editMode(editMode)
|
||||||
ui(new Ui::BreakpointsDialog),
|
|
||||||
editMode(editMode)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
|
|
||||||
connect(ui->breakpointPosition, &QLineEdit::textChanged, this, &BreakpointsDialog::refreshOkButton);
|
connect(ui->breakpointPosition, &QLineEdit::textChanged, this,
|
||||||
|
&BreakpointsDialog::refreshOkButton);
|
||||||
refreshOkButton();
|
refreshOkButton();
|
||||||
|
|
||||||
if (editMode) {
|
if (editMode) {
|
||||||
@ -24,15 +23,16 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
|||||||
setWindowTitle(tr("New breakpoint"));
|
setWindowTitle(tr("New breakpoint"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct
|
||||||
struct {
|
{
|
||||||
QString label;
|
QString label;
|
||||||
QString tooltip;
|
QString tooltip;
|
||||||
BreakpointDescription::PositionType type;
|
BreakpointDescription::PositionType type;
|
||||||
} positionTypes[] = {
|
} positionTypes[] = {
|
||||||
{tr("Address"), tr("Address or expression calculated when creating breakpoint"), BreakpointDescription::Address},
|
{ tr("Address"), tr("Address or expression calculated when creating breakpoint"),
|
||||||
{tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named},
|
BreakpointDescription::Address },
|
||||||
{tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module},
|
{ tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named },
|
||||||
|
{ tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module },
|
||||||
};
|
};
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto &item : positionTypes) {
|
for (auto &item : positionTypes) {
|
||||||
@ -41,8 +41,9 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
|||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->positionType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
connect(ui->positionType,
|
||||||
this, &BreakpointsDialog::onTypeChanged);
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
|
&BreakpointsDialog::onTypeChanged);
|
||||||
onTypeChanged();
|
onTypeChanged();
|
||||||
|
|
||||||
auto modules = Core()->getMemoryMap();
|
auto modules = Core()->getMemoryMap();
|
||||||
@ -50,7 +51,7 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
|||||||
for (const auto &module : modules) {
|
for (const auto &module : modules) {
|
||||||
moduleNames.insert(module.fileName);
|
moduleNames.insert(module.fileName);
|
||||||
}
|
}
|
||||||
for (const auto& module : moduleNames) {
|
for (const auto &module : moduleNames) {
|
||||||
ui->moduleName->addItem(module);
|
ui->moduleName->addItem(module);
|
||||||
}
|
}
|
||||||
ui->moduleName->setCurrentText("");
|
ui->moduleName->setCurrentText("");
|
||||||
@ -111,7 +112,8 @@ BreakpointsDialog::~BreakpointsDialog() {}
|
|||||||
BreakpointDescription BreakpointsDialog::getDescription()
|
BreakpointDescription BreakpointsDialog::getDescription()
|
||||||
{
|
{
|
||||||
BreakpointDescription breakpoint;
|
BreakpointDescription breakpoint;
|
||||||
auto positionType = ui->positionType->currentData().value<BreakpointDescription::PositionType>();
|
auto positionType =
|
||||||
|
ui->positionType->currentData().value<BreakpointDescription::PositionType>();
|
||||||
switch (positionType) {
|
switch (positionType) {
|
||||||
case BreakpointDescription::Address:
|
case BreakpointDescription::Address:
|
||||||
breakpoint.addr = Core()->math(ui->breakpointPosition->text());
|
breakpoint.addr = Core()->math(ui->breakpointPosition->text());
|
||||||
@ -167,7 +169,8 @@ void BreakpointsDialog::onTypeChanged()
|
|||||||
bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module);
|
bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module);
|
||||||
ui->moduleLabel->setEnabled(moduleEnabled);
|
ui->moduleLabel->setEnabled(moduleEnabled);
|
||||||
ui->moduleName->setEnabled(moduleEnabled);
|
ui->moduleName->setEnabled(moduleEnabled);
|
||||||
ui->breakpointPosition->setPlaceholderText(ui->positionType->currentData(Qt::ToolTipRole).toString());
|
ui->breakpointPosition->setPlaceholderText(
|
||||||
|
ui->positionType->currentData(Qt::ToolTipRole).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BreakpointsDialog::configureCheckboxRestrictions()
|
void BreakpointsDialog::configureCheckboxRestrictions()
|
||||||
|
@ -21,7 +21,8 @@ public:
|
|||||||
BreakpointDescription getDescription();
|
BreakpointDescription getDescription();
|
||||||
|
|
||||||
static void createNewBreakpoint(RVA address = RVA_INVALID, QWidget *parent = nullptr);
|
static void createNewBreakpoint(RVA address = RVA_INVALID, QWidget *parent = nullptr);
|
||||||
static void editBreakpoint(const BreakpointDescription& breakpoint, QWidget *parent = nullptr);
|
static void editBreakpoint(const BreakpointDescription &breakpoint, QWidget *parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::BreakpointsDialog> ui;
|
std::unique_ptr<Ui::BreakpointsDialog> ui;
|
||||||
bool editMode = false;
|
bool editMode = false;
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
|
|
||||||
CommentsDialog::CommentsDialog(QWidget *parent) :
|
CommentsDialog::CommentsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CommentsDialog)
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::CommentsDialog)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
@ -16,9 +14,7 @@ CommentsDialog::CommentsDialog(QWidget *parent) :
|
|||||||
|
|
||||||
CommentsDialog::~CommentsDialog() {}
|
CommentsDialog::~CommentsDialog() {}
|
||||||
|
|
||||||
void CommentsDialog::on_buttonBox_accepted()
|
void CommentsDialog::on_buttonBox_accepted() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommentsDialog::on_buttonBox_rejected()
|
void CommentsDialog::on_buttonBox_rejected()
|
||||||
{
|
{
|
||||||
@ -60,14 +56,14 @@ void CommentsDialog::addOrEditComment(RVA offset, QWidget *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommentsDialog::eventFilter(QObject */*obj*/, QEvent *event)
|
bool CommentsDialog::eventFilter(QObject * /*obj*/, QEvent *event)
|
||||||
{
|
{
|
||||||
if (event -> type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast <QKeyEvent *> (event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
|
||||||
// Confirm comment by pressing Ctrl/Cmd+Return
|
// Confirm comment by pressing Ctrl/Cmd+Return
|
||||||
if ((keyEvent -> modifiers() & Qt::ControlModifier) &&
|
if ((keyEvent->modifiers() & Qt::ControlModifier)
|
||||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return))) {
|
&& ((keyEvent->key() == Qt::Key_Enter) || (keyEvent->key() == Qt::Key_Return))) {
|
||||||
this->accept();
|
this->accept();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#include "EditFunctionDialog.h"
|
#include "EditFunctionDialog.h"
|
||||||
#include "ui_EditFunctionDialog.h"
|
#include "ui_EditFunctionDialog.h"
|
||||||
|
|
||||||
EditFunctionDialog::EditFunctionDialog(QWidget *parent) :
|
EditFunctionDialog::EditFunctionDialog(QWidget *parent)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::EditFunctionDialog)
|
||||||
ui(new Ui::EditFunctionDialog)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
@ -44,21 +43,22 @@ void EditFunctionDialog::setStackSizeText(const QString &stackSize)
|
|||||||
ui->stackSizeLineEdit->setText(stackSize);
|
ui->stackSizeLineEdit->setText(stackSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditFunctionDialog::setCallConList(const QStringList &callConList) {
|
void EditFunctionDialog::setCallConList(const QStringList &callConList)
|
||||||
|
{
|
||||||
ui->callConComboBox->addItems(callConList);
|
ui->callConComboBox->addItems(callConList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditFunctionDialog::setCallConSelected(const QString &selected) {
|
void EditFunctionDialog::setCallConSelected(const QString &selected)
|
||||||
|
{
|
||||||
ui->callConComboBox->setCurrentText(selected);
|
ui->callConComboBox->setCurrentText(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EditFunctionDialog::getCallConSelected() {
|
QString EditFunctionDialog::getCallConSelected()
|
||||||
|
{
|
||||||
return ui->callConComboBox->currentText();
|
return ui->callConComboBox->currentText();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditFunctionDialog::on_buttonBox_accepted()
|
void EditFunctionDialog::on_buttonBox_accepted() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditFunctionDialog::on_buttonBox_rejected()
|
void EditFunctionDialog::on_buttonBox_rejected()
|
||||||
{
|
{
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
#include "ui_EditInstructionDialog.h"
|
#include "ui_EditInstructionDialog.h"
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
|
|
||||||
EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent) :
|
EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::EditInstructionDialog), editMode(editMode)
|
||||||
ui(new Ui::EditInstructionDialog),
|
|
||||||
editMode(editMode)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->lineEdit->setMinimumWidth(400);
|
ui->lineEdit->setMinimumWidth(400);
|
||||||
@ -17,9 +15,7 @@ EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidg
|
|||||||
|
|
||||||
EditInstructionDialog::~EditInstructionDialog() {}
|
EditInstructionDialog::~EditInstructionDialog() {}
|
||||||
|
|
||||||
void EditInstructionDialog::on_buttonBox_accepted()
|
void EditInstructionDialog::on_buttonBox_accepted() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditInstructionDialog::on_buttonBox_rejected()
|
void EditInstructionDialog::on_buttonBox_rejected()
|
||||||
{
|
{
|
||||||
|
@ -8,9 +8,7 @@ namespace Ui {
|
|||||||
class EditInstructionDialog;
|
class EditInstructionDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InstructionEditMode {
|
enum InstructionEditMode { EDIT_NONE, EDIT_BYTES, EDIT_TEXT };
|
||||||
EDIT_NONE, EDIT_BYTES, EDIT_TEXT
|
|
||||||
};
|
|
||||||
|
|
||||||
class EditInstructionDialog : public QDialog
|
class EditInstructionDialog : public QDialog
|
||||||
{
|
{
|
||||||
@ -32,7 +30,8 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::EditInstructionDialog> ui;
|
std::unique_ptr<Ui::EditInstructionDialog> ui;
|
||||||
InstructionEditMode editMode; // true if editing intruction **bytes**; false if editing instruction **text**
|
InstructionEditMode
|
||||||
|
editMode; // true if editing intruction **bytes**; false if editing instruction **text**
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EDITINSTRUCTIONDIALOG_H
|
#endif // EDITINSTRUCTIONDIALOG_H
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) :
|
EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::EditMethodDialog)
|
||||||
ui(new Ui::EditMethodDialog)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||||
@ -24,15 +23,14 @@ EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) :
|
|||||||
updateVirtualUI();
|
updateVirtualUI();
|
||||||
validateInput();
|
validateInput();
|
||||||
|
|
||||||
connect(ui->virtualCheckBox, &QCheckBox::stateChanged, this, &EditMethodDialog::updateVirtualUI);
|
connect(ui->virtualCheckBox, &QCheckBox::stateChanged, this,
|
||||||
|
&EditMethodDialog::updateVirtualUI);
|
||||||
connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput);
|
connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditMethodDialog::~EditMethodDialog() {}
|
EditMethodDialog::~EditMethodDialog() {}
|
||||||
|
|
||||||
void EditMethodDialog::on_buttonBox_accepted()
|
void EditMethodDialog::on_buttonBox_accepted() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditMethodDialog::on_buttonBox_rejected()
|
void EditMethodDialog::on_buttonBox_rejected()
|
||||||
{
|
{
|
||||||
@ -73,7 +71,7 @@ void EditMethodDialog::setClass(const QString &className)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<classComboBox->count(); i++) {
|
for (int i = 0; i < classComboBox->count(); i++) {
|
||||||
QString cls = classComboBox->itemData(i).toString();
|
QString cls = classComboBox->itemData(i).toString();
|
||||||
if (cls == className) {
|
if (cls == className) {
|
||||||
classComboBox->setCurrentIndex(i);
|
classComboBox->setCurrentIndex(i);
|
||||||
@ -131,7 +129,8 @@ AnalMethodDescription EditMethodDialog::getMethod() const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditMethodDialog::showDialog(const QString &title, bool classFixed, QString *className, AnalMethodDescription *desc, QWidget *parent)
|
bool EditMethodDialog::showDialog(const QString &title, bool classFixed, QString *className,
|
||||||
|
AnalMethodDescription *desc, QWidget *parent)
|
||||||
{
|
{
|
||||||
EditMethodDialog dialog(classFixed, parent);
|
EditMethodDialog dialog(classFixed, parent);
|
||||||
dialog.setWindowTitle(title);
|
dialog.setWindowTitle(title);
|
||||||
|
@ -17,7 +17,8 @@ class EditMethodDialog : public QDialog
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param classFixed whether the user should be able to change the class. If false, a QComboBox will be shown, otherwise a plain QLabel.
|
* @param classFixed whether the user should be able to change the class. If false, a QComboBox
|
||||||
|
* will be shown, otherwise a plain QLabel.
|
||||||
*/
|
*/
|
||||||
explicit EditMethodDialog(bool classFixed, QWidget *parent = nullptr);
|
explicit EditMethodDialog(bool classFixed, QWidget *parent = nullptr);
|
||||||
~EditMethodDialog();
|
~EditMethodDialog();
|
||||||
@ -37,17 +38,20 @@ public:
|
|||||||
* @param desc initial data for the method information
|
* @param desc initial data for the method information
|
||||||
* @return whether the dialog was accepted by the user
|
* @return whether the dialog was accepted by the user
|
||||||
*/
|
*/
|
||||||
static bool showDialog(const QString &title, bool classFixed, QString *className, AnalMethodDescription *desc, QWidget *parent = nullptr);
|
static bool showDialog(const QString &title, bool classFixed, QString *className,
|
||||||
|
AnalMethodDescription *desc, QWidget *parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show the dialog to add a new method a given class
|
* @brief Show the dialog to add a new method a given class
|
||||||
*/
|
*/
|
||||||
static void newMethod(QString className = nullptr, const QString &meth = QString(), QWidget *parent = nullptr);
|
static void newMethod(QString className = nullptr, const QString &meth = QString(),
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show the dialog to edit a given method of a given class
|
* @brief Show the dialog to edit a given method of a given class
|
||||||
*/
|
*/
|
||||||
static void editMethod(const QString &className, const QString &meth, QWidget *parent = nullptr);
|
static void editMethod(const QString &className, const QString &meth,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
@ -62,7 +66,8 @@ private:
|
|||||||
QComboBox *classComboBox = nullptr;
|
QComboBox *classComboBox = nullptr;
|
||||||
QLabel *classLabel = nullptr;
|
QLabel *classLabel = nullptr;
|
||||||
/**
|
/**
|
||||||
* This will only be used when the dialog was created with classFixed = true in order to remember the class name.
|
* This will only be used when the dialog was created with classFixed = true in order to
|
||||||
|
* remember the class name.
|
||||||
*/
|
*/
|
||||||
QString fixedClass;
|
QString fixedClass;
|
||||||
|
|
||||||
|
@ -2,25 +2,24 @@
|
|||||||
#include "ui_EditStringDialog.h"
|
#include "ui_EditStringDialog.h"
|
||||||
|
|
||||||
EditStringDialog::EditStringDialog(QWidget *parent)
|
EditStringDialog::EditStringDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent), ui(new Ui::EditStringDialog {})
|
||||||
, ui(new Ui::EditStringDialog{})
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->spinBox_size->setMinimum(0);
|
ui->spinBox_size->setMinimum(0);
|
||||||
ui->lineEdit_address->setMinimumWidth(150);
|
ui->lineEdit_address->setMinimumWidth(150);
|
||||||
ui->spinBox_size->setFocus();
|
ui->spinBox_size->setFocus();
|
||||||
ui->comboBox_type->addItems({"Auto", "ASCII/Latin1", "UTF-8"});
|
ui->comboBox_type->addItems({ "Auto", "ASCII/Latin1", "UTF-8" });
|
||||||
connect(ui->checkBox_autoSize, &QCheckBox::toggled, ui->spinBox_size, &QSpinBox::setDisabled);
|
connect(ui->checkBox_autoSize, &QCheckBox::toggled, ui->spinBox_size, &QSpinBox::setDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditStringDialog::~EditStringDialog() { }
|
EditStringDialog::~EditStringDialog() {}
|
||||||
|
|
||||||
void EditStringDialog::setStringStartAddress(uint64_t address)
|
void EditStringDialog::setStringStartAddress(uint64_t address)
|
||||||
{
|
{
|
||||||
ui->lineEdit_address->setText(QString::number(address, 16));
|
ui->lineEdit_address->setText(QString::number(address, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditStringDialog::getStringStartAddress(uint64_t& returnValue) const
|
bool EditStringDialog::getStringStartAddress(uint64_t &returnValue) const
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
returnValue = ui->lineEdit_address->text().toLongLong(&status, 16);
|
returnValue = ui->lineEdit_address->text().toLongLong(&status, 16);
|
||||||
@ -34,7 +33,7 @@ void EditStringDialog::setStringSizeValue(uint32_t size)
|
|||||||
|
|
||||||
int EditStringDialog::getStringSizeValue() const
|
int EditStringDialog::getStringSizeValue() const
|
||||||
{
|
{
|
||||||
if( ui->checkBox_autoSize->isChecked() ) {
|
if (ui->checkBox_autoSize->isChecked()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,18 +44,14 @@ EditStringDialog::StringType EditStringDialog::getStringType() const
|
|||||||
{
|
{
|
||||||
const int indexVal = ui->comboBox_type->currentIndex();
|
const int indexVal = ui->comboBox_type->currentIndex();
|
||||||
|
|
||||||
switch(indexVal)
|
switch (indexVal) {
|
||||||
{
|
case 0: {
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
return EditStringDialog::StringType::Auto;
|
return EditStringDialog::StringType::Auto;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1: {
|
||||||
{
|
|
||||||
return EditStringDialog::StringType::ASCII_LATIN1;
|
return EditStringDialog::StringType::ASCII_LATIN1;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2: {
|
||||||
{
|
|
||||||
return EditStringDialog::StringType::UTF8;
|
return EditStringDialog::StringType::UTF8;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -13,7 +13,7 @@ class EditStringDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class StringType {Auto, ASCII_LATIN1, UTF8};
|
enum class StringType { Auto, ASCII_LATIN1, UTF8 };
|
||||||
explicit EditStringDialog(QWidget *parent = nullptr);
|
explicit EditStringDialog(QWidget *parent = nullptr);
|
||||||
~EditStringDialog();
|
~EditStringDialog();
|
||||||
|
|
||||||
@ -31,7 +31,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool getStringStartAddress(uint64_t &returnValue) const;
|
bool getStringStartAddress(uint64_t &returnValue) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the size of string in the dialog
|
* @brief Sets the size of string in the dialog
|
||||||
*
|
*
|
||||||
|
@ -6,16 +6,13 @@
|
|||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget *parent)
|
||||||
EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget *parent) :
|
: QDialog(parent), ui(new Ui::EditVariablesDialog), functionAddress(RVA_INVALID)
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::EditVariablesDialog),
|
|
||||||
functionAddress(RVA_INVALID)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditVariablesDialog::applyFields);
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditVariablesDialog::applyFields);
|
||||||
connect<void(QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged,
|
connect<void (QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged, this,
|
||||||
this, &EditVariablesDialog::updateFields);
|
&EditVariablesDialog::updateFields);
|
||||||
|
|
||||||
QString fcnName = Core()->cmdRawAt("afn.", offset).trimmed();
|
QString fcnName = Core()->cmdRawAt("afn.", offset).trimmed();
|
||||||
functionAddress = offset;
|
functionAddress = offset;
|
||||||
@ -61,7 +58,8 @@ void EditVariablesDialog::applyFields()
|
|||||||
Core()->cmdRaw(QString("afvt %1 %2").arg(desc.name).arg(ui->typeComboBox->currentText()));
|
Core()->cmdRaw(QString("afvt %1 %2").arg(desc.name).arg(ui->typeComboBox->currentText()));
|
||||||
|
|
||||||
// TODO Remove all those replace once rizin command parser is fixed
|
// TODO Remove all those replace once rizin command parser is fixed
|
||||||
QString newName = ui->nameEdit->text().replace(QLatin1Char(' '), QLatin1Char('_'))
|
QString newName = ui->nameEdit->text()
|
||||||
|
.replace(QLatin1Char(' '), QLatin1Char('_'))
|
||||||
.replace(QLatin1Char('\\'), QLatin1Char('_'))
|
.replace(QLatin1Char('\\'), QLatin1Char('_'))
|
||||||
.replace(QLatin1Char('/'), QLatin1Char('_'));
|
.replace(QLatin1Char('/'), QLatin1Char('_'));
|
||||||
if (newName != desc.name) {
|
if (newName != desc.name) {
|
||||||
@ -86,10 +84,9 @@ void EditVariablesDialog::updateFields()
|
|||||||
ui->typeComboBox->setCurrentText(desc.type);
|
ui->typeComboBox->setCurrentText(desc.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EditVariablesDialog::populateTypesComboBox()
|
void EditVariablesDialog::populateTypesComboBox()
|
||||||
{
|
{
|
||||||
//gets all loaded types, structures and enums and puts them in a list
|
// gets all loaded types, structures and enums and puts them in a list
|
||||||
|
|
||||||
QStringList userStructures;
|
QStringList userStructures;
|
||||||
QStringList userEnumerations;
|
QStringList userEnumerations;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user