mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-21 14:16:08 +00:00
Apply clang-format
This commit is contained in:
parent
a62f138e2f
commit
48ae2150a9
@ -21,13 +21,13 @@
|
||||
#include <QLibraryInfo>
|
||||
#include <QFontDatabase>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtNetwork/QtNetwork>
|
||||
# include <QtNetwork/QtNetwork>
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#if CUTTER_RZGHIDRA_STATIC
|
||||
#include <RzGhidraDecompiler.h>
|
||||
# include <RzGhidraDecompiler.h>
|
||||
#endif
|
||||
|
||||
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);
|
||||
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
|
||||
// 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.";
|
||||
}
|
||||
|
||||
|
||||
// Set QString codec to 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::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
#endif
|
||||
@ -82,9 +82,10 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msg.setWindowTitle(QObject::tr("Version mismatch!"));
|
||||
msg.setText(QString(
|
||||
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(
|
||||
localVersion, rzversion));
|
||||
msg.setText(QString(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(localVersion, rzversion));
|
||||
if (msg.exec() == QMessageBox::No) {
|
||||
std::exit(1);
|
||||
}
|
||||
@ -134,7 +135,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
|
||||
if (clOptions.args.empty()) {
|
||||
// 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()) {
|
||||
mainWindow->displayWelcomeDialog();
|
||||
}
|
||||
@ -144,14 +146,14 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions);
|
||||
}
|
||||
|
||||
|
||||
#ifdef APPIMAGE
|
||||
{
|
||||
auto appdir = QDir(QCoreApplication::applicationDirPath()); // appdir/bin
|
||||
appdir.cdUp(); // 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());
|
||||
|
||||
auto jsdecHome = appdir;
|
||||
@ -167,11 +169,13 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
rzprefix.cd("Resources"); // Contents/Resources/rz
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
}
|
||||
#endif
|
||||
@ -221,7 +225,7 @@ bool CutterApplication::event(QEvent *e)
|
||||
// We already dropped a file in macOS, let's spawn another instance
|
||||
// (Like the File -> Open)
|
||||
QString fileName = openEvent->file();
|
||||
launchNewInstance({fileName});
|
||||
launchNewInstance({ fileName });
|
||||
} else {
|
||||
QString fileName = openEvent->file();
|
||||
m_FileAlreadyDropped = true;
|
||||
@ -241,8 +245,8 @@ bool CutterApplication::loadTranslations()
|
||||
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
|
||||
return true;
|
||||
}
|
||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
const auto &allLocales =
|
||||
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
bool cutterTrLoaded = false;
|
||||
|
||||
@ -259,7 +263,8 @@ bool CutterApplication::loadTranslations()
|
||||
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
|
||||
|
||||
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);
|
||||
cutterTrLoaded = true;
|
||||
trCutter = nullptr;
|
||||
@ -299,52 +304,50 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
|
||||
QCommandLineParser cmd_parser;
|
||||
cmd_parser.setApplicationDescription(
|
||||
QObject::tr("A Qt and C++ GUI for rizin reverse engineering framework"));
|
||||
QObject::tr("A Qt and C++ GUI for rizin reverse engineering framework"));
|
||||
cmd_parser.addHelpOption();
|
||||
cmd_parser.addVersionOption();
|
||||
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
||||
|
||||
QCommandLineOption analOption({"A", "analysis"},
|
||||
QObject::tr("Automatically open file and optionally start analysis. "
|
||||
"Needs filename to be specified. May be a value between 0 and 2:"
|
||||
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
|
||||
QObject::tr("level"));
|
||||
QCommandLineOption analOption(
|
||||
{ "A", "analysis" },
|
||||
QObject::tr("Automatically open file and optionally start analysis. "
|
||||
"Needs filename to be specified. May be a value between 0 and 2:"
|
||||
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
|
||||
QObject::tr("level"));
|
||||
cmd_parser.addOption(analOption);
|
||||
|
||||
QCommandLineOption formatOption({"F", "format"},
|
||||
QCommandLineOption formatOption({ "F", "format" },
|
||||
QObject::tr("Force using a specific file format (bin plugin)"),
|
||||
QObject::tr("name"));
|
||||
cmd_parser.addOption(formatOption);
|
||||
|
||||
QCommandLineOption baddrOption({"B", "base"},
|
||||
QCommandLineOption baddrOption({ "B", "base" },
|
||||
QObject::tr("Load binary at a specific base address"),
|
||||
QObject::tr("base address"));
|
||||
cmd_parser.addOption(baddrOption);
|
||||
|
||||
QCommandLineOption scriptOption("i",
|
||||
QObject::tr("Run script file"),
|
||||
QObject::tr("file"));
|
||||
QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
|
||||
cmd_parser.addOption(scriptOption);
|
||||
|
||||
QCommandLineOption writeModeOption({"w", "writemode"},
|
||||
QCommandLineOption writeModeOption({ "w", "writemode" },
|
||||
QObject::tr("Open file in write mode"));
|
||||
cmd_parser.addOption(writeModeOption);
|
||||
|
||||
|
||||
QCommandLineOption pythonHomeOption("pythonhome",
|
||||
QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
||||
"PYTHONHOME");
|
||||
QCommandLineOption pythonHomeOption(
|
||||
"pythonhome", QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
||||
"PYTHONHOME");
|
||||
cmd_parser.addOption(pythonHomeOption);
|
||||
|
||||
QCommandLineOption disableRedirectOption("no-output-redirect",
|
||||
QObject::tr("Disable output redirection."
|
||||
" Some of the output in console widget will not be visible."
|
||||
" Use this option when debuging a crash or freeze and output "
|
||||
" redirection is causing some messages to be lost."));
|
||||
QCommandLineOption disableRedirectOption(
|
||||
"no-output-redirect",
|
||||
QObject::tr("Disable output redirection."
|
||||
" Some of the output in console widget will not be visible."
|
||||
" Use this option when debuging a crash or freeze and output "
|
||||
" redirection is causing some messages to be lost."));
|
||||
cmd_parser.addOption(disableRedirectOption);
|
||||
|
||||
QCommandLineOption disablePlugins("no-plugins",
|
||||
QObject::tr("Do not load plugins"));
|
||||
QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
|
||||
cmd_parser.addOption(disablePlugins);
|
||||
|
||||
QCommandLineOption disableCutterPlugins("no-cutter-plugins",
|
||||
@ -352,7 +355,7 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
cmd_parser.addOption(disableCutterPlugins);
|
||||
|
||||
QCommandLineOption disableRizinPlugins("no-rizin-plugins",
|
||||
QObject::tr("Do not load rizin plugins"));
|
||||
QObject::tr("Do not load rizin plugins"));
|
||||
cmd_parser.addOption(disableRizinPlugins);
|
||||
|
||||
cmd_parser.process(*this);
|
||||
@ -366,7 +369,9 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
|
||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
|
||||
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;
|
||||
}
|
||||
switch (analLevel) {
|
||||
@ -384,7 +389,9 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
|
||||
if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -406,10 +413,10 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
opts.fileOpenOptions.analCmd = {};
|
||||
break;
|
||||
case AutomaticAnalysisLevel::AAA:
|
||||
opts.fileOpenOptions.analCmd = { {"aaa", "Auto analysis"} };
|
||||
opts.fileOpenOptions.analCmd = { { "aaa", "Auto analysis" } };
|
||||
break;
|
||||
case AutomaticAnalysisLevel::AAAA:
|
||||
opts.fileOpenOptions.analCmd = { {"aaaa", "Auto analysis (experimental)"} };
|
||||
opts.fileOpenOptions.analCmd = { { "aaaa", "Auto analysis (experimental)" } };
|
||||
break;
|
||||
}
|
||||
opts.fileOpenOptions.script = cmd_parser.value(scriptOption);
|
||||
@ -439,7 +446,6 @@ bool CutterApplication::parseCommandLineOptions()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CutterProxyStyle::polish(QWidget *widget)
|
||||
{
|
||||
QProxyStyle::polish(widget);
|
||||
|
@ -8,11 +8,10 @@
|
||||
|
||||
#include "core/MainWindow.h"
|
||||
|
||||
enum class AutomaticAnalysisLevel {
|
||||
Ask, None, AAA, AAAA
|
||||
};
|
||||
enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA };
|
||||
|
||||
struct CutterCommandLineOptions {
|
||||
struct CutterCommandLineOptions
|
||||
{
|
||||
QStringList args;
|
||||
AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask;
|
||||
InitialOptions fileOpenOptions;
|
||||
@ -30,12 +29,10 @@ public:
|
||||
CutterApplication(int &argc, char **argv);
|
||||
~CutterApplication();
|
||||
|
||||
MainWindow *getMainWindow()
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
MainWindow *getMainWindow() { return mainWindow; }
|
||||
|
||||
void launchNewInstance(const QStringList &args = {});
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e);
|
||||
|
||||
@ -50,13 +47,13 @@ private:
|
||||
* @return false if options have error
|
||||
*/
|
||||
bool parseCommandLineOptions();
|
||||
|
||||
private:
|
||||
bool m_FileAlreadyDropped;
|
||||
MainWindow *mainWindow;
|
||||
CutterCommandLineOptions clOptions;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief CutterProxyStyle is used to force shortcuts displaying in context menu
|
||||
*/
|
||||
|
25
src/Main.cpp
25
src/Main.cpp
@ -10,7 +10,6 @@
|
||||
#include <QJsonArray>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Attempt to connect to a parent console and configure outputs.
|
||||
*
|
||||
@ -51,7 +50,6 @@ static void connectToConsole()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef CUTTER_ENABLE_CRASH_REPORTS
|
||||
@ -77,12 +75,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
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
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
CutterApplication a(argc, argv);
|
||||
@ -93,12 +93,13 @@ int main(int argc, char *argv[])
|
||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
UpdateWorker *updateWorker = new UpdateWorker;
|
||||
QObject::connect(updateWorker, &UpdateWorker::checkComplete,
|
||||
[=](const QVersionNumber &version, const QString & error) {
|
||||
if (error.isEmpty() && version > UpdateWorker::currentVersionNumber()) {
|
||||
updateWorker->showUpdateDialog(true);
|
||||
}
|
||||
updateWorker->deleteLater();
|
||||
});
|
||||
[=](const QVersionNumber &version, const QString &error) {
|
||||
if (error.isEmpty()
|
||||
&& version > UpdateWorker::currentVersionNumber()) {
|
||||
updateWorker->showUpdateDialog(true);
|
||||
}
|
||||
updateWorker->deleteLater();
|
||||
});
|
||||
updateWorker->checkCurrentVersion(7000);
|
||||
#endif
|
||||
}
|
||||
|
@ -11,4 +11,4 @@
|
||||
#include "../plugins/CutterPlugin.h"
|
||||
#include "../menus/AddressableItemContextMenu.h"
|
||||
|
||||
#endif //CUTTER_BINDINGS_H
|
||||
#endif // CUTTER_BINDINGS_H
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <stdexcept>
|
||||
|
||||
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
|
||||
QObject *parent) :
|
||||
AddressableItemModel<QSortFilterProxyModel>(parent)
|
||||
QObject *parent)
|
||||
: AddressableItemModel<QSortFilterProxyModel>(parent)
|
||||
{
|
||||
setSourceModel(sourceModel);
|
||||
addressableSourceModel = sourceModel;
|
||||
|
@ -17,17 +17,22 @@ public:
|
||||
* @param index item intex
|
||||
* @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;
|
||||
};
|
||||
|
||||
template <class ParentModel = QAbstractItemModel>
|
||||
class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
||||
template<class ParentModel = QAbstractItemModel>
|
||||
class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
||||
{
|
||||
static_assert (std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
||||
"ParentModel needs to inherit from QAbstractItemModel");
|
||||
static_assert(std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
||||
"ParentModel needs to inherit from QAbstractItemModel");
|
||||
|
||||
public:
|
||||
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
|
||||
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
|
||||
virtual ~AddressableItemModel() {}
|
||||
QAbstractItemModel *asItemModel() { return this; }
|
||||
};
|
||||
@ -35,12 +40,14 @@ public:
|
||||
class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
|
||||
{
|
||||
using ParentClass = AddressableItemModel<QSortFilterProxyModel>;
|
||||
|
||||
public:
|
||||
AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent);
|
||||
|
||||
RVA address(const QModelIndex &index) const override;
|
||||
QString name(const QModelIndex &) const override;
|
||||
void setSourceModel(AddressableItemModelI *sourceModel);
|
||||
|
||||
private:
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly
|
||||
AddressableItemModelI *addressableSourceModel;
|
||||
|
@ -6,14 +6,9 @@
|
||||
#include <QDebug>
|
||||
#include <QCheckBox>
|
||||
|
||||
AnalTask::AnalTask() :
|
||||
AsyncTask()
|
||||
{
|
||||
}
|
||||
AnalTask::AnalTask() : AsyncTask() {}
|
||||
|
||||
AnalTask::~AnalTask()
|
||||
{
|
||||
}
|
||||
AnalTask::~AnalTask() {}
|
||||
|
||||
void AnalTask::interrupt()
|
||||
{
|
||||
@ -21,7 +16,8 @@ void AnalTask::interrupt()
|
||||
rz_cons_singleton()->context->breaked = true;
|
||||
}
|
||||
|
||||
QString AnalTask::getTitle() {
|
||||
QString AnalTask::getTitle()
|
||||
{
|
||||
// If no file is loaded we consider it's Initial Analysis
|
||||
QJsonArray openedFiles = Core()->getOpenedFiles();
|
||||
if (!openedFiles.size()) {
|
||||
@ -36,7 +32,6 @@ void AnalTask::runTask()
|
||||
if (options.writeEnabled) {
|
||||
perms |= RZ_PERM_W;
|
||||
emit Core()->ioModeChanged();
|
||||
|
||||
}
|
||||
|
||||
// Demangle (must be before file Core()->loadFile)
|
||||
@ -47,13 +42,9 @@ void AnalTask::runTask()
|
||||
if (!openedFiles.size() && options.filename.length()) {
|
||||
log(tr("Loading the file..."));
|
||||
openFailed = false;
|
||||
bool fileLoaded = Core()->loadFile(options.filename,
|
||||
options.binLoadAddr,
|
||||
options.mapAddr,
|
||||
perms,
|
||||
options.useVA,
|
||||
options.loadBinInfo,
|
||||
options.forceBinPlugin);
|
||||
bool fileLoaded =
|
||||
Core()->loadFile(options.filename, options.binLoadAddr, options.mapAddr, perms,
|
||||
options.useVA, options.loadBinInfo, options.forceBinPlugin);
|
||||
if (!fileLoaded) {
|
||||
// Something wrong happened, fallback to open dialog
|
||||
openFailed = true;
|
||||
|
@ -19,11 +19,11 @@ public:
|
||||
|
||||
QString getTitle() override;
|
||||
|
||||
void setOptions(const InitialOptions &options) { this->options = options; }
|
||||
void setOptions(const InitialOptions &options) { this->options = options; }
|
||||
|
||||
void interrupt() override;
|
||||
|
||||
bool getOpenFileFailed() { return openFailed; }
|
||||
bool getOpenFileFailed() { return openFailed; }
|
||||
|
||||
protected:
|
||||
void runTask() override;
|
||||
|
@ -1,9 +1,7 @@
|
||||
|
||||
#include "AsyncTask.h"
|
||||
|
||||
AsyncTask::AsyncTask()
|
||||
: QObject(nullptr),
|
||||
QRunnable()
|
||||
AsyncTask::AsyncTask() : QObject(nullptr), QRunnable()
|
||||
{
|
||||
setAutoDelete(false);
|
||||
running = false;
|
||||
@ -64,15 +62,12 @@ void AsyncTask::log(QString s)
|
||||
emit logChanged(logBuffer);
|
||||
}
|
||||
|
||||
AsyncTaskManager::AsyncTaskManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
AsyncTaskManager::AsyncTaskManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
threadPool = new QThreadPool(this);
|
||||
}
|
||||
|
||||
AsyncTaskManager::~AsyncTaskManager()
|
||||
{
|
||||
}
|
||||
AsyncTaskManager::~AsyncTaskManager() {}
|
||||
|
||||
void AsyncTaskManager::start(AsyncTask::Ptr task)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
class AsyncTaskManager;
|
||||
|
||||
class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable
|
||||
class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -30,17 +30,17 @@ public:
|
||||
void wait();
|
||||
bool wait(int timeout);
|
||||
virtual void interrupt();
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isRunning() { return running; }
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isRunning() { return running; }
|
||||
|
||||
const QString &getLog() { return logBuffer; }
|
||||
const QElapsedTimer &getTimer() { return timer; }
|
||||
qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; }
|
||||
const QString &getLog() { return logBuffer; }
|
||||
const QElapsedTimer &getTimer() { return timer; }
|
||||
qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; }
|
||||
|
||||
virtual QString getTitle() { return QString(); }
|
||||
virtual QString getTitle() { return QString(); }
|
||||
|
||||
protected:
|
||||
virtual void runTask() =0;
|
||||
virtual void runTask() = 0;
|
||||
|
||||
void log(QString s);
|
||||
|
||||
@ -78,5 +78,4 @@ signals:
|
||||
void tasksChanged();
|
||||
};
|
||||
|
||||
|
||||
#endif //ASYNCTASK_H
|
||||
#endif // ASYNCTASK_H
|
@ -1,8 +1,6 @@
|
||||
#include "BasicBlockHighlighter.h"
|
||||
|
||||
BasicBlockHighlighter::BasicBlockHighlighter()
|
||||
{
|
||||
}
|
||||
BasicBlockHighlighter::BasicBlockHighlighter() {}
|
||||
|
||||
BasicBlockHighlighter::~BasicBlockHighlighter()
|
||||
{
|
||||
@ -41,7 +39,7 @@ BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address)
|
||||
|
||||
it = bbMap.find(address);
|
||||
if (it != bbMap.end()) {
|
||||
return it->second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -6,12 +6,13 @@ class BasicBlockHighlighter;
|
||||
#include "Cutter.h"
|
||||
#include <map>
|
||||
|
||||
struct BasicBlock {
|
||||
struct BasicBlock
|
||||
{
|
||||
RVA address;
|
||||
QColor color;
|
||||
};
|
||||
|
||||
typedef std::map<RVA, BasicBlock*>::iterator BasicBlockIt;
|
||||
typedef std::map<RVA, BasicBlock *>::iterator BasicBlockIt;
|
||||
|
||||
class BasicBlockHighlighter
|
||||
{
|
||||
@ -24,7 +25,7 @@ public:
|
||||
BasicBlock *getBasicBlock(RVA address);
|
||||
|
||||
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()) {
|
||||
const BasicInstruction &prev = biMap[addrs.front()];
|
||||
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()];
|
||||
if (next.address < address + size && next.address + next.size > address + size) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -52,7 +52,7 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
|
||||
void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color)
|
||||
{
|
||||
clear(address, size);
|
||||
biMap[address] = {address, size, color};
|
||||
biMap[address] = { address, size, color };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include <map>
|
||||
#include <QColor>
|
||||
|
||||
struct BasicInstruction {
|
||||
struct BasicInstruction
|
||||
{
|
||||
RVA address;
|
||||
RVA size;
|
||||
QColor color;
|
||||
|
@ -11,13 +11,13 @@
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
/**
|
||||
* Not really a segment tree for storing segments as referred in academic literature. Can be considered a
|
||||
* full, almost perfect, augmented binary tree. In the context of competitive programming often called segment tree.
|
||||
* Not really a segment tree for storing segments as referred in academic literature. Can be
|
||||
* 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)
|
||||
* method which calculates inner node values from children nodes.
|
||||
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left,
|
||||
* NodeType& right) method which calculates inner node values from children nodes.
|
||||
*
|
||||
* \tparam NodeTypeT type of each tree element
|
||||
* \tparam FinalType final child class used for curiously recurring template pattern
|
||||
@ -33,11 +33,7 @@ public:
|
||||
* @brief Create tree with \a size leaves.
|
||||
* @param size number of leaves in the tree
|
||||
*/
|
||||
explicit SegmentTreeBase(size_t size)
|
||||
: size(size)
|
||||
, nodeCount(2 * size)
|
||||
, nodes(nodeCount)
|
||||
{}
|
||||
explicit SegmentTreeBase(size_t size) : size(size), nodeCount(2 * size), nodes(nodeCount) {}
|
||||
|
||||
/**
|
||||
* @brief Create a tree with given size and initial value.
|
||||
@ -46,38 +42,23 @@ public:
|
||||
* @param size number of leaves
|
||||
* @param initialValue initial leave value
|
||||
*/
|
||||
SegmentTreeBase(size_t size, const NodeType &initialValue)
|
||||
: SegmentTreeBase(size)
|
||||
SegmentTreeBase(size_t size, const NodeType &initialValue) : SegmentTreeBase(size)
|
||||
{
|
||||
init(initialValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Curiously recurring template pattern
|
||||
FinalType &This()
|
||||
{
|
||||
return static_cast<FinalType &>(*this);
|
||||
}
|
||||
FinalType &This() { return static_cast<FinalType &>(*this); }
|
||||
|
||||
// Curiously recurring template pattern
|
||||
const FinalType &This() const
|
||||
{
|
||||
return static_cast<const FinalType &>(*this);
|
||||
}
|
||||
const FinalType &This() const { return static_cast<const FinalType &>(*this); }
|
||||
|
||||
size_t leavePositionToIndex(NodePosition pos) const
|
||||
{
|
||||
return pos - size;
|
||||
}
|
||||
size_t leavePositionToIndex(NodePosition pos) const { return pos - size; }
|
||||
|
||||
NodePosition leaveIndexToPosition(size_t index) const
|
||||
{
|
||||
return index + size;
|
||||
}
|
||||
NodePosition leaveIndexToPosition(size_t index) const { return index + size; }
|
||||
|
||||
bool isLeave(NodePosition position) const
|
||||
{
|
||||
return position >= size;
|
||||
}
|
||||
bool isLeave(NodePosition position) const { return position >= size; }
|
||||
|
||||
/**
|
||||
* @brief Calculate inner node values from leaves.
|
||||
@ -111,6 +92,7 @@ template<class NodeType, class FinalType>
|
||||
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
|
||||
{
|
||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||
|
||||
public:
|
||||
using BaseType::BaseType;
|
||||
|
||||
@ -125,7 +107,8 @@ public:
|
||||
this->nodes[pos] = value;
|
||||
while (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;
|
||||
}
|
||||
}
|
||||
@ -141,6 +124,7 @@ public:
|
||||
class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree>
|
||||
{
|
||||
using BaseType = PointSetSegmentTree<int, PointSetMinTree>;
|
||||
|
||||
public:
|
||||
using NodeType = int;
|
||||
|
||||
@ -159,16 +143,15 @@ public:
|
||||
*/
|
||||
int rightMostLessThan(size_t position, int value)
|
||||
{
|
||||
auto isGood = [&](size_t pos) {
|
||||
return nodes[pos] < value;
|
||||
};
|
||||
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||
// right side exclusive range [l;r)
|
||||
size_t goodSubtree = 0;
|
||||
for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r;
|
||||
l >>= 1, r >>= 1) {
|
||||
l >>= 1, r >>= 1) {
|
||||
if (l & 1) {
|
||||
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;
|
||||
}
|
||||
++l;
|
||||
@ -202,13 +185,11 @@ public:
|
||||
*/
|
||||
int leftMostLessThan(size_t position, int value)
|
||||
{
|
||||
auto isGood = [&](size_t pos) {
|
||||
return nodes[pos] < value;
|
||||
};
|
||||
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||
// right side exclusive range [l;r)
|
||||
size_t goodSubtree = 0;
|
||||
for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r;
|
||||
l >>= 1, r >>= 1) {
|
||||
l >>= 1, r >>= 1) {
|
||||
if (l & 1) {
|
||||
if (isGood(l)) {
|
||||
goodSubtree = l;
|
||||
@ -220,7 +201,8 @@ public:
|
||||
--r;
|
||||
if (isGood(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.
|
||||
*
|
||||
* 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
|
||||
* operation stored in \a promise for nodePosition to the direct children nodes.
|
||||
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies
|
||||
* the applies the operation stored in \a promise for nodePosition to the direct children nodes.
|
||||
*
|
||||
* \tparam NodeType type of tree nodes
|
||||
* \tparam PromiseType type describing operation that needs to be applied to subtree
|
||||
* \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>
|
||||
{
|
||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param size Number of tree leaves.
|
||||
* @param neutralPromise Promise value that doesn't modify tree nodes.
|
||||
*/
|
||||
LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise)
|
||||
: BaseType(size)
|
||||
, neutralPromiseElement(neutralPromise)
|
||||
, promise(size, neutralPromise)
|
||||
: BaseType(size), neutralPromiseElement(neutralPromise), promise(size, neutralPromise)
|
||||
{
|
||||
h = 0;
|
||||
size_t v = size;
|
||||
@ -324,7 +306,8 @@ protected:
|
||||
while (p > 1) {
|
||||
auto parent = p >> 1;
|
||||
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;
|
||||
}
|
||||
@ -337,19 +320,16 @@ protected:
|
||||
std::vector<PromiseType> promise;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure supporting range assignment and range maximum operations.
|
||||
*/
|
||||
class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>
|
||||
{
|
||||
using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>;
|
||||
|
||||
public:
|
||||
using ValueType = int;
|
||||
RangeAssignMaxTree(size_t size, ValueType initialValue)
|
||||
: BaseType(size, initialValue, 0)
|
||||
{
|
||||
}
|
||||
RangeAssignMaxTree(size_t size, ValueType initialValue) : BaseType(size, initialValue, 0) {}
|
||||
|
||||
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
|
||||
{
|
||||
|
@ -9,11 +9,9 @@
|
||||
void openIssue()
|
||||
{
|
||||
QString url, osInfo, format, arch, type;
|
||||
//Pull in info needed for git issue
|
||||
osInfo = QSysInfo::productType() + " " +
|
||||
(QSysInfo::productVersion() == "unknown"
|
||||
? ""
|
||||
: QSysInfo::productVersion());
|
||||
// Pull in info needed for git issue
|
||||
osInfo = QSysInfo::productType() + " "
|
||||
+ (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
|
||||
QJsonDocument docu = Core()->getFileInfo();
|
||||
QJsonObject coreObj = docu.object()["core"].toObject();
|
||||
QJsonObject binObj = docu.object()["bin"].toObject();
|
||||
@ -30,16 +28,18 @@ void openIssue()
|
||||
arch = "N/A";
|
||||
type = "N/A";
|
||||
}
|
||||
url =
|
||||
"https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* Operating System: "
|
||||
+ osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL +
|
||||
"\n* File format: " + format + "\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"
|
||||
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n"
|
||||
"4. See error\n\n**Expected behavior**\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"
|
||||
"**Additional context**\nAdd any other context about the problem here.";
|
||||
url = "https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* "
|
||||
"Operating System: "
|
||||
+ osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL + "\n* File format: " + format
|
||||
+ "\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"
|
||||
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll "
|
||||
"down to '....'\n"
|
||||
"4. See error\n\n**Expected behavior**\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"
|
||||
"**Additional context**\nAdd any other context about the problem here.";
|
||||
|
||||
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
|
||||
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ template<typename T>
|
||||
class CachedFontMetrics
|
||||
{
|
||||
public:
|
||||
explicit CachedFontMetrics(const QFont &font)
|
||||
: mFontMetrics(font)
|
||||
explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font)
|
||||
{
|
||||
memset(mWidths, 0, sizeof(mWidths));
|
||||
mHeight = mFontMetrics.height();
|
||||
@ -20,7 +19,7 @@ public:
|
||||
|
||||
T width(const QChar &ch)
|
||||
{
|
||||
//return mFontMetrics.width(ch);
|
||||
// return mFontMetrics.width(ch);
|
||||
auto unicode = ch.unicode();
|
||||
if (unicode >= 0xD800) {
|
||||
if (unicode >= 0xE000)
|
||||
@ -49,10 +48,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
T height()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
T height() { return mHeight; }
|
||||
|
||||
T position(const QString &text, T offset)
|
||||
{
|
||||
@ -84,7 +80,7 @@ private:
|
||||
|
||||
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);
|
||||
#else
|
||||
return mFontMetrics.horizontalAdvance(c);
|
||||
@ -93,7 +89,7 @@ private:
|
||||
|
||||
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);
|
||||
#else
|
||||
return mFontMetrics.horizontalAdvance(s);
|
||||
|
@ -10,80 +10,46 @@
|
||||
#include "common/Configuration.h"
|
||||
|
||||
const QStringList ColorThemeWorker::cutterSpecificOptions = {
|
||||
"wordHighlight",
|
||||
"lineHighlight",
|
||||
"gui.main",
|
||||
"gui.imports",
|
||||
"highlightPC",
|
||||
"gui.navbar.err",
|
||||
"gui.navbar.seek",
|
||||
"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",
|
||||
"wordHighlight", "lineHighlight", "gui.main",
|
||||
"gui.imports", "highlightPC", "gui.navbar.err",
|
||||
"gui.navbar.seek", "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"
|
||||
};
|
||||
|
||||
const QStringList ColorThemeWorker::rizinUnusedOptions = {
|
||||
"linehl",
|
||||
"wordhl",
|
||||
"graph.box",
|
||||
"graph.box2",
|
||||
"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"
|
||||
"linehl", "wordhl", "graph.box", "graph.box2", "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;
|
||||
rz_mem_free(szThemes);
|
||||
if (!QDir(customRzThemesLocationPath).exists()) {
|
||||
QDir().mkpath(customRzThemesLocationPath);
|
||||
}
|
||||
|
||||
QDir currDir { QStringLiteral("%1%2%3")
|
||||
.arg(rz_sys_prefix(nullptr))
|
||||
.arg(RZ_SYS_DIR)
|
||||
.arg(RZ_THEMES)
|
||||
QDir currDir {
|
||||
QStringLiteral("%1%2%3").arg(rz_sys_prefix(nullptr)).arg(RZ_SYS_DIR).arg(RZ_THEMES)
|
||||
};
|
||||
if (currDir.exists()) {
|
||||
standardRzThemesLocationPath = currDir.absolutePath();
|
||||
} else {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Standard themes not found"),
|
||||
tr("The Rizin standard themes could not be found in '%1'. "
|
||||
"Most likely, Rizin is not properly installed.")
|
||||
.arg(currDir.path())
|
||||
);
|
||||
QMessageBox::critical(nullptr, tr("Standard themes not found"),
|
||||
tr("The Rizin standard themes could not be found in '%1'. "
|
||||
"Most likely, Rizin is not properly installed.")
|
||||
.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 r2, g2, b2, a2;
|
||||
@ -102,12 +68,10 @@ QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) c
|
||||
return res;
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::copy(const QString &srcThemeName,
|
||||
const QString ©ThemeName) const
|
||||
QString ColorThemeWorker::copy(const QString &srcThemeName, const QString ©ThemeName) const
|
||||
{
|
||||
if (!isThemeExist(srcThemeName)) {
|
||||
return tr("Theme <b>%1</b> does not exist.")
|
||||
.arg(srcThemeName);
|
||||
return tr("Theme <b>%1</b> does not exist.").arg(srcThemeName);
|
||||
}
|
||||
|
||||
return save(getTheme(srcThemeName), copyThemeName);
|
||||
@ -117,8 +81,7 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
|
||||
{
|
||||
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
|
||||
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
return tr("The file <b>%1</b> cannot be opened.")
|
||||
.arg(QFileInfo(fOut).filePath());
|
||||
return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
|
||||
}
|
||||
|
||||
QJsonObject obj = theme.object();
|
||||
@ -137,12 +100,12 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
|
||||
}
|
||||
if (cutterSpecificOptions.contains(it.key())) {
|
||||
fOut.write(QString("#~%1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexArgb).remove('#'))
|
||||
.toUtf8());
|
||||
.arg(it.key(), color.name(QColor::HexArgb).remove('#'))
|
||||
.toUtf8());
|
||||
} else {
|
||||
fOut.write(QString("ec %1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexRgb).remove('#'))
|
||||
.toUtf8());
|
||||
.arg(it.key(), color.name(QColor::HexRgb).remove('#'))
|
||||
.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +124,7 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
|
||||
return themes.contains(name);
|
||||
}
|
||||
|
||||
QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
|
||||
{
|
||||
int r, g, b, a;
|
||||
QVariantMap theme;
|
||||
@ -178,7 +141,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
||||
auto arr = it.value().toList();
|
||||
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;
|
||||
@ -186,9 +149,9 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
colorFlags = Configuration::relevantThemes[themeName];
|
||||
}
|
||||
|
||||
for (auto& it : cutterSpecificOptions) {
|
||||
for (auto &it : cutterSpecificOptions) {
|
||||
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)) {
|
||||
@ -198,12 +161,14 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
}
|
||||
QStringList sl;
|
||||
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] == '#') {
|
||||
continue;
|
||||
}
|
||||
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
|
||||
// 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;
|
||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
||||
auto &value = it.value();
|
||||
@ -222,7 +188,6 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
} else {
|
||||
obj[it.key()] = QJsonValue::fromVariant(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QJsonDocument(obj);
|
||||
@ -239,26 +204,23 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const
|
||||
|
||||
QFile file(QDir(customRzThemesLocationPath).filePath(themeName));
|
||||
if (file.isWritable()) {
|
||||
return tr("You have no permission to write to <b>%1</b>")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("You have no permission to write to <b>%1</b>").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
return tr("File <b>%1</b> can not be opened.")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("File <b>%1</b> can not be opened.").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
if (!file.remove()) {
|
||||
return tr("File <b>%1</b> can not be removed.")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("File <b>%1</b> can not be removed.").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::importTheme(const QString& file) const
|
||||
QString ColorThemeWorker::importTheme(const QString &file) const
|
||||
{
|
||||
QFileInfo src(file);
|
||||
if (!src.exists()) {
|
||||
return tr("File <b>%1</b> does not exist.").arg(file);
|
||||
}
|
||||
if (!src.exists()) {
|
||||
return tr("File <b>%1</b> does not exist.").arg(file);
|
||||
}
|
||||
|
||||
bool ok;
|
||||
bool isTheme = isFileTheme(file, &ok);
|
||||
@ -276,35 +238,36 @@ QString ColorThemeWorker::importTheme(const QString& file) const
|
||||
}
|
||||
|
||||
if (QFile::copy(file, QDir(customRzThemesLocationPath).filePath(name))) {
|
||||
return "";
|
||||
} else {
|
||||
return tr("Error occurred during importing. "
|
||||
"Please make sure you have an access to "
|
||||
"the directory <b>%1</b> and try again.")
|
||||
.arg(src.dir().path());
|
||||
return "";
|
||||
} else {
|
||||
return tr("Error occurred during importing. "
|
||||
"Please make sure you have an access to "
|
||||
"the directory <b>%1</b> and try again.")
|
||||
.arg(src.dir().path());
|
||||
}
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::renameTheme(const QString& themeName, const QString& newName) const
|
||||
QString ColorThemeWorker::renameTheme(const QString &themeName, const QString &newName) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (!isCustomTheme(themeName)) {
|
||||
return tr("You can not rename standard Rizin themes.");
|
||||
}
|
||||
if (!isCustomTheme(themeName)) {
|
||||
return tr("You can not rename standard Rizin themes.");
|
||||
}
|
||||
|
||||
QDir dir = customRzThemesLocationPath;
|
||||
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
||||
if (!ok) {
|
||||
return tr("Something went wrong during renaming. "
|
||||
"Please make sure you have access to the directory <b>\"%1\"</b>.").arg(dir.path());
|
||||
}
|
||||
return "";
|
||||
QDir dir = customRzThemesLocationPath;
|
||||
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
||||
if (!ok) {
|
||||
return tr("Something went wrong during renaming. "
|
||||
"Please make sure you have access to the directory <b>\"%1\"</b>.")
|
||||
.arg(dir.path());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
||||
bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
|
||||
{
|
||||
QFile f(filePath);
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
@ -314,10 +277,12 @@ bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
||||
|
||||
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
|
||||
QString options = (Core()->cmdj("ecj").object().keys() << cutterSpecificOptions)
|
||||
.join('|')
|
||||
.replace(".", "\\.");
|
||||
.join('|')
|
||||
.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
|
||||
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
|
||||
|
||||
|
@ -40,7 +40,6 @@ public:
|
||||
|
||||
virtual ~ColorThemeWorker() {}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copies @a srcThemeName with name @a copyThemeName.
|
||||
* @param srcThemeName
|
||||
@ -59,10 +58,11 @@ public:
|
||||
* Name of theme to save.
|
||||
* @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
|
||||
* Name of theme to check.
|
||||
*/
|
||||
@ -75,7 +75,8 @@ public:
|
||||
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
|
||||
* Theme to get.
|
||||
*/
|
||||
@ -93,13 +94,13 @@ public:
|
||||
* @brief Imports theme from @a file.
|
||||
* @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.
|
||||
* @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.
|
||||
|
@ -1,11 +1,7 @@
|
||||
#include "Colors.h"
|
||||
#include "common/Configuration.h"
|
||||
|
||||
Colors::Colors()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Colors::Colors() {}
|
||||
|
||||
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
|
||||
{
|
||||
@ -101,4 +97,3 @@ QString Colors::getColor(ut64 type)
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,8 @@ CommandTask::CommandTask(const QString &cmd, ColorMode colorMode, bool outFormat
|
||||
{
|
||||
}
|
||||
|
||||
void CommandTask::runTask() {
|
||||
void CommandTask::runTask()
|
||||
{
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("scr.color", colorMode);
|
||||
auto res = Core()->cmdTask(cmd);
|
||||
|
@ -5,16 +5,22 @@
|
||||
#include "common/AsyncTask.h"
|
||||
#include "core/Cutter.h"
|
||||
|
||||
class CUTTER_EXPORT CommandTask : public AsyncTask
|
||||
class CUTTER_EXPORT CommandTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
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"); }
|
||||
|
||||
signals:
|
||||
void finished(const QString &result);
|
||||
@ -28,4 +34,4 @@ private:
|
||||
bool outFormatHtml;
|
||||
};
|
||||
|
||||
#endif //COMMANDTASK_H
|
||||
#endif // COMMANDTASK_H
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include <QApplication>
|
||||
|
||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
#include <KSyntaxHighlighting/repository.h>
|
||||
#include <KSyntaxHighlighting/theme.h>
|
||||
#include <KSyntaxHighlighting/definition.h>
|
||||
# include <KSyntaxHighlighting/repository.h>
|
||||
# include <KSyntaxHighlighting/theme.h>
|
||||
# include <KSyntaxHighlighting/definition.h>
|
||||
#endif
|
||||
|
||||
#include "common/ColorThemeWorker.h"
|
||||
@ -21,75 +21,71 @@
|
||||
* and for light - only light ones.
|
||||
*/
|
||||
const QHash<QString, ColorFlags> Configuration::relevantThemes = {
|
||||
{ "ayu", DarkFlag },
|
||||
{ "consonance", DarkFlag },
|
||||
{ "darkda", DarkFlag },
|
||||
{ "onedark", DarkFlag },
|
||||
{ "solarized", DarkFlag },
|
||||
{ "zenburn", DarkFlag },
|
||||
{ "cutter", LightFlag },
|
||||
{ "dark", LightFlag },
|
||||
{ "matrix", LightFlag },
|
||||
{ "tango", LightFlag },
|
||||
{ "white", LightFlag }
|
||||
{ "ayu", DarkFlag }, { "consonance", DarkFlag }, { "darkda", DarkFlag },
|
||||
{ "onedark", DarkFlag }, { "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_DARK_COLOR_THEME = "ayu";
|
||||
|
||||
|
||||
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
|
||||
{ "gui.cflow", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
||||
{ "gui.dataoffset", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
||||
{ "gui.imports", { { DarkFlag, QColor(0x32, 0x8c, 0xff) },
|
||||
{ LightFlag, QColor(0x32, 0x8c, 0xff) }} },
|
||||
{ "gui.item_invalid", { { DarkFlag, QColor(0x9b, 0x9b, 0x9b) },
|
||||
{ LightFlag, QColor(0x9b, 0x9b, 0x9b) }} },
|
||||
{ "gui.main", { { DarkFlag, QColor(0x00, 0x80, 0x00) },
|
||||
{ LightFlag, QColor(0x00, 0x80, 0x00) }} },
|
||||
{ "gui.item_unsafe", { { DarkFlag, QColor(0xff, 0x81, 0x7b) },
|
||||
{ LightFlag, QColor(0xff, 0x81, 0x7b) }} },
|
||||
{ "gui.navbar.seek", { { DarkFlag, QColor(0xe9, 0x56, 0x56) },
|
||||
{ LightFlag, QColor(0xff, 0x00, 0x00) }} },
|
||||
{ "gui.navbar.pc", { { DarkFlag, QColor(0x42, 0xee, 0xf4) },
|
||||
{ LightFlag, QColor(0x42, 0xee, 0xf4) }} },
|
||||
{ "gui.navbar.code", { { DarkFlag, QColor(0x82, 0xc8, 0x6f) },
|
||||
{ LightFlag, QColor(0x68, 0xe5, 0x45) }} },
|
||||
{ "gui.navbar.str", { { DarkFlag, QColor(0x6f, 0x86, 0xd8) },
|
||||
{ LightFlag, QColor(0x45, 0x68, 0xe5) }} },
|
||||
{ "gui.navbar.sym", { { DarkFlag, QColor(0xdd, 0xa3, 0x68) },
|
||||
{ LightFlag, QColor(0xe5, 0x96, 0x45) }} },
|
||||
{ "gui.navbar.empty", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0xdc, 0xec, 0xf5) }} },
|
||||
{ "gui.breakpoint_background", { { DarkFlag, QColor(0x8c, 0x4c, 0x4c) },
|
||||
{ LightFlag, QColor(0xe9, 0x8f, 0x8f) }} },
|
||||
{ "gui.overview.node", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
||||
{ "gui.tooltip.background", { { DarkFlag, QColor(0x2a, 0x2c, 0x2e) },
|
||||
{ LightFlag, QColor(0xfa, 0xfc, 0xfe) }} },
|
||||
{ "gui.tooltip.foreground", { { DarkFlag, QColor(0xfa, 0xfc, 0xfe) },
|
||||
{ LightFlag, QColor(0x2a, 0x2c, 0x2e) }} },
|
||||
{ "gui.border", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0x91, 0xc8, 0xfa) }} },
|
||||
{ "gui.background", { { DarkFlag, QColor(0x25, 0x28, 0x2b) },
|
||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
||||
{ "gui.alt_background", { { DarkFlag, QColor(0x1c, 0x1f, 0x24) },
|
||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
||||
{ "gui.disass_selected", { { DarkFlag, QColor(0x1f, 0x22, 0x28) },
|
||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
||||
{ "lineHighlight", { { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
||||
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) }} },
|
||||
{ "wordHighlight", { { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
|
||||
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) }} },
|
||||
{ "highlightPC", { { DarkFlag, QColor(0x57, 0x1a, 0x07) },
|
||||
{ LightFlag, QColor(0xd6, 0xff, 0xd2) }} },
|
||||
{ "gui.overview.fill", { { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
|
||||
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) }} },
|
||||
{ "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) }} }
|
||||
{ "gui.cflow",
|
||||
{ { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
|
||||
{ "gui.dataoffset",
|
||||
{ { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
|
||||
{ "gui.imports",
|
||||
{ { DarkFlag, QColor(0x32, 0x8c, 0xff) }, { LightFlag, QColor(0x32, 0x8c, 0xff) } } },
|
||||
{ "gui.item_invalid",
|
||||
{ { DarkFlag, QColor(0x9b, 0x9b, 0x9b) }, { LightFlag, QColor(0x9b, 0x9b, 0x9b) } } },
|
||||
{ "gui.main",
|
||||
{ { DarkFlag, QColor(0x00, 0x80, 0x00) }, { LightFlag, QColor(0x00, 0x80, 0x00) } } },
|
||||
{ "gui.item_unsafe",
|
||||
{ { DarkFlag, QColor(0xff, 0x81, 0x7b) }, { LightFlag, QColor(0xff, 0x81, 0x7b) } } },
|
||||
{ "gui.navbar.seek",
|
||||
{ { DarkFlag, QColor(0xe9, 0x56, 0x56) }, { LightFlag, QColor(0xff, 0x00, 0x00) } } },
|
||||
{ "gui.navbar.pc",
|
||||
{ { DarkFlag, QColor(0x42, 0xee, 0xf4) }, { LightFlag, QColor(0x42, 0xee, 0xf4) } } },
|
||||
{ "gui.navbar.code",
|
||||
{ { DarkFlag, QColor(0x82, 0xc8, 0x6f) }, { LightFlag, QColor(0x68, 0xe5, 0x45) } } },
|
||||
{ "gui.navbar.str",
|
||||
{ { DarkFlag, QColor(0x6f, 0x86, 0xd8) }, { LightFlag, QColor(0x45, 0x68, 0xe5) } } },
|
||||
{ "gui.navbar.sym",
|
||||
{ { DarkFlag, QColor(0xdd, 0xa3, 0x68) }, { LightFlag, QColor(0xe5, 0x96, 0x45) } } },
|
||||
{ "gui.navbar.empty",
|
||||
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xdc, 0xec, 0xf5) } } },
|
||||
{ "gui.breakpoint_background",
|
||||
{ { DarkFlag, QColor(0x8c, 0x4c, 0x4c) }, { LightFlag, QColor(0xe9, 0x8f, 0x8f) } } },
|
||||
{ "gui.overview.node",
|
||||
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
|
||||
{ "gui.tooltip.background",
|
||||
{ { DarkFlag, QColor(0x2a, 0x2c, 0x2e) }, { LightFlag, QColor(0xfa, 0xfc, 0xfe) } } },
|
||||
{ "gui.tooltip.foreground",
|
||||
{ { DarkFlag, QColor(0xfa, 0xfc, 0xfe) }, { LightFlag, QColor(0x2a, 0x2c, 0x2e) } } },
|
||||
{ "gui.border",
|
||||
{ { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0x91, 0xc8, 0xfa) } } },
|
||||
{ "gui.background",
|
||||
{ { DarkFlag, QColor(0x25, 0x28, 0x2b) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
|
||||
{ "gui.alt_background",
|
||||
{ { DarkFlag, QColor(0x1c, 0x1f, 0x24) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
|
||||
{ "gui.disass_selected",
|
||||
{ { DarkFlag, QColor(0x1f, 0x22, 0x28) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
|
||||
{ "lineHighlight",
|
||||
{ { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
||||
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } },
|
||||
{ "wordHighlight",
|
||||
{ { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
|
||||
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) } } },
|
||||
{ "highlightPC",
|
||||
{ { DarkFlag, QColor(0x57, 0x1a, 0x07) }, { LightFlag, QColor(0xd6, 0xff, 0xd2) } } },
|
||||
{ "gui.overview.fill",
|
||||
{ { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
|
||||
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) } } },
|
||||
{ "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;
|
||||
@ -97,54 +93,50 @@ Configuration *Configuration::mPtr = nullptr;
|
||||
/**
|
||||
* @brief All asm.* options saved as settings. Values are the default values.
|
||||
*/
|
||||
static const QHash<QString, QVariant> asmOptions = {
|
||||
{ "asm.esil", false },
|
||||
{ "asm.pseudo", false },
|
||||
{ "asm.offset", true },
|
||||
{ "asm.xrefs", false },
|
||||
{ "asm.indent", false },
|
||||
{ "asm.describe", false },
|
||||
{ "asm.slow", true },
|
||||
{ "asm.lines", true },
|
||||
{ "asm.lines.fcn", true },
|
||||
{ "asm.flags.offset", false },
|
||||
{ "asm.emu", false },
|
||||
{ "emu.str", false},
|
||||
{ "asm.cmt.right", true },
|
||||
{ "asm.cmt.col", 35 },
|
||||
{ "asm.var.summary", false },
|
||||
{ "asm.bytes", false },
|
||||
{ "asm.size", false },
|
||||
{ "asm.bytes.space", false },
|
||||
{ "asm.lbytes", true },
|
||||
{ "asm.nbytes", 10 },
|
||||
{ "asm.syntax", "intel" },
|
||||
{ "asm.ucase", false },
|
||||
{ "asm.bb.line", false },
|
||||
{ "asm.capitalize", false },
|
||||
{ "asm.sub.var", true },
|
||||
{ "asm.sub.varonly", true },
|
||||
{ "asm.tabs", 8 },
|
||||
{ "asm.tabs.off", 5 },
|
||||
{ "asm.marks", false },
|
||||
{ "asm.refptr", false },
|
||||
{ "asm.flags.real", true },
|
||||
{ "asm.reloff", false },
|
||||
{ "asm.reloff.flags", false },
|
||||
{ "esil.breakoninvalid",true },
|
||||
{ "graph.offset", false}
|
||||
};
|
||||
|
||||
static const QHash<QString, QVariant> asmOptions = { { "asm.esil", false },
|
||||
{ "asm.pseudo", false },
|
||||
{ "asm.offset", true },
|
||||
{ "asm.xrefs", false },
|
||||
{ "asm.indent", false },
|
||||
{ "asm.describe", false },
|
||||
{ "asm.slow", true },
|
||||
{ "asm.lines", true },
|
||||
{ "asm.lines.fcn", true },
|
||||
{ "asm.flags.offset", false },
|
||||
{ "asm.emu", false },
|
||||
{ "emu.str", false },
|
||||
{ "asm.cmt.right", true },
|
||||
{ "asm.cmt.col", 35 },
|
||||
{ "asm.var.summary", false },
|
||||
{ "asm.bytes", false },
|
||||
{ "asm.size", false },
|
||||
{ "asm.bytes.space", false },
|
||||
{ "asm.lbytes", true },
|
||||
{ "asm.nbytes", 10 },
|
||||
{ "asm.syntax", "intel" },
|
||||
{ "asm.ucase", false },
|
||||
{ "asm.bb.line", false },
|
||||
{ "asm.capitalize", false },
|
||||
{ "asm.sub.var", true },
|
||||
{ "asm.sub.varonly", true },
|
||||
{ "asm.tabs", 8 },
|
||||
{ "asm.tabs.off", 5 },
|
||||
{ "asm.marks", false },
|
||||
{ "asm.refptr", false },
|
||||
{ "asm.flags.real", true },
|
||||
{ "asm.reloff", false },
|
||||
{ "asm.reloff.flags", false },
|
||||
{ "esil.breakoninvalid", true },
|
||||
{ "graph.offset", false } };
|
||||
|
||||
Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
|
||||
{
|
||||
mPtr = this;
|
||||
if (!s.isWritable()) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Critical!"),
|
||||
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
|
||||
.arg(s.fileName())
|
||||
);
|
||||
QMessageBox::critical(
|
||||
nullptr, tr("Critical!"),
|
||||
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
|
||||
.arg(s.fileName()));
|
||||
}
|
||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
kSyntaxHighlightingRepository = nullptr;
|
||||
@ -200,7 +192,7 @@ void Configuration::resetAll()
|
||||
{
|
||||
// Don't reset all rizin vars, that currently breaks a bunch of stuff.
|
||||
// settingsFile.remove()+loadInitials() should reset all settings configurable using Cutter GUI.
|
||||
//Core()->cmdRaw("e-");
|
||||
// Core()->cmdRaw("e-");
|
||||
|
||||
Core()->setSettings();
|
||||
// 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)
|
||||
{
|
||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
const auto &allLocales =
|
||||
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
for (auto &it : allLocales) {
|
||||
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
||||
@ -375,9 +367,9 @@ const QFont Configuration::getBaseFont() const
|
||||
|
||||
const QFont Configuration::getFont() const
|
||||
{
|
||||
QFont font = getBaseFont();
|
||||
font.setPointSizeF(font.pointSizeF() * getZoomFactor());
|
||||
return font;
|
||||
QFont font = getBaseFont();
|
||||
font.setPointSizeF(font.pointSizeF() * getZoomFactor());
|
||||
return font;
|
||||
}
|
||||
|
||||
void Configuration::setFont(const QFont &font)
|
||||
@ -391,26 +383,26 @@ void Configuration::refreshFont()
|
||||
emit fontsUpdated();
|
||||
}
|
||||
|
||||
qreal Configuration::getZoomFactor() const {
|
||||
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
||||
return qMax(fontZoom, 0.1);
|
||||
qreal Configuration::getZoomFactor() const
|
||||
{
|
||||
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
||||
return qMax(fontZoom, 0.1);
|
||||
}
|
||||
|
||||
void Configuration::setZoomFactor(qreal zoom) {
|
||||
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
||||
emit fontsUpdated();
|
||||
void Configuration::setZoomFactor(qreal zoom)
|
||||
{
|
||||
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
||||
emit fontsUpdated();
|
||||
}
|
||||
|
||||
QString Configuration::getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const
|
||||
{
|
||||
return s.value("lastThemeOf." + currInterfaceTheme.name,
|
||||
Config()->getColorTheme()).toString();
|
||||
return s.value("lastThemeOf." + currInterfaceTheme.name, Config()->getColorTheme()).toString();
|
||||
}
|
||||
|
||||
void Configuration::setInterfaceTheme(int theme)
|
||||
{
|
||||
if (theme >= cutterInterfaceThemesList().size() ||
|
||||
theme < 0) {
|
||||
if (theme >= cutterInterfaceThemesList().size() || theme < 0) {
|
||||
theme = 0;
|
||||
}
|
||||
s.setValue("ColorPalette", theme);
|
||||
@ -464,10 +456,9 @@ KSyntaxHighlighting::Theme Configuration::getKSyntaxHighlightingTheme()
|
||||
if (!repo) {
|
||||
return KSyntaxHighlighting::Theme();
|
||||
}
|
||||
return repo->defaultTheme(
|
||||
getCurrentTheme()->flag & DarkFlag
|
||||
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
||||
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
||||
return repo->defaultTheme(getCurrentTheme()->flag & DarkFlag
|
||||
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
||||
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -487,9 +478,8 @@ QSyntaxHighlighter *Configuration::createSyntaxHighlighter(QTextDocument *docume
|
||||
|
||||
QString Configuration::getLogoFile()
|
||||
{
|
||||
return windowColorIsDark()
|
||||
? QString(":/img/cutter_white_plain.svg")
|
||||
: QString(":/img/cutter_plain.svg");
|
||||
return windowColorIsDark() ? QString(":/img/cutter_white_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);
|
||||
}
|
||||
|
||||
void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme)
|
||||
void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme,
|
||||
const QString &theme)
|
||||
{
|
||||
s.setValue("lastThemeOf." + currInterfaceTheme.name, theme);
|
||||
}
|
||||
@ -572,13 +563,13 @@ void Configuration::applySavedAsmOptions()
|
||||
}
|
||||
}
|
||||
|
||||
const QList<CutterInterfaceTheme>& Configuration::cutterInterfaceThemesList()
|
||||
const QList<CutterInterfaceTheme> &Configuration::cutterInterfaceThemesList()
|
||||
{
|
||||
static const QList<CutterInterfaceTheme> list = {
|
||||
{ "Native", Configuration::nativeWindowIsDark() ? DarkFlag : LightFlag },
|
||||
{ "Dark", DarkFlag },
|
||||
{ "Dark", DarkFlag },
|
||||
{ "Midnight", DarkFlag },
|
||||
{ "Light", LightFlag }
|
||||
{ "Light", LightFlag }
|
||||
};
|
||||
return list;
|
||||
}
|
||||
@ -599,7 +590,6 @@ QVariant Configuration::getConfigVar(const QString &key)
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
bool Configuration::getConfigBool(const QString &key)
|
||||
{
|
||||
return getConfigVar(key).toBool();
|
||||
@ -644,8 +634,8 @@ QStringList Configuration::getAvailableTranslations()
|
||||
if (!dir.exists()) {
|
||||
continue;
|
||||
}
|
||||
const QStringList &currTrFileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files,
|
||||
QDir::Name);
|
||||
const QStringList &currTrFileNames =
|
||||
dir.entryList(QStringList("cutter_*.qm"), QDir::Files, QDir::Name);
|
||||
for (const auto &trFile : currTrFileNames) {
|
||||
fileNamesSet << trFile;
|
||||
}
|
||||
@ -655,16 +645,16 @@ QStringList Configuration::getAvailableTranslations()
|
||||
std::sort(fileNames.begin(), fileNames.end());
|
||||
QStringList languages;
|
||||
QString currLanguageName;
|
||||
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
auto allLocales =
|
||||
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
for (auto i : fileNames) {
|
||||
QString localeName = i.mid(sizeof("cutter_") - 1, 2);
|
||||
for (auto j : allLocales) {
|
||||
if (j.name().startsWith(localeName)) {
|
||||
currLanguageName = j.nativeLanguageName();
|
||||
currLanguageName = currLanguageName.at(0).toUpper() +
|
||||
currLanguageName.right(currLanguageName.length() - 1);
|
||||
currLanguageName = currLanguageName.at(0).toUpper()
|
||||
+ currLanguageName.right(currLanguageName.length() - 1);
|
||||
languages << currLanguageName;
|
||||
break;
|
||||
}
|
||||
|
@ -10,26 +10,25 @@
|
||||
|
||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
namespace KSyntaxHighlighting {
|
||||
class Repository;
|
||||
class Theme;
|
||||
class Repository;
|
||||
class Theme;
|
||||
}
|
||||
#endif
|
||||
|
||||
class QSyntaxHighlighter;
|
||||
class QTextDocument;
|
||||
|
||||
|
||||
enum ColorFlags {
|
||||
LightFlag = 1,
|
||||
DarkFlag = 2,
|
||||
};
|
||||
|
||||
struct CutterInterfaceTheme {
|
||||
struct CutterInterfaceTheme
|
||||
{
|
||||
QString name;
|
||||
ColorFlags flag;
|
||||
};
|
||||
|
||||
|
||||
class CUTTER_EXPORT Configuration : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -56,7 +55,7 @@ private:
|
||||
void applySavedAsmOptions();
|
||||
|
||||
public:
|
||||
static const QList<CutterInterfaceTheme>& cutterInterfaceThemesList();
|
||||
static const QList<CutterInterfaceTheme> &cutterInterfaceThemesList();
|
||||
static const QHash<QString, ColorFlags> relevantThemes;
|
||||
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
||||
|
||||
@ -83,7 +82,7 @@ public:
|
||||
* @brief Gets the configured font set by the font selection box
|
||||
* @return the configured font
|
||||
*/
|
||||
const QFont getBaseFont() const;
|
||||
const QFont getBaseFont() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the configured font with the point size adjusted by the configured zoom
|
||||
@ -101,10 +100,7 @@ public:
|
||||
void setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme);
|
||||
QString getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const;
|
||||
void setInterfaceTheme(int theme);
|
||||
int getInterfaceTheme()
|
||||
{
|
||||
return s.value("ColorPalette", 0).toInt();
|
||||
}
|
||||
int getInterfaceTheme() { return s.value("ColorPalette", 0).toInt(); }
|
||||
|
||||
const CutterInterfaceTheme *getCurrentTheme();
|
||||
|
||||
@ -126,7 +122,7 @@ public:
|
||||
// Asm Options
|
||||
void resetToDefaultAsmOptions();
|
||||
|
||||
QString getColorTheme() const { return s.value("theme", "cutter").toString(); }
|
||||
QString getColorTheme() const { return s.value("theme", "cutter").toString(); }
|
||||
void setColorTheme(const QString &theme);
|
||||
/**
|
||||
* @brief Change current color theme if it doesn't much native theme's darkness.
|
||||
@ -164,27 +160,16 @@ public:
|
||||
bool isDecompilerAnnotationHighlighterEnabled();
|
||||
|
||||
// Graph
|
||||
int getGraphBlockMaxChars() const
|
||||
{
|
||||
return s.value("graph.maxcols", 100).toInt();
|
||||
}
|
||||
void setGraphBlockMaxChars(int ch)
|
||||
{
|
||||
s.setValue("graph.maxcols", ch);
|
||||
}
|
||||
int getGraphBlockMaxChars() const { return s.value("graph.maxcols", 100).toInt(); }
|
||||
void setGraphBlockMaxChars(int ch) { s.setValue("graph.maxcols", ch); }
|
||||
|
||||
int getGraphMinFontSize() const
|
||||
{
|
||||
return s.value("graph.minfontsize", 4).toInt();
|
||||
}
|
||||
int getGraphMinFontSize() const { return s.value("graph.minfontsize", 4).toInt(); }
|
||||
|
||||
void setGraphMinFontSize(int sz)
|
||||
{
|
||||
s.setValue("graph.minfontsize", sz);
|
||||
}
|
||||
void setGraphMinFontSize(int 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();
|
||||
double getBitmapExportScaleFactor();
|
||||
@ -202,7 +187,8 @@ public:
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
|
@ -14,12 +14,12 @@
|
||||
#include <QMap>
|
||||
#include <QProcess>
|
||||
|
||||
#if defined (Q_OS_LINUX)
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
#elif defined (Q_OS_WIN32)
|
||||
#include "client/windows/handler/exception_handler.h"
|
||||
#elif defined (Q_OS_MACOS)
|
||||
#include "client/mac/handler/exception_handler.h"
|
||||
#if defined(Q_OS_LINUX)
|
||||
# include "client/linux/handler/exception_handler.h"
|
||||
#elif defined(Q_OS_WIN32)
|
||||
# include "client/windows/handler/exception_handler.h"
|
||||
#elif defined(Q_OS_MACOS)
|
||||
# include "client/mac/handler/exception_handler.h"
|
||||
#endif // Q_OS
|
||||
|
||||
static google_breakpad::ExceptionHandler *exceptionHandler = nullptr;
|
||||
@ -32,30 +32,27 @@ static void finishCrashHandler()
|
||||
#ifdef Q_OS_WIN32
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const wchar_t *_dump_dir,
|
||||
const wchar_t *_minidump_id,
|
||||
void *context, EXCEPTION_POINTERS *exinfo,
|
||||
MDRawAssertionInfo *assertion,
|
||||
bool success)
|
||||
bool callback(const wchar_t *_dump_dir, const wchar_t *_minidump_id, void *context,
|
||||
EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool success)
|
||||
{
|
||||
const QDir dir = QString::fromWCharArray(_dump_dir);
|
||||
const QString id = QString::fromWCharArray(_minidump_id);
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
#elif defined (Q_OS_LINUX)
|
||||
#elif defined(Q_OS_LINUX)
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const google_breakpad::MinidumpDescriptor &md, void *context, bool b)
|
||||
{
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", md.path() });
|
||||
{ "--start-crash-handler", md.path() });
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
#elif defined (Q_OS_MACOS)
|
||||
#elif defined(Q_OS_MACOS)
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded)
|
||||
@ -63,7 +60,7 @@ bool callback(const char *dump_dir, const char *minidump_id, void *context, bool
|
||||
const QDir dir = QString::fromUtf8(dump_dir);
|
||||
const QString id = QString::fromUtf8(minidump_id);
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
@ -77,29 +74,22 @@ void initCrashHandler()
|
||||
// Here will be placed crash dump at the first place
|
||||
// and then moved if needed
|
||||
|
||||
#if defined (Q_OS_LINUX)
|
||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(google_breakpad::MinidumpDescriptor(tmpLocation),
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
true,
|
||||
-1);
|
||||
#elif defined (Q_OS_MACOS)
|
||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
true,
|
||||
nullptr);
|
||||
#if defined(Q_OS_LINUX)
|
||||
static std::string tmpLocation =
|
||||
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
google_breakpad::MinidumpDescriptor(tmpLocation), nullptr, callback, nullptr, true, -1);
|
||||
#elif defined(Q_OS_MACOS)
|
||||
static std::string tmpLocation =
|
||||
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback,
|
||||
nullptr, true, nullptr);
|
||||
#else
|
||||
static std::wstring tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
static std::wstring tmpLocation =
|
||||
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
||||
exceptionHandler =
|
||||
new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback, nullptr,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
#endif
|
||||
atexit(finishCrashHandler);
|
||||
}
|
||||
@ -125,14 +115,13 @@ void showCrashDialog(const QString &dumpFile)
|
||||
if (placementFailCounter == 4) {
|
||||
break;
|
||||
}
|
||||
dumpSaveFileName = QFileDialog::getSaveFileName(nullptr,
|
||||
QObject::tr("Choose a directory to save the crash dump in"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
|
||||
QDir::separator() +
|
||||
"Cutter_crash_dump_"
|
||||
+ QDate::currentDate().toString("dd.MM.yy") + "_"
|
||||
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
||||
QObject::tr("Minidump (*.dmp)"));
|
||||
dumpSaveFileName = QFileDialog::getSaveFileName(
|
||||
nullptr, QObject::tr("Choose a directory to save the crash dump in"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
|
||||
+ QDir::separator() + "Cutter_crash_dump_"
|
||||
+ QDate::currentDate().toString("dd.MM.yy") + "_"
|
||||
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
||||
QObject::tr("Minidump (*.dmp)"));
|
||||
|
||||
if (dumpSaveFileName.isEmpty()) {
|
||||
return;
|
||||
@ -141,18 +130,18 @@ void showCrashDialog(const QString &dumpFile)
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
QMessageBox::critical(nullptr,
|
||||
QObject::tr("Save Crash Dump"),
|
||||
QMessageBox::critical(nullptr, QObject::tr("Save Crash Dump"),
|
||||
QObject::tr("Failed to write to %1.<br/>"
|
||||
"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);
|
||||
|
||||
if (ok) {
|
||||
QMessageBox info;
|
||||
info.setWindowTitle(QObject::tr("Success"));
|
||||
info.setText(QObject::tr("<a href=\"%1\">Crash dump</a> was successfully created.")
|
||||
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
info.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
info.button(QMessageBox::Yes)->setText(QObject::tr("Open an Issue"));
|
||||
@ -164,8 +153,7 @@ void showCrashDialog(const QString &dumpFile)
|
||||
openIssue();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(nullptr,
|
||||
QObject::tr("Error"),
|
||||
QMessageBox::critical(nullptr, QObject::tr("Error"),
|
||||
QObject::tr("Error occurred during crash dump creation."));
|
||||
}
|
||||
} else {
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
* If CUTTER_ENABLE_CRASH_REPORTS is true, initializes
|
||||
* crash handling and reporting, otherwise does nothing.
|
||||
*/
|
||||
*/
|
||||
void initCrashHandler();
|
||||
|
||||
void showCrashDialog(const QString &dumpFile);
|
||||
|
@ -6,8 +6,7 @@
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
|
||||
namespace Cutter
|
||||
{
|
||||
namespace Cutter {
|
||||
|
||||
struct CutterLayout
|
||||
{
|
||||
|
@ -3,10 +3,7 @@
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
|
||||
CutterSeekable::CutterSeekable(QObject *parent)
|
||||
:
|
||||
QObject(parent)
|
||||
CutterSeekable::CutterSeekable(QObject *parent) : QObject(parent)
|
||||
{
|
||||
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged);
|
||||
}
|
||||
@ -38,7 +35,6 @@ void CutterSeekable::updateSeek(RVA addr, bool localOnly)
|
||||
emit seekableSeekChanged(addr);
|
||||
}
|
||||
|
||||
|
||||
void CutterSeekable::seekPrev()
|
||||
{
|
||||
if (synchronized) {
|
||||
@ -65,20 +61,19 @@ bool CutterSeekable::isSynchronized()
|
||||
|
||||
void CutterSeekable::seekToReference(RVA offset)
|
||||
{
|
||||
if (offset == RVA_INVALID)
|
||||
{
|
||||
if (offset == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RVA target;
|
||||
QList<XrefDescription> refs = Core()->getXRefs(offset, false, false);
|
||||
|
||||
|
||||
if (refs.length()) {
|
||||
if (refs.length() > 1) {
|
||||
qWarning() << tr("More than one (%1) references here. Weird behaviour expected.")
|
||||
.arg(refs.length());
|
||||
.arg(refs.length());
|
||||
}
|
||||
|
||||
|
||||
target = refs.at(0).to;
|
||||
if (target != RVA_INVALID) {
|
||||
seek(target);
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class CUTTER_EXPORT CutterSeekable : public QObject
|
||||
class CUTTER_EXPORT CutterSeekable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -45,7 +45,8 @@ public:
|
||||
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
|
||||
*/
|
||||
void seekToReference(RVA offset);
|
||||
|
@ -6,19 +6,17 @@
|
||||
#include <QJsonArray>
|
||||
|
||||
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
|
||||
: QObject(parent),
|
||||
id(id),
|
||||
name(name)
|
||||
: QObject(parent), id(id), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage){
|
||||
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
|
||||
{
|
||||
std::string temporary = warningMessage.toStdString();
|
||||
return rz_annotated_code_new(strdup(temporary.c_str()));
|
||||
}
|
||||
|
||||
JSDecDecompiler::JSDecDecompiler(QObject *parent)
|
||||
: Decompiler("jsdec", "jsdec", parent)
|
||||
JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", parent)
|
||||
{
|
||||
task = nullptr;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
/**
|
||||
* Implements a decompiler that can be registered using CutterCore::registerDecompiler()
|
||||
*/
|
||||
class CUTTER_EXPORT Decompiler: public QObject
|
||||
class CUTTER_EXPORT Decompiler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -25,19 +25,19 @@ public:
|
||||
|
||||
static RzAnnotatedCode *makeWarning(QString warningMessage);
|
||||
|
||||
QString getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
virtual bool isRunning() { return false; }
|
||||
QString getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
virtual bool isRunning() { return false; }
|
||||
virtual bool isCancelable() { return false; }
|
||||
|
||||
virtual void decompileAt(RVA addr) =0;
|
||||
virtual void decompileAt(RVA addr) = 0;
|
||||
virtual void cancel() {}
|
||||
|
||||
signals:
|
||||
void finished(RzAnnotatedCode *codeDecompiled);
|
||||
};
|
||||
|
||||
class JSDecDecompiler: public Decompiler
|
||||
class JSDecDecompiler : public Decompiler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -48,9 +48,9 @@ public:
|
||||
explicit JSDecDecompiler(QObject *parent = nullptr);
|
||||
void decompileAt(RVA addr) override;
|
||||
|
||||
bool isRunning() override { return task != nullptr; }
|
||||
bool isRunning() override { return task != nullptr; }
|
||||
|
||||
static bool isAvailable();
|
||||
};
|
||||
|
||||
#endif //DECOMPILER_H
|
||||
#endif // DECOMPILER_H
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||
{
|
||||
setupTheme();
|
||||
connect(Config(), &Configuration::colorsUpdated, this, [this]() {
|
||||
@ -21,18 +20,19 @@ void DecompilerHighlighter::setAnnotations(RzAnnotatedCode *code)
|
||||
|
||||
void DecompilerHighlighter::setupTheme()
|
||||
{
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
RSyntaxHighlightType type;
|
||||
QString name;
|
||||
} mapping[] = {
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD, "pop"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT, "comment"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE, "func_var_type"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME, "fname"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER, "args"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE, "func_var"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE, "num"},
|
||||
{RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE, "flag"},
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD, "pop" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT, "comment" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE, "func_var_type" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME, "fname" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER, "args" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE, "func_var" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE, "num" },
|
||||
{ RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE, "flag" },
|
||||
};
|
||||
for (const auto &pair : mapping) {
|
||||
assert(pair.type < format.size());
|
||||
@ -49,10 +49,12 @@ void DecompilerHighlighter::highlightBlock(const QString &)
|
||||
size_t start = block.position();
|
||||
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;
|
||||
rz_pvector_foreach(annotations.get(), iter) {
|
||||
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation*>(*iter);
|
||||
rz_pvector_foreach(annotations.get(), iter)
|
||||
{
|
||||
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation *>(*iter);
|
||||
if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
@ -22,17 +22,17 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Set the code with annotations to be used for highlighting.
|
||||
*
|
||||
*
|
||||
* It is callers responsibility to ensure that it is synchronized with currentTextDocument and
|
||||
* has sufficiently long lifetime.
|
||||
*
|
||||
* @param code
|
||||
*
|
||||
* @param code
|
||||
*/
|
||||
void setAnnotations(RzAnnotatedCode *code);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
|
||||
private:
|
||||
void setupTheme();
|
||||
|
||||
|
@ -10,11 +10,9 @@ void DirectionalComboBox::showPopup()
|
||||
QComboBox::showPopup();
|
||||
QWidget *popup = this->findChild<QFrame *>();
|
||||
if (popupUpwards) {
|
||||
popup->move(popup->x(),
|
||||
mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
||||
popup->move(popup->x(), mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
||||
} else {
|
||||
popup->move(popup->x(),
|
||||
mapToGlobal(this->rect().topLeft()).y());
|
||||
popup->move(popup->x(), mapToGlobal(this->rect().topLeft()).y());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <QComboBox>
|
||||
/**
|
||||
* @brief Custom QComboBox created to prevent the menu popup from opening up at different
|
||||
* offsets for different items, which may result in list items being rendered outside
|
||||
* offsets for different items, which may result in list items being rendered outside
|
||||
* of the screen/containing widget.
|
||||
*/
|
||||
class DirectionalComboBox : public QComboBox
|
||||
@ -20,4 +20,3 @@ private:
|
||||
|
||||
void showPopup();
|
||||
};
|
||||
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
class FunctionsTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QString getTitle() override { return tr("Fetching Functions"); }
|
||||
QString getTitle() override { return tr("Fetching Functions"); }
|
||||
|
||||
signals:
|
||||
void fetchFinished(const QList<FunctionDescription> &strings);
|
||||
@ -23,4 +23,4 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
#endif //FUNCTIONSTASK_H
|
||||
#endif // FUNCTIONSTASK_H
|
||||
|
@ -18,10 +18,10 @@
|
||||
static QAbstractItemView::ScrollMode scrollMode()
|
||||
{
|
||||
const bool use_scrollperpixel = true;
|
||||
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel : QAbstractItemView::ScrollPerItem;
|
||||
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
|
||||
: QAbstractItemView::ScrollPerItem;
|
||||
}
|
||||
|
||||
|
||||
namespace qhelpers {
|
||||
|
||||
QString formatBytecount(const uint64_t bytecount)
|
||||
@ -31,12 +31,12 @@ QString formatBytecount(const uint64_t bytecount)
|
||||
}
|
||||
|
||||
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;
|
||||
QTextStream stream(&str);
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp)
|
||||
<< ' ' << suffixes[exp] << 'B';
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) << ' ' << suffixes[exp]
|
||||
<< 'B';
|
||||
return stream.readAll();
|
||||
}
|
||||
|
||||
@ -161,25 +161,24 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||
return (textEdit->height()
|
||||
- (textEdit->contentsMargins().top()
|
||||
+ textEdit->contentsMargins().bottom()
|
||||
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
|
||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||
return (plainTextEdit->height()
|
||||
- (plainTextEdit->contentsMargins().top()
|
||||
+ plainTextEdit->contentsMargins().bottom()
|
||||
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
|
||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
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'));
|
||||
int replaceStrLen = replaceStr.length();
|
||||
@ -194,7 +193,8 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
* and loaded icon
|
||||
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an
|
||||
* object which has to be used and loaded icon
|
||||
* @param supportedIconsNames list of <object ptr, icon name>
|
||||
* @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,
|
||||
std::function<void(void *, const QIcon &)> setter)
|
||||
@ -232,7 +233,7 @@ void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
||||
iconPath = iconsDirPath;
|
||||
// Verify that indeed there is an alternative icon in this theme
|
||||
// Otherwise, fallback to the regular icon folder
|
||||
if (QFile::exists(iconPath + relativeThemeDir + p.second)) {
|
||||
if (QFile::exists(iconPath + relativeThemeDir + p.second)) {
|
||||
iconPath += relativeThemeDir;
|
||||
}
|
||||
setter(p.first, QIcon(iconPath + p.second));
|
||||
@ -272,11 +273,8 @@ void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex)
|
||||
void emitColumnChanged(QAbstractItemModel *model, int column)
|
||||
{
|
||||
if (model && model->rowCount()) {
|
||||
emit model->dataChanged(
|
||||
model->index(0, column),
|
||||
model->index(model->rowCount() - 1, column),
|
||||
{ Qt::DisplayRole }
|
||||
);
|
||||
emit model->dataChanged(model->index(0, column),
|
||||
model->index(model->rowCount() - 1, column), { Qt::DisplayRole });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,9 @@ class QPaintDevice;
|
||||
class QComboBox;
|
||||
|
||||
#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
|
||||
#define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
|
||||
# define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
|
||||
#endif
|
||||
|
||||
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(QTreeWidget *tw, int padding);
|
||||
CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
|
||||
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
||||
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str,
|
||||
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 setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
||||
|
||||
|
||||
struct CUTTER_EXPORT SizePolicyMinMax {
|
||||
struct CUTTER_EXPORT SizePolicyMinMax
|
||||
{
|
||||
QSizePolicy sizePolicy;
|
||||
int min;
|
||||
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 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 qreal devicePixelRatio(const QPaintDevice *p);
|
||||
@ -73,7 +77,7 @@ CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
|
||||
*/
|
||||
CUTTER_EXPORT void selectIndexByData(QComboBox *comboBox, QVariant data, int defaultIndex = -1);
|
||||
/**
|
||||
* @brief Emit data change signal in a model's column (DisplayRole)
|
||||
* @brief Emit data change signal in a model's column (DisplayRole)
|
||||
* @param model - model containing data with changes
|
||||
* @param column - column in the model
|
||||
*/
|
||||
|
@ -16,8 +16,8 @@ static qreal GetDevicePixelRatio(qreal devicePixelRatio)
|
||||
}
|
||||
|
||||
HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio)
|
||||
: QPixmap(int(width * GetDevicePixelRatio(devicePixelRatio)),
|
||||
int(height * GetDevicePixelRatio(devicePixelRatio)))
|
||||
: QPixmap(int(width *GetDevicePixelRatio(devicePixelRatio)),
|
||||
int(height *GetDevicePixelRatio(devicePixelRatio)))
|
||||
{
|
||||
setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio));
|
||||
}
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
Highlighter::Highlighter(QTextDocument *parent) :
|
||||
QSyntaxHighlighter(parent)
|
||||
Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||
{
|
||||
HighlightingRule rule;
|
||||
|
||||
@ -28,7 +27,6 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
|
||||
singleLineCommentFormat.setFontWeight(QFont::Bold);
|
||||
singleLineCommentFormat.setForeground(QColor(63, 195, 128));
|
||||
rule.pattern.setPattern(";[^\n]*");
|
||||
@ -57,17 +55,19 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
|
||||
|
||||
while (startIndex >= 0) {
|
||||
QRegularExpressionMatch commentEndMatch = QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
||||
QRegularExpressionMatch commentEndMatch =
|
||||
QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
||||
int endIndex = commentEndMatch.capturedStart();
|
||||
int commentLength;
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ commentEndMatch.capturedLength();
|
||||
commentLength = endIndex - startIndex + commentEndMatch.capturedLength();
|
||||
}
|
||||
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:
|
||||
CutterCore *core;
|
||||
|
||||
struct HighlightingRule {
|
||||
struct HighlightingRule
|
||||
{
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
@ -42,4 +43,4 @@ private:
|
||||
QTextCharFormat functionFormat;
|
||||
};
|
||||
|
||||
#endif // HIGHLIGHTER_H
|
||||
#endif // HIGHLIGHTER_H
|
||||
|
@ -51,17 +51,17 @@ bool IOModesController::prepareForWriting()
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle(QObject::tr("Write error"));
|
||||
msgBox.setText(
|
||||
QObject::tr("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"
|
||||
"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 "
|
||||
"via File -> Commit modifications to disk."));
|
||||
msgBox.setText(QObject::tr(
|
||||
"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"
|
||||
"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 "
|
||||
"via File -> Commit modifications to disk."));
|
||||
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
|
||||
QAbstractButton *reopenButton = msgBox.addButton(QObject::tr("Reopen in Write mode"),
|
||||
QMessageBox::YesRole);
|
||||
QAbstractButton *iocacheButton = msgBox.addButton(QObject::tr("Enable Cache mode"),
|
||||
QMessageBox::YesRole);
|
||||
QAbstractButton *reopenButton =
|
||||
msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole);
|
||||
QAbstractButton *iocacheButton =
|
||||
msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
@ -95,10 +95,13 @@ bool IOModesController::askCommitUnsavedChanges()
|
||||
{
|
||||
// Check if there are uncommitted changes
|
||||
if (!allChangesComitted()) {
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(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?"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(
|
||||
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?"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
|
||||
| QMessageBox::Cancel));
|
||||
if (ret == QMessageBox::Save) {
|
||||
Core()->commitWriteCache();
|
||||
} else if (ret == QMessageBox::Discard) {
|
||||
|
@ -7,7 +7,8 @@
|
||||
/**
|
||||
* @brief The CommandDescription struct is a pair of a Rizin command and its description
|
||||
*/
|
||||
struct CommandDescription {
|
||||
struct CommandDescription
|
||||
{
|
||||
QString command;
|
||||
QString description;
|
||||
};
|
||||
@ -37,10 +38,10 @@ struct InitialOptions
|
||||
|
||||
QString pdbFile;
|
||||
QString script;
|
||||
|
||||
QList<CommandDescription> analCmd = { {"aaa", "Auto analysis"} };
|
||||
|
||||
QList<CommandDescription> analCmd = { { "aaa", "Auto analysis" } };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif //CUTTER_JSON_H
|
||||
#endif // CUTTER_JSON_H
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "JsonModel.h"
|
||||
|
||||
JsonModel::JsonModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
JsonModel::JsonModel(QObject *parent) : QAbstractItemModel(parent)
|
||||
{
|
||||
mRootItem = new JsonTreeItem;
|
||||
mHeaders.append("key");
|
||||
@ -42,10 +41,8 @@ QVariant JsonModel::data(const QModelIndex &index, int role) const
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
|
||||
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
|
||||
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
|
||||
if (index.column() == 0)
|
||||
@ -122,4 +119,3 @@ int JsonModel::columnCount(const QModelIndex &parent) const
|
||||
Q_UNUSED(parent)
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
~JsonModel();
|
||||
|
||||
private:
|
||||
JsonTreeItem *mRootItem;
|
||||
QJsonDocument mDocument;
|
||||
|
@ -73,9 +73,9 @@ JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
||||
JsonTreeItem *rootItem = new JsonTreeItem(parent);
|
||||
rootItem->setKey("root");
|
||||
|
||||
if ( value.isObject()) {
|
||||
if (value.isObject()) {
|
||||
|
||||
//Get all QJsonValue childs
|
||||
// Get all QJsonValue childs
|
||||
for (const QString &key : value.toObject().keys()) {
|
||||
QJsonValue v = value.toObject().value(key);
|
||||
JsonTreeItem *child = load(v, rootItem);
|
||||
@ -84,8 +84,8 @@ JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
||||
rootItem->appendChild(child);
|
||||
}
|
||||
|
||||
} else if ( value.isArray()) {
|
||||
//Get all QJsonValue childs
|
||||
} else if (value.isArray()) {
|
||||
// Get all QJsonValue childs
|
||||
int index = 0;
|
||||
for (const QJsonValue &v : value.toArray()) {
|
||||
|
||||
|
@ -8,20 +8,23 @@
|
||||
/**
|
||||
* @brief Pool of singly linked lists.
|
||||
*
|
||||
* Should not be used as general purpose container. Use only for algorithms that require linked lists ability
|
||||
* to split and concatenate them. All the data is owned by LinkedListPool.
|
||||
* Should not be used as general purpose container. Use only for algorithms that require linked
|
||||
* 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
|
||||
* all the memory for multiple lists during construction. Uses std::vector as backing container.
|
||||
* In contrast to std::list and std::forward_list doesn't allocate each node separately.
|
||||
* LinkedListPool can reserve all the memory for multiple lists during construction. Uses
|
||||
* std::vector as backing container.
|
||||
*/
|
||||
template<class T>
|
||||
class LinkedListPool
|
||||
{
|
||||
using IndexType = size_t;
|
||||
struct Item {
|
||||
struct Item
|
||||
{
|
||||
IndexType next;
|
||||
T value;
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief List iterator.
|
||||
@ -32,27 +35,19 @@ public:
|
||||
{
|
||||
IndexType index = 0;
|
||||
LinkedListPool<T> *pool = nullptr;
|
||||
ListIterator(IndexType index, LinkedListPool<T> *pool)
|
||||
: index(index)
|
||||
, pool(pool)
|
||||
{}
|
||||
ListIterator(IndexType index, LinkedListPool<T> *pool) : index(index), pool(pool) {}
|
||||
|
||||
friend class LinkedListPool<T>;
|
||||
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = T;
|
||||
using difference_type = size_t;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
using pointer = T *;
|
||||
using reference = T &;
|
||||
ListIterator() = default;
|
||||
reference operator*()
|
||||
{
|
||||
return pool->data[index].value;
|
||||
}
|
||||
pointer operator->()
|
||||
{
|
||||
return &pool->data[index].value;
|
||||
}
|
||||
reference operator*() { return pool->data[index].value; }
|
||||
pointer operator->() { return &pool->data[index].value; }
|
||||
|
||||
ListIterator &operator++()
|
||||
{
|
||||
@ -65,24 +60,18 @@ public:
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
bool operator!=(const ListIterator &b) const
|
||||
{
|
||||
return index != b.index || pool != b.pool;
|
||||
};
|
||||
bool operator!=(const ListIterator &b) const { return index != b.index || pool != b.pool; };
|
||||
/**
|
||||
* @brief Test if iterator points to valid value.
|
||||
*/
|
||||
explicit operator bool() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
explicit operator bool() const { return index; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Single list within LinkedListPool.
|
||||
*
|
||||
* List only refers to chain of elements. Copying it doesn't copy any element. Item data is owned by
|
||||
* LinkedListPool.
|
||||
* List only refers to chain of elements. Copying it doesn't copy any element. Item data is
|
||||
* owned by LinkedListPool.
|
||||
*
|
||||
* Use LinkedListPool::makeList to create non-empty list.
|
||||
*/
|
||||
@ -91,28 +80,22 @@ public:
|
||||
IndexType head = 0;
|
||||
IndexType tail = 0;
|
||||
friend class LinkedListPool;
|
||||
List(IndexType head, IndexType tail)
|
||||
: head(head)
|
||||
, tail(tail)
|
||||
{}
|
||||
List(IndexType head, IndexType tail) : head(head), tail(tail) {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Create an empty list
|
||||
*/
|
||||
List() = default;
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return head == 0;
|
||||
}
|
||||
bool isEmpty() const { return head == 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a linked list pool with capacity for \a initialCapacity list items.
|
||||
* @param initialCapacity number of elements to preallocate.
|
||||
*/
|
||||
LinkedListPool(size_t initialCapacity)
|
||||
: data(1)
|
||||
LinkedListPool(size_t initialCapacity) : data(1)
|
||||
{
|
||||
data.reserve(initialCapacity + 1); // [0] element reserved
|
||||
}
|
||||
@ -120,22 +103,23 @@ public:
|
||||
/**
|
||||
* @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
|
||||
* @return List containing single value \a value .
|
||||
*/
|
||||
List makeList(const T &value)
|
||||
{
|
||||
size_t position = data.size();
|
||||
data.push_back(Item{0, value});
|
||||
return {position, position};
|
||||
data.push_back(Item { 0, value });
|
||||
return { position, position };
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* will affect both lists.
|
||||
* After performing the operation, list passed as argument and return list point to the same
|
||||
* items. Modifying them will affect both lists.
|
||||
*
|
||||
* @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 .
|
||||
@ -143,14 +127,15 @@ public:
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
List splitHead(const List &list, const ListIterator &end)
|
||||
@ -166,7 +151,7 @@ public:
|
||||
last = data[last].next;
|
||||
}
|
||||
data[last].next = 0;
|
||||
return List {list.head, last};
|
||||
return List { list.head, last };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,15 +159,9 @@ public:
|
||||
* @param list
|
||||
* @return Iterator pointing to the first item in the list.
|
||||
*/
|
||||
ListIterator head(const List &list)
|
||||
{
|
||||
return iteratorFromIndex(list.head);
|
||||
}
|
||||
ListIterator head(const List &list) { return iteratorFromIndex(list.head); }
|
||||
|
||||
ListIterator end(const List &list)
|
||||
{
|
||||
return std::next(iteratorFromIndex(list.tail));
|
||||
}
|
||||
ListIterator end(const List &list) { return std::next(iteratorFromIndex(list.tail)); }
|
||||
|
||||
List append(const List &head, const List &tail)
|
||||
{
|
||||
@ -192,18 +171,15 @@ public:
|
||||
if (tail.isEmpty()) {
|
||||
return head;
|
||||
}
|
||||
List result{head.head, tail.tail};
|
||||
List result { head.head, tail.tail };
|
||||
data[head.tail].next = tail.head;
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
ListIterator iteratorFromIndex(IndexType index)
|
||||
{
|
||||
return ListIterator{ index, this };
|
||||
}
|
||||
ListIterator iteratorFromIndex(IndexType index) { return ListIterator { index, this }; }
|
||||
|
||||
std::vector<Item> data;
|
||||
};
|
||||
|
||||
|
||||
#endif // LINKED_LIST_POOL
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
#include "common/MdHighlighter.h"
|
||||
|
||||
MdHighlighter::MdHighlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||
{
|
||||
HighlightingRule rule;
|
||||
|
||||
@ -11,8 +10,10 @@ MdHighlighter::MdHighlighter(QTextDocument *parent)
|
||||
keywordFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
QStringList keywordPatterns;
|
||||
keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b" << "\\*\\*([^\\\\]+)\\*\\*"
|
||||
<< "\\*([^\\\\]+)\\*" << "\\_([^\\\\]+)\\_"
|
||||
keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b"
|
||||
<< "\\*\\*([^\\\\]+)\\*\\*"
|
||||
<< "\\*([^\\\\]+)\\*"
|
||||
<< "\\_([^\\\\]+)\\_"
|
||||
<< "\\_\\_([^\\\\]+)\\_\\_";
|
||||
|
||||
for (const QString &pattern : keywordPatterns) {
|
||||
|
@ -20,7 +20,8 @@ protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
struct HighlightingRule {
|
||||
struct HighlightingRule
|
||||
{
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
@ -34,4 +35,4 @@ private:
|
||||
QTextCharFormat functionFormat;
|
||||
};
|
||||
|
||||
#endif // MDHIGHLIGHTER_H
|
||||
#endif // MDHIGHLIGHTER_H
|
||||
|
@ -9,18 +9,23 @@ class QRectF;
|
||||
class QFontMetrics;
|
||||
class QFontMetricsF;
|
||||
|
||||
template<typename T> struct Metrics {};
|
||||
template<typename T>
|
||||
struct Metrics
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct Metrics<int>
|
||||
template<>
|
||||
struct Metrics<int>
|
||||
{
|
||||
using Rect = QRect;
|
||||
using FontMetrics = QFontMetrics;
|
||||
};
|
||||
|
||||
template<> struct Metrics<qreal>
|
||||
template<>
|
||||
struct Metrics<qreal>
|
||||
{
|
||||
using Rect = QRectF;
|
||||
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 timerInterval = 50;
|
||||
|
||||
ProgressIndicator::ProgressIndicator(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
ProgressIndicator::ProgressIndicator(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
updateAnimationTimer();
|
||||
}
|
||||
|
||||
ProgressIndicator::~ProgressIndicator()
|
||||
{
|
||||
}
|
||||
ProgressIndicator::~ProgressIndicator() {}
|
||||
|
||||
void ProgressIndicator::setProgressIndicatorVisible(bool visible)
|
||||
{
|
||||
@ -77,13 +74,9 @@ void ProgressIndicator::paintEvent(QPaintEvent *)
|
||||
QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0);
|
||||
|
||||
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;
|
||||
painter.setOpacity((float)state / arms);
|
||||
painter.drawLine(line * QTransform()
|
||||
.translate(origin.x(), origin.y())
|
||||
.rotate(angle * i));
|
||||
painter.drawLine(line * QTransform().translate(origin.x(), origin.y()).rotate(angle * i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ProgressIndicator: public QWidget
|
||||
class ProgressIndicator : public QWidget
|
||||
{
|
||||
public:
|
||||
ProgressIndicator(QWidget *parent = nullptr);
|
||||
@ -13,10 +13,10 @@ public:
|
||||
QSize minimumSizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
bool getProgressIndicatorVisible() const { return progressIndicatorVisible; }
|
||||
bool getProgressIndicatorVisible() const { return progressIndicatorVisible; }
|
||||
void setProgressIndicatorVisible(bool visible);
|
||||
|
||||
bool getAnimating() const { return animating; }
|
||||
bool getAnimating() const { return animating; }
|
||||
void setAnimating(bool animating);
|
||||
|
||||
protected:
|
||||
@ -33,5 +33,4 @@ private:
|
||||
void updateAnimationTimer();
|
||||
};
|
||||
|
||||
|
||||
#endif //PROGRESSINDICATOR_H
|
||||
#endif // PROGRESSINDICATOR_H
|
||||
|
@ -16,7 +16,7 @@ PyObject *api_cmd(PyObject *self, PyObject *args)
|
||||
{
|
||||
Q_UNUSED(self);
|
||||
char *command;
|
||||
char *result = (char *) "";
|
||||
char *result = (char *)"";
|
||||
QString cmdRes;
|
||||
QByteArray cmdBytes;
|
||||
if (PyArg_ParseTuple(args, "s:command", &command)) {
|
||||
@ -41,9 +41,8 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
char *message;
|
||||
int debug = 0;
|
||||
static const char *kwlist[] = { "", "debug", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i",
|
||||
const_cast<char**>(kwlist),
|
||||
&message, &debug)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", const_cast<char **>(kwlist), &message,
|
||||
&debug)) {
|
||||
return NULL;
|
||||
}
|
||||
Core()->message(QString(message), debug);
|
||||
@ -52,28 +51,16 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
}
|
||||
|
||||
PyMethodDef CutterMethods[] = {
|
||||
{
|
||||
"version", api_version, METH_NOARGS,
|
||||
"Returns Cutter current version"
|
||||
},
|
||||
{
|
||||
"cmd", api_cmd, METH_VARARGS,
|
||||
"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}
|
||||
{ "version", api_version, METH_NOARGS, "Returns Cutter current version" },
|
||||
{ "cmd", api_cmd, METH_VARARGS, "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_HEAD_INIT, "_cutter", NULL, -1, CutterMethods,
|
||||
NULL, NULL, NULL, NULL
|
||||
PyModuleDef_HEAD_INIT, "_cutter", NULL, -1, CutterMethods, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyObject *PyInit_api()
|
||||
|
@ -11,9 +11,9 @@
|
||||
#include <QDir>
|
||||
|
||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||
#include <shiboken.h>
|
||||
#include <pyside.h>
|
||||
#include <signalmanager.h>
|
||||
# include <shiboken.h>
|
||||
# include <pyside.h>
|
||||
# include <signalmanager.h>
|
||||
#endif
|
||||
|
||||
#include "QtResImporter.h"
|
||||
@ -28,29 +28,25 @@ PythonManager *PythonManager::getInstance()
|
||||
return uniqueInstance;
|
||||
}
|
||||
|
||||
PythonManager::PythonManager()
|
||||
{
|
||||
}
|
||||
PythonManager::PythonManager() {}
|
||||
|
||||
PythonManager::~PythonManager()
|
||||
{
|
||||
}
|
||||
PythonManager::~PythonManager() {}
|
||||
|
||||
void PythonManager::initPythonHome()
|
||||
{
|
||||
#if defined(APPIMAGE) || defined(MACOS_PYTHON_FRAMEWORK_BUNDLED)
|
||||
if (customPythonHome.isNull()) {
|
||||
auto pythonHomeDir = QDir(QCoreApplication::applicationDirPath());
|
||||
# ifdef APPIMAGE
|
||||
# ifdef APPIMAGE
|
||||
// Executable is in appdir/bin
|
||||
pythonHomeDir.cdUp();
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() << " for AppImage.";
|
||||
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED
|
||||
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED
|
||||
// @executable_path/../Frameworks/Python.framework/Versions/Current
|
||||
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() <<
|
||||
" for macOS Application Bundle.";
|
||||
# endif
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath()
|
||||
<< " for macOS Application Bundle.";
|
||||
# endif
|
||||
customPythonHome = pythonHomeDir.absolutePath();
|
||||
}
|
||||
#endif
|
||||
@ -85,11 +81,11 @@ void PythonManager::initialize()
|
||||
}
|
||||
|
||||
#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);
|
||||
auto pyQApp = reinterpret_cast<SbkObject*>(realData[0]);
|
||||
auto pyQObjectType = reinterpret_cast<PyTypeObject*>(realData[1]);
|
||||
void **realData = reinterpret_cast<void **>(data);
|
||||
auto pyQApp = reinterpret_cast<SbkObject *>(realData[0]);
|
||||
auto pyQObjectType = reinterpret_cast<PyTypeObject *>(realData[1]);
|
||||
|
||||
if (pyObj == pyQApp || !PyObject_TypeCheck(pyObj, pyQObjectType)) {
|
||||
return;
|
||||
@ -112,8 +108,8 @@ static void pySideDestructionVisitor(SbkObject* pyObj, void* data)
|
||||
}
|
||||
|
||||
Shiboken::Object::setValidCpp(pyObj, false);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, pyQObjectType));
|
||||
Py_BEGIN_ALLOW_THREADS Shiboken::callCppDestructor<QObject>(
|
||||
Shiboken::Object::cppPointer(pyObj, pyQObjectType));
|
||||
Py_END_ALLOW_THREADS
|
||||
};
|
||||
#endif
|
||||
@ -125,15 +121,16 @@ void PythonManager::shutdown()
|
||||
restoreThread();
|
||||
|
||||
#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());
|
||||
|
||||
// see PySide::destroyQCoreApplication()
|
||||
PySide::SignalManager::instance().clear();
|
||||
Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
|
||||
SbkObject* pyQApp = bm.retrieveWrapper(QCoreApplication::instance());
|
||||
PyTypeObject* pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
|
||||
void* data[2] = {pyQApp, pyQObjectType};
|
||||
Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
|
||||
SbkObject *pyQApp = bm.retrieveWrapper(QCoreApplication::instance());
|
||||
PyTypeObject *pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
|
||||
void *data[2] = { pyQApp, pyQObjectType };
|
||||
bm.visitAllPyObjects(&pySideDestructionVisitor, &data);
|
||||
|
||||
PySide::runCleanupFunctions();
|
||||
@ -146,7 +143,8 @@ void PythonManager::shutdown()
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
void PythonManager::addPythonPath(char *path) {
|
||||
void PythonManager::addPythonPath(char *path)
|
||||
{
|
||||
restoreThread();
|
||||
|
||||
PyObject *sysModule = PyImport_ImportModule("sys");
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
#ifdef CUTTER_ENABLE_PYTHON
|
||||
|
||||
#include <QObject>
|
||||
# include <QObject>
|
||||
|
||||
typedef struct _ts PyThreadState;
|
||||
typedef struct _object PyObject;
|
||||
|
||||
class PythonManager: public QObject
|
||||
class PythonManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -37,8 +37,8 @@ public:
|
||||
class ThreadHolder
|
||||
{
|
||||
public:
|
||||
ThreadHolder() { getInstance()->restoreThread(); }
|
||||
~ThreadHolder() { getInstance()->saveThread(); }
|
||||
ThreadHolder() { getInstance()->restoreThread(); }
|
||||
~ThreadHolder() { getInstance()->saveThread(); }
|
||||
};
|
||||
|
||||
signals:
|
||||
@ -51,7 +51,7 @@ private:
|
||||
int pyThreadStateCounter = 0;
|
||||
};
|
||||
|
||||
#define Python() (PythonManager::getInstance())
|
||||
# define Python() (PythonManager::getInstance())
|
||||
|
||||
#endif // CUTTER_ENABLE_PYTHON
|
||||
|
||||
|
@ -23,9 +23,8 @@ PyObject *QtResGetCode(const char *name)
|
||||
QByteArray data = moduleFile.readAll();
|
||||
moduleFile.close();
|
||||
|
||||
PyObject *codeObject = Py_CompileString(data.constData(),
|
||||
moduleFile.fileName().toLocal8Bit().constData(),
|
||||
Py_file_input);
|
||||
PyObject *codeObject = Py_CompileString(
|
||||
data.constData(), moduleFile.fileName().toLocal8Bit().constData(), Py_file_input);
|
||||
if (!codeObject) {
|
||||
qWarning() << "Couldn't compile " << moduleFile.fileName();
|
||||
}
|
||||
@ -68,15 +67,12 @@ PyObject *qtres_get_code(PyObject *self, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyMethodDef QtResMethods[] = {
|
||||
{ "exists", qtres_exists, METH_VARARGS, NULL },
|
||||
{ "get_code", qtres_get_code, METH_VARARGS, NULL },
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
PyMethodDef QtResMethods[] = { { "exists", qtres_exists, METH_VARARGS, NULL },
|
||||
{ "get_code", qtres_get_code, METH_VARARGS, NULL },
|
||||
{ NULL, NULL, 0, NULL } };
|
||||
|
||||
PyModuleDef QtResModule = {
|
||||
PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods,
|
||||
NULL, NULL, NULL, NULL
|
||||
PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyObject *PyInit_qtres()
|
||||
|
@ -2,8 +2,8 @@
|
||||
#include "RefreshDeferrer.h"
|
||||
#include "widgets/CutterDockWidget.h"
|
||||
|
||||
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent) : QObject(parent),
|
||||
acc(acc)
|
||||
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent)
|
||||
: 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
|
||||
*/
|
||||
virtual void accumulate(RefreshDeferrerParams params) =0;
|
||||
virtual void accumulate(RefreshDeferrerParams params) = 0;
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
virtual void clear() =0;
|
||||
virtual void clear() = 0;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @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>
|
||||
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
||||
class ReplacingRefreshDeferrerAccumulator : public RefreshDeferrerAccumulator
|
||||
{
|
||||
private:
|
||||
T *value = nullptr;
|
||||
@ -58,16 +58,16 @@ private:
|
||||
|
||||
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)
|
||||
: replaceIfNull(replaceIfNull) {}
|
||||
|
||||
~ReplacingRefreshDeferrerAccumulator() override
|
||||
: replaceIfNull(replaceIfNull)
|
||||
{
|
||||
delete value;
|
||||
}
|
||||
|
||||
~ReplacingRefreshDeferrerAccumulator() override { delete value; }
|
||||
|
||||
protected:
|
||||
void accumulate(RefreshDeferrerParams params) override
|
||||
{
|
||||
@ -78,10 +78,7 @@ protected:
|
||||
value = static_cast<T *>(params);
|
||||
}
|
||||
|
||||
void ignoreParams(RefreshDeferrerParams params) override
|
||||
{
|
||||
delete static_cast<T *>(params);
|
||||
}
|
||||
void ignoreParams(RefreshDeferrerParams params) override { delete static_cast<T *>(params); }
|
||||
|
||||
void clear() override
|
||||
{
|
||||
@ -89,25 +86,22 @@ protected:
|
||||
value = nullptr;
|
||||
}
|
||||
|
||||
virtual RefreshDeferrerParamsResult result() override
|
||||
{
|
||||
return value;
|
||||
}
|
||||
virtual RefreshDeferrerParamsResult result() override { return value; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate incoming events while
|
||||
* refreshing is deferred.
|
||||
* This class can handle the logic necessary to defer the refreshing of widgets when they are not
|
||||
* visible. It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate
|
||||
* incoming events while refreshing is deferred.
|
||||
*
|
||||
* Example (don't write it like this in practice, use the convenience methods in CutterDockWidget):
|
||||
* ```
|
||||
* // in the constructor of a widget
|
||||
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false), this);
|
||||
* this->refreshDeferrer->registerFor(this);
|
||||
* connect(this->refreshDeferrer, &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
|
||||
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false),
|
||||
* this); this->refreshDeferrer->registerFor(this); connect(this->refreshDeferrer,
|
||||
* &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
|
||||
* // 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.
|
||||
* this->doRefresh(*param);
|
||||
@ -151,4 +145,4 @@ signals:
|
||||
void refreshNow(const RefreshDeferrerParamsResult paramsResult);
|
||||
};
|
||||
|
||||
#endif //REFRESHDEFERRER_H
|
||||
#endif // REFRESHDEFERRER_H
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
#ifdef APPIMAGE
|
||||
static QDir appimageRoot()
|
||||
{
|
||||
@ -37,7 +36,8 @@ static QStringList substitutePaths(const QStringList &paths)
|
||||
QStringList result;
|
||||
result.reserve(paths.size());
|
||||
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));
|
||||
}
|
||||
return result;
|
||||
@ -46,8 +46,8 @@ static QStringList substitutePaths(const QStringList &paths)
|
||||
QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
|
||||
QStandardPaths::LocateOptions options)
|
||||
{
|
||||
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs to be done
|
||||
// after substitutions
|
||||
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs
|
||||
// to be done after substitutions
|
||||
QStringList result;
|
||||
for (auto path : standardLocations(type)) {
|
||||
QString filePath = path + QLatin1Char('/') + fileName;
|
||||
@ -81,4 +81,3 @@ QStringList Cutter::getTranslationsDirectories()
|
||||
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,11 @@
|
||||
*/
|
||||
|
||||
namespace Cutter {
|
||||
QStringList locateAll(
|
||||
QStandardPaths::StandardLocation type,
|
||||
const QString &fileName,
|
||||
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
|
||||
QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
|
||||
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
|
||||
QStringList standardLocations(QStandardPaths::StandardLocation type);
|
||||
QString writableLocation(QStandardPaths::StandardLocation type);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get list of available translation directories (depends on configuration and OS)
|
||||
* @return list of directories
|
||||
|
@ -6,12 +6,11 @@
|
||||
#include <QTextBlock>
|
||||
#include <QTextFragment>
|
||||
|
||||
//TODO: fix performance (possibly use QTextLayout?)
|
||||
|
||||
// TODO: fix performance (possibly use QTextLayout?)
|
||||
|
||||
template<typename T>
|
||||
void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
|
||||
const List &richText, CachedFontMetrics<T> *fontMetrics)
|
||||
const List &richText, CachedFontMetrics<T> *fontMetrics)
|
||||
{
|
||||
QPen pen;
|
||||
QPen highlightPen;
|
||||
@ -21,24 +20,24 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
|
||||
T backgroundWidth = textWidth;
|
||||
if (backgroundWidth + xinc > w)
|
||||
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;
|
||||
switch (curRichText.flags) {
|
||||
case FlagNone: //defaults
|
||||
case FlagNone: // defaults
|
||||
pen.setColor(ConfigColor("btext").name());
|
||||
painter->setPen(pen);
|
||||
break;
|
||||
case FlagColor: //color only
|
||||
case FlagColor: // color only
|
||||
pen.setColor(curRichText.textColor);
|
||||
painter->setPen(pen);
|
||||
break;
|
||||
case FlagBackground: //background only
|
||||
case FlagBackground: // background only
|
||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||
brush.setColor(curRichText.textBackground);
|
||||
painter->fillRect(QRectF(x + xinc, y, backgroundWidth, h), brush);
|
||||
}
|
||||
break;
|
||||
case FlagAll: //color+background
|
||||
case FlagAll: // color+background
|
||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||
brush.setColor(curRichText.textBackground);
|
||||
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;
|
||||
#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()) {
|
||||
highlightPen.setColor(curRichText.highlightColor);
|
||||
highlightPen.setWidth(curRichText.highlightWidth);
|
||||
painter->setPen(highlightPen);
|
||||
T highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1;
|
||||
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1, x + xinc + backgroundWidth - 1,
|
||||
y + h - 1);
|
||||
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1,
|
||||
x + xinc + backgroundWidth - 1, y + h - 1);
|
||||
}
|
||||
xinc += textWidth;
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w, qreal h, qreal xinc,
|
||||
const List &richText, CachedFontMetrics<qreal> *fontMetrics);
|
||||
|
||||
template void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w,
|
||||
qreal h, qreal xinc, const List &richText,
|
||||
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 textHtml The HTML source. Any previous content will be preserved and new content will be appended at the end.
|
||||
* @param textPlain The plain text. 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
|
||||
* 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)
|
||||
{
|
||||
for (const CustomRichText_t &curRichText : richText) {
|
||||
if (curRichText.text == " ") { //blank
|
||||
if (curRichText.text == " ") { // blank
|
||||
textHtml += " ";
|
||||
textPlain += " ";
|
||||
continue;
|
||||
}
|
||||
switch (curRichText.flags) {
|
||||
case FlagNone: //defaults
|
||||
case FlagNone: // defaults
|
||||
textHtml += "<span>";
|
||||
break;
|
||||
case FlagColor: //color only
|
||||
case FlagColor: // color only
|
||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||
break;
|
||||
case FlagBackground: //background only
|
||||
if (curRichText.textBackground !=
|
||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"background-color:%1\">").arg(curRichText.textBackground.name());
|
||||
case FlagBackground: // background only
|
||||
if (curRichText.textBackground
|
||||
!= Qt::transparent) // QColor::name() returns "#000000" for transparent color.
|
||||
// That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"background-color:%1\">")
|
||||
.arg(curRichText.textBackground.name());
|
||||
else
|
||||
textHtml += QString("<span>");
|
||||
break;
|
||||
case FlagAll: //color+background
|
||||
if (curRichText.textBackground !=
|
||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"color:%1; background-color:%2\">").arg(
|
||||
curRichText.textColor.name(), curRichText.textBackground.name());
|
||||
case FlagAll: // color+background
|
||||
if (curRichText.textBackground
|
||||
!= Qt::transparent) // QColor::name() returns "#000000" for transparent color.
|
||||
// That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"color:%1; background-color:%2\">")
|
||||
.arg(curRichText.textColor.name(),
|
||||
curRichText.textBackground.name());
|
||||
else
|
||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||
break;
|
||||
}
|
||||
if (curRichText.highlight) //Underline highlighted token
|
||||
if (curRichText.highlight) // Underline highlighted token
|
||||
textHtml += "<u>";
|
||||
textHtml += curRichText.text.toHtmlEscaped();
|
||||
if (curRichText.highlight)
|
||||
textHtml += "</u>";
|
||||
textHtml += "</span>"; //Close the tag
|
||||
textHtml += "</span>"; // Close the tag
|
||||
textPlain += curRichText.text;
|
||||
}
|
||||
}
|
||||
@ -185,7 +191,8 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
|
||||
auto &text = r.back();
|
||||
|
||||
if (text.text.length() >= indicatorCropLength) {
|
||||
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength, indicator);
|
||||
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength,
|
||||
indicator);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10,21 +10,18 @@
|
||||
#include <vector>
|
||||
|
||||
class QFontMetricsF;
|
||||
template<typename T> class CachedFontMetrics;
|
||||
template<typename T>
|
||||
class CachedFontMetrics;
|
||||
class QPainter;
|
||||
|
||||
class RichTextPainter
|
||||
{
|
||||
public:
|
||||
//structures
|
||||
enum CustomRichTextFlags {
|
||||
FlagNone,
|
||||
FlagColor,
|
||||
FlagBackground,
|
||||
FlagAll
|
||||
};
|
||||
// structures
|
||||
enum CustomRichTextFlags { FlagNone, FlagColor, FlagBackground, FlagAll };
|
||||
|
||||
struct CustomRichText_t {
|
||||
struct CustomRichText_t
|
||||
{
|
||||
QString text;
|
||||
QColor textColor;
|
||||
QColor textBackground;
|
||||
@ -37,10 +34,10 @@ public:
|
||||
|
||||
typedef std::vector<CustomRichText_t> List;
|
||||
|
||||
//functions
|
||||
// functions
|
||||
template<typename T = qreal>
|
||||
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
|
||||
const List &richText, CachedFontMetrics<T> *fontMetrics);
|
||||
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText,
|
||||
CachedFontMetrics<T> *fontMetrics);
|
||||
static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
|
||||
|
||||
static List fromTextDocument(const QTextDocument &doc);
|
||||
|
@ -33,10 +33,9 @@ void RizinTask::taskFinished()
|
||||
|
||||
RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient)
|
||||
{
|
||||
task = rz_core_cmd_task_new(Core()->core(),
|
||||
cmd.toLocal8Bit().constData(),
|
||||
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback),
|
||||
this);
|
||||
task = rz_core_cmd_task_new(
|
||||
Core()->core(), cmd.toLocal8Bit().constData(),
|
||||
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback), this);
|
||||
task->transient = transient;
|
||||
rz_core_task_incref(task);
|
||||
}
|
||||
@ -74,9 +73,8 @@ const char *RizinCmdTask::getResultRaw()
|
||||
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
|
||||
: fcn(fcn), res(nullptr)
|
||||
{
|
||||
task = rz_core_function_task_new(Core()->core(),
|
||||
static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner),
|
||||
this);
|
||||
task = rz_core_function_task_new(
|
||||
Core()->core(), static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner), this);
|
||||
task->transient = transient;
|
||||
rz_core_task_incref(task);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "core/Cutter.h"
|
||||
|
||||
class CUTTER_EXPORT RizinTask: public QObject
|
||||
class CUTTER_EXPORT RizinTask : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -27,7 +27,7 @@ signals:
|
||||
void finished();
|
||||
};
|
||||
|
||||
class CUTTER_EXPORT RizinCmdTask: public RizinTask
|
||||
class CUTTER_EXPORT RizinCmdTask : public RizinTask
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -42,7 +42,7 @@ public:
|
||||
const char *getResultRaw();
|
||||
};
|
||||
|
||||
class CUTTER_EXPORT RizinFunctionTask: public RizinTask
|
||||
class CUTTER_EXPORT RizinFunctionTask : public RizinTask
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -2,14 +2,9 @@
|
||||
#include "common/RunScriptTask.h"
|
||||
#include "core/MainWindow.h"
|
||||
|
||||
RunScriptTask::RunScriptTask() :
|
||||
AsyncTask()
|
||||
{
|
||||
}
|
||||
RunScriptTask::RunScriptTask() : AsyncTask() {}
|
||||
|
||||
RunScriptTask::~RunScriptTask()
|
||||
{
|
||||
}
|
||||
RunScriptTask::~RunScriptTask() {}
|
||||
|
||||
void RunScriptTask::interrupt()
|
||||
{
|
||||
|
@ -12,13 +12,9 @@ public:
|
||||
explicit RunScriptTask();
|
||||
~RunScriptTask();
|
||||
|
||||
QString getTitle() override {
|
||||
return tr("Run Script");
|
||||
}
|
||||
QString getTitle() override { return tr("Run Script"); }
|
||||
|
||||
void setFileName(const QString &fileName) {
|
||||
this->fileName = fileName;
|
||||
}
|
||||
void setFileName(const QString &fileName) { this->fileName = fileName; }
|
||||
|
||||
void interrupt() override;
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include <QTextCursor>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word)
|
||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
|
||||
const QString &word)
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> selections;
|
||||
QTextEdit::ExtraSelection highlightSelection;
|
||||
@ -23,8 +24,8 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
|
||||
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||
|
||||
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
|
||||
highlightSelection.cursor = document->find(word, highlightSelection.cursor,
|
||||
QTextDocument::FindWholeWords);
|
||||
highlightSelection.cursor =
|
||||
document->find(word, highlightSelection.cursor, QTextDocument::FindWholeWords);
|
||||
|
||||
if (!highlightSelection.cursor.isNull()) {
|
||||
highlightSelection.format.setBackground(highlightWordColor);
|
||||
@ -35,7 +36,6 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
|
||||
return selections;
|
||||
}
|
||||
|
||||
|
||||
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor)
|
||||
{
|
||||
QTextEdit::ExtraSelection highlightSelection;
|
||||
@ -52,7 +52,6 @@ QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor
|
||||
return createLineHighlight(cursor, highlightColor);
|
||||
}
|
||||
|
||||
|
||||
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
|
||||
{
|
||||
QColor highlightColor = ConfigColor("highlightPC");
|
||||
|
@ -12,25 +12,27 @@ class QString;
|
||||
* @param word
|
||||
* @return
|
||||
*/
|
||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word);
|
||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
|
||||
const QString &word);
|
||||
|
||||
/**
|
||||
* @brief createLineHighlight
|
||||
* @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
|
||||
*/
|
||||
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);
|
||||
|
||||
/**
|
||||
* @brief This function responsible to highlight the currently selected line
|
||||
* @brief This function responsible to highlight the currently selected line
|
||||
* @param cursor - a Cursor object represents the line to be highlighted
|
||||
* @return ExtraSelection with highlighted line
|
||||
*/
|
||||
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor);
|
||||
|
||||
/**
|
||||
* @brief This function responsible to highlight the program counter line
|
||||
* @brief This function responsible to highlight the program counter line
|
||||
* @param cursor - a Cursor object represents the line to be highlighted
|
||||
* @return ExtraSelection with highlighted line
|
||||
*/
|
||||
@ -43,4 +45,4 @@ QTextEdit::ExtraSelection createLineHighlightPC(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)
|
||||
{
|
||||
if(newSettings.value("settings_migrated", false).toBool()) {
|
||||
if (newSettings.value("settings_migrated", false).toBool()) {
|
||||
return false;
|
||||
}
|
||||
QSettings oldSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, "Cutter", "Cutter");
|
||||
@ -29,7 +29,7 @@ static bool migrateSettingsPre18(QSettings &newSettings)
|
||||
}
|
||||
|
||||
#define CUTTER_SETTINGS_VERSION_CURRENT 6
|
||||
#define CUTTER_SETTINGS_VERSION_KEY "version"
|
||||
#define CUTTER_SETTINGS_VERSION_KEY "version"
|
||||
|
||||
/*
|
||||
* How Settings migrations work:
|
||||
@ -40,28 +40,30 @@ static bool migrateSettingsPre18(QSettings &newSettings)
|
||||
* 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("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
|
||||
// replace occurences of "PseudocodeWidget" with "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 defaultState = settings.value("state").toByteArray();
|
||||
|
||||
auto debugGeometry = settings.value("debug.geometry").toByteArray();
|
||||
auto debugState = settings.value("debug.state").toByteArray();
|
||||
|
||||
|
||||
const auto docks = settings.value("docks", 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();
|
||||
#else
|
||||
QSet<QString> unsyncDocks(unsyncList.begin(), unsyncList.end());
|
||||
@ -105,11 +107,11 @@ static void migrateSettingsTo3(QSettings &settings) {
|
||||
|
||||
static void renameAsmOption(QSettings &settings, const QString &oldName, const QString &newName)
|
||||
{
|
||||
if (settings.contains(oldName)) {
|
||||
auto value = settings.value(oldName);
|
||||
settings.remove(oldName);
|
||||
settings.setValue(newName, value);
|
||||
}
|
||||
if (settings.contains(oldName)) {
|
||||
auto value = settings.value(oldName);
|
||||
settings.remove(oldName);
|
||||
settings.setValue(newName, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void migrateSettingsTo4(QSettings &settings)
|
||||
@ -134,29 +136,35 @@ void Cutter::initializeSettings()
|
||||
QSettings settings;
|
||||
|
||||
int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt();
|
||||
if(settingsVersion == 0) {
|
||||
if (settingsVersion == 0) {
|
||||
migrateSettingsPre18(settings);
|
||||
}
|
||||
|
||||
if(settings.allKeys().length() > 0) {
|
||||
if (settings.allKeys().length() > 0) {
|
||||
if (settingsVersion > CUTTER_SETTINGS_VERSION_CURRENT) {
|
||||
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++) {
|
||||
qInfo() << "Migrating Settings to Version" << v;
|
||||
switch (v) {
|
||||
case 1:
|
||||
migrateSettingsTo1(settings); break;
|
||||
migrateSettingsTo1(settings);
|
||||
break;
|
||||
case 2:
|
||||
migrateSettingsTo2(settings); break;
|
||||
migrateSettingsTo2(settings);
|
||||
break;
|
||||
case 3:
|
||||
migrateSettingsTo3(settings); break;
|
||||
migrateSettingsTo3(settings);
|
||||
break;
|
||||
case 4:
|
||||
migrateSettingsTo4(settings); break;
|
||||
migrateSettingsTo4(settings);
|
||||
break;
|
||||
case 5:
|
||||
migrateSettingsTo5(settings); break;
|
||||
migrateSettingsTo5(settings);
|
||||
break;
|
||||
case 6:
|
||||
migrateSettingsTo6(settings); break;
|
||||
migrateSettingsTo6(settings);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -166,12 +174,13 @@ void Cutter::initializeSettings()
|
||||
settings.setValue(CUTTER_SETTINGS_VERSION_KEY, CUTTER_SETTINGS_VERSION_CURRENT);
|
||||
}
|
||||
|
||||
#define THEME_VERSION_CURRENT 1
|
||||
#define THEME_VERSION_KEY "theme_version"
|
||||
#define THEME_VERSION_CURRENT 1
|
||||
#define THEME_VERSION_KEY "theme_version"
|
||||
|
||||
static void removeObsoleteOptionsFromCustomThemes() {
|
||||
static void removeObsoleteOptionsFromCustomThemes()
|
||||
{
|
||||
const QStringList options = Core()->cmdj("ecj").object().keys()
|
||||
<< ColorThemeWorker::cutterSpecificOptions;
|
||||
<< ColorThemeWorker::cutterSpecificOptions;
|
||||
for (auto theme : Core()->cmdList("eco*")) {
|
||||
theme = theme.trimmed();
|
||||
if (!ThemeWorker().isCustomTheme(theme)) {
|
||||
@ -179,7 +188,7 @@ static void removeObsoleteOptionsFromCustomThemes() {
|
||||
}
|
||||
QJsonObject updatedTheme;
|
||||
auto sch = ThemeWorker().getTheme(theme).object();
|
||||
for (const auto& key : sch.keys()) {
|
||||
for (const auto &key : sch.keys()) {
|
||||
if (options.contains(key)) {
|
||||
updatedTheme.insert(key, sch[key]);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include <core/Cutter.h>
|
||||
|
||||
namespace Cutter {
|
||||
void initializeSettings();
|
||||
void migrateThemes();
|
||||
void initializeSettings();
|
||||
void migrateThemes();
|
||||
}
|
||||
|
||||
#endif // COMMON_SETTINGS_UPGRADE_H
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
class StringsTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QString getTitle() override { return tr("Searching for Strings"); }
|
||||
QString getTitle() override { return tr("Searching for Strings"); }
|
||||
|
||||
signals:
|
||||
void stringSearchFinished(const QList<StringDescription> &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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <QIconEngine>
|
||||
#include <QPalette>
|
||||
|
||||
class SvgIconEngine: public QIconEngine
|
||||
class SvgIconEngine : public QIconEngine
|
||||
{
|
||||
private:
|
||||
QByteArray svgData;
|
||||
@ -19,7 +19,6 @@ public:
|
||||
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
|
||||
QIconEngine *clone() const 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
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
@ -21,38 +23,56 @@ void SyntaxHighlighter::updateTheme()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
, commentStartExpression("/\\*")
|
||||
, commentEndExpression("\\*/")
|
||||
: QSyntaxHighlighter(parent), commentStartExpression("/\\*"), commentEndExpression("\\*/")
|
||||
{
|
||||
HighlightingRule rule;
|
||||
QStringList keywordPatterns;
|
||||
|
||||
//C language keywords
|
||||
keywordPatterns << "\\bauto\\b" << "\\bdouble\\b" << "\\bint\\b"
|
||||
<< "\\bstruct\\b" << "\\bbreak\\b" << "\\belse\\b"
|
||||
<< "\\blong\\b" << "\\switch\\b" << "\\bcase\\b"
|
||||
<< "\\benum\\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";
|
||||
// C language keywords
|
||||
keywordPatterns << "\\bauto\\b"
|
||||
<< "\\bdouble\\b"
|
||||
<< "\\bint\\b"
|
||||
<< "\\bstruct\\b"
|
||||
<< "\\bbreak\\b"
|
||||
<< "\\belse\\b"
|
||||
<< "\\blong\\b"
|
||||
<< "\\switch\\b"
|
||||
<< "\\bcase\\b"
|
||||
<< "\\benum\\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;
|
||||
keywordFormat.setForeground(QColor(80, 200, 215));
|
||||
|
||||
for ( const auto &pattern : keywordPatterns ) {
|
||||
for (const auto &pattern : keywordPatterns) {
|
||||
rule.pattern.setPattern(pattern);
|
||||
rule.format = keywordFormat;
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
//Functions
|
||||
// Functions
|
||||
rule.pattern.setPattern("\\b[A-Za-z0-9_]+(?=\\()");
|
||||
rule.format.clearBackground();
|
||||
rule.format.clearForeground();
|
||||
@ -60,14 +80,14 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
||||
rule.format.setForeground(Qt::darkCyan);
|
||||
highlightingRules.append(rule);
|
||||
|
||||
//single-line comment
|
||||
// single-line comment
|
||||
rule.pattern.setPattern("//[^\n]*");
|
||||
rule.format.clearBackground();
|
||||
rule.format.clearForeground();
|
||||
rule.format.setForeground(Qt::gray);
|
||||
highlightingRules.append(rule);
|
||||
|
||||
//quotation
|
||||
// quotation
|
||||
rule.pattern.setPattern("\".*\"");
|
||||
rule.format.clearBackground();
|
||||
rule.format.clearForeground();
|
||||
@ -79,7 +99,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
|
||||
|
||||
void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
for ( const auto &it : highlightingRules ) {
|
||||
for (const auto &it : highlightingRules) {
|
||||
auto matchIterator = it.pattern.globalMatch(text);
|
||||
while (matchIterator.hasNext()) {
|
||||
const auto match = matchIterator.next();
|
||||
@ -103,8 +123,7 @@ void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ match.capturedLength();
|
||||
commentLength = endIndex - startIndex + match.capturedLength();
|
||||
}
|
||||
|
||||
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
|
||||
#include <KSyntaxHighlighting/syntaxhighlighter.h>
|
||||
# include <KSyntaxHighlighting/syntaxhighlighter.h>
|
||||
|
||||
class SyntaxHighlighter : public KSyntaxHighlighting::SyntaxHighlighter
|
||||
{
|
||||
@ -40,7 +40,8 @@ protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
private:
|
||||
struct HighlightingRule {
|
||||
struct HighlightingRule
|
||||
{
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -10,10 +10,10 @@
|
||||
/**
|
||||
* @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
|
||||
* be configured using `e` configuration and doesn't accept arguments. TempConfig::set calls can be chained.
|
||||
* If a command or Rizin method accepts arguments directly it is preferred to use those instead of temporary modifying
|
||||
* global configuration.
|
||||
* Modified values will be restored at the end of scope. This is useful when using a Rizin command
|
||||
* that can only be configured using `e` configuration and doesn't accept arguments. TempConfig::set
|
||||
* calls can be chained. If a command or Rizin method accepts arguments directly it is preferred to
|
||||
* use those instead of temporary modifying global configuration.
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
@ -36,9 +36,9 @@ public:
|
||||
TempConfig &set(const QString &key, bool value);
|
||||
|
||||
private:
|
||||
TempConfig(const TempConfig&) = delete;
|
||||
TempConfig &operator=(const TempConfig&) = delete;
|
||||
TempConfig(const TempConfig &) = delete;
|
||||
TempConfig &operator=(const TempConfig &) = delete;
|
||||
QMap<QString, QVariant> resetValues;
|
||||
};
|
||||
|
||||
#endif //TEMPCONFIG_H
|
||||
#endif // TEMPCONFIG_H
|
||||
|
@ -1,37 +1,37 @@
|
||||
#include "UpdateWorker.h"
|
||||
|
||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
#include <QUrl>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QEventLoop>
|
||||
#include <QDataStream>
|
||||
#include <QJsonObject>
|
||||
#include <QApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QDesktopServices>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
# include <QUrl>
|
||||
# include <QFile>
|
||||
# include <QTimer>
|
||||
# include <QEventLoop>
|
||||
# include <QDataStream>
|
||||
# include <QJsonObject>
|
||||
# include <QApplication>
|
||||
# include <QJsonDocument>
|
||||
# include <QDesktopServices>
|
||||
# include <QtNetwork/QNetworkReply>
|
||||
# include <QtNetwork/QNetworkRequest>
|
||||
|
||||
#include <QProgressDialog>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include "common/Configuration.h"
|
||||
#include "CutterConfig.h"
|
||||
# include <QProgressDialog>
|
||||
# include <QPushButton>
|
||||
# include <QFileDialog>
|
||||
# include <QMessageBox>
|
||||
# include "common/Configuration.h"
|
||||
# include "CutterConfig.h"
|
||||
#endif
|
||||
|
||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
UpdateWorker::UpdateWorker(QObject *parent) :
|
||||
QObject(parent), pending(false)
|
||||
UpdateWorker::UpdateWorker(QObject *parent) : QObject(parent), pending(false)
|
||||
{
|
||||
connect(&t, &QTimer::timeout, this, [this]() {
|
||||
if (pending) {
|
||||
disconnect(checkReply, nullptr, this, nullptr);
|
||||
checkReply->close();
|
||||
checkReply->deleteLater();
|
||||
emit checkComplete(QVersionNumber(), tr("Time limit exceeded during version check. Please check your "
|
||||
"internet connection and try again."));
|
||||
emit checkComplete(QVersionNumber(),
|
||||
tr("Time limit exceeded during version check. Please check your "
|
||||
"internet connection and try again."));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -47,8 +47,7 @@ void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
|
||||
t.start();
|
||||
|
||||
checkReply = nm.get(request);
|
||||
connect(checkReply, &QNetworkReply::finished,
|
||||
this, &UpdateWorker::serveVersionCheckReply);
|
||||
connect(checkReply, &QNetworkReply::finished, this, &UpdateWorker::serveVersionCheckReply);
|
||||
pending = true;
|
||||
}
|
||||
|
||||
@ -60,26 +59,27 @@ void UpdateWorker::download(QString filename, QString version)
|
||||
QNetworkRequest request;
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
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);
|
||||
|
||||
downloadReply = nm.get(request);
|
||||
connect(downloadReply, &QNetworkReply::downloadProgress,
|
||||
this, &UpdateWorker::process);
|
||||
connect(downloadReply, &QNetworkReply::finished,
|
||||
this, &UpdateWorker::serveDownloadFinish);
|
||||
connect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
|
||||
connect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
|
||||
}
|
||||
|
||||
void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
||||
{
|
||||
QMessageBox mb;
|
||||
mb.setWindowTitle(tr("Version control"));
|
||||
mb.setText(tr("There is an update available for Cutter.<br/>")
|
||||
+ "<b>" + tr("Current version:") + "</b> " CUTTER_VERSION_FULL "<br/>"
|
||||
+ "<b>" + tr("Latest version:") + "</b> " + latestVersion.toString() + "<br/><br/>"
|
||||
mb.setText(tr("There is an update available for Cutter.<br/>") + "<b>" + tr("Current version:")
|
||||
+ "</b> " CUTTER_VERSION_FULL "<br/>" + "<b>" + tr("Latest version:") + "</b> "
|
||||
+ latestVersion.toString() + "<br/><br/>"
|
||||
+ tr("For update, please check the link:<br/>")
|
||||
+ 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."));
|
||||
if (showDontCheckForUpdatesButton) {
|
||||
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok);
|
||||
@ -93,31 +93,23 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
||||
if (ret == QMessageBox::Reset) {
|
||||
Config()->setAutoUpdateEnabled(false);
|
||||
} else if (ret == QMessageBox::Save) {
|
||||
QString fullFileName =
|
||||
QFileDialog::getSaveFileName(nullptr,
|
||||
tr("Choose directory for downloading"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
|
||||
QDir::separator() + getRepositoryFileName(),
|
||||
QString("%1 (*.%1)").arg(getRepositeryExt()));
|
||||
QString fullFileName = QFileDialog::getSaveFileName(
|
||||
nullptr, tr("Choose directory for downloading"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator()
|
||||
+ getRepositoryFileName(),
|
||||
QString("%1 (*.%1)").arg(getRepositeryExt()));
|
||||
if (!fullFileName.isEmpty()) {
|
||||
QProgressDialog progressDial(tr("Downloading update..."),
|
||||
tr("Cancel"),
|
||||
0, 100);
|
||||
QProgressDialog progressDial(tr("Downloading update..."), tr("Cancel"), 0, 100);
|
||||
connect(this, &UpdateWorker::downloadProcess, &progressDial,
|
||||
[&progressDial](size_t curr, size_t total) {
|
||||
progressDial.setValue(100.0f * curr / total);
|
||||
});
|
||||
connect(&progressDial, &QProgressDialog::canceled,
|
||||
this, &UpdateWorker::abortDownload);
|
||||
connect(this, &UpdateWorker::downloadFinished,
|
||||
&progressDial, &QProgressDialog::cancel);
|
||||
connect(this, &UpdateWorker::downloadFinished, this,
|
||||
[](QString filePath){
|
||||
QMessageBox info(QMessageBox::Information,
|
||||
tr("Download finished!"),
|
||||
progressDial.setValue(100.0f * curr / total);
|
||||
});
|
||||
connect(&progressDial, &QProgressDialog::canceled, this, &UpdateWorker::abortDownload);
|
||||
connect(this, &UpdateWorker::downloadFinished, &progressDial, &QProgressDialog::cancel);
|
||||
connect(this, &UpdateWorker::downloadFinished, this, [](QString filePath) {
|
||||
QMessageBox info(QMessageBox::Information, tr("Download finished!"),
|
||||
tr("Latest version of Cutter was succesfully downloaded!"),
|
||||
QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok,
|
||||
nullptr);
|
||||
QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok, nullptr);
|
||||
info.button(QMessageBox::Open)->setText(tr("Open file"));
|
||||
info.button(QMessageBox::Yes)->setText(tr("Open download folder"));
|
||||
int r = info.exec();
|
||||
@ -140,10 +132,8 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
|
||||
|
||||
void UpdateWorker::abortDownload()
|
||||
{
|
||||
disconnect(downloadReply, &QNetworkReply::finished,
|
||||
this, &UpdateWorker::serveDownloadFinish);
|
||||
disconnect(downloadReply, &QNetworkReply::downloadProgress,
|
||||
this, &UpdateWorker::process);
|
||||
disconnect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
|
||||
disconnect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
|
||||
downloadReply->close();
|
||||
downloadReply->deleteLater();
|
||||
downloadFile.remove();
|
||||
@ -157,7 +147,10 @@ void UpdateWorker::serveVersionCheckReply()
|
||||
if (checkReply->error()) {
|
||||
errStr = checkReply->errorString();
|
||||
} else {
|
||||
versionReplyStr = QJsonDocument::fromJson(checkReply->readAll()).object().value("tag_name").toString();
|
||||
versionReplyStr = QJsonDocument::fromJson(checkReply->readAll())
|
||||
.object()
|
||||
.value("tag_name")
|
||||
.toString();
|
||||
versionReplyStr.remove('v');
|
||||
}
|
||||
QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
|
||||
@ -188,30 +181,28 @@ void UpdateWorker::process(size_t bytesReceived, size_t bytesTotal)
|
||||
|
||||
QString UpdateWorker::getRepositeryExt() const
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
# ifdef Q_OS_LINUX
|
||||
return "AppImage";
|
||||
#elif defined (Q_OS_WIN64) || defined (Q_OS_WIN32)
|
||||
# elif defined(Q_OS_WIN64) || defined(Q_OS_WIN32)
|
||||
return "zip";
|
||||
#elif defined (Q_OS_MACOS)
|
||||
# elif defined(Q_OS_MACOS)
|
||||
return "dmg";
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
QString UpdateWorker::getRepositoryFileName() const
|
||||
{
|
||||
QString downloadFileName;
|
||||
#ifdef Q_OS_LINUX
|
||||
# ifdef Q_OS_LINUX
|
||||
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";
|
||||
#elif defined (Q_OS_MACOS)
|
||||
# elif defined(Q_OS_MACOS)
|
||||
downloadFileName = "Cutter-v%1-x%2.macOS.dmg";
|
||||
#endif
|
||||
downloadFileName = downloadFileName
|
||||
.arg(latestVersion.toString())
|
||||
.arg(QSysInfo::buildAbi().split('-').at(2).contains("64")
|
||||
? "64"
|
||||
: "32");
|
||||
# endif
|
||||
downloadFileName =
|
||||
downloadFileName.arg(latestVersion.toString())
|
||||
.arg(QSysInfo::buildAbi().split('-').at(2).contains("64") ? "64" : "32");
|
||||
|
||||
return downloadFileName;
|
||||
}
|
||||
|
@ -4,18 +4,18 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
#define CUTTER_UPDATE_WORKER_AVAILABLE 1
|
||||
# define CUTTER_UPDATE_WORKER_AVAILABLE 1
|
||||
#else
|
||||
#define CUTTER_UPDATE_WORKER_AVAILABLE 0
|
||||
# define CUTTER_UPDATE_WORKER_AVAILABLE 0
|
||||
#endif
|
||||
|
||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
# include <QDir>
|
||||
# include <QTimer>
|
||||
# include <QObject>
|
||||
# include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
#include <QVersionNumber>
|
||||
# include <QVersionNumber>
|
||||
#endif
|
||||
|
||||
#if CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
@ -68,7 +68,8 @@ public:
|
||||
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();
|
||||
|
||||
@ -102,7 +103,6 @@ signals:
|
||||
*/
|
||||
void downloadProcess(size_t bytesReceived, size_t bytesTotal);
|
||||
|
||||
|
||||
/**
|
||||
* @fn UpdateWorker::downloadFinished(QString filename)
|
||||
*
|
||||
@ -138,5 +138,5 @@ private:
|
||||
QNetworkReply *checkReply;
|
||||
};
|
||||
|
||||
#endif //CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
#endif // CUTTER_UPDATE_WORKER_AVAILABLE
|
||||
#endif // UPDATEWORKER_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@ class RizinTaskDialog;
|
||||
|
||||
class RzCoreLocked;
|
||||
|
||||
class CUTTER_EXPORT CutterCore: public QObject
|
||||
class CUTTER_EXPORT CutterCore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -52,7 +52,7 @@ public:
|
||||
|
||||
AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; }
|
||||
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
|
||||
/* Core functions (commands) */
|
||||
static QString sanitizeStringForCommand(QString s);
|
||||
@ -75,12 +75,17 @@ public:
|
||||
* If you want to seek to an address, you should use CutterCore::seek.
|
||||
*/
|
||||
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
|
||||
* is executing raw commands, and thus ignores multiple commands and overcome 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.
|
||||
* is executing raw commands, and thus ignores multiple commands and overcome 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
|
||||
*/
|
||||
QString cmdRaw(const char *cmd);
|
||||
@ -91,12 +96,12 @@ public:
|
||||
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
|
||||
* without triggering the seekChanged event nor adding new entries to the seek history. By nature, the
|
||||
* API is executing a single command without going through Rizin shell, 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
|
||||
* only the first command will be executed.
|
||||
* @brief Execute a Rizin command \a cmd at \a address. The function will preform a silent seek
|
||||
* to the address without triggering the seekChanged event nor adding new entries to the seek
|
||||
* history. By nature, the API is executing a single command without going through Rizin shell,
|
||||
* 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 only the first command will be executed.
|
||||
* @param address - an address to which Cutter will temporarily seek.
|
||||
* @return the output of the command
|
||||
*/
|
||||
@ -105,12 +110,18 @@ public:
|
||||
/**
|
||||
* @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 QString &str) { return cmdj(str.toUtf8().constData()); }
|
||||
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()); }
|
||||
QString cmdTask(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.
|
||||
*/
|
||||
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();
|
||||
|
||||
QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
|
||||
@ -253,7 +267,8 @@ public:
|
||||
void renameClass(const QString &oldName, const QString &newName);
|
||||
void deleteClass(const QString &cls);
|
||||
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);
|
||||
|
||||
/* File related methods */
|
||||
@ -445,7 +460,8 @@ public:
|
||||
* Register a new decompiler
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@ -536,7 +552,6 @@ public:
|
||||
*/
|
||||
QString getTypeAsC(QString name, QString category);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds new types
|
||||
* 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'
|
||||
* in the function in which the specified offset is a part of.
|
||||
* @param variableName Name of the local variable.
|
||||
* @param findWrites If this is true, then locations at which modification happen to the specified
|
||||
* local variable is fetched. Else, the locations at which the local is variable is read is fetched.
|
||||
* @param findWrites If this is true, then locations at which modification happen to the
|
||||
* 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.
|
||||
* @return A list of XrefDescriptions that contains details of all the writes or reads that happen to the
|
||||
* variable 'variableName'.
|
||||
* @return A list of XrefDescriptions that contains details of all the writes or reads that
|
||||
* happen to the variable 'variableName'.
|
||||
*/
|
||||
QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset);
|
||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
|
||||
@ -622,9 +638,9 @@ public:
|
||||
void commitWriteCache();
|
||||
|
||||
/**
|
||||
* @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it will be immediately
|
||||
* committed to the file on disk, thus modify the file. This function wrap Rizin function which re-open the file with
|
||||
* the desired permissions.
|
||||
* @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it
|
||||
* will be immediately committed to the file on disk, thus modify the file. This function wrap
|
||||
* Rizin function which re-open the file with the desired permissions.
|
||||
* @param enabled
|
||||
*/
|
||||
void setWriteMode(bool enabled);
|
||||
@ -732,7 +748,7 @@ private:
|
||||
|
||||
class CUTTER_EXPORT RzCoreLocked
|
||||
{
|
||||
CutterCore * const core;
|
||||
CutterCore *const core;
|
||||
|
||||
public:
|
||||
explicit RzCoreLocked(CutterCore *core);
|
||||
|
@ -10,17 +10,20 @@
|
||||
|
||||
// Workaround for compile errors on Windows
|
||||
#ifdef Q_OS_WIN
|
||||
#undef min
|
||||
#undef max
|
||||
# undef min
|
||||
# undef max
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
// Rizin list iteration macros
|
||||
#define CutterRListForeach(list, it, type, x) \
|
||||
if (list) for (it = list->head; it && ((x=static_cast<type*>(it->data))); it = it->n)
|
||||
#define CutterRListForeach(list, it, type, x) \
|
||||
if (list) \
|
||||
for (it = list->head; it && ((x = static_cast<type *>(it->data))); it = it->n)
|
||||
|
||||
#define CutterRVectorForeach(vec, it, type) \
|
||||
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))
|
||||
#define CutterRVectorForeach(vec, it, type) \
|
||||
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))
|
||||
|
||||
// Global information for Cutter
|
||||
#define APPNAME "Cutter"
|
||||
@ -31,7 +34,8 @@
|
||||
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
|
||||
|
||||
@ -56,20 +60,18 @@ inline QString RHexString(RVA size)
|
||||
}
|
||||
|
||||
#ifdef CUTTER_SOURCE_BUILD
|
||||
#define CUTTER_EXPORT Q_DECL_EXPORT
|
||||
# define CUTTER_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define CUTTER_EXPORT Q_DECL_IMPORT
|
||||
# define CUTTER_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__has_cpp_attribute)
|
||||
#if __has_cpp_attribute(deprecated)
|
||||
#define CUTTER_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#endif
|
||||
# if __has_cpp_attribute(deprecated)
|
||||
# define CUTTER_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(CUTTER_DEPRECATED)
|
||||
#define CUTTER_DEPRECATED(msg)
|
||||
# define CUTTER_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
#endif // CUTTERCORE_H
|
||||
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include <QColor>
|
||||
#include "core/CutterCommon.h"
|
||||
|
||||
struct FunctionDescription {
|
||||
struct FunctionDescription
|
||||
{
|
||||
RVA offset;
|
||||
RVA linearSize;
|
||||
RVA nargs;
|
||||
@ -31,7 +32,8 @@ struct FunctionDescription {
|
||||
}
|
||||
};
|
||||
|
||||
struct ImportDescription {
|
||||
struct ImportDescription
|
||||
{
|
||||
RVA plt;
|
||||
int ordinal;
|
||||
QString bind;
|
||||
@ -40,7 +42,8 @@ struct ImportDescription {
|
||||
QString libname;
|
||||
};
|
||||
|
||||
struct ExportDescription {
|
||||
struct ExportDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA size;
|
||||
@ -69,40 +72,46 @@ struct ZignatureDescription
|
||||
QStringList refs;
|
||||
};
|
||||
|
||||
struct TypeDescription {
|
||||
struct TypeDescription
|
||||
{
|
||||
QString type;
|
||||
int size;
|
||||
QString format;
|
||||
QString category;
|
||||
};
|
||||
|
||||
struct SearchDescription {
|
||||
struct SearchDescription
|
||||
{
|
||||
RVA offset;
|
||||
int size;
|
||||
QString code;
|
||||
QString data;
|
||||
};
|
||||
|
||||
struct SymbolDescription {
|
||||
struct SymbolDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
QString bind;
|
||||
QString type;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct CommentDescription {
|
||||
struct CommentDescription
|
||||
{
|
||||
RVA offset;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct RelocDescription {
|
||||
struct RelocDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
QString type;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct StringDescription {
|
||||
struct StringDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
QString string;
|
||||
QString type;
|
||||
@ -111,18 +120,21 @@ struct StringDescription {
|
||||
ut32 size;
|
||||
};
|
||||
|
||||
struct FlagspaceDescription {
|
||||
struct FlagspaceDescription
|
||||
{
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct FlagDescription {
|
||||
struct FlagDescription
|
||||
{
|
||||
RVA offset;
|
||||
RVA size;
|
||||
QString name;
|
||||
QString realname;
|
||||
};
|
||||
|
||||
struct SectionDescription {
|
||||
struct SectionDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA size;
|
||||
@ -132,7 +144,8 @@ struct SectionDescription {
|
||||
QString entropy;
|
||||
};
|
||||
|
||||
struct SegmentDescription {
|
||||
struct SegmentDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA size;
|
||||
@ -141,7 +154,8 @@ struct SegmentDescription {
|
||||
QString perm;
|
||||
};
|
||||
|
||||
struct EntrypointDescription {
|
||||
struct EntrypointDescription
|
||||
{
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA baddr;
|
||||
@ -150,7 +164,8 @@ struct EntrypointDescription {
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct XrefDescription {
|
||||
struct XrefDescription
|
||||
{
|
||||
RVA from;
|
||||
QString from_str;
|
||||
RVA to;
|
||||
@ -158,14 +173,16 @@ struct XrefDescription {
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct RzBinPluginDescription {
|
||||
struct RzBinPluginDescription
|
||||
{
|
||||
QString name;
|
||||
QString description;
|
||||
QString license;
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct RzIOPluginDescription {
|
||||
struct RzIOPluginDescription
|
||||
{
|
||||
QString name;
|
||||
QString description;
|
||||
QString license;
|
||||
@ -173,12 +190,14 @@ struct RzIOPluginDescription {
|
||||
QList<QString> uris;
|
||||
};
|
||||
|
||||
struct RzCorePluginDescription {
|
||||
struct RzCorePluginDescription
|
||||
{
|
||||
QString name;
|
||||
QString description;
|
||||
};
|
||||
|
||||
struct RzAsmPluginDescription {
|
||||
struct RzAsmPluginDescription
|
||||
{
|
||||
QString name;
|
||||
QString architecture;
|
||||
QString author;
|
||||
@ -188,29 +207,34 @@ struct RzAsmPluginDescription {
|
||||
QString license;
|
||||
};
|
||||
|
||||
struct DisassemblyLine {
|
||||
struct DisassemblyLine
|
||||
{
|
||||
RVA offset;
|
||||
QString text;
|
||||
RVA arrow;
|
||||
};
|
||||
|
||||
struct BinClassBaseClassDescription {
|
||||
struct BinClassBaseClassDescription
|
||||
{
|
||||
QString name;
|
||||
RVA offset;
|
||||
};
|
||||
|
||||
struct BinClassMethodDescription {
|
||||
struct BinClassMethodDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr = RVA_INVALID;
|
||||
st64 vtableOffset = -1;
|
||||
};
|
||||
|
||||
struct BinClassFieldDescription {
|
||||
struct BinClassFieldDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr = RVA_INVALID;
|
||||
};
|
||||
|
||||
struct BinClassDescription {
|
||||
struct BinClassDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr = RVA_INVALID;
|
||||
RVA vtableAddr = RVA_INVALID;
|
||||
@ -220,25 +244,29 @@ struct BinClassDescription {
|
||||
QList<BinClassFieldDescription> fields;
|
||||
};
|
||||
|
||||
struct AnalMethodDescription {
|
||||
struct AnalMethodDescription
|
||||
{
|
||||
QString name;
|
||||
RVA addr;
|
||||
st64 vtableOffset;
|
||||
};
|
||||
|
||||
struct AnalBaseClassDescription {
|
||||
struct AnalBaseClassDescription
|
||||
{
|
||||
QString id;
|
||||
RVA offset;
|
||||
QString className;
|
||||
};
|
||||
|
||||
struct AnalVTableDescription {
|
||||
struct AnalVTableDescription
|
||||
{
|
||||
QString id;
|
||||
ut64 offset;
|
||||
ut64 addr;
|
||||
};
|
||||
|
||||
struct ResourcesDescription {
|
||||
struct ResourcesDescription
|
||||
{
|
||||
QString name;
|
||||
RVA vaddr;
|
||||
ut64 index;
|
||||
@ -247,12 +275,14 @@ struct ResourcesDescription {
|
||||
QString lang;
|
||||
};
|
||||
|
||||
struct VTableDescription {
|
||||
struct VTableDescription
|
||||
{
|
||||
RVA addr;
|
||||
QList<BinClassMethodDescription> methods;
|
||||
};
|
||||
|
||||
struct BlockDescription {
|
||||
struct BlockDescription
|
||||
{
|
||||
RVA addr;
|
||||
RVA size;
|
||||
int flags;
|
||||
@ -264,14 +294,16 @@ struct BlockDescription {
|
||||
ut8 rwx;
|
||||
};
|
||||
|
||||
struct BlockStatistics {
|
||||
struct BlockStatistics
|
||||
{
|
||||
RVA from;
|
||||
RVA to;
|
||||
RVA blocksize;
|
||||
QList<BlockDescription> blocks;
|
||||
};
|
||||
|
||||
struct MemoryMapDescription {
|
||||
struct MemoryMapDescription
|
||||
{
|
||||
RVA addrStart;
|
||||
RVA addrEnd;
|
||||
QString name;
|
||||
@ -280,7 +312,8 @@ struct MemoryMapDescription {
|
||||
QString permission;
|
||||
};
|
||||
|
||||
struct BreakpointDescription {
|
||||
struct BreakpointDescription
|
||||
{
|
||||
enum PositionType {
|
||||
Address,
|
||||
Named,
|
||||
@ -302,26 +335,30 @@ struct BreakpointDescription {
|
||||
bool enabled = true;
|
||||
};
|
||||
|
||||
struct ProcessDescription {
|
||||
struct ProcessDescription
|
||||
{
|
||||
int pid;
|
||||
int uid;
|
||||
QString status;
|
||||
QString path;
|
||||
};
|
||||
|
||||
struct RefDescription {
|
||||
struct RefDescription
|
||||
{
|
||||
QString ref;
|
||||
QColor refColor;
|
||||
};
|
||||
|
||||
struct VariableDescription {
|
||||
struct VariableDescription
|
||||
{
|
||||
enum class RefType { SP, BP, Reg };
|
||||
RefType refType;
|
||||
QString name;
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct RegisterRefValueDescription {
|
||||
struct RegisterRefValueDescription
|
||||
{
|
||||
QString name;
|
||||
QString value;
|
||||
QString ref;
|
||||
|
@ -117,14 +117,14 @@
|
||||
#define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)")
|
||||
|
||||
template<class T>
|
||||
T *getNewInstance(MainWindow *m) { return new T(m); }
|
||||
T *getNewInstance(MainWindow *m)
|
||||
{
|
||||
return new T(m);
|
||||
}
|
||||
|
||||
using namespace Cutter;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
core(Core()),
|
||||
ui(new Ui::MainWindow)
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow)
|
||||
{
|
||||
tabsOnTop = false;
|
||||
configuration = Config();
|
||||
@ -132,9 +132,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
initUI();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
MainWindow::~MainWindow() {}
|
||||
|
||||
void MainWindow::initUI()
|
||||
{
|
||||
@ -146,18 +144,19 @@ void MainWindow::initUI()
|
||||
|
||||
connect(ui->actionExtraDecompiler, &QAction::triggered, this, &MainWindow::addExtraDecompiler);
|
||||
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->actionCommitChanges, &QAction::triggered, this, [this]() {
|
||||
Core()->commitWriteCache();
|
||||
});
|
||||
connect(ui->actionCommitChanges, &QAction::triggered, this,
|
||||
[this]() { Core()->commitWriteCache(); });
|
||||
ui->actionCommitChanges->setEnabled(false);
|
||||
connect(Core(), &CutterCore::ioCacheChanged, ui->actionCommitChanges, &QAction::setEnabled);
|
||||
|
||||
widgetTypeToConstructorMap.insert(GraphWidget::getWidgetType(), getNewInstance<GraphWidget>);
|
||||
widgetTypeToConstructorMap.insert(DisassemblyWidget::getWidgetType(),
|
||||
getNewInstance<DisassemblyWidget>);
|
||||
widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(), getNewInstance<HexdumpWidget>);
|
||||
widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(),
|
||||
getNewInstance<HexdumpWidget>);
|
||||
widgetTypeToConstructorMap.insert(DecompilerWidget::getWidgetType(),
|
||||
getNewInstance<DecompilerWidget>);
|
||||
|
||||
@ -175,13 +174,17 @@ void MainWindow::initUI()
|
||||
|
||||
// G and S goes to goto entry
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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::newMessage,
|
||||
this->consoleDock, &ConsoleWidget::addOutput);
|
||||
connect(core, &CutterCore::newDebugMessage,
|
||||
this->consoleDock, &ConsoleWidget::addDebugOutput);
|
||||
connect(core, &CutterCore::newMessage, this->consoleDock, &ConsoleWidget::addOutput);
|
||||
connect(core, &CutterCore::newDebugMessage, this->consoleDock, &ConsoleWidget::addDebugOutput);
|
||||
|
||||
connect(core, &CutterCore::showMemoryWidgetRequested,
|
||||
this, static_cast<void(MainWindow::*)()>(&MainWindow::showMemoryWidget));
|
||||
connect(core, &CutterCore::showMemoryWidgetRequested, this,
|
||||
static_cast<void (MainWindow::*)()>(&MainWindow::showMemoryWidget));
|
||||
|
||||
updateTasksIndicator();
|
||||
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
|
||||
@ -247,7 +248,8 @@ void MainWindow::initUI()
|
||||
ui->menuWindows->setToolTipsVisible(true);
|
||||
if (plugins.empty()) {
|
||||
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);
|
||||
} else if (ui->menuPlugins->isEmpty()) {
|
||||
ui->menuPlugins->menuAction()->setToolTip(
|
||||
@ -255,7 +257,7 @@ void MainWindow::initUI()
|
||||
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)
|
||||
ui->actionGrouped_dock_dragging->setVisible(false);
|
||||
@ -342,10 +344,10 @@ void MainWindow::initToolBar()
|
||||
this->visualNavbar->setMovable(false);
|
||||
addToolBarBreak(Qt::TopToolBarArea);
|
||||
addToolBar(visualNavbar);
|
||||
QObject::connect(configuration, &Configuration::colorsUpdated, this, [this]() {
|
||||
this->visualNavbar->updateGraphicsScene();
|
||||
});
|
||||
QObject::connect(configuration, &Configuration::interfaceThemeChanged, this, &MainWindow::chooseThemeIcons);
|
||||
QObject::connect(configuration, &Configuration::colorsUpdated, this,
|
||||
[this]() { this->visualNavbar->updateGraphicsScene(); });
|
||||
QObject::connect(configuration, &Configuration::interfaceThemeChanged, this,
|
||||
&MainWindow::chooseThemeIcons);
|
||||
}
|
||||
|
||||
void MainWindow::initDocks()
|
||||
@ -356,9 +358,8 @@ void MainWindow::initDocks()
|
||||
overviewDock = new OverviewWidget(this);
|
||||
overviewDock->hide();
|
||||
actionOverview = overviewDock->toggleViewAction();
|
||||
connect(overviewDock, &OverviewWidget::isAvailableChanged, this, [this](bool isAvailable) {
|
||||
actionOverview->setEnabled(isAvailable);
|
||||
});
|
||||
connect(overviewDock, &OverviewWidget::isAvailableChanged, this,
|
||||
[this](bool isAvailable) { actionOverview->setEnabled(isAvailable); });
|
||||
actionOverview->setEnabled(overviewDock->getIsAvailable());
|
||||
actionOverview->setChecked(overviewDock->getUserOpened());
|
||||
|
||||
@ -370,14 +371,10 @@ void MainWindow::initDocks()
|
||||
stringsDock = new StringsWidget(this);
|
||||
|
||||
QList<CutterDockWidget *> debugDocks = {
|
||||
stackDock = new StackWidget(this),
|
||||
threadsDock = new ThreadsWidget(this),
|
||||
processesDock = new ProcessesWidget(this),
|
||||
backtraceDock = new BacktraceWidget(this),
|
||||
registersDock = new RegistersWidget(this),
|
||||
memoryMapDock = new MemoryMapWidget(this),
|
||||
breakpointDock = new BreakpointWidget(this),
|
||||
registerRefsDock = new RegisterRefsWidget(this)
|
||||
stackDock = new StackWidget(this), threadsDock = new ThreadsWidget(this),
|
||||
processesDock = new ProcessesWidget(this), backtraceDock = new BacktraceWidget(this),
|
||||
registersDock = new RegistersWidget(this), memoryMapDock = new MemoryMapWidget(this),
|
||||
breakpointDock = new BreakpointWidget(this), registerRefsDock = new RegisterRefsWidget(this)
|
||||
};
|
||||
|
||||
QList<CutterDockWidget *> infoDocks = {
|
||||
@ -415,15 +412,8 @@ void MainWindow::initDocks()
|
||||
};
|
||||
|
||||
QList<CutterDockWidget *> windowDocks = {
|
||||
dashboardDock,
|
||||
nullptr,
|
||||
functionsDock,
|
||||
overviewDock,
|
||||
nullptr,
|
||||
searchDock,
|
||||
stringsDock,
|
||||
typesDock,
|
||||
nullptr,
|
||||
dashboardDock, nullptr, functionsDock, overviewDock, nullptr,
|
||||
searchDock, stringsDock, typesDock, nullptr,
|
||||
};
|
||||
ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks));
|
||||
QList<CutterDockWidget *> windowDocks2 = {
|
||||
@ -556,8 +546,8 @@ void MainWindow::openNewFileFailed()
|
||||
mb.setIcon(QMessageBox::Critical);
|
||||
mb.setStandardButtons(QMessageBox::Ok);
|
||||
mb.setWindowTitle(tr("Cannot open file!"));
|
||||
mb.setText(
|
||||
tr("Could not open the file! Make sure the file exists and that you have the correct permissions."));
|
||||
mb.setText(tr("Could not open the file! Make sure the file exists and that you have the "
|
||||
"correct permissions."));
|
||||
mb.exec();
|
||||
}
|
||||
|
||||
@ -615,9 +605,7 @@ bool MainWindow::openProject(const QString &file)
|
||||
const char *s = rz_project_err_message(err);
|
||||
QString msg = tr("Failed to open project: %1").arg(QString::fromUtf8(s));
|
||||
RzListIter *it;
|
||||
CutterRListForeach(res, it, const char, s) {
|
||||
msg += "\n" + QString::fromUtf8(s);
|
||||
}
|
||||
CutterRListForeach(res, it, const char, s) { msg += "\n" + QString::fromUtf8(s); }
|
||||
QMessageBox::critical(this, tr("Open Project"), msg);
|
||||
rz_list_free(res);
|
||||
return false;
|
||||
@ -656,7 +644,6 @@ void MainWindow::finalizeOpen()
|
||||
Config()->adjustColorThemeDarkness();
|
||||
setViewLayout(getViewLayout(LAYOUT_DEFAULT));
|
||||
|
||||
|
||||
// Set focus to disasm or graph widget
|
||||
// Graph with function in it has focus priority over DisasmWidget.
|
||||
// If there are no graph/disasm widgets focus on MainWindow
|
||||
@ -730,7 +717,8 @@ void MainWindow::showProjectSaveError(RzProjectErr err)
|
||||
return;
|
||||
}
|
||||
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)
|
||||
@ -742,7 +730,7 @@ void MainWindow::setFilename(const QString &fn)
|
||||
{
|
||||
// Add file name to window title
|
||||
this->filename = fn;
|
||||
this->setWindowTitle(APPNAME" – " + fn);
|
||||
this->setWindowTitle(APPNAME " – " + fn);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
@ -757,9 +745,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
|
||||
activateWindow();
|
||||
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(this, APPNAME,
|
||||
tr("Do you really want to exit?\nSave your project before closing!"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(
|
||||
this, APPNAME, tr("Do you really want to exit?\nSave your project before closing!"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
|
||||
| QMessageBox::Cancel));
|
||||
if (ret == QMessageBox::Cancel) {
|
||||
event->ignore();
|
||||
return;
|
||||
@ -855,12 +844,10 @@ void MainWindow::lockDocks(bool lock)
|
||||
}
|
||||
} else {
|
||||
for (QDockWidget *dockWidget : findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::DockWidgetClosable |
|
||||
QDockWidget::DockWidgetMovable |
|
||||
QDockWidget::DockWidgetFloatable);
|
||||
dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::restoreDocks()
|
||||
@ -924,22 +911,15 @@ void MainWindow::restoreDocks()
|
||||
|
||||
bool MainWindow::isDebugWidget(QDockWidget *dock) const
|
||||
{
|
||||
return dock == stackDock ||
|
||||
dock == registersDock ||
|
||||
dock == backtraceDock ||
|
||||
dock == threadsDock ||
|
||||
dock == memoryMapDock ||
|
||||
dock == breakpointDock ||
|
||||
dock == processesDock ||
|
||||
dock == registerRefsDock;
|
||||
return dock == stackDock || dock == registersDock || dock == backtraceDock
|
||||
|| dock == threadsDock || dock == memoryMapDock || dock == breakpointDock
|
||||
|| dock == processesDock || dock == registerRefsDock;
|
||||
}
|
||||
|
||||
bool MainWindow::isExtraMemoryWidget(QDockWidget *dock) const
|
||||
{
|
||||
return qobject_cast<GraphWidget*>(dock) ||
|
||||
qobject_cast<HexdumpWidget*>(dock) ||
|
||||
qobject_cast<DisassemblyWidget*>(dock) ||
|
||||
qobject_cast<DecompilerWidget*>(dock);
|
||||
return qobject_cast<GraphWidget *>(dock) || qobject_cast<HexdumpWidget *>(dock)
|
||||
|| qobject_cast<DisassemblyWidget *>(dock) || qobject_cast<DecompilerWidget *>(dock);
|
||||
}
|
||||
|
||||
MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore()
|
||||
@ -971,7 +951,7 @@ QString MainWindow::getUniqueObjectName(const QString &widgetType) const
|
||||
id++;
|
||||
}
|
||||
|
||||
return widgetType + ";" + QString::number(id);
|
||||
return widgetType + ";" + QString::number(id);
|
||||
}
|
||||
|
||||
void MainWindow::showMemoryWidget()
|
||||
@ -998,15 +978,14 @@ void MainWindow::showMemoryWidget(MemoryWidgetType type)
|
||||
memoryDockWidget->raiseMemoryWidget();
|
||||
}
|
||||
|
||||
QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType)
|
||||
QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType)
|
||||
{
|
||||
QMenu *menu = new QMenu(parent);
|
||||
// Memory dock widgets
|
||||
for (auto &dock : dockWidgets) {
|
||||
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
|
||||
if (memoryWidget->getType() == MemoryWidgetType::Graph
|
||||
|| memoryWidget->getType() == MemoryWidgetType::Decompiler)
|
||||
{
|
||||
|| memoryWidget->getType() == MemoryWidgetType::Decompiler) {
|
||||
if (addressType == AddressTypeHint::Data) {
|
||||
continue;
|
||||
}
|
||||
@ -1037,9 +1016,8 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHi
|
||||
menu->addSeparator();
|
||||
auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) {
|
||||
QAction *action = new QAction(label, menu);
|
||||
connect(action, &QAction::triggered, this, [this, address, type]() {
|
||||
addNewMemoryWidget(type, address, false);
|
||||
});
|
||||
connect(action, &QAction::triggered, this,
|
||||
[this, address, type]() { addNewMemoryWidget(type, address, false); });
|
||||
menu->addAction(action);
|
||||
};
|
||||
createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly);
|
||||
@ -1091,7 +1069,7 @@ MemoryDockWidget *MainWindow::addNewMemoryWidget(MemoryWidgetType type, RVA addr
|
||||
|
||||
void MainWindow::initBackForwardMenu()
|
||||
{
|
||||
auto prepareButtonMenu = [this](QAction *action) -> QMenu* {
|
||||
auto prepareButtonMenu = [this](QAction *action) -> QMenu * {
|
||||
QToolButton *button = qobject_cast<QToolButton *>(ui->mainToolBar->widgetForAction(action));
|
||||
if (!button) {
|
||||
return nullptr;
|
||||
@ -1101,9 +1079,7 @@ void MainWindow::initBackForwardMenu()
|
||||
button->setPopupMode(QToolButton::DelayedPopup);
|
||||
button->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(button, &QWidget::customContextMenuRequested, button,
|
||||
[menu, button] (const QPoint &pos) {
|
||||
menu->exec(button->mapToGlobal(pos));
|
||||
});
|
||||
[menu, button](const QPoint &pos) { menu->exec(button->mapToGlobal(pos)); });
|
||||
|
||||
QFontMetrics metrics(fontMetrics());
|
||||
// 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)) {
|
||||
menu->setObjectName("historyMenu");
|
||||
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
|
||||
updateHistoryMenu(menu, false);
|
||||
});
|
||||
connect(menu, &QMenu::aboutToShow, menu,
|
||||
[this, menu]() { updateHistoryMenu(menu, false); });
|
||||
}
|
||||
if (auto menu = prepareButtonMenu(ui->actionForward)) {
|
||||
menu->setObjectName("forwardHistoryMenu");
|
||||
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
|
||||
updateHistoryMenu(menu, true);
|
||||
});
|
||||
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() { updateHistoryMenu(menu, true); });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1147,7 +1120,8 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
|
||||
if (history != redo || current) { // Include current in both directions
|
||||
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
|
||||
QString label = QString("%1 (%2)").arg(name, addressString);
|
||||
@ -1186,7 +1160,6 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
|
||||
}
|
||||
++steps;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::updateLayoutsMenu()
|
||||
@ -1198,9 +1171,8 @@ void MainWindow::updateLayoutsMenu()
|
||||
continue;
|
||||
}
|
||||
auto action = new QAction(it.key(), ui->menuLayouts);
|
||||
connect(action, &QAction::triggered, this, [this, name]() {
|
||||
setViewLayout(getViewLayout(name));
|
||||
});
|
||||
connect(action, &QAction::triggered, this,
|
||||
[this, name]() { setViewLayout(getViewLayout(name)); });
|
||||
ui->menuLayouts->addAction(action);
|
||||
}
|
||||
}
|
||||
@ -1214,9 +1186,11 @@ void MainWindow::saveNamedLayout()
|
||||
names.removeAll(LAYOUT_DEFAULT);
|
||||
while (name.isEmpty() || isBuiltinLayoutName(name)) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@ -1261,17 +1235,12 @@ void MainWindow::removeWidget(CutterDockWidget *widget)
|
||||
|
||||
void MainWindow::showZenDocks()
|
||||
{
|
||||
const QList<QDockWidget *> zenDocks = { functionsDock,
|
||||
dashboardDock,
|
||||
stringsDock,
|
||||
searchDock,
|
||||
importsDock
|
||||
};
|
||||
const QList<QDockWidget *> zenDocks = { functionsDock, dashboardDock, stringsDock, searchDock,
|
||||
importsDock };
|
||||
functionDockWidthToRestore = functionsDock->maximumWidth();
|
||||
functionsDock->setMaximumWidth(200);
|
||||
for (auto w : dockWidgets) {
|
||||
if (zenDocks.contains(w) ||
|
||||
isExtraMemoryWidget(w)) {
|
||||
if (zenDocks.contains(w) || isExtraMemoryWidget(w)) {
|
||||
w->show();
|
||||
}
|
||||
}
|
||||
@ -1280,27 +1249,19 @@ void MainWindow::showZenDocks()
|
||||
|
||||
void MainWindow::showDebugDocks()
|
||||
{
|
||||
const QList<QDockWidget *> debugDocks = { functionsDock,
|
||||
stringsDock,
|
||||
searchDock,
|
||||
stackDock,
|
||||
registersDock,
|
||||
backtraceDock,
|
||||
threadsDock,
|
||||
memoryMapDock,
|
||||
breakpointDock
|
||||
};
|
||||
const QList<QDockWidget *> debugDocks = { functionsDock, stringsDock, searchDock,
|
||||
stackDock, registersDock, backtraceDock,
|
||||
threadsDock, memoryMapDock, breakpointDock };
|
||||
functionDockWidthToRestore = functionsDock->maximumWidth();
|
||||
functionsDock->setMaximumWidth(200);
|
||||
auto registerWidth = qhelpers::forceWidth(registersDock, std::min(500, this->width() / 4));
|
||||
auto registerHeight = qhelpers::forceHeight(registersDock, std::max(100, height() / 2));
|
||||
QDockWidget *widgetToFocus = nullptr;
|
||||
for (auto w : dockWidgets) {
|
||||
if (debugDocks.contains(w) ||
|
||||
isExtraMemoryWidget(w)) {
|
||||
if (debugDocks.contains(w) || isExtraMemoryWidget(w)) {
|
||||
w->show();
|
||||
}
|
||||
if (qobject_cast<DisassemblyWidget*>(w)) {
|
||||
if (qobject_cast<DisassemblyWidget *>(w)) {
|
||||
widgetToFocus = w;
|
||||
}
|
||||
}
|
||||
@ -1313,12 +1274,12 @@ void MainWindow::showDebugDocks()
|
||||
|
||||
void MainWindow::dockOnMainArea(QDockWidget *widget)
|
||||
{
|
||||
QDockWidget* best = nullptr;
|
||||
QDockWidget *best = nullptr;
|
||||
float bestScore = 1;
|
||||
// choose best existing area for placing the new widget
|
||||
for (auto dock : dockWidgets) {
|
||||
if (dock->isHidden() || dock == widget ||
|
||||
dock->isFloating() || // tabifying onto floating dock using code doesn't work well
|
||||
if (dock->isHidden() || dock == widget || dock->isFloating()
|
||||
|| // tabifying onto floating dock using code doesn't work well
|
||||
dock->parentWidget() != this) { // floating group isn't considered floating
|
||||
continue;
|
||||
}
|
||||
@ -1392,19 +1353,16 @@ void MainWindow::setViewLayout(const CutterLayout &layout)
|
||||
|
||||
QStringList docksToCreate;
|
||||
if (isDefault) {
|
||||
docksToCreate = QStringList {
|
||||
DisassemblyWidget::getWidgetType(),
|
||||
GraphWidget::getWidgetType(),
|
||||
HexdumpWidget::getWidgetType(),
|
||||
DecompilerWidget::getWidgetType()
|
||||
};
|
||||
docksToCreate =
|
||||
QStringList { DisassemblyWidget::getWidgetType(), GraphWidget::getWidgetType(),
|
||||
HexdumpWidget::getWidgetType(), DecompilerWidget::getWidgetType() };
|
||||
} else {
|
||||
docksToCreate = layout.viewProperties.keys();
|
||||
}
|
||||
|
||||
for (const auto &it : docksToCreate) {
|
||||
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);
|
||||
if (widgetTypeToConstructorMap.contains(className)) {
|
||||
auto widget = widgetTypeToConstructorMap[className](this);
|
||||
@ -1490,7 +1448,8 @@ void MainWindow::saveLayouts(QSettings &settings)
|
||||
settings.setValue("state", layout.state);
|
||||
settings.setValue("geometry", layout.geometry);
|
||||
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());
|
||||
}
|
||||
settings.setValue("docks", properties);
|
||||
@ -1498,7 +1457,6 @@ void MainWindow::saveLayouts(QSettings &settings)
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionDefault_triggered()
|
||||
{
|
||||
if (core->currentlyDebugging) {
|
||||
@ -1510,7 +1468,6 @@ void MainWindow::on_actionDefault_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MainWindow::on_actionNew_triggered
|
||||
* Open a new Cutter session.
|
||||
@ -1518,7 +1475,7 @@ void MainWindow::on_actionDefault_triggered()
|
||||
void MainWindow::on_actionNew_triggered()
|
||||
{
|
||||
// Create a new Cutter process
|
||||
static_cast<CutterApplication*>(qApp)->launchNewInstance();
|
||||
static_cast<CutterApplication *>(qApp)->launchNewInstance();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_triggered()
|
||||
@ -1538,8 +1495,8 @@ void MainWindow::on_actionRun_Script_triggered()
|
||||
dialog.setViewMode(QFileDialog::Detail);
|
||||
dialog.setDirectory(QDir::home());
|
||||
|
||||
const QString &fileName = QDir::toNativeSeparators(dialog.getOpenFileName(this,
|
||||
tr("Select Rizin script")));
|
||||
const QString &fileName =
|
||||
QDir::toNativeSeparators(dialog.getOpenFileName(this, tr("Select Rizin script")));
|
||||
if (fileName.isEmpty()) // Cancel was pressed
|
||||
return;
|
||||
|
||||
@ -1581,10 +1538,9 @@ void MainWindow::on_actionTabs_on_Top_triggered()
|
||||
|
||||
void MainWindow::on_actionReset_settings_triggered()
|
||||
{
|
||||
QMessageBox::StandardButton ret =
|
||||
(QMessageBox::StandardButton)QMessageBox::question(this, APPNAME,
|
||||
tr("Do you really want to clear all settings?"),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
QMessageBox::StandardButton ret = (QMessageBox::StandardButton)QMessageBox::question(
|
||||
this, APPNAME, tr("Do you really want to clear all settings?"),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if (ret == QMessageBox::Ok) {
|
||||
Config()->resetAll();
|
||||
readSettings();
|
||||
@ -1620,7 +1576,7 @@ void MainWindow::on_actionRefresh_contents_triggered()
|
||||
|
||||
void MainWindow::on_actionPreferences_triggered()
|
||||
{
|
||||
if (!findChild<PreferencesDialog*>()) {
|
||||
if (!findChild<PreferencesDialog *>()) {
|
||||
auto dialog = new PreferencesDialog(this);
|
||||
dialog->show();
|
||||
}
|
||||
@ -1661,7 +1617,7 @@ void MainWindow::on_actionAnalyze_triggered()
|
||||
{
|
||||
auto *analTask = new AnalTask();
|
||||
InitialOptions options;
|
||||
options.analCmd = { {"aaa", "Auto analysis"} };
|
||||
options.analCmd = { { "aaa", "Auto analysis" } };
|
||||
analTask->setOptions(options);
|
||||
AsyncTask::Ptr analTaskPtr(analTask);
|
||||
|
||||
@ -1810,13 +1766,13 @@ bool MainWindow::eventFilter(QObject *, QEvent *event)
|
||||
|
||||
bool MainWindow::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FontChange
|
||||
|| event->type() == QEvent::StyleChange
|
||||
if (event->type() == QEvent::FontChange || event->type() == QEvent::StyleChange
|
||||
|| 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);
|
||||
#else
|
||||
QMetaObject::invokeMethod(Config(), &Configuration::refreshFont, Qt::ConnectionType::QueuedConnection);
|
||||
QMetaObject::invokeMethod(Config(), &Configuration::refreshFont,
|
||||
Qt::ConnectionType::QueuedConnection);
|
||||
#endif
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
@ -1843,31 +1799,30 @@ void MainWindow::messageBoxWarning(QString title, QString message)
|
||||
void MainWindow::chooseThemeIcons()
|
||||
{
|
||||
// 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->actionBackward, QStringLiteral("arrow_left.svg") },
|
||||
{ ui->actionBackward, QStringLiteral("arrow_left.svg") },
|
||||
};
|
||||
|
||||
|
||||
// Set the correct icon for the QAction
|
||||
qhelpers::setThemeIcons(kSupportedIconsNames, [](void *obj, const QIcon &icon) {
|
||||
static_cast<QAction*>(obj)->setIcon(icon);
|
||||
static_cast<QAction *>(obj)->setIcon(icon);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::onZoomIn()
|
||||
{
|
||||
Config()->setZoomFactor(Config()->getZoomFactor() + 0.1);
|
||||
Config()->setZoomFactor(Config()->getZoomFactor() + 0.1);
|
||||
}
|
||||
|
||||
void MainWindow::onZoomOut()
|
||||
{
|
||||
Config()->setZoomFactor(Config()->getZoomFactor() - 0.1);
|
||||
Config()->setZoomFactor(Config()->getZoomFactor() - 0.1);
|
||||
}
|
||||
|
||||
void MainWindow::onZoomReset()
|
||||
{
|
||||
Config()->setZoomFactor(1.0);
|
||||
Config()->setZoomFactor(1.0);
|
||||
}
|
||||
|
||||
QMenu *MainWindow::getContextMenuExtensions(ContextMenuType type)
|
||||
|
@ -90,10 +90,14 @@ public:
|
||||
void addMemoryDockWidget(MemoryDockWidget *widget);
|
||||
void removeWidget(CutterDockWidget *widget);
|
||||
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.")
|
||||
void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *) { addPluginDockWidget(dockWidget); }
|
||||
void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *)
|
||||
{
|
||||
addPluginDockWidget(dockWidget);
|
||||
}
|
||||
void addPluginDockWidget(CutterDockWidget *dockWidget);
|
||||
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
|
||||
/**
|
||||
@ -104,19 +108,17 @@ public:
|
||||
QMenu *getMenuByType(MenuType type);
|
||||
void addMenuFileAction(QAction *action);
|
||||
|
||||
QString getFilename() const
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
QString getFilename() const { return filename; }
|
||||
void messageBoxWarning(QString title, QString message);
|
||||
|
||||
QString getUniqueObjectName(const QString &widgetType) const;
|
||||
void showMemoryWidget();
|
||||
void showMemoryWidget(MemoryWidgetType type);
|
||||
enum class AddressTypeHint { Function, Data, Unknown };
|
||||
QMenu *createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType = AddressTypeHint::Unknown);
|
||||
void setCurrentMemoryWidget(MemoryDockWidget* memoryWidget);
|
||||
MemoryDockWidget* getLastMemoryWidget();
|
||||
QMenu *createShowInMenu(QWidget *parent, RVA address,
|
||||
AddressTypeHint addressType = AddressTypeHint::Unknown);
|
||||
void setCurrentMemoryWidget(MemoryDockWidget *memoryWidget);
|
||||
MemoryDockWidget *getLastMemoryWidget();
|
||||
|
||||
/* Context menu plugins */
|
||||
enum class ContextMenuType { Disassembly, Addressable };
|
||||
@ -202,6 +204,7 @@ private slots:
|
||||
void onZoomReset();
|
||||
|
||||
void setAvailableIOModeOptions();
|
||||
|
||||
private:
|
||||
CutterCore *core;
|
||||
|
||||
@ -221,41 +224,41 @@ private:
|
||||
|
||||
QList<CutterDockWidget *> dockWidgets;
|
||||
QList<CutterDockWidget *> pluginDocks;
|
||||
OverviewWidget *overviewDock = nullptr;
|
||||
OverviewWidget *overviewDock = nullptr;
|
||||
QAction *actionOverview = nullptr;
|
||||
EntrypointWidget *entrypointDock = nullptr;
|
||||
FunctionsWidget *functionsDock = nullptr;
|
||||
ImportsWidget *importsDock = nullptr;
|
||||
ExportsWidget *exportsDock = nullptr;
|
||||
HeadersWidget *headersDock = nullptr;
|
||||
TypesWidget *typesDock = nullptr;
|
||||
SearchWidget *searchDock = nullptr;
|
||||
SymbolsWidget *symbolsDock = nullptr;
|
||||
RelocsWidget *relocsDock = nullptr;
|
||||
CommentsWidget *commentsDock = nullptr;
|
||||
StringsWidget *stringsDock = nullptr;
|
||||
FlagsWidget *flagsDock = nullptr;
|
||||
Dashboard *dashboardDock = nullptr;
|
||||
SdbWidget *sdbDock = nullptr;
|
||||
SectionsWidget *sectionsDock = nullptr;
|
||||
SegmentsWidget *segmentsDock = nullptr;
|
||||
ZignaturesWidget *zignaturesDock = nullptr;
|
||||
ConsoleWidget *consoleDock = nullptr;
|
||||
ClassesWidget *classesDock = nullptr;
|
||||
ResourcesWidget *resourcesDock = nullptr;
|
||||
VTablesWidget *vTablesDock = nullptr;
|
||||
CutterDockWidget *stackDock = nullptr;
|
||||
CutterDockWidget *threadsDock = nullptr;
|
||||
CutterDockWidget *processesDock = nullptr;
|
||||
CutterDockWidget *registersDock = nullptr;
|
||||
CutterDockWidget *backtraceDock = nullptr;
|
||||
CutterDockWidget *memoryMapDock = nullptr;
|
||||
NewFileDialog *newFileDialog = nullptr;
|
||||
CutterDockWidget *breakpointDock = nullptr;
|
||||
CutterDockWidget *registerRefsDock = nullptr;
|
||||
RizinGraphWidget *rzGraphDock = nullptr;
|
||||
CallGraphWidget *callGraphDock = nullptr;
|
||||
CallGraphWidget *globalCallGraphDock = nullptr;
|
||||
EntrypointWidget *entrypointDock = nullptr;
|
||||
FunctionsWidget *functionsDock = nullptr;
|
||||
ImportsWidget *importsDock = nullptr;
|
||||
ExportsWidget *exportsDock = nullptr;
|
||||
HeadersWidget *headersDock = nullptr;
|
||||
TypesWidget *typesDock = nullptr;
|
||||
SearchWidget *searchDock = nullptr;
|
||||
SymbolsWidget *symbolsDock = nullptr;
|
||||
RelocsWidget *relocsDock = nullptr;
|
||||
CommentsWidget *commentsDock = nullptr;
|
||||
StringsWidget *stringsDock = nullptr;
|
||||
FlagsWidget *flagsDock = nullptr;
|
||||
Dashboard *dashboardDock = nullptr;
|
||||
SdbWidget *sdbDock = nullptr;
|
||||
SectionsWidget *sectionsDock = nullptr;
|
||||
SegmentsWidget *segmentsDock = nullptr;
|
||||
ZignaturesWidget *zignaturesDock = nullptr;
|
||||
ConsoleWidget *consoleDock = nullptr;
|
||||
ClassesWidget *classesDock = nullptr;
|
||||
ResourcesWidget *resourcesDock = nullptr;
|
||||
VTablesWidget *vTablesDock = nullptr;
|
||||
CutterDockWidget *stackDock = nullptr;
|
||||
CutterDockWidget *threadsDock = nullptr;
|
||||
CutterDockWidget *processesDock = nullptr;
|
||||
CutterDockWidget *registersDock = nullptr;
|
||||
CutterDockWidget *backtraceDock = nullptr;
|
||||
CutterDockWidget *memoryMapDock = nullptr;
|
||||
NewFileDialog *newFileDialog = nullptr;
|
||||
CutterDockWidget *breakpointDock = nullptr;
|
||||
CutterDockWidget *registerRefsDock = nullptr;
|
||||
RizinGraphWidget *rzGraphDock = nullptr;
|
||||
CallGraphWidget *callGraphDock = nullptr;
|
||||
CallGraphWidget *globalCallGraphDock = nullptr;
|
||||
|
||||
QMenu *disassemblyContextMenuExtensions = nullptr;
|
||||
QMenu *addressableContextMenuExtensions = nullptr;
|
||||
@ -266,7 +269,8 @@ private:
|
||||
void initToolBar();
|
||||
void initDocks();
|
||||
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(const QString &name);
|
||||
@ -275,7 +279,6 @@ private:
|
||||
void loadLayouts(QSettings &settings);
|
||||
void saveLayouts(QSettings &settings);
|
||||
|
||||
|
||||
void updateMemberPointers();
|
||||
void restoreDocks();
|
||||
void showZenDocks();
|
||||
@ -309,12 +312,13 @@ private:
|
||||
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* lastMemoryWidget = nullptr;
|
||||
MemoryDockWidget *lastSyncMemoryWidget = nullptr;
|
||||
MemoryDockWidget *lastMemoryWidget = nullptr;
|
||||
int functionDockWidthToRestore = 0;
|
||||
};
|
||||
|
||||
|
@ -18,37 +18,39 @@
|
||||
|
||||
#include "CutterConfig.h"
|
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AboutDialog)
|
||||
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
ui->logoSvgWidget->load(Config()->getLogoFile());
|
||||
|
||||
QString aboutString(tr("Version") + " " CUTTER_VERSION_FULL "<br/>"
|
||||
+ tr("Using rizin-") + RZ_GITTAP + "<br/>"
|
||||
+ buildQtVersionString()
|
||||
+ "<p><b>" + tr("Optional Features:") + "</b><br/>"
|
||||
+ QString("Python: %1<br/>").arg(
|
||||
QString aboutString(
|
||||
tr("Version") + " " CUTTER_VERSION_FULL "<br/>" + tr("Using rizin-") + RZ_GITTAP
|
||||
+ "<br/>" + buildQtVersionString() + "<p><b>" + tr("Optional Features:") + "</b><br/>"
|
||||
+ QString("Python: %1<br/>")
|
||||
.arg(
|
||||
#ifdef CUTTER_ENABLE_PYTHON
|
||||
"ON"
|
||||
"ON"
|
||||
#else
|
||||
"OFF"
|
||||
"OFF"
|
||||
#endif
|
||||
)
|
||||
+ QString("Python Bindings: %2</p>").arg(
|
||||
)
|
||||
+ QString("Python Bindings: %2</p>")
|
||||
.arg(
|
||||
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
|
||||
"ON"
|
||||
"ON"
|
||||
#else
|
||||
"OFF"
|
||||
"OFF"
|
||||
#endif
|
||||
)
|
||||
+ "<h2>" + tr("License") + "</h2>"
|
||||
+ tr("This Software is released under the GNU General Public License v3.0")
|
||||
+ "<h2>" + tr("Authors") + "</h2>"
|
||||
+ tr("Cutter is developed by the community and maintained by its core and development teams.<br/>")
|
||||
+ tr("Check our <a href='https://github.com/rizinorg/cutter/graphs/contributors'>contributors page</a> for the full list of contributors."));
|
||||
)
|
||||
+ "<h2>" + tr("License") + "</h2>"
|
||||
+ tr("This Software is released under the GNU General Public License v3.0") + "<h2>"
|
||||
+ tr("Authors") + "</h2>"
|
||||
+ tr("Cutter is developed by the community and maintained by its core and development "
|
||||
"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);
|
||||
|
||||
QSignalBlocker s(ui->updatesCheckBox);
|
||||
@ -97,17 +99,18 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
|
||||
|
||||
connect(&updateWorker, &UpdateWorker::checkComplete, &waitDialog, &QProgressDialog::cancel);
|
||||
connect(&updateWorker, &UpdateWorker::checkComplete,
|
||||
[&updateWorker](const QVersionNumber & version, const QString & error) {
|
||||
if (!error.isEmpty()) {
|
||||
QMessageBox::critical(nullptr, tr("Error!"), error);
|
||||
} else {
|
||||
if (version <= UpdateWorker::currentVersionNumber()) {
|
||||
QMessageBox::information(nullptr, tr("Version control"), tr("Cutter is up to date!"));
|
||||
} else {
|
||||
updateWorker.showUpdateDialog(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
[&updateWorker](const QVersionNumber &version, const QString &error) {
|
||||
if (!error.isEmpty()) {
|
||||
QMessageBox::critical(nullptr, tr("Error!"), error);
|
||||
} else {
|
||||
if (version <= UpdateWorker::currentVersionNumber()) {
|
||||
QMessageBox::information(nullptr, tr("Version control"),
|
||||
tr("Cutter is up to date!"));
|
||||
} else {
|
||||
updateWorker.showUpdateDialog(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateWorker.checkCurrentVersion(7000);
|
||||
waitDialog.exec();
|
||||
@ -123,13 +126,13 @@ static QString compilerString()
|
||||
{
|
||||
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
|
||||
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)");
|
||||
#endif
|
||||
return QLatin1String("Clang " ) + QString::number(__clang_major__) + QLatin1Char('.')
|
||||
+ QString::number(__clang_minor__) + isAppleString;
|
||||
# endif
|
||||
return QLatin1String("Clang ") + QString::number(__clang_major__) + QLatin1Char('.')
|
||||
+ QString::number(__clang_minor__) + isAppleString;
|
||||
#elif defined(Q_CC_GNU)
|
||||
return QLatin1String("GCC " ) + QLatin1String(__VERSION__);
|
||||
return QLatin1String("GCC ") + QLatin1String(__VERSION__);
|
||||
#elif defined(Q_CC_MSVC)
|
||||
if (_MSC_VER > 1999)
|
||||
return QLatin1String("MSVC <unknown>");
|
||||
@ -143,7 +146,6 @@ static QString compilerString()
|
||||
|
||||
QString AboutDialog::buildQtVersionString(void)
|
||||
{
|
||||
return tr("Based on Qt %1 (%2, %3 bit)").arg(QLatin1String(qVersion()),
|
||||
compilerString(),
|
||||
QString::number(QSysInfo::WordSize));
|
||||
return tr("Based on Qt %1 (%2, %3 bit)")
|
||||
.arg(QLatin1String(qVersion()), compilerString(), QString::number(QSysInfo::WordSize));
|
||||
}
|
||||
|
@ -26,14 +26,14 @@ private slots:
|
||||
* @fn AboutDialog::on_checkForUpdatesButton_clicked()
|
||||
*
|
||||
* @brief Initiates process of checking for updates.
|
||||
*/
|
||||
*/
|
||||
void on_checkForUpdatesButton_clicked();
|
||||
|
||||
/**
|
||||
* @fn AboutDialog::on_updatesCheckBox_stateChanged(int state)
|
||||
*
|
||||
* @brief Changes value of autoUpdateEnabled option in settings.
|
||||
*/
|
||||
*/
|
||||
void on_updatesCheckBox_stateChanged(int state);
|
||||
|
||||
private:
|
||||
|
@ -4,11 +4,8 @@
|
||||
|
||||
#include "ui_AsyncTaskDialog.h"
|
||||
|
||||
|
||||
AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::AsyncTaskDialog),
|
||||
task(task)
|
||||
: QDialog(parent), ui(new Ui::AsyncTaskDialog), task(task)
|
||||
{
|
||||
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::finished, this, [this]() {
|
||||
close();
|
||||
});
|
||||
connect(task.data(), &AsyncTask::finished, this, [this]() { close(); });
|
||||
|
||||
updateLog(task->getLog());
|
||||
|
||||
@ -32,9 +27,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
|
||||
updateProgressTimer();
|
||||
}
|
||||
|
||||
AsyncTaskDialog::~AsyncTaskDialog()
|
||||
{
|
||||
}
|
||||
AsyncTaskDialog::~AsyncTaskDialog() {}
|
||||
|
||||
void AsyncTaskDialog::updateLog(const QString &log)
|
||||
{
|
||||
|
@ -21,8 +21,8 @@ public:
|
||||
AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent = nullptr);
|
||||
~AsyncTaskDialog();
|
||||
|
||||
void setInterruptOnClose(bool v) { interruptOnClose = v; }
|
||||
bool getInterruptOnClose() { return interruptOnClose; }
|
||||
void setInterruptOnClose(bool v) { interruptOnClose = v; }
|
||||
bool getInterruptOnClose() { return interruptOnClose; }
|
||||
|
||||
public slots:
|
||||
void reject() override;
|
||||
@ -42,4 +42,4 @@ private:
|
||||
bool interruptOnClose = false;
|
||||
};
|
||||
|
||||
#endif //ASYNCTASKDIALOG_H
|
||||
#endif // ASYNCTASKDIALOG_H
|
||||
|
@ -10,8 +10,7 @@
|
||||
// ------------
|
||||
// ProcessModel
|
||||
// ------------
|
||||
ProcessModel::ProcessModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
ProcessModel::ProcessModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
updateData();
|
||||
}
|
||||
@ -125,7 +124,8 @@ QString ProcessBeingAnalysedProxyModel::processPathToFilename(const QString &pat
|
||||
bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
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);
|
||||
return procFilename == processBeingAnalysedFilename;
|
||||
@ -134,10 +134,10 @@ bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex
|
||||
bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left,
|
||||
const QModelIndex &right) const
|
||||
{
|
||||
ProcessDescription leftProc = left.data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription rightProc = right.data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription leftProc =
|
||||
left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription rightProc =
|
||||
right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
|
||||
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
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
ProcessDescription leftProc = left.data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription rightProc = right.data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription leftProc =
|
||||
left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
ProcessDescription rightProc =
|
||||
right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
|
||||
|
||||
return ProcessModel::lessThan(leftProc, rightProc, left.column());
|
||||
}
|
||||
@ -171,9 +172,7 @@ bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig
|
||||
// ----------------
|
||||
// AttachProcDialog
|
||||
// ----------------
|
||||
AttachProcDialog::AttachProcDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AttachProcDialog)
|
||||
AttachProcDialog::AttachProcDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AttachProcDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
@ -232,13 +231,19 @@ void AttachProcDialog::updateModelData()
|
||||
|
||||
if (allViewHadSelection) {
|
||||
allViewPrevScrollPos = allView->verticalScrollBar()->value();
|
||||
allViewPrevPID = allView->selectionModel()->currentIndex().data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
||||
allViewPrevPID = allView->selectionModel()
|
||||
->currentIndex()
|
||||
.data(ProcessModel::ProcDescriptionRole)
|
||||
.value<ProcessDescription>()
|
||||
.pid;
|
||||
}
|
||||
if (smallViewHadSelection) {
|
||||
smallViewPrevScrollPos = smallView->verticalScrollBar()->value();
|
||||
smallViewPrevPID = smallView->selectionModel()->currentIndex().data(
|
||||
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
||||
smallViewPrevPID = smallView->selectionModel()
|
||||
->currentIndex()
|
||||
.data(ProcessModel::ProcDescriptionRole)
|
||||
.value<ProcessDescription>()
|
||||
.pid;
|
||||
}
|
||||
|
||||
// Let the model update
|
||||
@ -246,16 +251,18 @@ void AttachProcDialog::updateModelData()
|
||||
|
||||
// Restore the selection and scroll position
|
||||
if (allViewHadSelection) {
|
||||
QModelIndexList idx = allView->model()->match(
|
||||
allView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(allViewPrevPID));
|
||||
QModelIndexList idx =
|
||||
allView->model()->match(allView->model()->index(0, 0), Qt::DisplayRole,
|
||||
QVariant::fromValue(allViewPrevPID));
|
||||
if (!idx.isEmpty()) {
|
||||
allView->setCurrentIndex(idx.first());
|
||||
allView->verticalScrollBar()->setValue(allViewPrevScrollPos);
|
||||
}
|
||||
}
|
||||
if (smallViewHadSelection) {
|
||||
QModelIndexList idx = smallView->model()->match(
|
||||
smallView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(smallViewPrevPID));
|
||||
QModelIndexList idx =
|
||||
smallView->model()->match(smallView->model()->index(0, 0), Qt::DisplayRole,
|
||||
QVariant::fromValue(smallViewPrevPID));
|
||||
|
||||
if (!idx.isEmpty()) {
|
||||
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
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
void AttachProcDialog::on_buttonBox_accepted()
|
||||
{
|
||||
}
|
||||
void AttachProcDialog::on_buttonBox_accepted() {}
|
||||
|
||||
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
|
||||
if (wasAllProcViewLastPressed && ui->allProcView->selectionModel()->hasSelection()) {
|
||||
pid = ui->allProcView->selectionModel()->currentIndex().
|
||||
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
||||
pid = ui->allProcView->selectionModel()
|
||||
->currentIndex()
|
||||
.data(ProcessModel::ProcDescriptionRole)
|
||||
.value<ProcessDescription>()
|
||||
.pid;
|
||||
} else if (!wasAllProcViewLastPressed
|
||||
&& ui->procBeingAnalyzedView->selectionModel()->hasSelection()) {
|
||||
pid = ui->procBeingAnalyzedView->selectionModel()->currentIndex().
|
||||
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid;
|
||||
pid = ui->procBeingAnalyzedView->selectionModel()
|
||||
->currentIndex()
|
||||
.data(ProcessModel::ProcDescriptionRole)
|
||||
.value<ProcessDescription>()
|
||||
.pid;
|
||||
} else {
|
||||
// Error attaching. No process selected! Happens when you press ENTER but
|
||||
// there was no process with the same name as the one being analyzed.
|
||||
|
@ -15,8 +15,7 @@ class MainWindow;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
|
||||
class ProcessModel: public QAbstractListModel
|
||||
class ProcessModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -34,14 +33,13 @@ public:
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) 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:
|
||||
void updateData();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ProcessProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -54,7 +52,6 @@ protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
};
|
||||
|
||||
|
||||
class ProcessBeingAnalysedProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -71,8 +68,6 @@ private:
|
||||
QString processPathToFilename(const QString &path) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class AttachProcDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -7,15 +7,14 @@
|
||||
#include <QCompleter>
|
||||
#include <QCheckBox>
|
||||
|
||||
BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::BreakpointsDialog),
|
||||
editMode(editMode)
|
||||
BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::BreakpointsDialog), editMode(editMode)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
|
||||
connect(ui->breakpointPosition, &QLineEdit::textChanged, this, &BreakpointsDialog::refreshOkButton);
|
||||
connect(ui->breakpointPosition, &QLineEdit::textChanged, this,
|
||||
&BreakpointsDialog::refreshOkButton);
|
||||
refreshOkButton();
|
||||
|
||||
if (editMode) {
|
||||
@ -24,15 +23,16 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
||||
setWindowTitle(tr("New breakpoint"));
|
||||
}
|
||||
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
QString label;
|
||||
QString tooltip;
|
||||
BreakpointDescription::PositionType type;
|
||||
} positionTypes[] = {
|
||||
{tr("Address"), tr("Address or expression calculated when creating breakpoint"), BreakpointDescription::Address},
|
||||
{tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named},
|
||||
{tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module},
|
||||
{ tr("Address"), tr("Address or expression calculated when creating breakpoint"),
|
||||
BreakpointDescription::Address },
|
||||
{ tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named },
|
||||
{ tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module },
|
||||
};
|
||||
int index = 0;
|
||||
for (auto &item : positionTypes) {
|
||||
@ -41,8 +41,9 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
||||
index++;
|
||||
}
|
||||
|
||||
connect(ui->positionType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &BreakpointsDialog::onTypeChanged);
|
||||
connect(ui->positionType,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&BreakpointsDialog::onTypeChanged);
|
||||
onTypeChanged();
|
||||
|
||||
auto modules = Core()->getMemoryMap();
|
||||
@ -50,7 +51,7 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
|
||||
for (const auto &module : modules) {
|
||||
moduleNames.insert(module.fileName);
|
||||
}
|
||||
for (const auto& module : moduleNames) {
|
||||
for (const auto &module : moduleNames) {
|
||||
ui->moduleName->addItem(module);
|
||||
}
|
||||
ui->moduleName->setCurrentText("");
|
||||
@ -111,7 +112,8 @@ BreakpointsDialog::~BreakpointsDialog() {}
|
||||
BreakpointDescription BreakpointsDialog::getDescription()
|
||||
{
|
||||
BreakpointDescription breakpoint;
|
||||
auto positionType = ui->positionType->currentData().value<BreakpointDescription::PositionType>();
|
||||
auto positionType =
|
||||
ui->positionType->currentData().value<BreakpointDescription::PositionType>();
|
||||
switch (positionType) {
|
||||
case BreakpointDescription::Address:
|
||||
breakpoint.addr = Core()->math(ui->breakpointPosition->text());
|
||||
@ -167,7 +169,8 @@ void BreakpointsDialog::onTypeChanged()
|
||||
bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module);
|
||||
ui->moduleLabel->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()
|
||||
|
@ -21,7 +21,8 @@ public:
|
||||
BreakpointDescription getDescription();
|
||||
|
||||
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:
|
||||
std::unique_ptr<Ui::BreakpointsDialog> ui;
|
||||
bool editMode = false;
|
||||
|
@ -3,9 +3,7 @@
|
||||
|
||||
#include "core/Cutter.h"
|
||||
|
||||
CommentsDialog::CommentsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CommentsDialog)
|
||||
CommentsDialog::CommentsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CommentsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
@ -16,9 +14,7 @@ CommentsDialog::CommentsDialog(QWidget *parent) :
|
||||
|
||||
CommentsDialog::~CommentsDialog() {}
|
||||
|
||||
void CommentsDialog::on_buttonBox_accepted()
|
||||
{
|
||||
}
|
||||
void CommentsDialog::on_buttonBox_accepted() {}
|
||||
|
||||
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) {
|
||||
QKeyEvent *keyEvent = static_cast <QKeyEvent *> (event);
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
|
||||
// Confirm comment by pressing Ctrl/Cmd+Return
|
||||
if ((keyEvent -> modifiers() & Qt::ControlModifier) &&
|
||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return))) {
|
||||
if ((keyEvent->modifiers() & Qt::ControlModifier)
|
||||
&& ((keyEvent->key() == Qt::Key_Enter) || (keyEvent->key() == Qt::Key_Return))) {
|
||||
this->accept();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include "EditFunctionDialog.h"
|
||||
#include "ui_EditFunctionDialog.h"
|
||||
|
||||
EditFunctionDialog::EditFunctionDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::EditFunctionDialog)
|
||||
EditFunctionDialog::EditFunctionDialog(QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::EditFunctionDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
@ -44,21 +43,22 @@ void EditFunctionDialog::setStackSizeText(const QString &stackSize)
|
||||
ui->stackSizeLineEdit->setText(stackSize);
|
||||
}
|
||||
|
||||
void EditFunctionDialog::setCallConList(const QStringList &callConList) {
|
||||
void EditFunctionDialog::setCallConList(const QStringList &callConList)
|
||||
{
|
||||
ui->callConComboBox->addItems(callConList);
|
||||
}
|
||||
|
||||
void EditFunctionDialog::setCallConSelected(const QString &selected) {
|
||||
void EditFunctionDialog::setCallConSelected(const QString &selected)
|
||||
{
|
||||
ui->callConComboBox->setCurrentText(selected);
|
||||
}
|
||||
|
||||
QString EditFunctionDialog::getCallConSelected() {
|
||||
QString EditFunctionDialog::getCallConSelected()
|
||||
{
|
||||
return ui->callConComboBox->currentText();
|
||||
}
|
||||
|
||||
void EditFunctionDialog::on_buttonBox_accepted()
|
||||
{
|
||||
}
|
||||
void EditFunctionDialog::on_buttonBox_accepted() {}
|
||||
|
||||
void EditFunctionDialog::on_buttonBox_rejected()
|
||||
{
|
||||
|
@ -2,10 +2,8 @@
|
||||
#include "ui_EditInstructionDialog.h"
|
||||
#include "core/Cutter.h"
|
||||
|
||||
EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::EditInstructionDialog),
|
||||
editMode(editMode)
|
||||
EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::EditInstructionDialog), editMode(editMode)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->lineEdit->setMinimumWidth(400);
|
||||
@ -17,9 +15,7 @@ EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidg
|
||||
|
||||
EditInstructionDialog::~EditInstructionDialog() {}
|
||||
|
||||
void EditInstructionDialog::on_buttonBox_accepted()
|
||||
{
|
||||
}
|
||||
void EditInstructionDialog::on_buttonBox_accepted() {}
|
||||
|
||||
void EditInstructionDialog::on_buttonBox_rejected()
|
||||
{
|
||||
|
@ -8,9 +8,7 @@ namespace Ui {
|
||||
class EditInstructionDialog;
|
||||
}
|
||||
|
||||
enum InstructionEditMode {
|
||||
EDIT_NONE, EDIT_BYTES, EDIT_TEXT
|
||||
};
|
||||
enum InstructionEditMode { EDIT_NONE, EDIT_BYTES, EDIT_TEXT };
|
||||
|
||||
class EditInstructionDialog : public QDialog
|
||||
{
|
||||
@ -32,7 +30,8 @@ private slots:
|
||||
|
||||
private:
|
||||
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
|
||||
|
@ -3,9 +3,8 @@
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::EditMethodDialog)
|
||||
EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::EditMethodDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
@ -24,15 +23,14 @@ EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) :
|
||||
updateVirtualUI();
|
||||
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);
|
||||
}
|
||||
|
||||
EditMethodDialog::~EditMethodDialog() {}
|
||||
|
||||
void EditMethodDialog::on_buttonBox_accepted()
|
||||
{
|
||||
}
|
||||
void EditMethodDialog::on_buttonBox_accepted() {}
|
||||
|
||||
void EditMethodDialog::on_buttonBox_rejected()
|
||||
{
|
||||
@ -73,7 +71,7 @@ void EditMethodDialog::setClass(const QString &className)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i<classComboBox->count(); i++) {
|
||||
for (int i = 0; i < classComboBox->count(); i++) {
|
||||
QString cls = classComboBox->itemData(i).toString();
|
||||
if (cls == className) {
|
||||
classComboBox->setCurrentIndex(i);
|
||||
@ -131,7 +129,8 @@ AnalMethodDescription EditMethodDialog::getMethod() const
|
||||
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);
|
||||
dialog.setWindowTitle(title);
|
||||
|
@ -17,7 +17,8 @@ class EditMethodDialog : public QDialog
|
||||
|
||||
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);
|
||||
~EditMethodDialog();
|
||||
@ -37,17 +38,20 @@ public:
|
||||
* @param desc initial data for the method information
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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:
|
||||
void on_buttonBox_accepted();
|
||||
@ -62,7 +66,8 @@ private:
|
||||
QComboBox *classComboBox = 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;
|
||||
|
||||
|
@ -2,25 +2,24 @@
|
||||
#include "ui_EditStringDialog.h"
|
||||
|
||||
EditStringDialog::EditStringDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::EditStringDialog{})
|
||||
: QDialog(parent), ui(new Ui::EditStringDialog {})
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->spinBox_size->setMinimum(0);
|
||||
ui->lineEdit_address->setMinimumWidth(150);
|
||||
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);
|
||||
}
|
||||
|
||||
EditStringDialog::~EditStringDialog() { }
|
||||
EditStringDialog::~EditStringDialog() {}
|
||||
|
||||
void EditStringDialog::setStringStartAddress(uint64_t address)
|
||||
{
|
||||
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;
|
||||
returnValue = ui->lineEdit_address->text().toLongLong(&status, 16);
|
||||
@ -34,7 +33,7 @@ void EditStringDialog::setStringSizeValue(uint32_t size)
|
||||
|
||||
int EditStringDialog::getStringSizeValue() const
|
||||
{
|
||||
if( ui->checkBox_autoSize->isChecked() ) {
|
||||
if (ui->checkBox_autoSize->isChecked()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -43,20 +42,16 @@ int EditStringDialog::getStringSizeValue() const
|
||||
|
||||
EditStringDialog::StringType EditStringDialog::getStringType() const
|
||||
{
|
||||
const int indexVal = ui->comboBox_type->currentIndex();
|
||||
const int indexVal = ui->comboBox_type->currentIndex();
|
||||
|
||||
switch(indexVal)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
switch (indexVal) {
|
||||
case 0: {
|
||||
return EditStringDialog::StringType::Auto;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
case 1: {
|
||||
return EditStringDialog::StringType::ASCII_LATIN1;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
case 2: {
|
||||
return EditStringDialog::StringType::UTF8;
|
||||
}
|
||||
default:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user