Apply clang-format

This commit is contained in:
ITAYC0HEN 2021-01-24 16:50:13 +02:00 committed by karliss
parent a62f138e2f
commit 48ae2150a9
270 changed files with 4808 additions and 5435 deletions

View File

@ -38,7 +38,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
setAttribute(Qt::AA_UseHighDpiPixmaps); setAttribute(Qt::AA_UseHighDpiPixmaps);
setLayoutDirection(Qt::LeftToRight); setLayoutDirection(Qt::LeftToRight);
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First // WARN!!! Put initialization code below this line. Code above this line is mandatory to be run
// First
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Hack to force Cutter load internet connection related DLL's // Hack to force Cutter load internet connection related DLL's
@ -62,7 +63,6 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
qWarning() << "Cannot load Incosolata-Regular font."; qWarning() << "Cannot load Incosolata-Regular font.";
} }
// Set QString codec to UTF-8 // Set QString codec to UTF-8
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
@ -82,9 +82,10 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
msg.setIcon(QMessageBox::Critical); msg.setIcon(QMessageBox::Critical);
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msg.setWindowTitle(QObject::tr("Version mismatch!")); msg.setWindowTitle(QObject::tr("Version mismatch!"));
msg.setText(QString( msg.setText(QString(QObject::tr("The version used to compile Cutter (%1) does not match "
QObject::tr("The version used to compile Cutter (%1) does not match the binary version of rizin (%2). This could result in unexpected behaviour. Are you sure you want to continue?")).arg( "the binary version of rizin (%2). This could result in "
localVersion, rzversion)); "unexpected behaviour. Are you sure you want to continue?"))
.arg(localVersion, rzversion));
if (msg.exec() == QMessageBox::No) { if (msg.exec() == QMessageBox::No) {
std::exit(1); std::exit(1);
} }
@ -134,7 +135,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
if (clOptions.args.empty()) { if (clOptions.args.empty()) {
// check if this is the first execution of Cutter in this computer // check if this is the first execution of Cutter in this computer
// Note: the execution after the preferences been reset, will be considered as first-execution // Note: the execution after the preferences been reset, will be considered as
// first-execution
if (Config()->isFirstExecution()) { if (Config()->isFirstExecution()) {
mainWindow->displayWelcomeDialog(); mainWindow->displayWelcomeDialog();
} }
@ -144,14 +146,14 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions); mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions);
} }
#ifdef APPIMAGE #ifdef APPIMAGE
{ {
auto appdir = QDir(QCoreApplication::applicationDirPath()); // appdir/bin auto appdir = QDir(QCoreApplication::applicationDirPath()); // appdir/bin
appdir.cdUp(); // appdir appdir.cdUp(); // appdir
auto sleighHome = appdir; auto sleighHome = appdir;
sleighHome.cd("share/rizin/plugins/rz_ghidra_sleigh"); // appdir/share/rizin/plugins/rz_ghidra_sleigh sleighHome.cd(
"share/rizin/plugins/rz_ghidra_sleigh"); // appdir/share/rizin/plugins/rz_ghidra_sleigh
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath()); Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
auto jsdecHome = appdir; auto jsdecHome = appdir;
@ -167,11 +169,13 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
rzprefix.cd("Resources"); // Contents/Resources/rz rzprefix.cd("Resources"); // Contents/Resources/rz
auto sleighHome = rzprefix; auto sleighHome = rzprefix;
sleighHome.cd("share/rizin/plugins/rz_ghidra_sleigh"); // Contents/Resources/rz/share/rizin/plugins/rz_ghidra_sleigh sleighHome.cd(
"share/rizin/plugins/rz_ghidra_sleigh"); // Contents/Resources/rz/share/rizin/plugins/rz_ghidra_sleigh
Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath()); Core()->setConfig("ghidra.sleighhome", sleighHome.absolutePath());
auto jsdecHome = rzprefix; auto jsdecHome = rzprefix;
jsdecHome.cd("share/rizin/plugins/jsdec"); // Contents/Resources/rz/share/rizin/plugins/jsdec jsdecHome.cd(
"share/rizin/plugins/jsdec"); // Contents/Resources/rz/share/rizin/plugins/jsdec
qputenv("JSDEC_HOME", jsdecHome.absolutePath().toLocal8Bit()); qputenv("JSDEC_HOME", jsdecHome.absolutePath().toLocal8Bit());
} }
#endif #endif
@ -241,8 +245,8 @@ bool CutterApplication::loadTranslations()
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) { if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
return true; return true;
} }
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, const auto &allLocales =
QLocale::AnyCountry); QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
bool cutterTrLoaded = false; bool cutterTrLoaded = false;
@ -259,7 +263,8 @@ bool CutterApplication::loadTranslations()
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories(); const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
for (const auto &trPath : cutterTrPaths) { for (const auto &trPath : cutterTrPaths) {
if (trCutter && trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) { if (trCutter
&& trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) {
installTranslator(trCutter); installTranslator(trCutter);
cutterTrLoaded = true; cutterTrLoaded = true;
trCutter = nullptr; trCutter = nullptr;
@ -304,7 +309,8 @@ bool CutterApplication::parseCommandLineOptions()
cmd_parser.addVersionOption(); cmd_parser.addVersionOption();
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open.")); cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
QCommandLineOption analOption({"A", "analysis"}, QCommandLineOption analOption(
{ "A", "analysis" },
QObject::tr("Automatically open file and optionally start analysis. " QObject::tr("Automatically open file and optionally start analysis. "
"Needs filename to be specified. May be a value between 0 and 2:" "Needs filename to be specified. May be a value between 0 and 2:"
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"), " 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
@ -321,30 +327,27 @@ bool CutterApplication::parseCommandLineOptions()
QObject::tr("base address")); QObject::tr("base address"));
cmd_parser.addOption(baddrOption); cmd_parser.addOption(baddrOption);
QCommandLineOption scriptOption("i", QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
QObject::tr("Run script file"),
QObject::tr("file"));
cmd_parser.addOption(scriptOption); cmd_parser.addOption(scriptOption);
QCommandLineOption writeModeOption({ "w", "writemode" }, QCommandLineOption writeModeOption({ "w", "writemode" },
QObject::tr("Open file in write mode")); QObject::tr("Open file in write mode"));
cmd_parser.addOption(writeModeOption); cmd_parser.addOption(writeModeOption);
QCommandLineOption pythonHomeOption(
QCommandLineOption pythonHomeOption("pythonhome", "pythonhome", QObject::tr("PYTHONHOME to use for embedded python interpreter"),
QObject::tr("PYTHONHOME to use for embedded python interpreter"),
"PYTHONHOME"); "PYTHONHOME");
cmd_parser.addOption(pythonHomeOption); cmd_parser.addOption(pythonHomeOption);
QCommandLineOption disableRedirectOption("no-output-redirect", QCommandLineOption disableRedirectOption(
"no-output-redirect",
QObject::tr("Disable output redirection." QObject::tr("Disable output redirection."
" Some of the output in console widget will not be visible." " Some of the output in console widget will not be visible."
" Use this option when debuging a crash or freeze and output " " Use this option when debuging a crash or freeze and output "
" redirection is causing some messages to be lost.")); " redirection is causing some messages to be lost."));
cmd_parser.addOption(disableRedirectOption); cmd_parser.addOption(disableRedirectOption);
QCommandLineOption disablePlugins("no-plugins", QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
QObject::tr("Do not load plugins"));
cmd_parser.addOption(disablePlugins); cmd_parser.addOption(disablePlugins);
QCommandLineOption disableCutterPlugins("no-cutter-plugins", QCommandLineOption disableCutterPlugins("no-cutter-plugins",
@ -366,7 +369,9 @@ bool CutterApplication::parseCommandLineOptions()
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) { if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
fprintf(stderr, "%s\n", fprintf(stderr, "%s\n",
QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData()); QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.")
.toLocal8Bit()
.constData());
return false; return false;
} }
switch (analLevel) { switch (analLevel) {
@ -384,7 +389,9 @@ bool CutterApplication::parseCommandLineOptions()
if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) { if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) {
fprintf(stderr, "%s\n", fprintf(stderr, "%s\n",
QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData()); QObject::tr("Filename must be specified to start analysis automatically.")
.toLocal8Bit()
.constData());
return false; return false;
} }
@ -439,7 +446,6 @@ bool CutterApplication::parseCommandLineOptions()
return true; return true;
} }
void CutterProxyStyle::polish(QWidget *widget) void CutterProxyStyle::polish(QWidget *widget)
{ {
QProxyStyle::polish(widget); QProxyStyle::polish(widget);

View File

@ -8,11 +8,10 @@
#include "core/MainWindow.h" #include "core/MainWindow.h"
enum class AutomaticAnalysisLevel { enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA };
Ask, None, AAA, AAAA
};
struct CutterCommandLineOptions { struct CutterCommandLineOptions
{
QStringList args; QStringList args;
AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask; AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask;
InitialOptions fileOpenOptions; InitialOptions fileOpenOptions;
@ -30,12 +29,10 @@ public:
CutterApplication(int &argc, char **argv); CutterApplication(int &argc, char **argv);
~CutterApplication(); ~CutterApplication();
MainWindow *getMainWindow() MainWindow *getMainWindow() { return mainWindow; }
{
return mainWindow;
}
void launchNewInstance(const QStringList &args = {}); void launchNewInstance(const QStringList &args = {});
protected: protected:
bool event(QEvent *e); bool event(QEvent *e);
@ -50,13 +47,13 @@ private:
* @return false if options have error * @return false if options have error
*/ */
bool parseCommandLineOptions(); bool parseCommandLineOptions();
private: private:
bool m_FileAlreadyDropped; bool m_FileAlreadyDropped;
MainWindow *mainWindow; MainWindow *mainWindow;
CutterCommandLineOptions clOptions; CutterCommandLineOptions clOptions;
}; };
/** /**
* @brief CutterProxyStyle is used to force shortcuts displaying in context menu * @brief CutterProxyStyle is used to force shortcuts displaying in context menu
*/ */

View File

@ -10,7 +10,6 @@
#include <QJsonArray> #include <QJsonArray>
#include <iostream> #include <iostream>
/** /**
* @brief Attempt to connect to a parent console and configure outputs. * @brief Attempt to connect to a parent console and configure outputs.
* *
@ -51,7 +50,6 @@ static void connectToConsole()
} }
#endif #endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#ifdef CUTTER_ENABLE_CRASH_REPORTS #ifdef CUTTER_ENABLE_CRASH_REPORTS
@ -77,11 +75,13 @@ int main(int argc, char *argv[])
Cutter::initializeSettings(); Cutter::initializeSettings();
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins QCoreApplication::setAttribute(
Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) # if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
# endif # endif
#endif #endif
@ -94,7 +94,8 @@ int main(int argc, char *argv[])
UpdateWorker *updateWorker = new UpdateWorker; UpdateWorker *updateWorker = new UpdateWorker;
QObject::connect(updateWorker, &UpdateWorker::checkComplete, QObject::connect(updateWorker, &UpdateWorker::checkComplete,
[=](const QVersionNumber &version, const QString &error) { [=](const QVersionNumber &version, const QString &error) {
if (error.isEmpty() && version > UpdateWorker::currentVersionNumber()) { if (error.isEmpty()
&& version > UpdateWorker::currentVersionNumber()) {
updateWorker->showUpdateDialog(true); updateWorker->showUpdateDialog(true);
} }
updateWorker->deleteLater(); updateWorker->deleteLater();

View File

@ -4,8 +4,8 @@
#include <stdexcept> #include <stdexcept>
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel, AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
QObject *parent) : QObject *parent)
AddressableItemModel<QSortFilterProxyModel>(parent) : AddressableItemModel<QSortFilterProxyModel>(parent)
{ {
setSourceModel(sourceModel); setSourceModel(sourceModel);
addressableSourceModel = sourceModel; addressableSourceModel = sourceModel;

View File

@ -17,7 +17,11 @@ public:
* @param index item intex * @param index item intex
* @return Item name or empty QString if item doesn't have short descriptive name. * @return Item name or empty QString if item doesn't have short descriptive name.
*/ */
virtual QString name(const QModelIndex &index) const { Q_UNUSED(index) return QString(); } virtual QString name(const QModelIndex &index) const
{
Q_UNUSED(index)
return QString();
}
virtual QAbstractItemModel *asItemModel() = 0; virtual QAbstractItemModel *asItemModel() = 0;
}; };
@ -26,6 +30,7 @@ class CUTTER_EXPORT AddressableItemModel : public ParentModel, public Addressab
{ {
static_assert(std::is_base_of<QAbstractItemModel, ParentModel>::value, static_assert(std::is_base_of<QAbstractItemModel, ParentModel>::value,
"ParentModel needs to inherit from QAbstractItemModel"); "ParentModel needs to inherit from QAbstractItemModel");
public: public:
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {} explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
virtual ~AddressableItemModel() {} virtual ~AddressableItemModel() {}
@ -35,12 +40,14 @@ public:
class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel> class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
{ {
using ParentClass = AddressableItemModel<QSortFilterProxyModel>; using ParentClass = AddressableItemModel<QSortFilterProxyModel>;
public: public:
AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent); AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent);
RVA address(const QModelIndex &index) const override; RVA address(const QModelIndex &index) const override;
QString name(const QModelIndex &) const override; QString name(const QModelIndex &) const override;
void setSourceModel(AddressableItemModelI *sourceModel); void setSourceModel(AddressableItemModelI *sourceModel);
private: private:
void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly
AddressableItemModelI *addressableSourceModel; AddressableItemModelI *addressableSourceModel;

View File

@ -6,14 +6,9 @@
#include <QDebug> #include <QDebug>
#include <QCheckBox> #include <QCheckBox>
AnalTask::AnalTask() : AnalTask::AnalTask() : AsyncTask() {}
AsyncTask()
{
}
AnalTask::~AnalTask() AnalTask::~AnalTask() {}
{
}
void AnalTask::interrupt() void AnalTask::interrupt()
{ {
@ -21,7 +16,8 @@ void AnalTask::interrupt()
rz_cons_singleton()->context->breaked = true; rz_cons_singleton()->context->breaked = true;
} }
QString AnalTask::getTitle() { QString AnalTask::getTitle()
{
// If no file is loaded we consider it's Initial Analysis // If no file is loaded we consider it's Initial Analysis
QJsonArray openedFiles = Core()->getOpenedFiles(); QJsonArray openedFiles = Core()->getOpenedFiles();
if (!openedFiles.size()) { if (!openedFiles.size()) {
@ -36,7 +32,6 @@ void AnalTask::runTask()
if (options.writeEnabled) { if (options.writeEnabled) {
perms |= RZ_PERM_W; perms |= RZ_PERM_W;
emit Core()->ioModeChanged(); emit Core()->ioModeChanged();
} }
// Demangle (must be before file Core()->loadFile) // Demangle (must be before file Core()->loadFile)
@ -47,13 +42,9 @@ void AnalTask::runTask()
if (!openedFiles.size() && options.filename.length()) { if (!openedFiles.size() && options.filename.length()) {
log(tr("Loading the file...")); log(tr("Loading the file..."));
openFailed = false; openFailed = false;
bool fileLoaded = Core()->loadFile(options.filename, bool fileLoaded =
options.binLoadAddr, Core()->loadFile(options.filename, options.binLoadAddr, options.mapAddr, perms,
options.mapAddr, options.useVA, options.loadBinInfo, options.forceBinPlugin);
perms,
options.useVA,
options.loadBinInfo,
options.forceBinPlugin);
if (!fileLoaded) { if (!fileLoaded) {
// Something wrong happened, fallback to open dialog // Something wrong happened, fallback to open dialog
openFailed = true; openFailed = true;

View File

@ -1,9 +1,7 @@
#include "AsyncTask.h" #include "AsyncTask.h"
AsyncTask::AsyncTask() AsyncTask::AsyncTask() : QObject(nullptr), QRunnable()
: QObject(nullptr),
QRunnable()
{ {
setAutoDelete(false); setAutoDelete(false);
running = false; running = false;
@ -64,15 +62,12 @@ void AsyncTask::log(QString s)
emit logChanged(logBuffer); emit logChanged(logBuffer);
} }
AsyncTaskManager::AsyncTaskManager(QObject *parent) AsyncTaskManager::AsyncTaskManager(QObject *parent) : QObject(parent)
: QObject(parent)
{ {
threadPool = new QThreadPool(this); threadPool = new QThreadPool(this);
} }
AsyncTaskManager::~AsyncTaskManager() AsyncTaskManager::~AsyncTaskManager() {}
{
}
void AsyncTaskManager::start(AsyncTask::Ptr task) void AsyncTaskManager::start(AsyncTask::Ptr task)
{ {

View File

@ -78,5 +78,4 @@ signals:
void tasksChanged(); void tasksChanged();
}; };
#endif // ASYNCTASK_H #endif // ASYNCTASK_H

View File

@ -1,8 +1,6 @@
#include "BasicBlockHighlighter.h" #include "BasicBlockHighlighter.h"
BasicBlockHighlighter::BasicBlockHighlighter() BasicBlockHighlighter::BasicBlockHighlighter() {}
{
}
BasicBlockHighlighter::~BasicBlockHighlighter() BasicBlockHighlighter::~BasicBlockHighlighter()
{ {

View File

@ -6,7 +6,8 @@ class BasicBlockHighlighter;
#include "Cutter.h" #include "Cutter.h"
#include <map> #include <map>
struct BasicBlock { struct BasicBlock
{
RVA address; RVA address;
QColor color; QColor color;
}; };

View File

@ -5,7 +5,8 @@
#include <map> #include <map>
#include <QColor> #include <QColor>
struct BasicInstruction { struct BasicInstruction
{
RVA address; RVA address;
RVA size; RVA size;
QColor color; QColor color;

View File

@ -11,13 +11,13 @@
#include <cstdint> #include <cstdint>
#include <algorithm> #include <algorithm>
/** /**
* Not really a segment tree for storing segments as referred in academic literature. Can be considered a * Not really a segment tree for storing segments as referred in academic literature. Can be
* full, almost perfect, augmented binary tree. In the context of competitive programming often called segment tree. * considered a full, almost perfect, augmented binary tree. In the context of competitive
* programming often called segment tree.
* *
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left, NodeType& right) * Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left,
* method which calculates inner node values from children nodes. * NodeType& right) method which calculates inner node values from children nodes.
* *
* \tparam NodeTypeT type of each tree element * \tparam NodeTypeT type of each tree element
* \tparam FinalType final child class used for curiously recurring template pattern * \tparam FinalType final child class used for curiously recurring template pattern
@ -33,11 +33,7 @@ public:
* @brief Create tree with \a size leaves. * @brief Create tree with \a size leaves.
* @param size number of leaves in the tree * @param size number of leaves in the tree
*/ */
explicit SegmentTreeBase(size_t size) explicit SegmentTreeBase(size_t size) : size(size), nodeCount(2 * size), nodes(nodeCount) {}
: size(size)
, nodeCount(2 * size)
, nodes(nodeCount)
{}
/** /**
* @brief Create a tree with given size and initial value. * @brief Create a tree with given size and initial value.
@ -46,38 +42,23 @@ public:
* @param size number of leaves * @param size number of leaves
* @param initialValue initial leave value * @param initialValue initial leave value
*/ */
SegmentTreeBase(size_t size, const NodeType &initialValue) SegmentTreeBase(size_t size, const NodeType &initialValue) : SegmentTreeBase(size)
: SegmentTreeBase(size)
{ {
init(initialValue); init(initialValue);
} }
protected: protected:
// Curiously recurring template pattern // Curiously recurring template pattern
FinalType &This() FinalType &This() { return static_cast<FinalType &>(*this); }
{
return static_cast<FinalType &>(*this);
}
// Curiously recurring template pattern // Curiously recurring template pattern
const FinalType &This() const const FinalType &This() const { return static_cast<const FinalType &>(*this); }
{
return static_cast<const FinalType &>(*this);
}
size_t leavePositionToIndex(NodePosition pos) const size_t leavePositionToIndex(NodePosition pos) const { return pos - size; }
{
return pos - size;
}
NodePosition leaveIndexToPosition(size_t index) const NodePosition leaveIndexToPosition(size_t index) const { return index + size; }
{
return index + size;
}
bool isLeave(NodePosition position) const bool isLeave(NodePosition position) const { return position >= size; }
{
return position >= size;
}
/** /**
* @brief Calculate inner node values from leaves. * @brief Calculate inner node values from leaves.
@ -111,6 +92,7 @@ template<class NodeType, class FinalType>
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType> class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
{ {
using BaseType = SegmentTreeBase<NodeType, FinalType>; using BaseType = SegmentTreeBase<NodeType, FinalType>;
public: public:
using BaseType::BaseType; using BaseType::BaseType;
@ -125,7 +107,8 @@ public:
this->nodes[pos] = value; this->nodes[pos] = value;
while (pos > 1) { while (pos > 1) {
auto parrent = pos >> 1; auto parrent = pos >> 1;
this->This().updateFromChildren(this->nodes[parrent], this->nodes[pos], this->nodes[pos ^ 1]); this->This().updateFromChildren(this->nodes[parrent], this->nodes[pos],
this->nodes[pos ^ 1]);
pos = parrent; pos = parrent;
} }
} }
@ -141,6 +124,7 @@ public:
class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree> class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree>
{ {
using BaseType = PointSetSegmentTree<int, PointSetMinTree>; using BaseType = PointSetSegmentTree<int, PointSetMinTree>;
public: public:
using NodeType = int; using NodeType = int;
@ -159,16 +143,15 @@ public:
*/ */
int rightMostLessThan(size_t position, int value) int rightMostLessThan(size_t position, int value)
{ {
auto isGood = [&](size_t pos) { auto isGood = [&](size_t pos) { return nodes[pos] < value; };
return nodes[pos] < value;
};
// right side exclusive range [l;r) // right side exclusive range [l;r)
size_t goodSubtree = 0; size_t goodSubtree = 0;
for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r; for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r;
l >>= 1, r >>= 1) { l >>= 1, r >>= 1) {
if (l & 1) { if (l & 1) {
if (isGood(l)) { if (isGood(l)) {
// mark subtree as good but don't stop yet, there might be something good further to the right // mark subtree as good but don't stop yet, there might be something good
// further to the right
goodSubtree = l; goodSubtree = l;
} }
++l; ++l;
@ -202,9 +185,7 @@ public:
*/ */
int leftMostLessThan(size_t position, int value) int leftMostLessThan(size_t position, int value)
{ {
auto isGood = [&](size_t pos) { auto isGood = [&](size_t pos) { return nodes[pos] < value; };
return nodes[pos] < value;
};
// right side exclusive range [l;r) // right side exclusive range [l;r)
size_t goodSubtree = 0; size_t goodSubtree = 0;
for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r; for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r;
@ -220,7 +201,8 @@ public:
--r; --r;
if (isGood(r)) { if (isGood(r)) {
goodSubtree = r; goodSubtree = r;
// mark subtree as good but don't stop yet, there might be something good further to the left // mark subtree as good but don't stop yet, there might be something good
// further to the left
} }
} }
} }
@ -241,10 +223,11 @@ public:
/** /**
* \brief Tree that supports lazily applying an operation to range. * \brief Tree that supports lazily applying an operation to range.
* *
* Each inner node has a promise value describing an operation that needs to be applied to corresponding subtree. * Each inner node has a promise value describing an operation that needs to be applied to
* corresponding subtree.
* *
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies the applies the * Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies
* operation stored in \a promise for nodePosition to the direct children nodes. * the applies the operation stored in \a promise for nodePosition to the direct children nodes.
* *
* \tparam NodeType type of tree nodes * \tparam NodeType type of tree nodes
* \tparam PromiseType type describing operation that needs to be applied to subtree * \tparam PromiseType type describing operation that needs to be applied to subtree
@ -254,15 +237,14 @@ template <class NodeType, class PromiseType, class FinalType>
class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType> class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType>
{ {
using BaseType = SegmentTreeBase<NodeType, FinalType>; using BaseType = SegmentTreeBase<NodeType, FinalType>;
public: public:
/** /**
* @param size Number of tree leaves. * @param size Number of tree leaves.
* @param neutralPromise Promise value that doesn't modify tree nodes. * @param neutralPromise Promise value that doesn't modify tree nodes.
*/ */
LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise) LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise)
: BaseType(size) : BaseType(size), neutralPromiseElement(neutralPromise), promise(size, neutralPromise)
, neutralPromiseElement(neutralPromise)
, promise(size, neutralPromise)
{ {
h = 0; h = 0;
size_t v = size; size_t v = size;
@ -324,7 +306,8 @@ protected:
while (p > 1) { while (p > 1) {
auto parent = p >> 1; auto parent = p >> 1;
if (promise[parent] == neutralPromiseElement) { if (promise[parent] == neutralPromiseElement) {
This().updateFromChildren(this->nodes[parent], this->nodes[p & ~size_t(1)], this->nodes[p | 1]); This().updateFromChildren(this->nodes[parent], this->nodes[p & ~size_t(1)],
this->nodes[p | 1]);
} }
p = parent; p = parent;
} }
@ -337,19 +320,16 @@ protected:
std::vector<PromiseType> promise; std::vector<PromiseType> promise;
}; };
/** /**
* @brief Structure supporting range assignment and range maximum operations. * @brief Structure supporting range assignment and range maximum operations.
*/ */
class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree> class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>
{ {
using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>; using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>;
public: public:
using ValueType = int; using ValueType = int;
RangeAssignMaxTree(size_t size, ValueType initialValue) RangeAssignMaxTree(size_t size, ValueType initialValue) : BaseType(size, initialValue, 0) {}
: BaseType(size, initialValue, 0)
{
}
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right) void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
{ {

View File

@ -10,10 +10,8 @@ void openIssue()
{ {
QString url, osInfo, format, arch, type; QString url, osInfo, format, arch, type;
// Pull in info needed for git issue // Pull in info needed for git issue
osInfo = QSysInfo::productType() + " " + osInfo = QSysInfo::productType() + " "
(QSysInfo::productVersion() == "unknown" + (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
? ""
: QSysInfo::productVersion());
QJsonDocument docu = Core()->getFileInfo(); QJsonDocument docu = Core()->getFileInfo();
QJsonObject coreObj = docu.object()["core"].toObject(); QJsonObject coreObj = docu.object()["core"].toObject();
QJsonObject binObj = docu.object()["bin"].toObject(); QJsonObject binObj = docu.object()["bin"].toObject();
@ -30,12 +28,14 @@ void openIssue()
arch = "N/A"; arch = "N/A";
type = "N/A"; type = "N/A";
} }
url = url = "https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* "
"https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* Operating System: " "Operating System: "
+ osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL + + osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL + "\n* File format: " + format
"\n* File format: " + format + "\n * Arch: " + arch + "\n * Type: " + type + + "\n * Arch: " + arch + "\n * Type: " + type
"\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\n" + "\n\n**Describe the bug**\nA clear and concise description of what the bug "
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n" "is.\n\n**To Reproduce**\n"
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll "
"down to '....'\n"
"4. See error\n\n**Expected behavior**\n" "4. See error\n\n**Expected behavior**\n"
"A clear and concise description of what you expected to happen.\n\n" "A clear and concise description of what you expected to happen.\n\n"
"**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n" "**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n"

View File

@ -11,8 +11,7 @@ template<typename T>
class CachedFontMetrics class CachedFontMetrics
{ {
public: public:
explicit CachedFontMetrics(const QFont &font) explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font)
: mFontMetrics(font)
{ {
memset(mWidths, 0, sizeof(mWidths)); memset(mWidths, 0, sizeof(mWidths));
mHeight = mFontMetrics.height(); mHeight = mFontMetrics.height();
@ -49,10 +48,7 @@ public:
return result; return result;
} }
T height() T height() { return mHeight; }
{
return mHeight;
}
T position(const QString &text, T offset) T position(const QString &text, T offset)
{ {

View File

@ -10,51 +10,21 @@
#include "common/Configuration.h" #include "common/Configuration.h"
const QStringList ColorThemeWorker::cutterSpecificOptions = { const QStringList ColorThemeWorker::cutterSpecificOptions = {
"wordHighlight", "wordHighlight", "lineHighlight", "gui.main",
"lineHighlight", "gui.imports", "highlightPC", "gui.navbar.err",
"gui.main", "gui.navbar.seek", "gui.navbar.pc", "gui.navbar.sym",
"gui.imports", "gui.dataoffset", "gui.navbar.code", "gui.navbar.empty",
"highlightPC", "angui.navbar.str", "gui.disass_selected", "gui.breakpoint_background",
"gui.navbar.err", "gui.overview.node", "gui.overview.fill", "gui.overview.border",
"gui.navbar.seek", "gui.border", "gui.background", "gui.alt_background",
"gui.navbar.pc",
"gui.navbar.sym",
"gui.dataoffset",
"gui.navbar.code",
"gui.navbar.empty",
"angui.navbar.str",
"gui.disass_selected",
"gui.breakpoint_background",
"gui.overview.node",
"gui.overview.fill",
"gui.overview.border",
"gui.border",
"gui.background",
"gui.alt_background",
"gui.disass_selected" "gui.disass_selected"
}; };
const QStringList ColorThemeWorker::rizinUnusedOptions = { const QStringList ColorThemeWorker::rizinUnusedOptions = {
"linehl", "linehl", "wordhl", "graph.box", "graph.box2", "graph.box3",
"wordhl", "graph.box4", "graph.current", "graph.box2", "widget_sel", "widget_bg",
"graph.box", "label", "ai.write", "invalid", "ai.seq", "args",
"graph.box2", "ai.read", "ai.exec", "ai.ascii", "prompt", "graph.traced"
"graph.box3",
"graph.box4",
"graph.current",
"graph.box2",
"widget_sel",
"widget_bg",
"label",
"ai.write",
"invalid",
"ai.seq",
"args",
"ai.read",
"ai.exec",
"ai.ascii",
"prompt",
"graph.traced"
}; };
ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent) ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
@ -66,20 +36,16 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject (parent)
QDir().mkpath(customRzThemesLocationPath); QDir().mkpath(customRzThemesLocationPath);
} }
QDir currDir { QStringLiteral("%1%2%3") QDir currDir {
.arg(rz_sys_prefix(nullptr)) QStringLiteral("%1%2%3").arg(rz_sys_prefix(nullptr)).arg(RZ_SYS_DIR).arg(RZ_THEMES)
.arg(RZ_SYS_DIR)
.arg(RZ_THEMES)
}; };
if (currDir.exists()) { if (currDir.exists()) {
standardRzThemesLocationPath = currDir.absolutePath(); standardRzThemesLocationPath = currDir.absolutePath();
} else { } else {
QMessageBox::critical(nullptr, QMessageBox::critical(nullptr, tr("Standard themes not found"),
tr("Standard themes not found"),
tr("The Rizin standard themes could not be found in '%1'. " tr("The Rizin standard themes could not be found in '%1'. "
"Most likely, Rizin is not properly installed.") "Most likely, Rizin is not properly installed.")
.arg(currDir.path()) .arg(currDir.path()));
);
} }
} }
@ -102,12 +68,10 @@ QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) c
return res; return res;
} }
QString ColorThemeWorker::copy(const QString &srcThemeName, QString ColorThemeWorker::copy(const QString &srcThemeName, const QString &copyThemeName) const
const QString &copyThemeName) const
{ {
if (!isThemeExist(srcThemeName)) { if (!isThemeExist(srcThemeName)) {
return tr("Theme <b>%1</b> does not exist.") return tr("Theme <b>%1</b> does not exist.").arg(srcThemeName);
.arg(srcThemeName);
} }
return save(getTheme(srcThemeName), copyThemeName); return save(getTheme(srcThemeName), copyThemeName);
@ -117,8 +81,7 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
{ {
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName)); QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) { if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
return tr("The file <b>%1</b> cannot be opened.") return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
.arg(QFileInfo(fOut).filePath());
} }
QJsonObject obj = theme.object(); QJsonObject obj = theme.object();
@ -198,7 +161,9 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
} }
QStringList sl; QStringList sl;
for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) { for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
sl = line.replace("#~", "ec ").replace("rgb:", "#").split(' ', CUTTER_QT_SKIP_EMPTY_PARTS); sl = line.replace("#~", "ec ")
.replace("rgb:", "#")
.split(' ', CUTTER_QT_SKIP_EMPTY_PARTS);
if (sl.size() != 3 || sl[0][0] == '#') { if (sl.size() != 3 || sl[0][0] == '#') {
continue; continue;
} }
@ -213,7 +178,8 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
// manualy converting instead of using QJsonObject::fromVariantMap because // manualy converting instead of using QJsonObject::fromVariantMap because
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain // Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
// QJson values like QJsonArray. https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672 // QJson values like QJsonArray.
// https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
QJsonObject obj; QJsonObject obj;
for (auto it = theme.begin(); it != theme.end(); it++) { for (auto it = theme.begin(); it != theme.end(); it++) {
auto &value = it.value(); auto &value = it.value();
@ -222,7 +188,6 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
} else { } else {
obj[it.key()] = QJsonValue::fromVariant(value); obj[it.key()] = QJsonValue::fromVariant(value);
} }
} }
return QJsonDocument(obj); return QJsonDocument(obj);
@ -239,16 +204,13 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const
QFile file(QDir(customRzThemesLocationPath).filePath(themeName)); QFile file(QDir(customRzThemesLocationPath).filePath(themeName));
if (file.isWritable()) { if (file.isWritable()) {
return tr("You have no permission to write to <b>%1</b>") return tr("You have no permission to write to <b>%1</b>").arg(QFileInfo(file).filePath());
.arg(QFileInfo(file).filePath());
} }
if (!file.open(QFile::ReadOnly)) { if (!file.open(QFile::ReadOnly)) {
return tr("File <b>%1</b> can not be opened.") return tr("File <b>%1</b> can not be opened.").arg(QFileInfo(file).filePath());
.arg(QFileInfo(file).filePath());
} }
if (!file.remove()) { if (!file.remove()) {
return tr("File <b>%1</b> can not be removed.") return tr("File <b>%1</b> can not be removed.").arg(QFileInfo(file).filePath());
.arg(QFileInfo(file).filePath());
} }
return ""; return "";
} }
@ -299,7 +261,8 @@ QString ColorThemeWorker::renameTheme(const QString& themeName, const QString& n
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName)); bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
if (!ok) { if (!ok) {
return tr("Something went wrong during renaming. " return tr("Something went wrong during renaming. "
"Please make sure you have access to the directory <b>\"%1\"</b>.").arg(dir.path()); "Please make sure you have access to the directory <b>\"%1\"</b>.")
.arg(dir.path());
} }
return ""; return "";
} }
@ -317,7 +280,9 @@ bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
.join('|') .join('|')
.replace(".", "\\."); .replace(".", "\\.");
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options).arg(colors); QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
.arg(options)
.arg(colors);
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before // The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
QRegularExpression regexp("\\A(?:" + pattern + ")\\z"); QRegularExpression regexp("\\A(?:" + pattern + ")\\z");

View File

@ -40,7 +40,6 @@ public:
virtual ~ColorThemeWorker() {} virtual ~ColorThemeWorker() {}
/** /**
* @brief Copies @a srcThemeName with name @a copyThemeName. * @brief Copies @a srcThemeName with name @a copyThemeName.
* @param srcThemeName * @param srcThemeName
@ -62,7 +61,8 @@ public:
QString save(const QJsonDocument &theme, const QString &themeName) const; QString save(const QJsonDocument &theme, const QString &themeName) const;
/** /**
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or not. * @brief Returns whether or not @a themeName theme is custom (created by user or imported) or
* not.
* @param themeName * @param themeName
* Name of theme to check. * Name of theme to check.
*/ */
@ -75,7 +75,8 @@ public:
bool isThemeExist(const QString &name) const; bool isThemeExist(const QString &name) const;
/** /**
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red, Green, Blue). * @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red,
* Green, Blue).
* @param themeName * @param themeName
* Theme to get. * Theme to get.
*/ */

View File

@ -1,11 +1,7 @@
#include "Colors.h" #include "Colors.h"
#include "common/Configuration.h" #include "common/Configuration.h"
Colors::Colors() Colors::Colors() {}
{
}
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num) void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
{ {
@ -101,4 +97,3 @@ QString Colors::getColor(ut64 type)
return "invalid"; return "invalid";
} }
} }

View File

@ -7,7 +7,8 @@ CommandTask::CommandTask(const QString &cmd, ColorMode colorMode, bool outFormat
{ {
} }
void CommandTask::runTask() { void CommandTask::runTask()
{
TempConfig tempConfig; TempConfig tempConfig;
tempConfig.set("scr.color", colorMode); tempConfig.set("scr.color", colorMode);
auto res = Core()->cmdTask(cmd); auto res = Core()->cmdTask(cmd);

View File

@ -10,9 +10,15 @@ class CUTTER_EXPORT CommandTask : public AsyncTask
Q_OBJECT Q_OBJECT
public: public:
enum ColorMode {DISABLED=COLOR_MODE_DISABLED, MODE_16=COLOR_MODE_16, MODE_256=COLOR_MODE_256, MODE_16M=COLOR_MODE_16M}; enum ColorMode {
DISABLED = COLOR_MODE_DISABLED,
MODE_16 = COLOR_MODE_16,
MODE_256 = COLOR_MODE_256,
MODE_16M = COLOR_MODE_16M
};
CommandTask(const QString &cmd, ColorMode colorMode=ColorMode::DISABLED, bool outFormatHtml=false); CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED,
bool outFormatHtml = false);
QString getTitle() override { return tr("Running Command"); } QString getTitle() override { return tr("Running Command"); }

View File

@ -21,75 +21,71 @@
* and for light - only light ones. * and for light - only light ones.
*/ */
const QHash<QString, ColorFlags> Configuration::relevantThemes = { const QHash<QString, ColorFlags> Configuration::relevantThemes = {
{ "ayu", DarkFlag }, { "ayu", DarkFlag }, { "consonance", DarkFlag }, { "darkda", DarkFlag },
{ "consonance", DarkFlag }, { "onedark", DarkFlag }, { "solarized", DarkFlag }, { "zenburn", DarkFlag },
{ "darkda", DarkFlag }, { "cutter", LightFlag }, { "dark", LightFlag }, { "matrix", LightFlag },
{ "onedark", DarkFlag }, { "tango", LightFlag }, { "white", LightFlag }
{ "solarized", DarkFlag },
{ "zenburn", DarkFlag },
{ "cutter", LightFlag },
{ "dark", LightFlag },
{ "matrix", LightFlag },
{ "tango", LightFlag },
{ "white", LightFlag }
}; };
static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter"; static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter";
static const QString DEFAULT_DARK_COLOR_THEME = "ayu"; static const QString DEFAULT_DARK_COLOR_THEME = "ayu";
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = { const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
{ "gui.cflow", { { DarkFlag, QColor(0xff, 0xff, 0xff) }, { "gui.cflow",
{ LightFlag, QColor(0x00, 0x00, 0x00) }} }, { { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
{ "gui.dataoffset", { { DarkFlag, QColor(0xff, 0xff, 0xff) }, { "gui.dataoffset",
{ LightFlag, QColor(0x00, 0x00, 0x00) }} }, { { DarkFlag, QColor(0xff, 0xff, 0xff) }, { LightFlag, QColor(0x00, 0x00, 0x00) } } },
{ "gui.imports", { { DarkFlag, QColor(0x32, 0x8c, 0xff) }, { "gui.imports",
{ LightFlag, QColor(0x32, 0x8c, 0xff) }} }, { { DarkFlag, QColor(0x32, 0x8c, 0xff) }, { LightFlag, QColor(0x32, 0x8c, 0xff) } } },
{ "gui.item_invalid", { { DarkFlag, QColor(0x9b, 0x9b, 0x9b) }, { "gui.item_invalid",
{ LightFlag, QColor(0x9b, 0x9b, 0x9b) }} }, { { DarkFlag, QColor(0x9b, 0x9b, 0x9b) }, { LightFlag, QColor(0x9b, 0x9b, 0x9b) } } },
{ "gui.main", { { DarkFlag, QColor(0x00, 0x80, 0x00) }, { "gui.main",
{ LightFlag, QColor(0x00, 0x80, 0x00) }} }, { { DarkFlag, QColor(0x00, 0x80, 0x00) }, { LightFlag, QColor(0x00, 0x80, 0x00) } } },
{ "gui.item_unsafe", { { DarkFlag, QColor(0xff, 0x81, 0x7b) }, { "gui.item_unsafe",
{ LightFlag, QColor(0xff, 0x81, 0x7b) }} }, { { DarkFlag, QColor(0xff, 0x81, 0x7b) }, { LightFlag, QColor(0xff, 0x81, 0x7b) } } },
{ "gui.navbar.seek", { { DarkFlag, QColor(0xe9, 0x56, 0x56) }, { "gui.navbar.seek",
{ LightFlag, QColor(0xff, 0x00, 0x00) }} }, { { DarkFlag, QColor(0xe9, 0x56, 0x56) }, { LightFlag, QColor(0xff, 0x00, 0x00) } } },
{ "gui.navbar.pc", { { DarkFlag, QColor(0x42, 0xee, 0xf4) }, { "gui.navbar.pc",
{ LightFlag, QColor(0x42, 0xee, 0xf4) }} }, { { DarkFlag, QColor(0x42, 0xee, 0xf4) }, { LightFlag, QColor(0x42, 0xee, 0xf4) } } },
{ "gui.navbar.code", { { DarkFlag, QColor(0x82, 0xc8, 0x6f) }, { "gui.navbar.code",
{ LightFlag, QColor(0x68, 0xe5, 0x45) }} }, { { DarkFlag, QColor(0x82, 0xc8, 0x6f) }, { LightFlag, QColor(0x68, 0xe5, 0x45) } } },
{ "gui.navbar.str", { { DarkFlag, QColor(0x6f, 0x86, 0xd8) }, { "gui.navbar.str",
{ LightFlag, QColor(0x45, 0x68, 0xe5) }} }, { { DarkFlag, QColor(0x6f, 0x86, 0xd8) }, { LightFlag, QColor(0x45, 0x68, 0xe5) } } },
{ "gui.navbar.sym", { { DarkFlag, QColor(0xdd, 0xa3, 0x68) }, { "gui.navbar.sym",
{ LightFlag, QColor(0xe5, 0x96, 0x45) }} }, { { DarkFlag, QColor(0xdd, 0xa3, 0x68) }, { LightFlag, QColor(0xe5, 0x96, 0x45) } } },
{ "gui.navbar.empty", { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { "gui.navbar.empty",
{ LightFlag, QColor(0xdc, 0xec, 0xf5) }} }, { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xdc, 0xec, 0xf5) } } },
{ "gui.breakpoint_background", { { DarkFlag, QColor(0x8c, 0x4c, 0x4c) }, { "gui.breakpoint_background",
{ LightFlag, QColor(0xe9, 0x8f, 0x8f) }} }, { { DarkFlag, QColor(0x8c, 0x4c, 0x4c) }, { LightFlag, QColor(0xe9, 0x8f, 0x8f) } } },
{ "gui.overview.node", { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { "gui.overview.node",
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} }, { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
{ "gui.tooltip.background", { { DarkFlag, QColor(0x2a, 0x2c, 0x2e) }, { "gui.tooltip.background",
{ LightFlag, QColor(0xfa, 0xfc, 0xfe) }} }, { { DarkFlag, QColor(0x2a, 0x2c, 0x2e) }, { LightFlag, QColor(0xfa, 0xfc, 0xfe) } } },
{ "gui.tooltip.foreground", { { DarkFlag, QColor(0xfa, 0xfc, 0xfe) }, { "gui.tooltip.foreground",
{ LightFlag, QColor(0x2a, 0x2c, 0x2e) }} }, { { DarkFlag, QColor(0xfa, 0xfc, 0xfe) }, { LightFlag, QColor(0x2a, 0x2c, 0x2e) } } },
{ "gui.border", { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { "gui.border",
{ LightFlag, QColor(0x91, 0xc8, 0xfa) }} }, { { DarkFlag, QColor(0x64, 0x64, 0x64) }, { LightFlag, QColor(0x91, 0xc8, 0xfa) } } },
{ "gui.background", { { DarkFlag, QColor(0x25, 0x28, 0x2b) }, { "gui.background",
{ LightFlag, QColor(0xff, 0xff, 0xff) }} }, { { DarkFlag, QColor(0x25, 0x28, 0x2b) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
{ "gui.alt_background", { { DarkFlag, QColor(0x1c, 0x1f, 0x24) }, { "gui.alt_background",
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} }, { { DarkFlag, QColor(0x1c, 0x1f, 0x24) }, { LightFlag, QColor(0xf5, 0xfa, 0xff) } } },
{ "gui.disass_selected", { { DarkFlag, QColor(0x1f, 0x22, 0x28) }, { "gui.disass_selected",
{ LightFlag, QColor(0xff, 0xff, 0xff) }} }, { { DarkFlag, QColor(0x1f, 0x22, 0x28) }, { LightFlag, QColor(0xff, 0xff, 0xff) } } },
{ "lineHighlight", { { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) }, { "lineHighlight",
{ { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } }, { LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } },
{ "wordHighlight", { { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) }, { "wordHighlight",
{ { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) } } }, { LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) } } },
{ "highlightPC", { { DarkFlag, QColor(0x57, 0x1a, 0x07) }, { "highlightPC",
{ LightFlag, QColor(0xd6, 0xff, 0xd2) }} }, { { DarkFlag, QColor(0x57, 0x1a, 0x07) }, { LightFlag, QColor(0xd6, 0xff, 0xd2) } } },
{ "gui.overview.fill", { { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) }, { "gui.overview.fill",
{ { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) } } }, { LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) } } },
{ "gui.overview.border", { { DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32) }, { "gui.overview.border",
{ { DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32) },
{ LightFlag, QColor(0x63, 0xda, 0xe8, 0x32) } } }, { LightFlag, QColor(0x63, 0xda, 0xe8, 0x32) } } },
{ "gui.navbar.err", { { DarkFlag, QColor(0x03, 0xaa, 0xf5) }, { "gui.navbar.err",
{ LightFlag, QColor(0x03, 0xaa, 0xf5) }} } { { DarkFlag, QColor(0x03, 0xaa, 0xf5) }, { LightFlag, QColor(0x03, 0xaa, 0xf5) } } }
}; };
Configuration *Configuration::mPtr = nullptr; Configuration *Configuration::mPtr = nullptr;
@ -97,8 +93,7 @@ Configuration *Configuration::mPtr = nullptr;
/** /**
* @brief All asm.* options saved as settings. Values are the default values. * @brief All asm.* options saved as settings. Values are the default values.
*/ */
static const QHash<QString, QVariant> asmOptions = { static const QHash<QString, QVariant> asmOptions = { { "asm.esil", false },
{ "asm.esil", false },
{ "asm.pseudo", false }, { "asm.pseudo", false },
{ "asm.offset", true }, { "asm.offset", true },
{ "asm.xrefs", false }, { "asm.xrefs", false },
@ -132,19 +127,16 @@ static const QHash<QString, QVariant> asmOptions = {
{ "asm.reloff", false }, { "asm.reloff", false },
{ "asm.reloff.flags", false }, { "asm.reloff.flags", false },
{ "esil.breakoninvalid", true }, { "esil.breakoninvalid", true },
{ "graph.offset", false} { "graph.offset", false } };
};
Configuration::Configuration() : QObject(), nativePalette(qApp->palette()) Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
{ {
mPtr = this; mPtr = this;
if (!s.isWritable()) { if (!s.isWritable()) {
QMessageBox::critical(nullptr, QMessageBox::critical(
tr("Critical!"), nullptr, tr("Critical!"),
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"") tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
.arg(s.fileName()) .arg(s.fileName()));
);
} }
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING #ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
kSyntaxHighlightingRepository = nullptr; kSyntaxHighlightingRepository = nullptr;
@ -247,8 +239,8 @@ void Configuration::setLocale(const QLocale &l)
*/ */
bool Configuration::setLocaleByName(const QString &language) bool Configuration::setLocaleByName(const QString &language)
{ {
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, const auto &allLocales =
QLocale::AnyCountry); QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
for (auto &it : allLocales) { for (auto &it : allLocales) {
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) { if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
@ -391,26 +383,26 @@ void Configuration::refreshFont()
emit fontsUpdated(); emit fontsUpdated();
} }
qreal Configuration::getZoomFactor() const { qreal Configuration::getZoomFactor() const
{
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>(); qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
return qMax(fontZoom, 0.1); return qMax(fontZoom, 0.1);
} }
void Configuration::setZoomFactor(qreal zoom) { void Configuration::setZoomFactor(qreal zoom)
{
s.setValue("zoomFactor", qMax(zoom, 0.1)); s.setValue("zoomFactor", qMax(zoom, 0.1));
emit fontsUpdated(); emit fontsUpdated();
} }
QString Configuration::getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const QString Configuration::getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const
{ {
return s.value("lastThemeOf." + currInterfaceTheme.name, return s.value("lastThemeOf." + currInterfaceTheme.name, Config()->getColorTheme()).toString();
Config()->getColorTheme()).toString();
} }
void Configuration::setInterfaceTheme(int theme) void Configuration::setInterfaceTheme(int theme)
{ {
if (theme >= cutterInterfaceThemesList().size() || if (theme >= cutterInterfaceThemesList().size() || theme < 0) {
theme < 0) {
theme = 0; theme = 0;
} }
s.setValue("ColorPalette", theme); s.setValue("ColorPalette", theme);
@ -464,8 +456,7 @@ KSyntaxHighlighting::Theme Configuration::getKSyntaxHighlightingTheme()
if (!repo) { if (!repo) {
return KSyntaxHighlighting::Theme(); return KSyntaxHighlighting::Theme();
} }
return repo->defaultTheme( return repo->defaultTheme(getCurrentTheme()->flag & DarkFlag
getCurrentTheme()->flag & DarkFlag
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme ? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme); : KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
} }
@ -487,8 +478,7 @@ QSyntaxHighlighter *Configuration::createSyntaxHighlighter(QTextDocument *docume
QString Configuration::getLogoFile() QString Configuration::getLogoFile()
{ {
return windowColorIsDark() return windowColorIsDark() ? QString(":/img/cutter_white_plain.svg")
? QString(":/img/cutter_white_plain.svg")
: QString(":/img/cutter_plain.svg"); : QString(":/img/cutter_plain.svg");
} }
@ -502,7 +492,8 @@ void Configuration::setColor(const QString &name, const QColor &color)
s.setValue("colors." + name, color); s.setValue("colors." + name, color);
} }
void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme) void Configuration::setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme,
const QString &theme)
{ {
s.setValue("lastThemeOf." + currInterfaceTheme.name, theme); s.setValue("lastThemeOf." + currInterfaceTheme.name, theme);
} }
@ -599,7 +590,6 @@ QVariant Configuration::getConfigVar(const QString &key)
return QVariant(); return QVariant();
} }
bool Configuration::getConfigBool(const QString &key) bool Configuration::getConfigBool(const QString &key)
{ {
return getConfigVar(key).toBool(); return getConfigVar(key).toBool();
@ -644,8 +634,8 @@ QStringList Configuration::getAvailableTranslations()
if (!dir.exists()) { if (!dir.exists()) {
continue; continue;
} }
const QStringList &currTrFileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files, const QStringList &currTrFileNames =
QDir::Name); dir.entryList(QStringList("cutter_*.qm"), QDir::Files, QDir::Name);
for (const auto &trFile : currTrFileNames) { for (const auto &trFile : currTrFileNames) {
fileNamesSet << trFile; fileNamesSet << trFile;
} }
@ -655,16 +645,16 @@ QStringList Configuration::getAvailableTranslations()
std::sort(fileNames.begin(), fileNames.end()); std::sort(fileNames.begin(), fileNames.end());
QStringList languages; QStringList languages;
QString currLanguageName; QString currLanguageName;
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, auto allLocales =
QLocale::AnyCountry); QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
for (auto i : fileNames) { for (auto i : fileNames) {
QString localeName = i.mid(sizeof("cutter_") - 1, 2); QString localeName = i.mid(sizeof("cutter_") - 1, 2);
for (auto j : allLocales) { for (auto j : allLocales) {
if (j.name().startsWith(localeName)) { if (j.name().startsWith(localeName)) {
currLanguageName = j.nativeLanguageName(); currLanguageName = j.nativeLanguageName();
currLanguageName = currLanguageName.at(0).toUpper() + currLanguageName = currLanguageName.at(0).toUpper()
currLanguageName.right(currLanguageName.length() - 1); + currLanguageName.right(currLanguageName.length() - 1);
languages << currLanguageName; languages << currLanguageName;
break; break;
} }

View File

@ -18,18 +18,17 @@ namespace KSyntaxHighlighting {
class QSyntaxHighlighter; class QSyntaxHighlighter;
class QTextDocument; class QTextDocument;
enum ColorFlags { enum ColorFlags {
LightFlag = 1, LightFlag = 1,
DarkFlag = 2, DarkFlag = 2,
}; };
struct CutterInterfaceTheme { struct CutterInterfaceTheme
{
QString name; QString name;
ColorFlags flag; ColorFlags flag;
}; };
class CUTTER_EXPORT Configuration : public QObject class CUTTER_EXPORT Configuration : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -101,10 +100,7 @@ public:
void setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme); void setLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme, const QString &theme);
QString getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const; QString getLastThemeOf(const CutterInterfaceTheme &currInterfaceTheme) const;
void setInterfaceTheme(int theme); void setInterfaceTheme(int theme);
int getInterfaceTheme() int getInterfaceTheme() { return s.value("ColorPalette", 0).toInt(); }
{
return s.value("ColorPalette", 0).toInt();
}
const CutterInterfaceTheme *getCurrentTheme(); const CutterInterfaceTheme *getCurrentTheme();
@ -164,27 +160,16 @@ public:
bool isDecompilerAnnotationHighlighterEnabled(); bool isDecompilerAnnotationHighlighterEnabled();
// Graph // Graph
int getGraphBlockMaxChars() const int getGraphBlockMaxChars() const { return s.value("graph.maxcols", 100).toInt(); }
{ void setGraphBlockMaxChars(int ch) { s.setValue("graph.maxcols", ch); }
return s.value("graph.maxcols", 100).toInt();
}
void setGraphBlockMaxChars(int ch)
{
s.setValue("graph.maxcols", ch);
}
int getGraphMinFontSize() const int getGraphMinFontSize() const { return s.value("graph.minfontsize", 4).toInt(); }
{
return s.value("graph.minfontsize", 4).toInt();
}
void setGraphMinFontSize(int sz) void setGraphMinFontSize(int sz) { s.setValue("graph.minfontsize", sz); }
{
s.setValue("graph.minfontsize", sz);
}
/** /**
* @brief Getters and setters for the transaparent option state and scale factor for bitmap graph exports. * @brief Getters and setters for the transaparent option state and scale factor for bitmap
* graph exports.
*/ */
bool getBitmapTransparentState(); bool getBitmapTransparentState();
double getBitmapExportScaleFactor(); double getBitmapExportScaleFactor();
@ -202,7 +187,8 @@ public:
/** /**
* @brief Enable or disable the displaying of the entry offset in each graph block * @brief Enable or disable the displaying of the entry offset in each graph block
* @param enabled set this to true for displaying the entry offset in each graph block, false otherwise * @param enabled set this to true for displaying the entry offset in each graph block, false
* otherwise
*/ */
void setGraphBlockEntryOffset(bool enabled); void setGraphBlockEntryOffset(bool enabled);

View File

@ -32,11 +32,8 @@ static void finishCrashHandler()
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
// Called if crash dump was successfully created // Called if crash dump was successfully created
// Saves path to file // Saves path to file
bool callback(const wchar_t *_dump_dir, bool callback(const wchar_t *_dump_dir, const wchar_t *_minidump_id, void *context,
const wchar_t *_minidump_id, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool success)
void *context, EXCEPTION_POINTERS *exinfo,
MDRawAssertionInfo *assertion,
bool success)
{ {
const QDir dir = QString::fromWCharArray(_dump_dir); const QDir dir = QString::fromWCharArray(_dump_dir);
const QString id = QString::fromWCharArray(_minidump_id); const QString id = QString::fromWCharArray(_minidump_id);
@ -78,27 +75,20 @@ void initCrashHandler()
// and then moved if needed // and then moved if needed
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString(); static std::string tmpLocation =
exceptionHandler = new google_breakpad::ExceptionHandler(google_breakpad::MinidumpDescriptor(tmpLocation), QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
nullptr, exceptionHandler = new google_breakpad::ExceptionHandler(
callback, google_breakpad::MinidumpDescriptor(tmpLocation), nullptr, callback, nullptr, true, -1);
nullptr,
true,
-1);
#elif defined(Q_OS_MACOS) #elif defined(Q_OS_MACOS)
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString(); static std::string tmpLocation =
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation, QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
nullptr, exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback,
callback, nullptr, true, nullptr);
nullptr,
true,
nullptr);
#else #else
static std::wstring tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString(); static std::wstring tmpLocation =
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation, QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
nullptr, exceptionHandler =
callback, new google_breakpad::ExceptionHandler(tmpLocation, nullptr, callback, nullptr,
nullptr,
google_breakpad::ExceptionHandler::HANDLER_ALL); google_breakpad::ExceptionHandler::HANDLER_ALL);
#endif #endif
atexit(finishCrashHandler); atexit(finishCrashHandler);
@ -125,11 +115,10 @@ void showCrashDialog(const QString &dumpFile)
if (placementFailCounter == 4) { if (placementFailCounter == 4) {
break; break;
} }
dumpSaveFileName = QFileDialog::getSaveFileName(nullptr, dumpSaveFileName = QFileDialog::getSaveFileName(
QObject::tr("Choose a directory to save the crash dump in"), nullptr, QObject::tr("Choose a directory to save the crash dump in"),
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
QDir::separator() + + QDir::separator() + "Cutter_crash_dump_"
"Cutter_crash_dump_"
+ QDate::currentDate().toString("dd.MM.yy") + "_" + QDate::currentDate().toString("dd.MM.yy") + "_"
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp", + QTime::currentTime().toString("HH.mm.ss") + ".dmp",
QObject::tr("Minidump (*.dmp)")); QObject::tr("Minidump (*.dmp)"));
@ -141,11 +130,11 @@ void showCrashDialog(const QString &dumpFile)
ok = true; ok = true;
break; break;
} }
QMessageBox::critical(nullptr, QMessageBox::critical(nullptr, QObject::tr("Save Crash Dump"),
QObject::tr("Save Crash Dump"),
QObject::tr("Failed to write to %1.<br/>" QObject::tr("Failed to write to %1.<br/>"
"Please make sure you have access to that directory " "Please make sure you have access to that directory "
"and try again.").arg(QFileInfo(dumpSaveFileName).dir().path())); "and try again.")
.arg(QFileInfo(dumpSaveFileName).dir().path()));
} while (true); } while (true);
if (ok) { if (ok) {
@ -164,8 +153,7 @@ void showCrashDialog(const QString &dumpFile)
openIssue(); openIssue();
} }
} else { } else {
QMessageBox::critical(nullptr, QMessageBox::critical(nullptr, QObject::tr("Error"),
QObject::tr("Error"),
QObject::tr("Error occurred during crash dump creation.")); QObject::tr("Error occurred during crash dump creation."));
} }
} else { } else {

View File

@ -6,8 +6,7 @@
#include <QString> #include <QString>
#include <QVariantMap> #include <QVariantMap>
namespace Cutter namespace Cutter {
{
struct CutterLayout struct CutterLayout
{ {

View File

@ -3,10 +3,7 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
CutterSeekable::CutterSeekable(QObject *parent) : QObject(parent)
CutterSeekable::CutterSeekable(QObject *parent)
:
QObject(parent)
{ {
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged); connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged);
} }
@ -38,7 +35,6 @@ void CutterSeekable::updateSeek(RVA addr, bool localOnly)
emit seekableSeekChanged(addr); emit seekableSeekChanged(addr);
} }
void CutterSeekable::seekPrev() void CutterSeekable::seekPrev()
{ {
if (synchronized) { if (synchronized) {
@ -65,8 +61,7 @@ bool CutterSeekable::isSynchronized()
void CutterSeekable::seekToReference(RVA offset) void CutterSeekable::seekToReference(RVA offset)
{ {
if (offset == RVA_INVALID) if (offset == RVA_INVALID) {
{
return; return;
} }

View File

@ -45,7 +45,8 @@ public:
bool isSynchronized(); bool isSynchronized();
/** /**
* @brief seekToReference will seek to the function or the object which is referenced in a given offset * @brief seekToReference will seek to the function or the object which is referenced in a given
* offset
* @param offset - an address that contains a reference to jump to * @param offset - an address that contains a reference to jump to
*/ */
void seekToReference(RVA offset); void seekToReference(RVA offset);

View File

@ -6,19 +6,17 @@
#include <QJsonArray> #include <QJsonArray>
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent) Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
: QObject(parent), : QObject(parent), id(id), name(name)
id(id),
name(name)
{ {
} }
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage){ RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
{
std::string temporary = warningMessage.toStdString(); std::string temporary = warningMessage.toStdString();
return rz_annotated_code_new(strdup(temporary.c_str())); return rz_annotated_code_new(strdup(temporary.c_str()));
} }
JSDecDecompiler::JSDecDecompiler(QObject *parent) JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", parent)
: Decompiler("jsdec", "jsdec", parent)
{ {
task = nullptr; task = nullptr;
} }

View File

@ -4,8 +4,7 @@
#include <memory> #include <memory>
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent) DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
: QSyntaxHighlighter(parent)
{ {
setupTheme(); setupTheme();
connect(Config(), &Configuration::colorsUpdated, this, [this]() { connect(Config(), &Configuration::colorsUpdated, this, [this]() {
@ -21,7 +20,8 @@ void DecompilerHighlighter::setAnnotations(RzAnnotatedCode *code)
void DecompilerHighlighter::setupTheme() void DecompilerHighlighter::setupTheme()
{ {
struct { struct
{
RSyntaxHighlightType type; RSyntaxHighlightType type;
QString name; QString name;
} mapping[] = { } mapping[] = {
@ -49,9 +49,11 @@ void DecompilerHighlighter::highlightBlock(const QString &)
size_t start = block.position(); size_t start = block.position();
size_t end = block.position() + block.length(); size_t end = block.position() + block.length();
std::unique_ptr<RzPVector, decltype(&rz_pvector_free)> annotations(rz_annotated_code_annotations_range(code, start, end), &rz_pvector_free); std::unique_ptr<RzPVector, decltype(&rz_pvector_free)> annotations(
rz_annotated_code_annotations_range(code, start, end), &rz_pvector_free);
void **iter; void **iter;
rz_pvector_foreach(annotations.get(), iter) { rz_pvector_foreach(annotations.get(), iter)
{
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation *>(*iter); RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation *>(*iter);
if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) { if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
continue; continue;

View File

@ -29,10 +29,10 @@ public:
* @param code * @param code
*/ */
void setAnnotations(RzAnnotatedCode *code); void setAnnotations(RzAnnotatedCode *code);
protected: protected:
void highlightBlock(const QString &text) override; void highlightBlock(const QString &text) override;
private: private:
void setupTheme(); void setupTheme();

View File

@ -10,11 +10,9 @@ void DirectionalComboBox::showPopup()
QComboBox::showPopup(); QComboBox::showPopup();
QWidget *popup = this->findChild<QFrame *>(); QWidget *popup = this->findChild<QFrame *>();
if (popupUpwards) { if (popupUpwards) {
popup->move(popup->x(), popup->move(popup->x(), mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
} else { } else {
popup->move(popup->x(), popup->move(popup->x(), mapToGlobal(this->rect().topLeft()).y());
mapToGlobal(this->rect().topLeft()).y());
} }
} }

View File

@ -20,4 +20,3 @@ private:
void showPopup(); void showPopup();
}; };

View File

@ -18,10 +18,10 @@
static QAbstractItemView::ScrollMode scrollMode() static QAbstractItemView::ScrollMode scrollMode()
{ {
const bool use_scrollperpixel = true; const bool use_scrollperpixel = true;
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel : QAbstractItemView::ScrollPerItem; return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
: QAbstractItemView::ScrollPerItem;
} }
namespace qhelpers { namespace qhelpers {
QString formatBytecount(const uint64_t bytecount) QString formatBytecount(const uint64_t bytecount)
@ -35,8 +35,8 @@ QString formatBytecount(const uint64_t bytecount)
QString str; QString str;
QTextStream stream(&str); QTextStream stream(&str);
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) << ' ' << suffixes[exp]
<< ' ' << suffixes[exp] << 'B'; << 'B';
return stream.readAll(); return stream.readAll();
} }
@ -161,8 +161,7 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit)
{ {
QFontMetrics fontMetrics(textEdit->document()->defaultFont()); QFontMetrics fontMetrics(textEdit->document()->defaultFont());
return (textEdit->height() return (textEdit->height()
- (textEdit->contentsMargins().top() - (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
+ textEdit->contentsMargins().bottom()
+ (int)(textEdit->document()->documentMargin() * 2))) + (int)(textEdit->document()->documentMargin() * 2)))
/ fontMetrics.lineSpacing(); / fontMetrics.lineSpacing();
} }
@ -171,15 +170,15 @@ int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
{ {
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont()); QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
return (plainTextEdit->height() return (plainTextEdit->height()
- (plainTextEdit->contentsMargins().top() - (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
+ plainTextEdit->contentsMargins().bottom()
+ (int)(plainTextEdit->document()->documentMargin() * 2))) + (int)(plainTextEdit->document()->documentMargin() * 2)))
/ fontMetrics.lineSpacing(); / fontMetrics.lineSpacing();
} }
QByteArray applyColorToSvg(const QByteArray &data, QColor color) QByteArray applyColorToSvg(const QByteArray &data, QColor color)
{ {
static const QRegularExpression styleRegExp("(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")"); static const QRegularExpression styleRegExp(
"(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0')); QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
int replaceStrLen = replaceStr.length(); int replaceStrLen = replaceStr.length();
@ -194,7 +193,8 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color)
} }
int captureIndex = match.captured(1).isNull() ? 2 : 1; int captureIndex = match.captured(1).isNull() ? 2 : 1;
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex), replaceStr); xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex),
replaceStr);
offset = match.capturedStart(captureIndex) + replaceStrLen; offset = match.capturedStart(captureIndex) + replaceStrLen;
} }
@ -210,11 +210,12 @@ QByteArray applyColorToSvg(const QString &filename, QColor color)
} }
/** /**
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an object which has to be used * @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an
* and loaded icon * object which has to be used and loaded icon
* @param supportedIconsNames list of <object ptr, icon name> * @param supportedIconsNames list of <object ptr, icon name>
* @param setter functor which has to be called * @param setter functor which has to be called
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon &icon) { static_cast<QAction*>(o)->setIcon(icon); } * for example we need to set an action icon, the functor can be just [](void* o, const QIcon
* &icon) { static_cast<QAction*>(o)->setIcon(icon); }
*/ */
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames, void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
std::function<void(void *, const QIcon &)> setter) std::function<void(void *, const QIcon &)> setter)
@ -272,11 +273,8 @@ void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex)
void emitColumnChanged(QAbstractItemModel *model, int column) void emitColumnChanged(QAbstractItemModel *model, int column)
{ {
if (model && model->rowCount()) { if (model && model->rowCount()) {
emit model->dataChanged( emit model->dataChanged(model->index(0, column),
model->index(0, column), model->index(model->rowCount() - 1, column), { Qt::DisplayRole });
model->index(model->rowCount() - 1, column),
{ Qt::DisplayRole }
);
} }
} }

View File

@ -35,15 +35,18 @@ CUTTER_EXPORT QString formatBytecount(const uint64_t bytecount);
CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding); CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding);
CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding); CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView); CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(), CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str,
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString()); const QString &str2 = QString(),
const QString &str3 = QString(),
const QString &str4 = QString(),
const QString &str5 = QString());
CUTTER_EXPORT void setVerticalScrollMode(QAbstractItemView *tw); CUTTER_EXPORT void setVerticalScrollMode(QAbstractItemView *tw);
CUTTER_EXPORT void setCheckedWithoutSignals(QAbstractButton *button, bool checked); CUTTER_EXPORT void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
struct CUTTER_EXPORT SizePolicyMinMax
struct CUTTER_EXPORT SizePolicyMinMax { {
QSizePolicy sizePolicy; QSizePolicy sizePolicy;
int min; int min;
int max; int max;
@ -61,7 +64,8 @@ CUTTER_EXPORT int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color); CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color);
CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color); CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color);
CUTTER_EXPORT void setThemeIcons(QList<QPair<void*, QString>> supportedIconsNames, std::function<void(void *, const QIcon &)> setter); CUTTER_EXPORT void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
std::function<void(void *, const QIcon &)> setter);
CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu); CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu);
CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p); CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);

View File

@ -3,8 +3,7 @@
#include <QtGui> #include <QtGui>
Highlighter::Highlighter(QTextDocument *parent) : Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
QSyntaxHighlighter(parent)
{ {
HighlightingRule rule; HighlightingRule rule;
@ -28,7 +27,6 @@ Highlighter::Highlighter(QTextDocument *parent) :
highlightingRules.append(rule); highlightingRules.append(rule);
} }
singleLineCommentFormat.setFontWeight(QFont::Bold); singleLineCommentFormat.setFontWeight(QFont::Bold);
singleLineCommentFormat.setForeground(QColor(63, 195, 128)); singleLineCommentFormat.setForeground(QColor(63, 195, 128));
rule.pattern.setPattern(";[^\n]*"); rule.pattern.setPattern(";[^\n]*");
@ -57,17 +55,19 @@ void Highlighter::highlightBlock(const QString &text)
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart(); startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
while (startIndex >= 0) { while (startIndex >= 0) {
QRegularExpressionMatch commentEndMatch = QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex)); QRegularExpressionMatch commentEndMatch =
QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
int endIndex = commentEndMatch.capturedStart(); int endIndex = commentEndMatch.capturedStart();
int commentLength; int commentLength;
if (endIndex == -1) { if (endIndex == -1) {
setCurrentBlockState(1); setCurrentBlockState(1);
commentLength = text.length() - startIndex; commentLength = text.length() - startIndex;
} else { } else {
commentLength = endIndex - startIndex commentLength = endIndex - startIndex + commentEndMatch.capturedLength();
+ commentEndMatch.capturedLength();
} }
setFormat(startIndex, commentLength, multiLineCommentFormat); setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = QRegularExpression(commentStartRegularExpression).match(text.mid(startIndex + commentLength)).capturedStart(); startIndex = QRegularExpression(commentStartRegularExpression)
.match(text.mid(startIndex + commentLength))
.capturedStart();
} }
} }

View File

@ -24,7 +24,8 @@ protected:
private: private:
CutterCore *core; CutterCore *core;
struct HighlightingRule { struct HighlightingRule
{
QRegularExpression pattern; QRegularExpression pattern;
QTextCharFormat format; QTextCharFormat format;
}; };

View File

@ -51,17 +51,17 @@ bool IOModesController::prepareForWriting()
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Icon::Critical); msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle(QObject::tr("Write error")); msgBox.setWindowTitle(QObject::tr("Write error"));
msgBox.setText( msgBox.setText(QObject::tr(
QObject::tr("Your file is opened in read-only mode. " "Your file is opened in read-only mode. "
"Editing is only available when the file is opened in either Write or Cache modes.\n\n" "Editing is only available when the file is opened in either Write or Cache modes.\n\n"
"WARNING: In Write mode, any changes will be committed to the file on disk. " "WARNING: In Write mode, any changes will be committed to the file on disk. "
"For safety, please consider using Cache mode and then commit the changes manually " "For safety, please consider using Cache mode and then commit the changes manually "
"via File -> Commit modifications to disk.")); "via File -> Commit modifications to disk."));
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole); msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
QAbstractButton *reopenButton = msgBox.addButton(QObject::tr("Reopen in Write mode"), QAbstractButton *reopenButton =
QMessageBox::YesRole); msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole);
QAbstractButton *iocacheButton = msgBox.addButton(QObject::tr("Enable Cache mode"), QAbstractButton *iocacheButton =
QMessageBox::YesRole); msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole);
msgBox.exec(); msgBox.exec();
@ -95,10 +95,13 @@ bool IOModesController::askCommitUnsavedChanges()
{ {
// Check if there are uncommitted changes // Check if there are uncommitted changes
if (!allChangesComitted()) { if (!allChangesComitted()) {
QMessageBox::StandardButton ret = QMessageBox::question(NULL, QObject::tr("Uncomitted changes"), QMessageBox::StandardButton ret = QMessageBox::question(
QObject::tr("It seems that you have changes or patches that are not committed to the file.\n" NULL, QObject::tr("Uncomitted changes"),
QObject::tr("It seems that you have changes or patches that are not committed to "
"the file.\n"
"Do you want to commit them now?"), "Do you want to commit them now?"),
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)); (QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
| QMessageBox::Cancel));
if (ret == QMessageBox::Save) { if (ret == QMessageBox::Save) {
Core()->commitWriteCache(); Core()->commitWriteCache();
} else if (ret == QMessageBox::Discard) { } else if (ret == QMessageBox::Discard) {

View File

@ -7,7 +7,8 @@
/** /**
* @brief The CommandDescription struct is a pair of a Rizin command and its description * @brief The CommandDescription struct is a pair of a Rizin command and its description
*/ */
struct CommandDescription { struct CommandDescription
{
QString command; QString command;
QString description; QString description;
}; };

View File

@ -1,7 +1,6 @@
#include "JsonModel.h" #include "JsonModel.h"
JsonModel::JsonModel(QObject *parent) : JsonModel::JsonModel(QObject *parent) : QAbstractItemModel(parent)
QAbstractItemModel(parent)
{ {
mRootItem = new JsonTreeItem; mRootItem = new JsonTreeItem;
mHeaders.append("key"); mHeaders.append("key");
@ -42,10 +41,8 @@ QVariant JsonModel::data(const QModelIndex &index, int role) const
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer()); JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
if (index.column() == 0) if (index.column() == 0)
@ -122,4 +119,3 @@ int JsonModel::columnCount(const QModelIndex &parent) const
Q_UNUSED(parent) Q_UNUSED(parent)
return 2; return 2;
} }

View File

@ -28,6 +28,7 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
~JsonModel(); ~JsonModel();
private: private:
JsonTreeItem *mRootItem; JsonTreeItem *mRootItem;
QJsonDocument mDocument; QJsonDocument mDocument;

View File

@ -8,20 +8,23 @@
/** /**
* @brief Pool of singly linked lists. * @brief Pool of singly linked lists.
* *
* Should not be used as general purpose container. Use only for algorithms that require linked lists ability * Should not be used as general purpose container. Use only for algorithms that require linked
* to split and concatenate them. All the data is owned by LinkedListPool. * lists ability to split and concatenate them. All the data is owned by LinkedListPool.
* *
* In contrast to std::list and std::forward_list doesn't allocate each node separately. LinkedListPool can reserve * In contrast to std::list and std::forward_list doesn't allocate each node separately.
* all the memory for multiple lists during construction. Uses std::vector as backing container. * LinkedListPool can reserve all the memory for multiple lists during construction. Uses
* std::vector as backing container.
*/ */
template<class T> template<class T>
class LinkedListPool class LinkedListPool
{ {
using IndexType = size_t; using IndexType = size_t;
struct Item { struct Item
{
IndexType next; IndexType next;
T value; T value;
}; };
public: public:
/** /**
* @brief List iterator. * @brief List iterator.
@ -32,12 +35,10 @@ public:
{ {
IndexType index = 0; IndexType index = 0;
LinkedListPool<T> *pool = nullptr; LinkedListPool<T> *pool = nullptr;
ListIterator(IndexType index, LinkedListPool<T> *pool) ListIterator(IndexType index, LinkedListPool<T> *pool) : index(index), pool(pool) {}
: index(index)
, pool(pool)
{}
friend class LinkedListPool<T>; friend class LinkedListPool<T>;
public: public:
using iterator_category = std::forward_iterator_tag; using iterator_category = std::forward_iterator_tag;
using value_type = T; using value_type = T;
@ -45,14 +46,8 @@ public:
using pointer = T *; using pointer = T *;
using reference = T &; using reference = T &;
ListIterator() = default; ListIterator() = default;
reference operator*() reference operator*() { return pool->data[index].value; }
{ pointer operator->() { return &pool->data[index].value; }
return pool->data[index].value;
}
pointer operator->()
{
return &pool->data[index].value;
}
ListIterator &operator++() ListIterator &operator++()
{ {
@ -65,24 +60,18 @@ public:
operator++(); operator++();
return tmp; return tmp;
} }
bool operator!=(const ListIterator &b) const bool operator!=(const ListIterator &b) const { return index != b.index || pool != b.pool; };
{
return index != b.index || pool != b.pool;
};
/** /**
* @brief Test if iterator points to valid value. * @brief Test if iterator points to valid value.
*/ */
explicit operator bool() const explicit operator bool() const { return index; }
{
return index;
}
}; };
/** /**
* @brief Single list within LinkedListPool. * @brief Single list within LinkedListPool.
* *
* List only refers to chain of elements. Copying it doesn't copy any element. Item data is owned by * List only refers to chain of elements. Copying it doesn't copy any element. Item data is
* LinkedListPool. * owned by LinkedListPool.
* *
* Use LinkedListPool::makeList to create non-empty list. * Use LinkedListPool::makeList to create non-empty list.
*/ */
@ -91,28 +80,22 @@ public:
IndexType head = 0; IndexType head = 0;
IndexType tail = 0; IndexType tail = 0;
friend class LinkedListPool; friend class LinkedListPool;
List(IndexType head, IndexType tail) List(IndexType head, IndexType tail) : head(head), tail(tail) {}
: head(head)
, tail(tail)
{}
public: public:
/** /**
* @brief Create an empty list * @brief Create an empty list
*/ */
List() = default; List() = default;
bool isEmpty() const bool isEmpty() const { return head == 0; }
{
return head == 0;
}
}; };
/** /**
* @brief Create a linked list pool with capacity for \a initialCapacity list items. * @brief Create a linked list pool with capacity for \a initialCapacity list items.
* @param initialCapacity number of elements to preallocate. * @param initialCapacity number of elements to preallocate.
*/ */
LinkedListPool(size_t initialCapacity) LinkedListPool(size_t initialCapacity) : data(1)
: data(1)
{ {
data.reserve(initialCapacity + 1); // [0] element reserved data.reserve(initialCapacity + 1); // [0] element reserved
} }
@ -120,7 +103,8 @@ public:
/** /**
* @brief Create a list containing single item. * @brief Create a list containing single item.
* *
* Does not invalidate any iterators, but may cause item relocation when initialCapacity is exceeded. * Does not invalidate any iterators, but may cause item relocation when initialCapacity is
* exceeded.
* @param value value of element that will be inserted in the created list * @param value value of element that will be inserted in the created list
* @return List containing single value \a value . * @return List containing single value \a value .
*/ */
@ -134,8 +118,8 @@ public:
/** /**
* @brief Split list and return second half. * @brief Split list and return second half.
* *
* After performing the operation, list passed as argument and return list point to the same items. Modifying them * After performing the operation, list passed as argument and return list point to the same
* will affect both lists. * items. Modifying them will affect both lists.
* *
* @param list The list that needs to be split. * @param list The list that needs to be split.
* @param head Iterator to the first item in new list. Needs to be within \a list . * @param head Iterator to the first item in new list. Needs to be within \a list .
@ -150,7 +134,8 @@ public:
* @brief Split list and return first half. * @brief Split list and return first half.
* *
* @param list The list that needs to be split. * @param list The list that needs to be split.
* @param end Iterator to the first item that should not be included in returned list. Needs to be within \a list . * @param end Iterator to the first item that should not be included in returned list. Needs to
* be within \a list .
* @return Returns prefix of \a list. * @return Returns prefix of \a list.
*/ */
List splitHead(const List &list, const ListIterator &end) List splitHead(const List &list, const ListIterator &end)
@ -174,15 +159,9 @@ public:
* @param list * @param list
* @return Iterator pointing to the first item in the list. * @return Iterator pointing to the first item in the list.
*/ */
ListIterator head(const List &list) ListIterator head(const List &list) { return iteratorFromIndex(list.head); }
{
return iteratorFromIndex(list.head);
}
ListIterator end(const List &list) ListIterator end(const List &list) { return std::next(iteratorFromIndex(list.tail)); }
{
return std::next(iteratorFromIndex(list.tail));
}
List append(const List &head, const List &tail) List append(const List &head, const List &tail)
{ {
@ -196,14 +175,11 @@ public:
data[head.tail].next = tail.head; data[head.tail].next = tail.head;
return result; return result;
} }
private: private:
ListIterator iteratorFromIndex(IndexType index) ListIterator iteratorFromIndex(IndexType index) { return ListIterator { index, this }; }
{
return ListIterator{ index, this };
}
std::vector<Item> data; std::vector<Item> data;
}; };
#endif // LINKED_LIST_POOL #endif // LINKED_LIST_POOL

View File

@ -2,8 +2,7 @@
#include "common/MdHighlighter.h" #include "common/MdHighlighter.h"
MdHighlighter::MdHighlighter(QTextDocument *parent) MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
: QSyntaxHighlighter(parent)
{ {
HighlightingRule rule; HighlightingRule rule;
@ -11,8 +10,10 @@ MdHighlighter::MdHighlighter(QTextDocument *parent)
keywordFormat.setFontWeight(QFont::Bold); keywordFormat.setFontWeight(QFont::Bold);
QStringList keywordPatterns; QStringList keywordPatterns;
keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b" << "\\*\\*([^\\\\]+)\\*\\*" keywordPatterns << "^\\#{1,6}[ A-Za-z]+\\b"
<< "\\*([^\\\\]+)\\*" << "\\_([^\\\\]+)\\_" << "\\*\\*([^\\\\]+)\\*\\*"
<< "\\*([^\\\\]+)\\*"
<< "\\_([^\\\\]+)\\_"
<< "\\_\\_([^\\\\]+)\\_\\_"; << "\\_\\_([^\\\\]+)\\_\\_";
for (const QString &pattern : keywordPatterns) { for (const QString &pattern : keywordPatterns) {

View File

@ -20,7 +20,8 @@ protected:
void highlightBlock(const QString &text); void highlightBlock(const QString &text);
private: private:
struct HighlightingRule { struct HighlightingRule
{
QRegularExpression pattern; QRegularExpression pattern;
QTextCharFormat format; QTextCharFormat format;
}; };

View File

@ -9,15 +9,20 @@ class QRectF;
class QFontMetrics; class QFontMetrics;
class QFontMetricsF; class QFontMetricsF;
template<typename T> struct Metrics {}; template<typename T>
struct Metrics
{
};
template<> struct Metrics<int> template<>
struct Metrics<int>
{ {
using Rect = QRect; using Rect = QRect;
using FontMetrics = QFontMetrics; using FontMetrics = QFontMetrics;
}; };
template<> struct Metrics<qreal> template<>
struct Metrics<qreal>
{ {
using Rect = QRectF; using Rect = QRectF;
using FontMetrics = QFontMetricsF; using FontMetrics = QFontMetricsF;

View File

@ -9,15 +9,12 @@ static const int paddingInner = 8;
static const int arms = 12; static const int arms = 12;
static const int timerInterval = 50; static const int timerInterval = 50;
ProgressIndicator::ProgressIndicator(QWidget *parent) ProgressIndicator::ProgressIndicator(QWidget *parent) : QWidget(parent)
: QWidget(parent)
{ {
updateAnimationTimer(); updateAnimationTimer();
} }
ProgressIndicator::~ProgressIndicator() ProgressIndicator::~ProgressIndicator() {}
{
}
void ProgressIndicator::setProgressIndicatorVisible(bool visible) void ProgressIndicator::setProgressIndicatorVisible(bool visible)
{ {
@ -80,10 +77,6 @@ void ProgressIndicator::paintEvent(QPaintEvent *)
for (int i = 0; i < arms; i++) { for (int i = 0; i < arms; i++) {
int state = (i + (arms - animationState)) % arms; int state = (i + (arms - animationState)) % arms;
painter.setOpacity((float)state / arms); painter.setOpacity((float)state / arms);
painter.drawLine(line * QTransform() painter.drawLine(line * QTransform().translate(origin.x(), origin.y()).rotate(angle * i));
.translate(origin.x(), origin.y())
.rotate(angle * i));
} }
} }

View File

@ -33,5 +33,4 @@ private:
void updateAnimationTimer(); void updateAnimationTimer();
}; };
#endif // PROGRESSINDICATOR_H #endif // PROGRESSINDICATOR_H

View File

@ -41,9 +41,8 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
char *message; char *message;
int debug = 0; int debug = 0;
static const char *kwlist[] = { "", "debug", NULL }; static const char *kwlist[] = { "", "debug", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", const_cast<char **>(kwlist), &message,
const_cast<char**>(kwlist), &debug)) {
&message, &debug)) {
return NULL; return NULL;
} }
Core()->message(QString(message), debug); Core()->message(QString(message), debug);
@ -52,28 +51,16 @@ PyObject *api_message(PyObject *self, PyObject *args, PyObject *kwargs)
} }
PyMethodDef CutterMethods[] = { PyMethodDef CutterMethods[] = {
{ { "version", api_version, METH_NOARGS, "Returns Cutter current version" },
"version", api_version, METH_NOARGS, { "cmd", api_cmd, METH_VARARGS, "Execute a command inside Cutter" },
"Returns Cutter current version" { "refresh", api_refresh, METH_NOARGS, "Refresh Cutter widgets" },
}, { "message", (PyCFunction)(void *)/* don't remove this double cast! */ api_message,
{ METH_VARARGS | METH_KEYWORDS, "Print message" },
"cmd", api_cmd, METH_VARARGS,
"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 } { NULL, NULL, 0, NULL }
}; };
PyModuleDef CutterModule = { PyModuleDef CutterModule = {
PyModuleDef_HEAD_INIT, "_cutter", NULL, -1, CutterMethods, PyModuleDef_HEAD_INIT, "_cutter", NULL, -1, CutterMethods, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
}; };
PyObject *PyInit_api() PyObject *PyInit_api()

View File

@ -28,13 +28,9 @@ PythonManager *PythonManager::getInstance()
return uniqueInstance; return uniqueInstance;
} }
PythonManager::PythonManager() PythonManager::PythonManager() {}
{
}
PythonManager::~PythonManager() PythonManager::~PythonManager() {}
{
}
void PythonManager::initPythonHome() void PythonManager::initPythonHome()
{ {
@ -48,8 +44,8 @@ void PythonManager::initPythonHome()
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED # else // MACOS_PYTHON_FRAMEWORK_BUNDLED
// @executable_path/../Frameworks/Python.framework/Versions/Current // @executable_path/../Frameworks/Python.framework/Versions/Current
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current"); pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() << qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath()
" for macOS Application Bundle."; << " for macOS Application Bundle.";
# endif # endif
customPythonHome = pythonHomeDir.absolutePath(); customPythonHome = pythonHomeDir.absolutePath();
} }
@ -112,8 +108,8 @@ static void pySideDestructionVisitor(SbkObject* pyObj, void* data)
} }
Shiboken::Object::setValidCpp(pyObj, false); Shiboken::Object::setValidCpp(pyObj, false);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS Shiboken::callCppDestructor<QObject>(
Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, pyQObjectType)); Shiboken::Object::cppPointer(pyObj, pyQObjectType));
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
}; };
#endif #endif
@ -125,7 +121,8 @@ void PythonManager::shutdown()
restoreThread(); restoreThread();
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS #ifdef CUTTER_ENABLE_PYTHON_BINDINGS
// This is necessary to prevent a segfault when the CutterCore instance is deleted after the Shiboken::BindingManager // This is necessary to prevent a segfault when the CutterCore instance is deleted after the
// Shiboken::BindingManager
Core()->setProperty("_PySideInvalidatePtr", QVariant()); Core()->setProperty("_PySideInvalidatePtr", QVariant());
// see PySide::destroyQCoreApplication() // see PySide::destroyQCoreApplication()
@ -146,7 +143,8 @@ void PythonManager::shutdown()
Py_Finalize(); Py_Finalize();
} }
void PythonManager::addPythonPath(char *path) { void PythonManager::addPythonPath(char *path)
{
restoreThread(); restoreThread();
PyObject *sysModule = PyImport_ImportModule("sys"); PyObject *sysModule = PyImport_ImportModule("sys");

View File

@ -23,9 +23,8 @@ PyObject *QtResGetCode(const char *name)
QByteArray data = moduleFile.readAll(); QByteArray data = moduleFile.readAll();
moduleFile.close(); moduleFile.close();
PyObject *codeObject = Py_CompileString(data.constData(), PyObject *codeObject = Py_CompileString(
moduleFile.fileName().toLocal8Bit().constData(), data.constData(), moduleFile.fileName().toLocal8Bit().constData(), Py_file_input);
Py_file_input);
if (!codeObject) { if (!codeObject) {
qWarning() << "Couldn't compile " << moduleFile.fileName(); qWarning() << "Couldn't compile " << moduleFile.fileName();
} }
@ -68,15 +67,12 @@ PyObject *qtres_get_code(PyObject *self, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyMethodDef QtResMethods[] = { PyMethodDef QtResMethods[] = { { "exists", qtres_exists, METH_VARARGS, NULL },
{ "exists", qtres_exists, METH_VARARGS, NULL },
{ "get_code", qtres_get_code, METH_VARARGS, NULL }, { "get_code", qtres_get_code, METH_VARARGS, NULL },
{NULL, NULL, 0, NULL} { NULL, NULL, 0, NULL } };
};
PyModuleDef QtResModule = { PyModuleDef QtResModule = {
PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods, PyModuleDef_HEAD_INIT, "_qtres", NULL, -1, QtResMethods, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
}; };
PyObject *PyInit_qtres() PyObject *PyInit_qtres()

View File

@ -2,8 +2,8 @@
#include "RefreshDeferrer.h" #include "RefreshDeferrer.h"
#include "widgets/CutterDockWidget.h" #include "widgets/CutterDockWidget.h"
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent) : QObject(parent), RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent)
acc(acc) : QObject(parent), acc(acc)
{ {
} }
@ -41,4 +41,3 @@ void RefreshDeferrer::registerFor(CutterDockWidget *dockWidget)
} }
}); });
} }

View File

@ -42,12 +42,12 @@ protected:
virtual RefreshDeferrerParamsResult result() = 0; virtual RefreshDeferrerParamsResult result() = 0;
}; };
/** /**
* @brief Accumulator which simply replaces the current value by an incoming new one * @brief Accumulator which simply replaces the current value by an incoming new one
* @tparam T The type of the param to store * @tparam T The type of the param to store
* *
* This accumulator takes the ownership of all params passed to it and deletes them automatically if not needed anymore! * This accumulator takes the ownership of all params passed to it and deletes them automatically if
* not needed anymore!
*/ */
template<class T> template<class T>
class ReplacingRefreshDeferrerAccumulator : public RefreshDeferrerAccumulator class ReplacingRefreshDeferrerAccumulator : public RefreshDeferrerAccumulator
@ -58,16 +58,16 @@ private:
public: public:
/** /**
* \param Determines whether, if nullptr is passed, the current value should be replaced or kept. * \param Determines whether, if nullptr is passed, the current value should be replaced or
* kept.
*/ */
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true) explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
: replaceIfNull(replaceIfNull) {} : replaceIfNull(replaceIfNull)
~ReplacingRefreshDeferrerAccumulator() override
{ {
delete value;
} }
~ReplacingRefreshDeferrerAccumulator() override { delete value; }
protected: protected:
void accumulate(RefreshDeferrerParams params) override void accumulate(RefreshDeferrerParams params) override
{ {
@ -78,10 +78,7 @@ protected:
value = static_cast<T *>(params); value = static_cast<T *>(params);
} }
void ignoreParams(RefreshDeferrerParams params) override void ignoreParams(RefreshDeferrerParams params) override { delete static_cast<T *>(params); }
{
delete static_cast<T *>(params);
}
void clear() override void clear() override
{ {
@ -89,25 +86,22 @@ protected:
value = nullptr; value = nullptr;
} }
virtual RefreshDeferrerParamsResult result() override virtual RefreshDeferrerParamsResult result() override { return value; }
{
return value;
}
}; };
/** /**
* @brief Helper class for deferred refreshing in Widgets * @brief Helper class for deferred refreshing in Widgets
* *
* This class can handle the logic necessary to defer the refreshing of widgets when they are not visible. * This class can handle the logic necessary to defer the refreshing of widgets when they are not
* It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate incoming events while * visible. It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate
* refreshing is deferred. * incoming events while refreshing is deferred.
* *
* Example (don't write it like this in practice, use the convenience methods in CutterDockWidget): * Example (don't write it like this in practice, use the convenience methods in CutterDockWidget):
* ``` * ```
* // in the constructor of a widget * // in the constructor of a widget
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false), this); * this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false),
* this->refreshDeferrer->registerFor(this); * this); this->refreshDeferrer->registerFor(this); connect(this->refreshDeferrer,
* connect(this->refreshDeferrer, &RefreshDeferrer::refreshNow, this, [this](MyParam *param) { * &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
* // We attempted a refresh some time before, but it got deferred. * // We attempted a refresh some time before, but it got deferred.
* // Now the RefreshDeferrer tells us to do the refresh and gives us the accumulated param. * // Now the RefreshDeferrer tells us to do the refresh and gives us the accumulated param.
* this->doRefresh(*param); * this->doRefresh(*param);

View File

@ -6,7 +6,6 @@
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#ifdef APPIMAGE #ifdef APPIMAGE
static QDir appimageRoot() static QDir appimageRoot()
{ {
@ -37,7 +36,8 @@ static QStringList substitutePaths(const QStringList &paths)
QStringList result; QStringList result;
result.reserve(paths.size()); result.reserve(paths.size());
for (auto &path : paths) { for (auto &path : paths) {
// consider ignoring some of system folders for portable packages here or standardLocations if it depends on path type // consider ignoring some of system folders for portable packages here or standardLocations
// if it depends on path type
result.push_back(substitutePath(path)); result.push_back(substitutePath(path));
} }
return result; return result;
@ -46,8 +46,8 @@ static QStringList substitutePaths(const QStringList &paths)
QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
QStandardPaths::LocateOptions options) QStandardPaths::LocateOptions options)
{ {
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs to be done // This function is reimplemented here instead of forwarded to Qt becauase existence check needs
// after substitutions // to be done after substitutions
QStringList result; QStringList result;
for (auto path : standardLocations(type)) { for (auto path : standardLocations(type)) {
QString filePath = path + QLatin1Char('/') + fileName; QString filePath = path + QLatin1Char('/') + fileName;
@ -81,4 +81,3 @@ QStringList Cutter::getTranslationsDirectories()
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath); result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
return result; return result;
} }

View File

@ -11,14 +11,11 @@
*/ */
namespace Cutter { namespace Cutter {
QStringList locateAll( QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
QStandardPaths::StandardLocation type,
const QString &fileName,
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile); QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
QStringList standardLocations(QStandardPaths::StandardLocation type); QStringList standardLocations(QStandardPaths::StandardLocation type);
QString writableLocation(QStandardPaths::StandardLocation type); QString writableLocation(QStandardPaths::StandardLocation type);
/** /**
* @brief Get list of available translation directories (depends on configuration and OS) * @brief Get list of available translation directories (depends on configuration and OS)
* @return list of directories * @return list of directories

View File

@ -8,7 +8,6 @@
// TODO: fix performance (possibly use QTextLayout?) // TODO: fix performance (possibly use QTextLayout?)
template<typename T> template<typename T>
void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc,
const List &richText, CachedFontMetrics<T> *fontMetrics) const List &richText, CachedFontMetrics<T> *fontMetrics)
@ -52,29 +51,32 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
flags = Qt::TextBypassShaping; flags = Qt::TextBypassShaping;
#endif #endif
painter->drawText(typename Metrics<T>::Rect(x + xinc, y, w - xinc, h), flags, curRichText.text); painter->drawText(typename Metrics<T>::Rect(x + xinc, y, w - xinc, h), flags,
curRichText.text);
if (curRichText.highlight && curRichText.highlightColor.alpha()) { if (curRichText.highlight && curRichText.highlightColor.alpha()) {
highlightPen.setColor(curRichText.highlightColor); highlightPen.setColor(curRichText.highlightColor);
highlightPen.setWidth(curRichText.highlightWidth); highlightPen.setWidth(curRichText.highlightWidth);
painter->setPen(highlightPen); painter->setPen(highlightPen);
T highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1; T highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1;
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1, x + xinc + backgroundWidth - 1, painter->drawLine(x + xinc + highlightOffsetX, y + h - 1,
y + h - 1); x + xinc + backgroundWidth - 1, y + h - 1);
} }
xinc += textWidth; xinc += textWidth;
} }
} }
template template void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w,
void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x, qreal y, qreal w, qreal h, qreal xinc, qreal h, qreal xinc, const List &richText,
const List &richText, CachedFontMetrics<qreal> *fontMetrics); CachedFontMetrics<qreal> *fontMetrics);
/** /**
* @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other applications * @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other
* applications
* @param richText The rich text to be converted to HTML format * @param richText The rich text to be converted to HTML format
* @param textHtml The HTML source. Any previous content will be preserved and new content will be appended at the end. * @param textHtml The HTML source. Any previous content will be preserved and new content will be
* @param textPlain The plain text. Any previous content will be preserved and new content will be appended at the end. * appended at the end.
* @param textPlain The plain text. Any previous content will be preserved and new content will be
* appended at the end.
*/ */
void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain) void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain)
{ {
@ -92,17 +94,21 @@ void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QStr
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name()); textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
break; break;
case FlagBackground: // background only case FlagBackground: // background only
if (curRichText.textBackground != if (curRichText.textBackground
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank. != Qt::transparent) // QColor::name() returns "#000000" for transparent color.
textHtml += QString("<span style=\"background-color:%1\">").arg(curRichText.textBackground.name()); // That's not desired. Leave it blank.
textHtml += QString("<span style=\"background-color:%1\">")
.arg(curRichText.textBackground.name());
else else
textHtml += QString("<span>"); textHtml += QString("<span>");
break; break;
case FlagAll: // color+background case FlagAll: // color+background
if (curRichText.textBackground != if (curRichText.textBackground
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank. != Qt::transparent) // QColor::name() returns "#000000" for transparent color.
textHtml += QString("<span style=\"color:%1; background-color:%2\">").arg( // That's not desired. Leave it blank.
curRichText.textColor.name(), curRichText.textBackground.name()); textHtml += QString("<span style=\"color:%1; background-color:%2\">")
.arg(curRichText.textColor.name(),
curRichText.textBackground.name());
else else
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name()); textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
break; break;
@ -185,7 +191,8 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
auto &text = r.back(); auto &text = r.back();
if (text.text.length() >= indicatorCropLength) { if (text.text.length() >= indicatorCropLength) {
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength, indicator); text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength,
indicator);
break; break;
} }

View File

@ -10,21 +10,18 @@
#include <vector> #include <vector>
class QFontMetricsF; class QFontMetricsF;
template<typename T> class CachedFontMetrics; template<typename T>
class CachedFontMetrics;
class QPainter; class QPainter;
class RichTextPainter class RichTextPainter
{ {
public: public:
// structures // structures
enum CustomRichTextFlags { enum CustomRichTextFlags { FlagNone, FlagColor, FlagBackground, FlagAll };
FlagNone,
FlagColor,
FlagBackground,
FlagAll
};
struct CustomRichText_t { struct CustomRichText_t
{
QString text; QString text;
QColor textColor; QColor textColor;
QColor textBackground; QColor textBackground;
@ -39,8 +36,8 @@ public:
// functions // functions
template<typename T = qreal> template<typename T = qreal>
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText,
const List &richText, CachedFontMetrics<T> *fontMetrics); CachedFontMetrics<T> *fontMetrics);
static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain); static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
static List fromTextDocument(const QTextDocument &doc); static List fromTextDocument(const QTextDocument &doc);

View File

@ -33,10 +33,9 @@ void RizinTask::taskFinished()
RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient) RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient)
{ {
task = rz_core_cmd_task_new(Core()->core(), task = rz_core_cmd_task_new(
cmd.toLocal8Bit().constData(), Core()->core(), cmd.toLocal8Bit().constData(),
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback), static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback), this);
this);
task->transient = transient; task->transient = transient;
rz_core_task_incref(task); rz_core_task_incref(task);
} }
@ -74,9 +73,8 @@ const char *RizinCmdTask::getResultRaw()
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient) RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
: fcn(fcn), res(nullptr) : fcn(fcn), res(nullptr)
{ {
task = rz_core_function_task_new(Core()->core(), task = rz_core_function_task_new(
static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner), Core()->core(), static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner), this);
this);
task->transient = transient; task->transient = transient;
rz_core_task_incref(task); rz_core_task_incref(task);
} }

View File

@ -2,14 +2,9 @@
#include "common/RunScriptTask.h" #include "common/RunScriptTask.h"
#include "core/MainWindow.h" #include "core/MainWindow.h"
RunScriptTask::RunScriptTask() : RunScriptTask::RunScriptTask() : AsyncTask() {}
AsyncTask()
{
}
RunScriptTask::~RunScriptTask() RunScriptTask::~RunScriptTask() {}
{
}
void RunScriptTask::interrupt() void RunScriptTask::interrupt()
{ {

View File

@ -12,13 +12,9 @@ public:
explicit RunScriptTask(); explicit RunScriptTask();
~RunScriptTask(); ~RunScriptTask();
QString getTitle() override { QString getTitle() override { return tr("Run Script"); }
return tr("Run Script");
}
void setFileName(const QString &fileName) { void setFileName(const QString &fileName) { this->fileName = fileName; }
this->fileName = fileName;
}
void interrupt() override; void interrupt() override;

View File

@ -8,7 +8,8 @@
#include <QTextCursor> #include <QTextCursor>
#include <QPlainTextEdit> #include <QPlainTextEdit>
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word) QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
const QString &word)
{ {
QList<QTextEdit::ExtraSelection> selections; QList<QTextEdit::ExtraSelection> selections;
QTextEdit::ExtraSelection highlightSelection; QTextEdit::ExtraSelection highlightSelection;
@ -23,8 +24,8 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) { while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
highlightSelection.cursor = document->find(word, highlightSelection.cursor, highlightSelection.cursor =
QTextDocument::FindWholeWords); document->find(word, highlightSelection.cursor, QTextDocument::FindWholeWords);
if (!highlightSelection.cursor.isNull()) { if (!highlightSelection.cursor.isNull()) {
highlightSelection.format.setBackground(highlightWordColor); highlightSelection.format.setBackground(highlightWordColor);
@ -35,7 +36,6 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
return selections; return selections;
} }
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor) QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor)
{ {
QTextEdit::ExtraSelection highlightSelection; QTextEdit::ExtraSelection highlightSelection;
@ -52,7 +52,6 @@ QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor
return createLineHighlight(cursor, highlightColor); return createLineHighlight(cursor, highlightColor);
} }
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor) QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
{ {
QColor highlightColor = ConfigColor("highlightPC"); QColor highlightColor = ConfigColor("highlightPC");

View File

@ -12,12 +12,14 @@ class QString;
* @param word * @param word
* @return * @return
*/ */
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word); QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
const QString &word);
/** /**
* @brief createLineHighlight * @brief createLineHighlight
* @param cursor - a Cursor object represents the line to be highlighted * @param cursor - a Cursor object represents the line to be highlighted
* @param highlightColor - the color to be used for highlighting. The color is decided by the callee for different usages (BP, PC, Current line, ...) * @param highlightColor - the color to be used for highlighting. The color is decided by the callee
* for different usages (BP, PC, Current line, ...)
* @return ExtraSelection with highlighted line * @return ExtraSelection with highlighted line
*/ */
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor); QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);

View File

@ -40,25 +40,27 @@ static bool migrateSettingsPre18(QSettings &newSettings)
* This function takes care of migrating from EXACTLY version X-1 to X. * This function takes care of migrating from EXACTLY version X-1 to X.
*/ */
static void migrateSettingsTo1(QSettings &settings) { static void migrateSettingsTo1(QSettings &settings)
{
settings.remove("settings_migrated"); // now handled by version settings.remove("settings_migrated"); // now handled by version
settings.remove("updated_custom_themes"); // now handled by theme_version settings.remove("updated_custom_themes"); // now handled by theme_version
} }
static void migrateSettingsTo2(QSettings &settings) { static void migrateSettingsTo2(QSettings &settings)
{
QStringList docks = settings.value("docks").toStringList(); // get current list of docks QStringList docks = settings.value("docks").toStringList(); // get current list of docks
// replace occurences of "PseudocodeWidget" with "DecompilerWidget" // replace occurences of "PseudocodeWidget" with "DecompilerWidget"
settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget")); settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget"));
} }
static void migrateSettingsTo3(QSettings &settings) { static void migrateSettingsTo3(QSettings &settings)
{
auto defaultGeometry = settings.value("geometry").toByteArray(); auto defaultGeometry = settings.value("geometry").toByteArray();
auto defaultState = settings.value("state").toByteArray(); auto defaultState = settings.value("state").toByteArray();
auto debugGeometry = settings.value("debug.geometry").toByteArray(); auto debugGeometry = settings.value("debug.geometry").toByteArray();
auto debugState = settings.value("debug.state").toByteArray(); auto debugState = settings.value("debug.state").toByteArray();
const auto docks = settings.value("docks", QStringList()).toStringList(); const auto docks = settings.value("docks", QStringList()).toStringList();
auto unsyncList = settings.value("unsync", QStringList()).toStringList(); auto unsyncList = settings.value("unsync", QStringList()).toStringList();
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
@ -146,17 +148,23 @@ void Cutter::initializeSettings()
qInfo() << "Migrating Settings to Version" << v; qInfo() << "Migrating Settings to Version" << v;
switch (v) { switch (v) {
case 1: case 1:
migrateSettingsTo1(settings); break; migrateSettingsTo1(settings);
break;
case 2: case 2:
migrateSettingsTo2(settings); break; migrateSettingsTo2(settings);
break;
case 3: case 3:
migrateSettingsTo3(settings); break; migrateSettingsTo3(settings);
break;
case 4: case 4:
migrateSettingsTo4(settings); break; migrateSettingsTo4(settings);
break;
case 5: case 5:
migrateSettingsTo5(settings); break; migrateSettingsTo5(settings);
break;
case 6: case 6:
migrateSettingsTo6(settings); break; migrateSettingsTo6(settings);
break;
default: default:
break; break;
} }
@ -169,7 +177,8 @@ void Cutter::initializeSettings()
#define THEME_VERSION_CURRENT 1 #define THEME_VERSION_CURRENT 1
#define THEME_VERSION_KEY "theme_version" #define THEME_VERSION_KEY "theme_version"
static void removeObsoleteOptionsFromCustomThemes() { static void removeObsoleteOptionsFromCustomThemes()
{
const QStringList options = Core()->cmdj("ecj").object().keys() const QStringList options = Core()->cmdj("ecj").object().keys()
<< ColorThemeWorker::cutterSpecificOptions; << ColorThemeWorker::cutterSpecificOptions;
for (auto theme : Core()->cmdList("eco*")) { for (auto theme : Core()->cmdList("eco*")) {

View File

@ -14,7 +14,8 @@ SvgIconEngine::SvgIconEngine(const QString &filename)
this->svgData = file.readAll(); this->svgData = file.readAll();
} }
SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor) : SvgIconEngine(filename) SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor)
: SvgIconEngine(filename)
{ {
this->svgData = qhelpers::applyColorToSvg(svgData, tintColor); this->svgData = qhelpers::applyColorToSvg(svgData, tintColor);
} }

View File

@ -19,7 +19,6 @@ public:
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override; void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
QIconEngine *clone() const override; QIconEngine *clone() const override;
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override;
}; };
#endif // SVGICONENGINE_H #endif // SVGICONENGINE_H

View File

@ -7,9 +7,11 @@
# include <KSyntaxHighlighting/theme.h> # include <KSyntaxHighlighting/theme.h>
SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document) : KSyntaxHighlighting::SyntaxHighlighter(document) SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document)
: KSyntaxHighlighting::SyntaxHighlighter(document)
{ {
connect(Config(), &Configuration::kSyntaxHighlightingThemeChanged, this, &SyntaxHighlighter::updateTheme); connect(Config(), &Configuration::kSyntaxHighlightingThemeChanged, this,
&SyntaxHighlighter::updateTheme);
updateTheme(); updateTheme();
} }
@ -21,27 +23,45 @@ void SyntaxHighlighter::updateTheme()
#endif #endif
FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent) FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent) : QSyntaxHighlighter(parent), commentStartExpression("/\\*"), commentEndExpression("\\*/")
, commentStartExpression("/\\*")
, commentEndExpression("\\*/")
{ {
HighlightingRule rule; HighlightingRule rule;
QStringList keywordPatterns; QStringList keywordPatterns;
// C language keywords // C language keywords
keywordPatterns << "\\bauto\\b" << "\\bdouble\\b" << "\\bint\\b" keywordPatterns << "\\bauto\\b"
<< "\\bstruct\\b" << "\\bbreak\\b" << "\\belse\\b" << "\\bdouble\\b"
<< "\\blong\\b" << "\\switch\\b" << "\\bcase\\b" << "\\bint\\b"
<< "\\benum\\b" << "\\bregister\\b" << "\\btypedef\\b" << "\\bstruct\\b"
<< "\\bchar\\b" << "\\bextern\\b" << "\\breturn\\b" << "\\bbreak\\b"
<< "\\bunion\\b" << "\\bconst\\b" << "\\bfloat\\b" << "\\belse\\b"
<< "\\bshort\\b" << "\\bunsigned\\b" << "\\bcontinue\\b" << "\\blong\\b"
<< "\\bfor\\b" << "\\bsigned\\b" << "\\bvoid\\b" << "\\switch\\b"
<< "\\bdefault\\b" << "\\bgoto\\b" << "\\bsizeof\\b" << "\\bcase\\b"
<< "\\bvolatile\\b" << "\\bdo\\b" << "\\bif\\b" << "\\benum\\b"
<< "\\static\\b" << "\\while\\b"; << "\\bregister\\b"
<< "\\btypedef\\b"
<< "\\bchar\\b"
<< "\\bextern\\b"
<< "\\breturn\\b"
<< "\\bunion\\b"
<< "\\bconst\\b"
<< "\\bfloat\\b"
<< "\\bshort\\b"
<< "\\bunsigned\\b"
<< "\\bcontinue\\b"
<< "\\bfor\\b"
<< "\\bsigned\\b"
<< "\\bvoid\\b"
<< "\\bdefault\\b"
<< "\\bgoto\\b"
<< "\\bsizeof\\b"
<< "\\bvolatile\\b"
<< "\\bdo\\b"
<< "\\bif\\b"
<< "\\static\\b"
<< "\\while\\b";
QTextCharFormat keywordFormat; QTextCharFormat keywordFormat;
keywordFormat.setForeground(QColor(80, 200, 215)); keywordFormat.setForeground(QColor(80, 200, 215));
@ -103,8 +123,7 @@ void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
setCurrentBlockState(1); setCurrentBlockState(1);
commentLength = text.length() - startIndex; commentLength = text.length() - startIndex;
} else { } else {
commentLength = endIndex - startIndex commentLength = endIndex - startIndex + match.capturedLength();
+ match.capturedLength();
} }
setFormat(startIndex, commentLength, multiLineCommentFormat); setFormat(startIndex, commentLength, multiLineCommentFormat);

View File

@ -40,7 +40,8 @@ protected:
void highlightBlock(const QString &text) override; void highlightBlock(const QString &text) override;
private: private:
struct HighlightingRule { struct HighlightingRule
{
QRegularExpression pattern; QRegularExpression pattern;
QTextCharFormat format; QTextCharFormat format;
}; };

View File

@ -10,10 +10,10 @@
/** /**
* @brief Class for temporary modifying Rizin `e` configuration. * @brief Class for temporary modifying Rizin `e` configuration.
* *
* Modified values will be restored at the end of scope. This is useful when using a Rizin command that can only * Modified values will be restored at the end of scope. This is useful when using a Rizin command
* be configured using `e` configuration and doesn't accept arguments. TempConfig::set calls can be chained. * that can only be configured using `e` configuration and doesn't accept arguments. TempConfig::set
* If a command or Rizin method accepts arguments directly it is preferred to use those instead of temporary modifying * calls can be chained. If a command or Rizin method accepts arguments directly it is preferred to
* global configuration. * use those instead of temporary modifying global configuration.
* *
* \code * \code
* { * {

View File

@ -22,15 +22,15 @@
#endif #endif
#if CUTTER_UPDATE_WORKER_AVAILABLE #if CUTTER_UPDATE_WORKER_AVAILABLE
UpdateWorker::UpdateWorker(QObject *parent) : UpdateWorker::UpdateWorker(QObject *parent) : QObject(parent), pending(false)
QObject(parent), pending(false)
{ {
connect(&t, &QTimer::timeout, this, [this]() { connect(&t, &QTimer::timeout, this, [this]() {
if (pending) { if (pending) {
disconnect(checkReply, nullptr, this, nullptr); disconnect(checkReply, nullptr, this, nullptr);
checkReply->close(); checkReply->close();
checkReply->deleteLater(); checkReply->deleteLater();
emit checkComplete(QVersionNumber(), tr("Time limit exceeded during version check. Please check your " emit checkComplete(QVersionNumber(),
tr("Time limit exceeded during version check. Please check your "
"internet connection and try again.")); "internet connection and try again."));
} }
}); });
@ -47,8 +47,7 @@ void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
t.start(); t.start();
checkReply = nm.get(request); checkReply = nm.get(request);
connect(checkReply, &QNetworkReply::finished, connect(checkReply, &QNetworkReply::finished, this, &UpdateWorker::serveVersionCheckReply);
this, &UpdateWorker::serveVersionCheckReply);
pending = true; pending = true;
} }
@ -60,26 +59,27 @@ void UpdateWorker::download(QString filename, QString version)
QNetworkRequest request; QNetworkRequest request;
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
QUrl url(QString("https://github.com/rizinorg/cutter/releases/" QUrl url(QString("https://github.com/rizinorg/cutter/releases/"
"download/v%1/%2").arg(version).arg(getRepositoryFileName())); "download/v%1/%2")
.arg(version)
.arg(getRepositoryFileName()));
request.setUrl(url); request.setUrl(url);
downloadReply = nm.get(request); downloadReply = nm.get(request);
connect(downloadReply, &QNetworkReply::downloadProgress, connect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
this, &UpdateWorker::process); connect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
connect(downloadReply, &QNetworkReply::finished,
this, &UpdateWorker::serveDownloadFinish);
} }
void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton) void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
{ {
QMessageBox mb; QMessageBox mb;
mb.setWindowTitle(tr("Version control")); mb.setWindowTitle(tr("Version control"));
mb.setText(tr("There is an update available for Cutter.<br/>") mb.setText(tr("There is an update available for Cutter.<br/>") + "<b>" + tr("Current version:")
+ "<b>" + tr("Current version:") + "</b> " CUTTER_VERSION_FULL "<br/>" + "</b> " CUTTER_VERSION_FULL "<br/>" + "<b>" + tr("Latest version:") + "</b> "
+ "<b>" + tr("Latest version:") + "</b> " + latestVersion.toString() + "<br/><br/>" + latestVersion.toString() + "<br/><br/>"
+ tr("For update, please check the link:<br/>") + tr("For update, please check the link:<br/>")
+ QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">" + QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">"
"https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>").arg(latestVersion.toString()) "https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>")
.arg(latestVersion.toString())
+ tr("or click \"Download\" to download latest version of Cutter.")); + tr("or click \"Download\" to download latest version of Cutter."));
if (showDontCheckForUpdatesButton) { if (showDontCheckForUpdatesButton) {
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok); mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok);
@ -93,31 +93,23 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
if (ret == QMessageBox::Reset) { if (ret == QMessageBox::Reset) {
Config()->setAutoUpdateEnabled(false); Config()->setAutoUpdateEnabled(false);
} else if (ret == QMessageBox::Save) { } else if (ret == QMessageBox::Save) {
QString fullFileName = QString fullFileName = QFileDialog::getSaveFileName(
QFileDialog::getSaveFileName(nullptr, nullptr, tr("Choose directory for downloading"),
tr("Choose directory for downloading"), QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator()
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + getRepositoryFileName(),
QDir::separator() + getRepositoryFileName(),
QString("%1 (*.%1)").arg(getRepositeryExt())); QString("%1 (*.%1)").arg(getRepositeryExt()));
if (!fullFileName.isEmpty()) { if (!fullFileName.isEmpty()) {
QProgressDialog progressDial(tr("Downloading update..."), QProgressDialog progressDial(tr("Downloading update..."), tr("Cancel"), 0, 100);
tr("Cancel"),
0, 100);
connect(this, &UpdateWorker::downloadProcess, &progressDial, connect(this, &UpdateWorker::downloadProcess, &progressDial,
[&progressDial](size_t curr, size_t total) { [&progressDial](size_t curr, size_t total) {
progressDial.setValue(100.0f * curr / total); progressDial.setValue(100.0f * curr / total);
}); });
connect(&progressDial, &QProgressDialog::canceled, connect(&progressDial, &QProgressDialog::canceled, this, &UpdateWorker::abortDownload);
this, &UpdateWorker::abortDownload); connect(this, &UpdateWorker::downloadFinished, &progressDial, &QProgressDialog::cancel);
connect(this, &UpdateWorker::downloadFinished, connect(this, &UpdateWorker::downloadFinished, this, [](QString filePath) {
&progressDial, &QProgressDialog::cancel); QMessageBox info(QMessageBox::Information, tr("Download finished!"),
connect(this, &UpdateWorker::downloadFinished, this,
[](QString filePath){
QMessageBox info(QMessageBox::Information,
tr("Download finished!"),
tr("Latest version of Cutter was succesfully downloaded!"), tr("Latest version of Cutter was succesfully downloaded!"),
QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok, QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok, nullptr);
nullptr);
info.button(QMessageBox::Open)->setText(tr("Open file")); info.button(QMessageBox::Open)->setText(tr("Open file"));
info.button(QMessageBox::Yes)->setText(tr("Open download folder")); info.button(QMessageBox::Yes)->setText(tr("Open download folder"));
int r = info.exec(); int r = info.exec();
@ -140,10 +132,8 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
void UpdateWorker::abortDownload() void UpdateWorker::abortDownload()
{ {
disconnect(downloadReply, &QNetworkReply::finished, disconnect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish);
this, &UpdateWorker::serveDownloadFinish); disconnect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process);
disconnect(downloadReply, &QNetworkReply::downloadProgress,
this, &UpdateWorker::process);
downloadReply->close(); downloadReply->close();
downloadReply->deleteLater(); downloadReply->deleteLater();
downloadFile.remove(); downloadFile.remove();
@ -157,7 +147,10 @@ void UpdateWorker::serveVersionCheckReply()
if (checkReply->error()) { if (checkReply->error()) {
errStr = checkReply->errorString(); errStr = checkReply->errorString();
} else { } else {
versionReplyStr = QJsonDocument::fromJson(checkReply->readAll()).object().value("tag_name").toString(); versionReplyStr = QJsonDocument::fromJson(checkReply->readAll())
.object()
.value("tag_name")
.toString();
versionReplyStr.remove('v'); versionReplyStr.remove('v');
} }
QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr); QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
@ -207,11 +200,9 @@ QString UpdateWorker::getRepositoryFileName() const
# elif defined(Q_OS_MACOS) # elif defined(Q_OS_MACOS)
downloadFileName = "Cutter-v%1-x%2.macOS.dmg"; downloadFileName = "Cutter-v%1-x%2.macOS.dmg";
# endif # endif
downloadFileName = downloadFileName downloadFileName =
.arg(latestVersion.toString()) downloadFileName.arg(latestVersion.toString())
.arg(QSysInfo::buildAbi().split('-').at(2).contains("64") .arg(QSysInfo::buildAbi().split('-').at(2).contains("64") ? "64" : "32");
? "64"
: "32");
return downloadFileName; return downloadFileName;
} }

View File

@ -68,7 +68,8 @@ public:
void showUpdateDialog(bool showDontCheckForUpdatesButton); void showUpdateDialog(bool showDontCheckForUpdatesButton);
/** /**
* @return the version of this Cutter binary, derived from CUTTER_VERSION_MAJOR, CUTTER_VERSION_MINOR and CUTTER_VERSION_PATCH. * @return the version of this Cutter binary, derived from CUTTER_VERSION_MAJOR,
* CUTTER_VERSION_MINOR and CUTTER_VERSION_PATCH.
*/ */
static QVersionNumber currentVersionNumber(); static QVersionNumber currentVersionNumber();
@ -102,7 +103,6 @@ signals:
*/ */
void downloadProcess(size_t bytesReceived, size_t bytesTotal); void downloadProcess(size_t bytesReceived, size_t bytesTotal);
/** /**
* @fn UpdateWorker::downloadFinished(QString filename) * @fn UpdateWorker::downloadFinished(QString filename)
* *

View File

@ -120,14 +120,14 @@ static void updateOwnedCharPtr(char *&variable, const QString &newValue)
variable = strdup(data.data()); variable = strdup(data.data());
} }
static QString fromOwnedCharPtr(char *str) { static QString fromOwnedCharPtr(char *str)
{
QString result(str ? str : ""); QString result(str ? str : "");
rz_mem_free(str); rz_mem_free(str);
return result; return result;
} }
RzCoreLocked::RzCoreLocked(CutterCore *core) RzCoreLocked::RzCoreLocked(CutterCore *core) : core(core)
: core(core)
{ {
core->coreMutex.lock(); core->coreMutex.lock();
assert(core->coreLockDepth >= 0); assert(core->coreLockDepth >= 0);
@ -167,10 +167,11 @@ static void cutterREventCallback(RzEvent *, int type, void *user, void *data)
core->handleREvent(type, data); core->handleREvent(type, data);
} }
CutterCore::CutterCore(QObject *parent): CutterCore::CutterCore(QObject *parent)
QObject(parent) : QObject(parent)
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
, coreMutex(QMutex::Recursive) ,
coreMutex(QMutex::Recursive)
#endif #endif
{ {
} }
@ -200,7 +201,8 @@ void CutterCore::initialize(bool loadPlugins)
// Executable is in Contents/MacOS, prefix is Contents/Resources/rz // Executable is in Contents/MacOS, prefix is Contents/Resources/rz
prefix.cdUp(); prefix.cdUp();
prefix.cd("Resources"); prefix.cd("Resources");
qInfo() << "Setting Rizin prefix =" << prefix.absolutePath() << " for macOS Application Bundle."; qInfo() << "Setting Rizin prefix =" << prefix.absolutePath()
<< " for macOS Application Bundle.";
# endif # endif
setConfig("dir.prefix", prefix.absolutePath()); setConfig("dir.prefix", prefix.absolutePath());
@ -258,7 +260,8 @@ QVector<QString> CutterCore::getCutterRCFilePaths() const
for (auto &location : locations) { for (auto &location : locations) {
result.push_back(QFileInfo(QDir(location), ".cutterrc").absoluteFilePath()); result.push_back(QFileInfo(QDir(location), ".cutterrc").absoluteFilePath());
} }
result.push_back(QFileInfo(getCutterRCDefaultDirectory(), "rc").absoluteFilePath()); // File in config editor is from this path result.push_back(QFileInfo(getCutterRCDefaultDirectory(), "rc")
.absoluteFilePath()); // File in config editor is from this path
return result; return result;
} }
@ -288,7 +291,6 @@ void CutterCore::loadDefaultCutterRC()
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData()); rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
} }
QList<QString> CutterCore::sdbList(QString path) QList<QString> CutterCore::sdbList(QString path)
{ {
CORE_LOCK(); CORE_LOCK();
@ -297,7 +299,8 @@ QList<QString> CutterCore::sdbList(QString path)
if (root) { if (root) {
void *vsi; void *vsi;
ls_iter_t *iter; ls_iter_t *iter;
ls_foreach(root->ns, iter, vsi) { ls_foreach(root->ns, iter, vsi)
{
SdbNs *nsi = (SdbNs *)vsi; SdbNs *nsi = (SdbNs *)vsi;
list << nsi->name; list << nsi->name;
} }
@ -320,7 +323,8 @@ QList<QString> CutterCore::sdbListKeys(QString path)
void *vsi; void *vsi;
ls_iter_t *iter; ls_iter_t *iter;
SdbListPtr l = makeSdbListPtr(sdb_foreach_list(root, false)); SdbListPtr l = makeSdbListPtr(sdb_foreach_list(root, false));
ls_foreach(l, iter, vsi) { ls_foreach(l, iter, vsi)
{
SdbKv *nsi = (SdbKv *)vsi; SdbKv *nsi = (SdbKv *)vsi;
list << reinterpret_cast<char *>(nsi->base.key); list << reinterpret_cast<char *>(nsi->base.key);
} }
@ -344,7 +348,8 @@ bool CutterCore::sdbSet(QString path, QString key, QString val)
{ {
CORE_LOCK(); CORE_LOCK();
Sdb *db = sdb_ns_path(core->sdb, path.toUtf8().constData(), 1); Sdb *db = sdb_ns_path(core->sdb, path.toUtf8().constData(), 1);
if (!db) return false; if (!db)
return false;
return sdb_set(db, key.toUtf8().constData(), val.toUtf8().constData(), 0); return sdb_set(db, key.toUtf8().constData(), val.toUtf8().constData(), 0);
} }
@ -375,7 +380,8 @@ bool CutterCore::isRedirectableDebugee()
} }
// We are only able to redirect locally debugged unix processes // We are only able to redirect locally debugged unix processes
QJsonArray openFilesArray = cmdj("oj").array();; QJsonArray openFilesArray = cmdj("oj").array();
;
for (QJsonValue value : openFilesArray) { for (QJsonValue value : openFilesArray) {
QJsonObject openFile = value.toObject(); QJsonObject openFile = value.toObject();
QString URI = openFile["uri"].toString(); QString URI = openFile["uri"].toString();
@ -407,7 +413,8 @@ bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask>
QString res = task.data()->getResult(); QString res = task.data()->getResult();
if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) { if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) {
msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable this in Preferences"); msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can "
"disable this in Preferences");
} }
}); });
@ -529,7 +536,8 @@ QJsonDocument CutterCore::parseJson(const char *res, const char *cmd)
eprintf("Failed to parse JSON for command \"%s\": %s\n", cmd, eprintf("Failed to parse JSON for command \"%s\": %s\n", cmd,
jsonError.errorString().toLocal8Bit().constData()); jsonError.errorString().toLocal8Bit().constData());
} else { } else {
eprintf("Failed to parse JSON: %s\n", jsonError.errorString().toLocal8Bit().constData()); eprintf("Failed to parse JSON: %s\n",
jsonError.errorString().toLocal8Bit().constData());
} }
const int MAX_JSON_DUMP_SIZE = 8 * 1024; const int MAX_JSON_DUMP_SIZE = 8 * 1024;
if (json.length() > MAX_JSON_DUMP_SIZE) { if (json.length() > MAX_JSON_DUMP_SIZE) {
@ -560,7 +568,8 @@ QStringList CutterCore::autocomplete(const QString &cmd, RzLinePromptType prompt
QStringList r; QStringList r;
r.reserve(rz_pvector_len(&completion.args)); r.reserve(rz_pvector_len(&completion.args));
for (size_t i = 0; i < rz_pvector_len(&completion.args); i++) { for (size_t i = 0; i < rz_pvector_len(&completion.args); i++) {
r.push_back(QString::fromUtf8(reinterpret_cast<const char *>(rz_pvector_at(&completion.args, i)))); r.push_back(QString::fromUtf8(
reinterpret_cast<const char *>(rz_pvector_at(&completion.args, i))));
} }
rz_line_completion_fini(&completion); rz_line_completion_fini(&completion);
@ -579,8 +588,8 @@ QStringList CutterCore::autocomplete(const QString &cmd, RzLinePromptType prompt
* @param forceBinPlugin * @param forceBinPlugin
* @return * @return
*/ */
bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int va, bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int va, bool loadbin,
bool loadbin, const QString &forceBinPlugin) const QString &forceBinPlugin)
{ {
CORE_LOCK(); CORE_LOCK();
RzCoreFile *f; RzCoreFile *f;
@ -616,8 +625,8 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
} }
auto iod = core->io ? core->io->desc : NULL; auto iod = core->io ? core->io->desc : NULL;
auto debug = core->file && iod && (core->file->fd == iod->fd) && iod->plugin && \ auto debug =
iod->plugin->isdbg; core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg;
if (!debug && rz_flag_get(core->flags, "entry0")) { if (!debug && rz_flag_get(core->flags, "entry0")) {
rz_core_cmd0(core, "s entry0"); rz_core_cmd0(core, "s entry0");
@ -636,7 +645,8 @@ bool CutterCore::tryFile(QString path, bool rw)
CORE_LOCK(); CORE_LOCK();
RzCoreFile *cf; RzCoreFile *cf;
int flags = RZ_PERM_R; int flags = RZ_PERM_R;
if (rw) flags = RZ_PERM_RW; if (rw)
flags = RZ_PERM_RW;
cf = rz_core_file_open(core, path.toUtf8().constData(), flags, 0LL); cf = rz_core_file_open(core, path.toUtf8().constData(), flags, 0LL);
if (!cf) { if (!cf) {
return false; return false;
@ -657,7 +667,8 @@ bool CutterCore::mapFile(QString path, RVA mapaddr)
{ {
CORE_LOCK(); CORE_LOCK();
RVA addr = mapaddr != RVA_INVALID ? mapaddr : 0; RVA addr = mapaddr != RVA_INVALID ? mapaddr : 0;
ut64 baddr = Core()->getFileInfo().object()["bin"].toObject()["baddr"].toVariant().toULongLong(); ut64 baddr =
Core()->getFileInfo().object()["bin"].toObject()["baddr"].toVariant().toULongLong();
if (rz_core_file_open(core, path.toUtf8().constData(), RZ_PERM_RX, addr)) { if (rz_core_file_open(core, path.toUtf8().constData(), RZ_PERM_RX, addr)) {
rz_core_bin_load(core, path.toUtf8().constData(), baddr); rz_core_bin_load(core, path.toUtf8().constData(), baddr);
} else { } else {
@ -688,7 +699,8 @@ void CutterCore::renameFunctionVariable(QString newName, QString oldName, RVA fu
{ {
CORE_LOCK(); CORE_LOCK();
RzAnalysisFunction *function = rz_analysis_get_function_at(core->analysis, functionAddress); RzAnalysisFunction *function = rz_analysis_get_function_at(core->analysis, functionAddress);
RzAnalysisVar *variable = rz_analysis_function_get_var_byname(function, oldName.toUtf8().constData()); RzAnalysisVar *variable =
rz_analysis_function_get_var_byname(function, oldName.toUtf8().constData());
if (variable) { if (variable) {
rz_analysis_var_rename(variable, newName.toUtf8().constData(), true); rz_analysis_var_rename(variable, newName.toUtf8().constData(), true);
} }
@ -709,12 +721,20 @@ void CutterCore::delFlag(const QString &name)
QString CutterCore::getInstructionBytes(RVA addr) QString CutterCore::getInstructionBytes(RVA addr)
{ {
return cmdj("aoj @ " + RAddressString(addr)).array().first().toObject()[RJsonKey::bytes].toString(); return cmdj("aoj @ " + RAddressString(addr))
.array()
.first()
.toObject()[RJsonKey::bytes]
.toString();
} }
QString CutterCore::getInstructionOpcode(RVA addr) QString CutterCore::getInstructionOpcode(RVA addr)
{ {
return cmdj("aoj @ " + RAddressString(addr)).array().first().toObject()[RJsonKey::opcode].toString(); return cmdj("aoj @ " + RAddressString(addr))
.array()
.first()
.toObject()[RJsonKey::opcode]
.toString();
} }
void CutterCore::editInstruction(RVA addr, const QString &inst) void CutterCore::editInstruction(RVA addr, const QString &inst)
@ -755,27 +775,22 @@ void CutterCore::setToCode(RVA addr)
void CutterCore::setAsString(RVA addr, int size, StringTypeFormats type) void CutterCore::setAsString(RVA addr, int size, StringTypeFormats type)
{ {
if(RVA_INVALID == addr) if (RVA_INVALID == addr) {
{
return; return;
} }
QString command; QString command;
switch(type) switch (type) {
{ case StringTypeFormats::None: {
case StringTypeFormats::None:
{
command = "Cs"; command = "Cs";
break; break;
} }
case StringTypeFormats::ASCII_LATIN1: case StringTypeFormats::ASCII_LATIN1: {
{
command = "Csa"; command = "Csa";
break; break;
} }
case StringTypeFormats::UTF8: case StringTypeFormats::UTF8: {
{
command = "Cs8"; command = "Cs8";
break; break;
} }
@ -950,8 +965,9 @@ RVA CutterCore::nextOpAddr(RVA startAddr, int count)
{ {
CORE_LOCK(); CORE_LOCK();
QJsonArray array = Core()->cmdj("pdj " + QString::number(count + 1) + "@" + QString::number( QJsonArray array =
startAddr)).array(); Core()->cmdj("pdj " + QString::number(count + 1) + "@" + QString::number(startAddr))
.array();
if (array.isEmpty()) { if (array.isEmpty()) {
return startAddr + 1; return startAddr + 1;
} }
@ -1126,7 +1142,8 @@ QByteArray CutterCore::assemble(const QString &code)
QString CutterCore::disassemble(const QByteArray &data) QString CutterCore::disassemble(const QByteArray &data)
{ {
CORE_LOCK(); CORE_LOCK();
RzAsmCode *ac = rz_asm_mdisassemble(core->rasm, reinterpret_cast<const ut8 *>(data.constData()), data.length()); RzAsmCode *ac = rz_asm_mdisassemble(core->rasm, reinterpret_cast<const ut8 *>(data.constData()),
data.length());
QString code; QString code;
if (ac && ac->assembly) { if (ac && ac->assembly) {
code = QString::fromUtf8(ac->assembly); code = QString::fromUtf8(ac->assembly);
@ -1144,7 +1161,9 @@ RzAnalysisFunction *CutterCore::functionIn(ut64 addr)
{ {
CORE_LOCK(); CORE_LOCK();
RzList *fcns = rz_analysis_get_functions_in(core->analysis, addr); RzList *fcns = rz_analysis_get_functions_in(core->analysis, addr);
RzAnalysisFunction *fcn = !rz_list_empty(fcns) ? reinterpret_cast<RzAnalysisFunction *>(rz_list_first(fcns)) : nullptr; RzAnalysisFunction *fcn = !rz_list_empty(fcns)
? reinterpret_cast<RzAnalysisFunction *>(rz_list_first(fcns))
: nullptr;
rz_list_free(fcns); rz_list_free(fcns);
return fcn; return fcn;
} }
@ -1182,7 +1201,8 @@ RVA CutterCore::getFunctionEnd(RVA addr)
/** /**
* @brief finds the last instruction of a function in a given address * @brief finds the last instruction of a function in a given address
* @param addr - an address which belongs to a function * @param addr - an address which belongs to a function
* @returns if function exists, return the address of its last instruction. Otherwise return RVA_INVALID * @returns if function exists, return the address of its last instruction. Otherwise return
* RVA_INVALID
*/ */
RVA CutterCore::getLastFunctionInstruction(RVA addr) RVA CutterCore::getLastFunctionInstruction(RVA addr)
{ {
@ -1213,7 +1233,8 @@ void CutterCore::cmdEsil(const char *command)
// use cmd and not cmdRaw because of unexpected commands // use cmd and not cmdRaw because of unexpected commands
QString res = cmd(command); QString res = cmd(command);
if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) { if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) {
msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable this in Preferences"); msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable "
"this in Preferences");
} }
} }
@ -1241,8 +1262,13 @@ QJsonDocument CutterCore::getRegistersInfo()
RVA CutterCore::getOffsetJump(RVA addr) RVA CutterCore::getOffsetJump(RVA addr)
{ {
bool ok; bool ok;
RVA value = cmdj("aoj @" + QString::number( RVA value = cmdj("aoj @" + QString::number(addr))
addr)).array().first().toObject().value(RJsonKey::jump).toVariant().toULongLong(&ok); .array()
.first()
.toObject()
.value(RJsonKey::jump)
.toVariant()
.toULongLong(&ok);
if (!ok) { if (!ok) {
return RVA_INVALID; return RVA_INVALID;
@ -1251,7 +1277,6 @@ RVA CutterCore::getOffsetJump(RVA addr)
return value; return value;
} }
QList<Decompiler *> CutterCore::getDecompilers() QList<Decompiler *> CutterCore::getDecompilers()
{ {
return decompilers; return decompilers;
@ -1332,7 +1357,8 @@ RefDescription CutterCore::formatRefDesc(QJsonObject refItem)
break; break;
} }
if (!refItem["value"].isNull()) { if (!refItem["value"].isNull()) {
appendVar(desc.ref, RAddressString(refItem["value"].toVariant().toULongLong()), " ", ""); appendVar(desc.ref, RAddressString(refItem["value"].toVariant().toULongLong()), " ",
"");
} }
refItem = refItem["ref"].toObject(); refItem = refItem["ref"].toObject();
} while (!refItem.empty()); } while (!refItem.empty());
@ -1398,7 +1424,8 @@ QList<QJsonObject> CutterCore::getStack(int size, int depth)
return stack; return stack;
} }
QJsonObject CutterCore::getAddrRefs(RVA addr, int depth) { QJsonObject CutterCore::getAddrRefs(RVA addr, int depth)
{
QJsonObject json; QJsonObject json;
if (depth < 1 || addr == UT64_MAX) { if (depth < 1 || addr == UT64_MAX) {
return json; return json;
@ -1845,13 +1872,14 @@ void CutterCore::stopDebug()
currentlyEmulating = false; currentlyEmulating = false;
} else if (currentlyAttachedToPID != -1) { } else if (currentlyAttachedToPID != -1) {
// Use cmd because cmdRaw would not work with command concatenation // Use cmd because cmdRaw would not work with command concatenation
cmd(QString("dp- %1; o %2; .ar-").arg( cmd(QString("dp- %1; o %2; .ar-")
QString::number(currentlyAttachedToPID), currentlyOpenFile)); .arg(QString::number(currentlyAttachedToPID), currentlyOpenFile));
currentlyAttachedToPID = -1; currentlyAttachedToPID = -1;
} else { } else {
QString ptraceFiles = ""; QString ptraceFiles = "";
// close ptrace file descriptors left open // close ptrace file descriptors left open
QJsonArray openFilesArray = cmdj("oj").array();; QJsonArray openFilesArray = cmdj("oj").array();
;
for (QJsonValue value : openFilesArray) { for (QJsonValue value : openFilesArray) {
QJsonObject openFile = value.toObject(); QJsonObject openFile = value.toObject();
QString URI = openFile["uri"].toString(); QString URI = openFile["uri"].toString();
@ -2110,8 +2138,7 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config)
module = moduleNameData.data(); module = moduleNameData.data();
} }
breakpoint = rz_debug_bp_add(core->dbg, address, (config.hw && watchpoint_prot == 0), breakpoint = rz_debug_bp_add(core->dbg, address, (config.hw && watchpoint_prot == 0),
watchpoint_prot, watchpoint_prot, watchpoint_prot, watchpoint_prot, module, config.moduleDelta);
module, config.moduleDelta);
if (!breakpoint) { if (!breakpoint) {
QMessageBox::critical(nullptr, tr("Breakpoint error"), tr("Failed to create breakpoint")); QMessageBox::critical(nullptr, tr("Breakpoint error"), tr("Failed to create breakpoint"));
return; return;
@ -2128,8 +2155,8 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config)
} }
int index = std::find(core->dbg->bp->bps_idx, int index = std::find(core->dbg->bp->bps_idx,
core->dbg->bp->bps_idx + core->dbg->bp->bps_idx_count, core->dbg->bp->bps_idx + core->dbg->bp->bps_idx_count, breakpoint)
breakpoint) - core->dbg->bp->bps_idx; - core->dbg->bp->bps_idx;
breakpoint->enabled = config.enabled; breakpoint->enabled = config.enabled;
if (config.trace) { if (config.trace) {
@ -2240,7 +2267,6 @@ QList<BreakpointDescription> CutterCore::getBreakpoints()
return ret; return ret;
} }
QList<RVA> CutterCore::getBreakpointsAddresses() QList<RVA> CutterCore::getBreakpointsAddresses()
{ {
QList<RVA> bpAddresses; QList<RVA> bpAddresses;
@ -2257,8 +2283,7 @@ QList<RVA> CutterCore::getBreakpointsInFunction(RVA funcAddr)
QList<RVA> functionBreakpoints; QList<RVA> functionBreakpoints;
// Use std manipulations to take only the breakpoints that belong to this function // Use std manipulations to take only the breakpoints that belong to this function
std::copy_if(allBreakpoints.begin(), std::copy_if(allBreakpoints.begin(), allBreakpoints.end(),
allBreakpoints.end(),
std::back_inserter(functionBreakpoints), std::back_inserter(functionBreakpoints),
[this, funcAddr](RVA BPadd) { return getFunctionStart(BPadd) == funcAddr; }); [this, funcAddr](RVA BPadd) { return getFunctionStart(BPadd) == funcAddr; });
return functionBreakpoints; return functionBreakpoints;
@ -2399,9 +2424,7 @@ QStringList CutterCore::getAsmPluginNames()
QStringList ret; QStringList ret;
RzAsmPlugin *ap; RzAsmPlugin *ap;
CutterRListForeach(core->rasm->plugins, it, RzAsmPlugin, ap) { CutterRListForeach(core->rasm->plugins, it, RzAsmPlugin, ap) { ret << ap->name; }
ret << ap->name;
}
return ret; return ret;
} }
@ -2413,9 +2436,7 @@ QStringList CutterCore::getAnalPluginNames()
QStringList ret; QStringList ret;
RzAnalysisPlugin *ap; RzAnalysisPlugin *ap;
CutterRListForeach(core->analysis->plugins, it, RzAnalysisPlugin, ap) { CutterRListForeach(core->analysis->plugins, it, RzAnalysisPlugin, ap) { ret << ap->name; }
ret << ap->name;
}
return ret; return ret;
} }
@ -2498,7 +2519,8 @@ QList<RzAsmPluginDescription> CutterCore::getRAsmPluginDescriptions()
QList<RzAsmPluginDescription> ret; QList<RzAsmPluginDescription> ret;
RzAsmPlugin *ap; RzAsmPlugin *ap;
CutterRListForeach(core->rasm->plugins, it, RzAsmPlugin, ap) { CutterRListForeach(core->rasm->plugins, it, RzAsmPlugin, ap)
{
RzAsmPluginDescription plugin; RzAsmPluginDescription plugin;
plugin.name = ap->name; plugin.name = ap->name;
@ -2524,16 +2546,17 @@ QList<FunctionDescription> CutterCore::getAllFunctions()
RzListIter *iter; RzListIter *iter;
RzAnalysisFunction *fcn; RzAnalysisFunction *fcn;
CutterRListForeach (core->analysis->fcns, iter, RzAnalysisFunction, fcn) { CutterRListForeach(core->analysis->fcns, iter, RzAnalysisFunction, fcn)
{
FunctionDescription function; FunctionDescription function;
function.offset = fcn->addr; function.offset = fcn->addr;
function.linearSize = rz_analysis_function_linear_size(fcn); function.linearSize = rz_analysis_function_linear_size(fcn);
function.nargs = rz_analysis_var_count(core->analysis, fcn, 'b', 1) + function.nargs = rz_analysis_var_count(core->analysis, fcn, 'b', 1)
rz_analysis_var_count(core->analysis, fcn, 'r', 1) + + rz_analysis_var_count(core->analysis, fcn, 'r', 1)
rz_analysis_var_count(core->analysis, fcn, 's', 1); + rz_analysis_var_count(core->analysis, fcn, 's', 1);
function.nlocals = rz_analysis_var_count(core->analysis, fcn, 'b', 0) + function.nlocals = rz_analysis_var_count(core->analysis, fcn, 'b', 0)
rz_analysis_var_count(core->analysis, fcn, 'r', 0) + + rz_analysis_var_count(core->analysis, fcn, 'r', 0)
rz_analysis_var_count(core->analysis, fcn, 's', 0); + rz_analysis_var_count(core->analysis, fcn, 's', 0);
function.nbbs = rz_list_length(fcn->bbs); function.nbbs = rz_list_length(fcn->bbs);
function.calltype = fcn->cc ? QString::fromUtf8(fcn->cc) : QString(); function.calltype = fcn->cc ? QString::fromUtf8(fcn->cc) : QString();
function.name = fcn->name ? QString::fromUtf8(fcn->name) : QString(); function.name = fcn->name ? QString::fromUtf8(fcn->name) : QString();
@ -2604,7 +2627,8 @@ QList<SymbolDescription> CutterCore::getAllSymbols()
RzBinSymbol *bs; RzBinSymbol *bs;
if (core && core->bin && core->bin->cur && core->bin->cur->o) { if (core && core->bin && core->bin->cur && core->bin->cur->o) {
CutterRListForeach(core->bin->cur->o->symbols, it, RzBinSymbol, bs) { CutterRListForeach(core->bin->cur->o->symbols, it, RzBinSymbol, bs)
{
QString type = QString(bs->bind) + " " + QString(bs->type); QString type = QString(bs->bind) + " " + QString(bs->type);
SymbolDescription symbol; SymbolDescription symbol;
symbol.vaddr = bs->vaddr; symbol.vaddr = bs->vaddr;
@ -2617,7 +2641,8 @@ QList<SymbolDescription> CutterCore::getAllSymbols()
/* list entrypoints as symbols too */ /* list entrypoints as symbols too */
int n = 0; int n = 0;
RzBinAddr *entry; RzBinAddr *entry;
CutterRListForeach(core->bin->cur->o->entries, it, RzBinAddr, entry) { CutterRListForeach(core->bin->cur->o->entries, it, RzBinAddr, entry)
{
SymbolDescription symbol; SymbolDescription symbol;
symbol.vaddr = entry->vaddr; symbol.vaddr = entry->vaddr;
symbol.name = QString("entry") + QString::number(n++); symbol.name = QString("entry") + QString::number(n++);
@ -2715,7 +2740,8 @@ QList<RelocDescription> CutterCore::getAllRelocs()
auto relocs = core->bin->cur->o->relocs; auto relocs = core->bin->cur->o->relocs;
RBIter iter; RBIter iter;
RzBinReloc *br; RzBinReloc *br;
rz_rbtree_foreach (relocs, iter, br, RzBinReloc, vrb) { rz_rbtree_foreach(relocs, iter, br, RzBinReloc, vrb)
{
RelocDescription reloc; RelocDescription reloc;
reloc.vaddr = br->vaddr; reloc.vaddr = br->vaddr;
@ -3015,7 +3041,8 @@ QList<QString> CutterCore::getAllAnalClasses(bool sorted)
SdbListIter *it; SdbListIter *it;
void *entry; void *entry;
ls_foreach(l, it, entry) { ls_foreach(l, it, entry)
{
auto kv = reinterpret_cast<SdbKv *>(entry); auto kv = reinterpret_cast<SdbKv *>(entry);
ret.append(QString::fromUtf8(reinterpret_cast<const char *>(kv->base.key))); ret.append(QString::fromUtf8(reinterpret_cast<const char *>(kv->base.key)));
} }
@ -3035,7 +3062,8 @@ QList<AnalMethodDescription> CutterCore::getAnalClassMethods(const QString &cls)
ret.reserve(static_cast<int>(meths->len)); ret.reserve(static_cast<int>(meths->len));
RzAnalysisMethod *meth; RzAnalysisMethod *meth;
CutterRVectorForeach(meths, meth, RzAnalysisMethod) { CutterRVectorForeach(meths, meth, RzAnalysisMethod)
{
AnalMethodDescription desc; AnalMethodDescription desc;
desc.name = QString::fromUtf8(meth->name); desc.name = QString::fromUtf8(meth->name);
desc.addr = meth->addr; desc.addr = meth->addr;
@ -3059,7 +3087,8 @@ QList<AnalBaseClassDescription> CutterCore::getAnalClassBaseClasses(const QStrin
ret.reserve(static_cast<int>(bases->len)); ret.reserve(static_cast<int>(bases->len));
RzAnalysisBaseClass *base; RzAnalysisBaseClass *base;
CutterRVectorForeach(bases, base, RzAnalysisBaseClass) { CutterRVectorForeach(bases, base, RzAnalysisBaseClass)
{
AnalBaseClassDescription desc; AnalBaseClassDescription desc;
desc.id = QString::fromUtf8(base->id); desc.id = QString::fromUtf8(base->id);
desc.offset = base->offset; desc.offset = base->offset;
@ -3083,7 +3112,8 @@ QList<AnalVTableDescription> CutterCore::getAnalClassVTables(const QString &cls)
acVtables.reserve(static_cast<int>(vtables->len)); acVtables.reserve(static_cast<int>(vtables->len));
RzAnalysisVTable *vtable; RzAnalysisVTable *vtable;
CutterRVectorForeach(vtables, vtable, RzAnalysisVTable) { CutterRVectorForeach(vtables, vtable, RzAnalysisVTable)
{
AnalVTableDescription desc; AnalVTableDescription desc;
desc.id = QString::fromUtf8(vtable->id); desc.id = QString::fromUtf8(vtable->id);
desc.offset = vtable->offset; desc.offset = vtable->offset;
@ -3104,7 +3134,8 @@ void CutterCore::createNewClass(const QString &cls)
void CutterCore::renameClass(const QString &oldName, const QString &newName) void CutterCore::renameClass(const QString &oldName, const QString &newName)
{ {
CORE_LOCK(); CORE_LOCK();
rz_analysis_class_rename(core->analysis, oldName.toUtf8().constData(), newName.toUtf8().constData()); rz_analysis_class_rename(core->analysis, oldName.toUtf8().constData(),
newName.toUtf8().constData());
} }
void CutterCore::deleteClass(const QString &cls) void CutterCore::deleteClass(const QString &cls)
@ -3117,7 +3148,9 @@ bool CutterCore::getAnalMethod(const QString &cls, const QString &meth, AnalMeth
{ {
CORE_LOCK(); CORE_LOCK();
RzAnalysisMethod analMeth; RzAnalysisMethod analMeth;
if (rz_analysis_class_method_get(core->analysis, cls.toUtf8().constData(), meth.toUtf8().constData(), &analMeth) != RZ_ANALYSIS_CLASS_ERR_SUCCESS) { if (rz_analysis_class_method_get(core->analysis, cls.toUtf8().constData(),
meth.toUtf8().constData(), &analMeth)
!= RZ_ANALYSIS_CLASS_ERR_SUCCESS) {
return false; return false;
} }
desc->name = QString::fromUtf8(analMeth.name); desc->name = QString::fromUtf8(analMeth.name);
@ -3138,10 +3171,13 @@ void CutterCore::setAnalMethod(const QString &className, const AnalMethodDescrip
rz_analysis_class_method_fini(&analMeth); rz_analysis_class_method_fini(&analMeth);
} }
void CutterCore::renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName) void CutterCore::renameAnalMethod(const QString &className, const QString &oldMethodName,
const QString &newMethodName)
{ {
CORE_LOCK(); CORE_LOCK();
rz_analysis_class_method_rename(core->analysis, className.toUtf8().constData(), oldMethodName.toUtf8().constData(), newMethodName.toUtf8().constData()); rz_analysis_class_method_rename(core->analysis, className.toUtf8().constData(),
oldMethodName.toUtf8().constData(),
newMethodName.toUtf8().constData());
} }
QList<ResourcesDescription> CutterCore::getAllResources() QList<ResourcesDescription> CutterCore::getAllResources()
@ -3381,8 +3417,12 @@ QList<SearchDescription> CutterCore::getAllSearch(QString searchFor, QString spa
exp.code += gadget[RJsonKey::opcode].toString() + "; "; exp.code += gadget[RJsonKey::opcode].toString() + "; ";
} }
exp.offset = exp.offset = searchObject[RJsonKey::opcodes]
searchObject[RJsonKey::opcodes].toArray().first().toObject()[RJsonKey::offset].toVariant().toULongLong(); .toArray()
.first()
.toObject()[RJsonKey::offset]
.toVariant()
.toULongLong();
exp.size = searchObject[RJsonKey::size].toVariant().toULongLong(); exp.size = searchObject[RJsonKey::size].toVariant().toULongLong();
searchRef << exp; searchRef << exp;
@ -3462,7 +3502,8 @@ BlockStatistics CutterCore::getBlockStatistics(unsigned int blocksCount)
return blockStats; return blockStats;
} }
QList<XrefDescription> CutterCore::getXRefsForVariable(QString variableName, bool findWrites, RVA offset) QList<XrefDescription> CutterCore::getXRefsForVariable(QString variableName, bool findWrites,
RVA offset)
{ {
QList<XrefDescription> xrefList = QList<XrefDescription>(); QList<XrefDescription> xrefList = QList<XrefDescription>();
QJsonArray xrefsArray; QJsonArray xrefsArray;
@ -3642,8 +3683,9 @@ void CutterCore::loadPDB(const QString &file)
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines) QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
{ {
QJsonArray array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ") + QString::number( QJsonArray array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ")
offset)).array(); + QString::number(offset))
.array();
QList<DisassemblyLine> r; QList<DisassemblyLine> r;
for (const QJsonValueRef &value : array) { for (const QJsonValueRef &value : array) {
@ -3652,16 +3694,13 @@ QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
line.offset = object[RJsonKey::offset].toVariant().toULongLong(); line.offset = object[RJsonKey::offset].toVariant().toULongLong();
line.text = ansiEscapeToHtml(object[RJsonKey::text].toString()); line.text = ansiEscapeToHtml(object[RJsonKey::text].toString());
const auto &arrow = object[RJsonKey::arrow]; const auto &arrow = object[RJsonKey::arrow];
line.arrow = arrow.isNull() line.arrow = arrow.isNull() ? RVA_INVALID : arrow.toVariant().toULongLong();
? RVA_INVALID
: arrow.toVariant().toULongLong();
r << line; r << line;
} }
return r; return r;
} }
/** /**
* @brief return hexdump of <size> from an <offset> by a given formats * @brief return hexdump of <size> from an <offset> by a given formats
* @param address - the address from which to print the hexdump * @param address - the address from which to print the hexdump
@ -3691,10 +3730,7 @@ QString CutterCore::hexdump(RVA address, int size, HexdumpFormats format)
break; break;
} }
return cmdRawAt(QString("%1 %2") return cmdRawAt(QString("%1 %2").arg(command).arg(size), address);
.arg(command)
.arg(size),
address);
} }
QByteArray CutterCore::hexStringToBytes(const QString &hex) QByteArray CutterCore::hexStringToBytes(const QString &hex)
@ -3728,7 +3764,8 @@ QString CutterCore::getVersionInformation()
{ {
int i; int i;
QString versionInfo; QString versionInfo;
struct vcs_t { struct vcs_t
{
const char *name; const char *name;
const char *(*callback)(); const char *(*callback)();
} vcs[] = { } vcs[] = {
@ -3864,9 +3901,11 @@ bool CutterCore::isWriteModeEnabled()
{ {
using namespace std; using namespace std;
QJsonArray ans = cmdj("oj").array(); QJsonArray ans = cmdj("oj").array();
return find_if(begin(ans), end(ans), [](const QJsonValue &v) { return find_if(begin(ans), end(ans),
return v.toObject().value("raised").toBool(); [](const QJsonValue &v) { return v.toObject().value("raised").toBool(); })
})->toObject().value("writable").toBool(); ->toObject()
.value("writable")
.toBool();
} }
/** /**
@ -3880,8 +3919,7 @@ QStringList CutterCore::getDisassemblyPreview(RVA address, int num_of_lines)
{ {
// temporarily simplify the disasm output to get it colorful and simple to read // temporarily simplify the disasm output to get it colorful and simple to read
TempConfig tempConfig; TempConfig tempConfig;
tempConfig tempConfig.set("scr.color", COLOR_MODE_16M)
.set("scr.color", COLOR_MODE_16M)
.set("asm.lines", false) .set("asm.lines", false)
.set("asm.var", false) .set("asm.var", false)
.set("asm.comments", false) .set("asm.comments", false)
@ -3917,12 +3955,12 @@ QString CutterCore::getHexdumpPreview(RVA address, int size)
{ {
// temporarily simplify the disasm output to get it colorful and simple to read // temporarily simplify the disasm output to get it colorful and simple to read
TempConfig tempConfig; TempConfig tempConfig;
tempConfig tempConfig.set("scr.color", COLOR_MODE_16M)
.set("scr.color", COLOR_MODE_16M)
.set("asm.offset", true) .set("asm.offset", true)
.set("hex.header", false) .set("hex.header", false)
.set("hex.cols", 16); .set("hex.cols", 16);
return ansiEscapeToHtml(hexdump(address, size, HexdumpFormats::Normal)).replace(QLatin1Char('\n'), "<br>"); return ansiEscapeToHtml(hexdump(address, size, HexdumpFormats::Normal))
.replace(QLatin1Char('\n'), "<br>");
} }
QByteArray CutterCore::ioRead(RVA addr, int len) QByteArray CutterCore::ioRead(RVA addr, int len)

View File

@ -75,12 +75,17 @@ public:
* If you want to seek to an address, you should use CutterCore::seek. * If you want to seek to an address, you should use CutterCore::seek.
*/ */
bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task); bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task);
bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task) { return asyncCmd(str.toUtf8().constData(), task); } bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task)
{
return asyncCmd(str.toUtf8().constData(), task);
}
/** /**
* @brief Execute a Rizin command \a cmd. By nature, the API * @brief Execute a Rizin command \a cmd. By nature, the API
* is executing raw commands, and thus ignores multiple commands and overcome command injections. * is executing raw commands, and thus ignores multiple commands and overcome command
* @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf") will result in them treated as arguments to first command. * injections.
* @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf")
* will result in them treated as arguments to first command.
* @return the output of the command * @return the output of the command
*/ */
QString cmdRaw(const char *cmd); QString cmdRaw(const char *cmd);
@ -91,12 +96,12 @@ public:
QString cmdRaw(const QString &cmd) { return cmdRaw(cmd.toUtf8().constData()); }; QString cmdRaw(const QString &cmd) { return cmdRaw(cmd.toUtf8().constData()); };
/** /**
* @brief Execute a Rizin command \a cmd at \a address. The function will preform a silent seek to the address * @brief Execute a Rizin command \a cmd at \a address. The function will preform a silent seek
* without triggering the seekChanged event nor adding new entries to the seek history. By nature, the * to the address without triggering the seekChanged event nor adding new entries to the seek
* API is executing a single command without going through Rizin shell, and thus ignores multiple commands * history. By nature, the API is executing a single command without going through Rizin shell,
* and tries to overcome command injections. * and thus ignores multiple commands and tries to overcome command injections.
* @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then * @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7
* only the first command will be executed. * && pdf") then only the first command will be executed.
* @param address - an address to which Cutter will temporarily seek. * @param address - an address to which Cutter will temporarily seek.
* @return the output of the command * @return the output of the command
*/ */
@ -105,12 +110,18 @@ public:
/** /**
* @brief a wrapper around cmdRawAt(const char *cmd, RVA address). * @brief a wrapper around cmdRawAt(const char *cmd, RVA address).
*/ */
QString cmdRawAt(const QString &str, RVA address) { return cmdRawAt(str.toUtf8().constData(), address); } QString cmdRawAt(const QString &str, RVA address)
{
return cmdRawAt(str.toUtf8().constData(), address);
}
QJsonDocument cmdj(const char *str); QJsonDocument cmdj(const char *str);
QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); } QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
QJsonDocument cmdjAt(const char *str, RVA address); QJsonDocument cmdjAt(const char *str, RVA address);
QStringList cmdList(const char *str) { return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS); } QStringList cmdList(const char *str)
{
return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS);
}
QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); } QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); }
QString cmdTask(const QString &str); QString cmdTask(const QString &str);
QJsonDocument cmdjTask(const QString &str); QJsonDocument cmdjTask(const QString &str);
@ -132,7 +143,10 @@ public:
* If you want to seek to an address, you should use CutterCore::seek. * If you want to seek to an address, you should use CutterCore::seek.
*/ */
bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task); bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task);
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task) { return asyncCmdEsil(command.toUtf8().constData(), task); } bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task)
{
return asyncCmdEsil(command.toUtf8().constData(), task);
}
QString getVersionInformation(); QString getVersionInformation();
QJsonDocument parseJson(const char *res, const char *cmd = nullptr); QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
@ -253,7 +267,8 @@ public:
void renameClass(const QString &oldName, const QString &newName); void renameClass(const QString &oldName, const QString &newName);
void deleteClass(const QString &cls); void deleteClass(const QString &cls);
bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc); bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc);
void renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); void renameAnalMethod(const QString &className, const QString &oldMethodName,
const QString &newMethodName);
void setAnalMethod(const QString &cls, const AnalMethodDescription &meth); void setAnalMethod(const QString &cls, const AnalMethodDescription &meth);
/* File related methods */ /* File related methods */
@ -445,7 +460,8 @@ public:
* Register a new decompiler * Register a new decompiler
* *
* The decompiler must have a unique id, otherwise this method will fail. * The decompiler must have a unique id, otherwise this method will fail.
* The decompiler's parent will be set to this CutterCore instance, so it will automatically be freed later. * The decompiler's parent will be set to this CutterCore instance, so it will automatically be
* freed later.
* *
* @return whether the decompiler was registered successfully * @return whether the decompiler was registered successfully
*/ */
@ -536,7 +552,6 @@ public:
*/ */
QString getTypeAsC(QString name, QString category); QString getTypeAsC(QString name, QString category);
/** /**
* @brief Adds new types * @brief Adds new types
* It first uses the rz_parse_c_string() function from Rizin API to parse the * It first uses the rz_parse_c_string() function from Rizin API to parse the
@ -572,11 +587,12 @@ public:
* @brief Fetches all the writes or reads to the specified local variable 'variableName' * @brief Fetches all the writes or reads to the specified local variable 'variableName'
* in the function in which the specified offset is a part of. * in the function in which the specified offset is a part of.
* @param variableName Name of the local variable. * @param variableName Name of the local variable.
* @param findWrites If this is true, then locations at which modification happen to the specified * @param findWrites If this is true, then locations at which modification happen to the
* local variable is fetched. Else, the locations at which the local is variable is read is fetched. * specified local variable is fetched. Else, the locations at which the local is variable is
* read is fetched.
* @param offset An offset in the function in which the specified local variable exist. * @param offset An offset in the function in which the specified local variable exist.
* @return A list of XrefDescriptions that contains details of all the writes or reads that happen to the * @return A list of XrefDescriptions that contains details of all the writes or reads that
* variable 'variableName'. * happen to the variable 'variableName'.
*/ */
QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset); QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset);
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
@ -622,9 +638,9 @@ public:
void commitWriteCache(); void commitWriteCache();
/** /**
* @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it will be immediately * @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it
* committed to the file on disk, thus modify the file. This function wrap Rizin function which re-open the file with * will be immediately committed to the file on disk, thus modify the file. This function wrap
* the desired permissions. * Rizin function which re-open the file with the desired permissions.
* @param enabled * @param enabled
*/ */
void setWriteMode(bool enabled); void setWriteMode(bool enabled);

View File

@ -16,11 +16,14 @@
// Rizin list iteration macros // Rizin list iteration macros
#define CutterRListForeach(list, it, type, x) \ #define CutterRListForeach(list, it, type, x) \
if (list) for (it = list->head; it && ((x=static_cast<type*>(it->data))); it = it->n) if (list) \
for (it = list->head; it && ((x = static_cast<type *>(it->data))); it = it->n)
#define CutterRVectorForeach(vec, it, type) \ #define CutterRVectorForeach(vec, it, type) \
if ((vec) && (vec)->a) \ if ((vec) && (vec)->a) \
for (it = (type *)(vec)->a; (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); it = (type *)((char *)it + (vec)->elem_size)) for (it = (type *)(vec)->a; \
(char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); \
it = (type *)((char *)it + (vec)->elem_size))
// Global information for Cutter // Global information for Cutter
#define APPNAME "Cutter" #define APPNAME "Cutter"
@ -31,7 +34,8 @@
typedef ut64 RVA; typedef ut64 RVA;
/** /**
* @brief Maximum value of RVA. Do NOT use this for specifying invalid values, use RVA_INVALID instead. * @brief Maximum value of RVA. Do NOT use this for specifying invalid values, use RVA_INVALID
* instead.
*/ */
#define RVA_MAX UT64_MAX #define RVA_MAX UT64_MAX
@ -61,7 +65,6 @@ inline QString RHexString(RVA size)
# define CUTTER_EXPORT Q_DECL_IMPORT # define CUTTER_EXPORT Q_DECL_IMPORT
#endif #endif
#if defined(__has_cpp_attribute) #if defined(__has_cpp_attribute)
# if __has_cpp_attribute(deprecated) # if __has_cpp_attribute(deprecated)
# define CUTTER_DEPRECATED(msg) [[deprecated(msg)]] # define CUTTER_DEPRECATED(msg) [[deprecated(msg)]]
@ -72,4 +75,3 @@ inline QString RHexString(RVA size)
#endif #endif
#endif // CUTTERCORE_H #endif // CUTTERCORE_H

View File

@ -12,7 +12,8 @@
#include <QColor> #include <QColor>
#include "core/CutterCommon.h" #include "core/CutterCommon.h"
struct FunctionDescription { struct FunctionDescription
{
RVA offset; RVA offset;
RVA linearSize; RVA linearSize;
RVA nargs; RVA nargs;
@ -31,7 +32,8 @@ struct FunctionDescription {
} }
}; };
struct ImportDescription { struct ImportDescription
{
RVA plt; RVA plt;
int ordinal; int ordinal;
QString bind; QString bind;
@ -40,7 +42,8 @@ struct ImportDescription {
QString libname; QString libname;
}; };
struct ExportDescription { struct ExportDescription
{
RVA vaddr; RVA vaddr;
RVA paddr; RVA paddr;
RVA size; RVA size;
@ -69,40 +72,46 @@ struct ZignatureDescription
QStringList refs; QStringList refs;
}; };
struct TypeDescription { struct TypeDescription
{
QString type; QString type;
int size; int size;
QString format; QString format;
QString category; QString category;
}; };
struct SearchDescription { struct SearchDescription
{
RVA offset; RVA offset;
int size; int size;
QString code; QString code;
QString data; QString data;
}; };
struct SymbolDescription { struct SymbolDescription
{
RVA vaddr; RVA vaddr;
QString bind; QString bind;
QString type; QString type;
QString name; QString name;
}; };
struct CommentDescription { struct CommentDescription
{
RVA offset; RVA offset;
QString name; QString name;
}; };
struct RelocDescription { struct RelocDescription
{
RVA vaddr; RVA vaddr;
RVA paddr; RVA paddr;
QString type; QString type;
QString name; QString name;
}; };
struct StringDescription { struct StringDescription
{
RVA vaddr; RVA vaddr;
QString string; QString string;
QString type; QString type;
@ -111,18 +120,21 @@ struct StringDescription {
ut32 size; ut32 size;
}; };
struct FlagspaceDescription { struct FlagspaceDescription
{
QString name; QString name;
}; };
struct FlagDescription { struct FlagDescription
{
RVA offset; RVA offset;
RVA size; RVA size;
QString name; QString name;
QString realname; QString realname;
}; };
struct SectionDescription { struct SectionDescription
{
RVA vaddr; RVA vaddr;
RVA paddr; RVA paddr;
RVA size; RVA size;
@ -132,7 +144,8 @@ struct SectionDescription {
QString entropy; QString entropy;
}; };
struct SegmentDescription { struct SegmentDescription
{
RVA vaddr; RVA vaddr;
RVA paddr; RVA paddr;
RVA size; RVA size;
@ -141,7 +154,8 @@ struct SegmentDescription {
QString perm; QString perm;
}; };
struct EntrypointDescription { struct EntrypointDescription
{
RVA vaddr; RVA vaddr;
RVA paddr; RVA paddr;
RVA baddr; RVA baddr;
@ -150,7 +164,8 @@ struct EntrypointDescription {
QString type; QString type;
}; };
struct XrefDescription { struct XrefDescription
{
RVA from; RVA from;
QString from_str; QString from_str;
RVA to; RVA to;
@ -158,14 +173,16 @@ struct XrefDescription {
QString type; QString type;
}; };
struct RzBinPluginDescription { struct RzBinPluginDescription
{
QString name; QString name;
QString description; QString description;
QString license; QString license;
QString type; QString type;
}; };
struct RzIOPluginDescription { struct RzIOPluginDescription
{
QString name; QString name;
QString description; QString description;
QString license; QString license;
@ -173,12 +190,14 @@ struct RzIOPluginDescription {
QList<QString> uris; QList<QString> uris;
}; };
struct RzCorePluginDescription { struct RzCorePluginDescription
{
QString name; QString name;
QString description; QString description;
}; };
struct RzAsmPluginDescription { struct RzAsmPluginDescription
{
QString name; QString name;
QString architecture; QString architecture;
QString author; QString author;
@ -188,29 +207,34 @@ struct RzAsmPluginDescription {
QString license; QString license;
}; };
struct DisassemblyLine { struct DisassemblyLine
{
RVA offset; RVA offset;
QString text; QString text;
RVA arrow; RVA arrow;
}; };
struct BinClassBaseClassDescription { struct BinClassBaseClassDescription
{
QString name; QString name;
RVA offset; RVA offset;
}; };
struct BinClassMethodDescription { struct BinClassMethodDescription
{
QString name; QString name;
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
st64 vtableOffset = -1; st64 vtableOffset = -1;
}; };
struct BinClassFieldDescription { struct BinClassFieldDescription
{
QString name; QString name;
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
}; };
struct BinClassDescription { struct BinClassDescription
{
QString name; QString name;
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
RVA vtableAddr = RVA_INVALID; RVA vtableAddr = RVA_INVALID;
@ -220,25 +244,29 @@ struct BinClassDescription {
QList<BinClassFieldDescription> fields; QList<BinClassFieldDescription> fields;
}; };
struct AnalMethodDescription { struct AnalMethodDescription
{
QString name; QString name;
RVA addr; RVA addr;
st64 vtableOffset; st64 vtableOffset;
}; };
struct AnalBaseClassDescription { struct AnalBaseClassDescription
{
QString id; QString id;
RVA offset; RVA offset;
QString className; QString className;
}; };
struct AnalVTableDescription { struct AnalVTableDescription
{
QString id; QString id;
ut64 offset; ut64 offset;
ut64 addr; ut64 addr;
}; };
struct ResourcesDescription { struct ResourcesDescription
{
QString name; QString name;
RVA vaddr; RVA vaddr;
ut64 index; ut64 index;
@ -247,12 +275,14 @@ struct ResourcesDescription {
QString lang; QString lang;
}; };
struct VTableDescription { struct VTableDescription
{
RVA addr; RVA addr;
QList<BinClassMethodDescription> methods; QList<BinClassMethodDescription> methods;
}; };
struct BlockDescription { struct BlockDescription
{
RVA addr; RVA addr;
RVA size; RVA size;
int flags; int flags;
@ -264,14 +294,16 @@ struct BlockDescription {
ut8 rwx; ut8 rwx;
}; };
struct BlockStatistics { struct BlockStatistics
{
RVA from; RVA from;
RVA to; RVA to;
RVA blocksize; RVA blocksize;
QList<BlockDescription> blocks; QList<BlockDescription> blocks;
}; };
struct MemoryMapDescription { struct MemoryMapDescription
{
RVA addrStart; RVA addrStart;
RVA addrEnd; RVA addrEnd;
QString name; QString name;
@ -280,7 +312,8 @@ struct MemoryMapDescription {
QString permission; QString permission;
}; };
struct BreakpointDescription { struct BreakpointDescription
{
enum PositionType { enum PositionType {
Address, Address,
Named, Named,
@ -302,26 +335,30 @@ struct BreakpointDescription {
bool enabled = true; bool enabled = true;
}; };
struct ProcessDescription { struct ProcessDescription
{
int pid; int pid;
int uid; int uid;
QString status; QString status;
QString path; QString path;
}; };
struct RefDescription { struct RefDescription
{
QString ref; QString ref;
QColor refColor; QColor refColor;
}; };
struct VariableDescription { struct VariableDescription
{
enum class RefType { SP, BP, Reg }; enum class RefType { SP, BP, Reg };
RefType refType; RefType refType;
QString name; QString name;
QString type; QString type;
}; };
struct RegisterRefValueDescription { struct RegisterRefValueDescription
{
QString name; QString name;
QString value; QString value;
QString ref; QString ref;

View File

@ -117,14 +117,14 @@
#define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)") #define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)")
template<class T> template<class T>
T *getNewInstance(MainWindow *m) { return new T(m); } T *getNewInstance(MainWindow *m)
{
return new T(m);
}
using namespace Cutter; using namespace Cutter;
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow)
QMainWindow(parent),
core(Core()),
ui(new Ui::MainWindow)
{ {
tabsOnTop = false; tabsOnTop = false;
configuration = Config(); configuration = Config();
@ -132,9 +132,7 @@ MainWindow::MainWindow(QWidget *parent) :
initUI(); initUI();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow() {}
{
}
void MainWindow::initUI() void MainWindow::initUI()
{ {
@ -146,18 +144,19 @@ void MainWindow::initUI()
connect(ui->actionExtraDecompiler, &QAction::triggered, this, &MainWindow::addExtraDecompiler); connect(ui->actionExtraDecompiler, &QAction::triggered, this, &MainWindow::addExtraDecompiler);
connect(ui->actionExtraGraph, &QAction::triggered, this, &MainWindow::addExtraGraph); connect(ui->actionExtraGraph, &QAction::triggered, this, &MainWindow::addExtraGraph);
connect(ui->actionExtraDisassembly, &QAction::triggered, this, &MainWindow::addExtraDisassembly); connect(ui->actionExtraDisassembly, &QAction::triggered, this,
&MainWindow::addExtraDisassembly);
connect(ui->actionExtraHexdump, &QAction::triggered, this, &MainWindow::addExtraHexdump); connect(ui->actionExtraHexdump, &QAction::triggered, this, &MainWindow::addExtraHexdump);
connect(ui->actionCommitChanges, &QAction::triggered, this, [this]() { connect(ui->actionCommitChanges, &QAction::triggered, this,
Core()->commitWriteCache(); [this]() { Core()->commitWriteCache(); });
});
ui->actionCommitChanges->setEnabled(false); ui->actionCommitChanges->setEnabled(false);
connect(Core(), &CutterCore::ioCacheChanged, ui->actionCommitChanges, &QAction::setEnabled); connect(Core(), &CutterCore::ioCacheChanged, ui->actionCommitChanges, &QAction::setEnabled);
widgetTypeToConstructorMap.insert(GraphWidget::getWidgetType(), getNewInstance<GraphWidget>); widgetTypeToConstructorMap.insert(GraphWidget::getWidgetType(), getNewInstance<GraphWidget>);
widgetTypeToConstructorMap.insert(DisassemblyWidget::getWidgetType(), widgetTypeToConstructorMap.insert(DisassemblyWidget::getWidgetType(),
getNewInstance<DisassemblyWidget>); getNewInstance<DisassemblyWidget>);
widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(), getNewInstance<HexdumpWidget>); widgetTypeToConstructorMap.insert(HexdumpWidget::getWidgetType(),
getNewInstance<HexdumpWidget>);
widgetTypeToConstructorMap.insert(DecompilerWidget::getWidgetType(), widgetTypeToConstructorMap.insert(DecompilerWidget::getWidgetType(),
getNewInstance<DecompilerWidget>); getNewInstance<DecompilerWidget>);
@ -175,13 +174,17 @@ void MainWindow::initUI()
// G and S goes to goto entry // G and S goes to goto entry
QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this); QShortcut *goto_shortcut = new QShortcut(QKeySequence(Qt::Key_G), this);
connect(goto_shortcut, &QShortcut::activated, this->omnibar, [this](){ this->omnibar->setFocus(); }); connect(goto_shortcut, &QShortcut::activated, this->omnibar,
[this]() { this->omnibar->setFocus(); });
QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this); QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this);
connect(seek_shortcut, &QShortcut::activated, this->omnibar, [this](){ this->omnibar->setFocus(); }); connect(seek_shortcut, &QShortcut::activated, this->omnibar,
[this]() { this->omnibar->setFocus(); });
QShortcut *seek_to_func_end_shortcut = new QShortcut(QKeySequence(Qt::Key_Dollar), this); QShortcut *seek_to_func_end_shortcut = new QShortcut(QKeySequence(Qt::Key_Dollar), this);
connect(seek_to_func_end_shortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionLastInstruction); connect(seek_to_func_end_shortcut, &QShortcut::activated, this,
&MainWindow::seekToFunctionLastInstruction);
QShortcut *seek_to_func_start_shortcut = new QShortcut(QKeySequence(Qt::Key_AsciiCircum), this); QShortcut *seek_to_func_start_shortcut = new QShortcut(QKeySequence(Qt::Key_AsciiCircum), this);
connect(seek_to_func_start_shortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionStart); connect(seek_to_func_start_shortcut, &QShortcut::activated, this,
&MainWindow::seekToFunctionStart);
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this); QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
connect(refresh_shortcut, &QShortcut::activated, this, &MainWindow::refreshAll); connect(refresh_shortcut, &QShortcut::activated, this, &MainWindow::refreshAll);
@ -192,13 +195,11 @@ void MainWindow::initUI()
connect(core, &CutterCore::toggleDebugView, this, &MainWindow::toggleDebugView); connect(core, &CutterCore::toggleDebugView, this, &MainWindow::toggleDebugView);
connect(core, &CutterCore::newMessage, connect(core, &CutterCore::newMessage, this->consoleDock, &ConsoleWidget::addOutput);
this->consoleDock, &ConsoleWidget::addOutput); connect(core, &CutterCore::newDebugMessage, this->consoleDock, &ConsoleWidget::addDebugOutput);
connect(core, &CutterCore::newDebugMessage,
this->consoleDock, &ConsoleWidget::addDebugOutput);
connect(core, &CutterCore::showMemoryWidgetRequested, connect(core, &CutterCore::showMemoryWidgetRequested, this,
this, static_cast<void(MainWindow::*)()>(&MainWindow::showMemoryWidget)); static_cast<void (MainWindow::*)()>(&MainWindow::showMemoryWidget));
updateTasksIndicator(); updateTasksIndicator();
connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this, connect(core->getAsyncTaskManager(), &AsyncTaskManager::tasksChanged, this,
@ -247,7 +248,8 @@ void MainWindow::initUI()
ui->menuWindows->setToolTipsVisible(true); ui->menuWindows->setToolTipsVisible(true);
if (plugins.empty()) { if (plugins.empty()) {
ui->menuPlugins->menuAction()->setToolTip( ui->menuPlugins->menuAction()->setToolTip(
tr("No plugins are installed. Check the plugins section on Cutter documentation to learn more.")); tr("No plugins are installed. Check the plugins section on Cutter documentation to "
"learn more."));
ui->menuPlugins->setEnabled(false); ui->menuPlugins->setEnabled(false);
} else if (ui->menuPlugins->isEmpty()) { } else if (ui->menuPlugins->isEmpty()) {
ui->menuPlugins->menuAction()->setToolTip( ui->menuPlugins->menuAction()->setToolTip(
@ -342,10 +344,10 @@ void MainWindow::initToolBar()
this->visualNavbar->setMovable(false); this->visualNavbar->setMovable(false);
addToolBarBreak(Qt::TopToolBarArea); addToolBarBreak(Qt::TopToolBarArea);
addToolBar(visualNavbar); addToolBar(visualNavbar);
QObject::connect(configuration, &Configuration::colorsUpdated, this, [this]() { QObject::connect(configuration, &Configuration::colorsUpdated, this,
this->visualNavbar->updateGraphicsScene(); [this]() { this->visualNavbar->updateGraphicsScene(); });
}); QObject::connect(configuration, &Configuration::interfaceThemeChanged, this,
QObject::connect(configuration, &Configuration::interfaceThemeChanged, this, &MainWindow::chooseThemeIcons); &MainWindow::chooseThemeIcons);
} }
void MainWindow::initDocks() void MainWindow::initDocks()
@ -356,9 +358,8 @@ void MainWindow::initDocks()
overviewDock = new OverviewWidget(this); overviewDock = new OverviewWidget(this);
overviewDock->hide(); overviewDock->hide();
actionOverview = overviewDock->toggleViewAction(); actionOverview = overviewDock->toggleViewAction();
connect(overviewDock, &OverviewWidget::isAvailableChanged, this, [this](bool isAvailable) { connect(overviewDock, &OverviewWidget::isAvailableChanged, this,
actionOverview->setEnabled(isAvailable); [this](bool isAvailable) { actionOverview->setEnabled(isAvailable); });
});
actionOverview->setEnabled(overviewDock->getIsAvailable()); actionOverview->setEnabled(overviewDock->getIsAvailable());
actionOverview->setChecked(overviewDock->getUserOpened()); actionOverview->setChecked(overviewDock->getUserOpened());
@ -370,14 +371,10 @@ void MainWindow::initDocks()
stringsDock = new StringsWidget(this); stringsDock = new StringsWidget(this);
QList<CutterDockWidget *> debugDocks = { QList<CutterDockWidget *> debugDocks = {
stackDock = new StackWidget(this), stackDock = new StackWidget(this), threadsDock = new ThreadsWidget(this),
threadsDock = new ThreadsWidget(this), processesDock = new ProcessesWidget(this), backtraceDock = new BacktraceWidget(this),
processesDock = new ProcessesWidget(this), registersDock = new RegistersWidget(this), memoryMapDock = new MemoryMapWidget(this),
backtraceDock = new BacktraceWidget(this), breakpointDock = new BreakpointWidget(this), registerRefsDock = new RegisterRefsWidget(this)
registersDock = new RegistersWidget(this),
memoryMapDock = new MemoryMapWidget(this),
breakpointDock = new BreakpointWidget(this),
registerRefsDock = new RegisterRefsWidget(this)
}; };
QList<CutterDockWidget *> infoDocks = { QList<CutterDockWidget *> infoDocks = {
@ -415,15 +412,8 @@ void MainWindow::initDocks()
}; };
QList<CutterDockWidget *> windowDocks = { QList<CutterDockWidget *> windowDocks = {
dashboardDock, dashboardDock, nullptr, functionsDock, overviewDock, nullptr,
nullptr, searchDock, stringsDock, typesDock, nullptr,
functionsDock,
overviewDock,
nullptr,
searchDock,
stringsDock,
typesDock,
nullptr,
}; };
ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks)); ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks));
QList<CutterDockWidget *> windowDocks2 = { QList<CutterDockWidget *> windowDocks2 = {
@ -556,8 +546,8 @@ void MainWindow::openNewFileFailed()
mb.setIcon(QMessageBox::Critical); mb.setIcon(QMessageBox::Critical);
mb.setStandardButtons(QMessageBox::Ok); mb.setStandardButtons(QMessageBox::Ok);
mb.setWindowTitle(tr("Cannot open file!")); mb.setWindowTitle(tr("Cannot open file!"));
mb.setText( mb.setText(tr("Could not open the file! Make sure the file exists and that you have the "
tr("Could not open the file! Make sure the file exists and that you have the correct permissions.")); "correct permissions."));
mb.exec(); mb.exec();
} }
@ -615,9 +605,7 @@ bool MainWindow::openProject(const QString &file)
const char *s = rz_project_err_message(err); const char *s = rz_project_err_message(err);
QString msg = tr("Failed to open project: %1").arg(QString::fromUtf8(s)); QString msg = tr("Failed to open project: %1").arg(QString::fromUtf8(s));
RzListIter *it; RzListIter *it;
CutterRListForeach(res, it, const char, s) { CutterRListForeach(res, it, const char, s) { msg += "\n" + QString::fromUtf8(s); }
msg += "\n" + QString::fromUtf8(s);
}
QMessageBox::critical(this, tr("Open Project"), msg); QMessageBox::critical(this, tr("Open Project"), msg);
rz_list_free(res); rz_list_free(res);
return false; return false;
@ -656,7 +644,6 @@ void MainWindow::finalizeOpen()
Config()->adjustColorThemeDarkness(); Config()->adjustColorThemeDarkness();
setViewLayout(getViewLayout(LAYOUT_DEFAULT)); setViewLayout(getViewLayout(LAYOUT_DEFAULT));
// Set focus to disasm or graph widget // Set focus to disasm or graph widget
// Graph with function in it has focus priority over DisasmWidget. // Graph with function in it has focus priority over DisasmWidget.
// If there are no graph/disasm widgets focus on MainWindow // If there are no graph/disasm widgets focus on MainWindow
@ -730,7 +717,8 @@ void MainWindow::showProjectSaveError(RzProjectErr err)
return; return;
} }
const char *s = rz_project_err_message(err); const char *s = rz_project_err_message(err);
QMessageBox::critical(this, tr("Save Project"), tr("Failed to save project: %1").arg(QString::fromUtf8(s))); QMessageBox::critical(this, tr("Save Project"),
tr("Failed to save project: %1").arg(QString::fromUtf8(s)));
} }
void MainWindow::refreshOmniBar(const QStringList &flags) void MainWindow::refreshOmniBar(const QStringList &flags)
@ -757,9 +745,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
activateWindow(); activateWindow();
QMessageBox::StandardButton ret = QMessageBox::question(this, APPNAME, QMessageBox::StandardButton ret = QMessageBox::question(
tr("Do you really want to exit?\nSave your project before closing!"), this, APPNAME, tr("Do you really want to exit?\nSave your project before closing!"),
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)); (QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard
| QMessageBox::Cancel));
if (ret == QMessageBox::Cancel) { if (ret == QMessageBox::Cancel) {
event->ignore(); event->ignore();
return; return;
@ -855,12 +844,10 @@ void MainWindow::lockDocks(bool lock)
} }
} else { } else {
for (QDockWidget *dockWidget : findChildren<QDockWidget *>()) { for (QDockWidget *dockWidget : findChildren<QDockWidget *>()) {
dockWidget->setFeatures(QDockWidget::DockWidgetClosable | dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable
QDockWidget::DockWidgetMovable | | QDockWidget::DockWidgetFloatable);
QDockWidget::DockWidgetFloatable);
} }
} }
} }
void MainWindow::restoreDocks() void MainWindow::restoreDocks()
@ -924,22 +911,15 @@ void MainWindow::restoreDocks()
bool MainWindow::isDebugWidget(QDockWidget *dock) const bool MainWindow::isDebugWidget(QDockWidget *dock) const
{ {
return dock == stackDock || return dock == stackDock || dock == registersDock || dock == backtraceDock
dock == registersDock || || dock == threadsDock || dock == memoryMapDock || dock == breakpointDock
dock == backtraceDock || || dock == processesDock || dock == registerRefsDock;
dock == threadsDock ||
dock == memoryMapDock ||
dock == breakpointDock ||
dock == processesDock ||
dock == registerRefsDock;
} }
bool MainWindow::isExtraMemoryWidget(QDockWidget *dock) const bool MainWindow::isExtraMemoryWidget(QDockWidget *dock) const
{ {
return qobject_cast<GraphWidget*>(dock) || return qobject_cast<GraphWidget *>(dock) || qobject_cast<HexdumpWidget *>(dock)
qobject_cast<HexdumpWidget*>(dock) || || qobject_cast<DisassemblyWidget *>(dock) || qobject_cast<DecompilerWidget *>(dock);
qobject_cast<DisassemblyWidget*>(dock) ||
qobject_cast<DecompilerWidget*>(dock);
} }
MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore() MemoryWidgetType MainWindow::getMemoryWidgetTypeToRestore()
@ -1005,8 +985,7 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHi
for (auto &dock : dockWidgets) { for (auto &dock : dockWidgets) {
if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) { if (auto memoryWidget = qobject_cast<MemoryDockWidget *>(dock)) {
if (memoryWidget->getType() == MemoryWidgetType::Graph if (memoryWidget->getType() == MemoryWidgetType::Graph
|| memoryWidget->getType() == MemoryWidgetType::Decompiler) || memoryWidget->getType() == MemoryWidgetType::Decompiler) {
{
if (addressType == AddressTypeHint::Data) { if (addressType == AddressTypeHint::Data) {
continue; continue;
} }
@ -1037,9 +1016,8 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHi
menu->addSeparator(); menu->addSeparator();
auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) { auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) {
QAction *action = new QAction(label, menu); QAction *action = new QAction(label, menu);
connect(action, &QAction::triggered, this, [this, address, type]() { connect(action, &QAction::triggered, this,
addNewMemoryWidget(type, address, false); [this, address, type]() { addNewMemoryWidget(type, address, false); });
});
menu->addAction(action); menu->addAction(action);
}; };
createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly); createAddNewWidgetAction(tr("New disassembly"), MemoryWidgetType::Disassembly);
@ -1101,9 +1079,7 @@ void MainWindow::initBackForwardMenu()
button->setPopupMode(QToolButton::DelayedPopup); button->setPopupMode(QToolButton::DelayedPopup);
button->setContextMenuPolicy(Qt::CustomContextMenu); button->setContextMenuPolicy(Qt::CustomContextMenu);
connect(button, &QWidget::customContextMenuRequested, button, connect(button, &QWidget::customContextMenuRequested, button,
[menu, button] (const QPoint &pos) { [menu, button](const QPoint &pos) { menu->exec(button->mapToGlobal(pos)); });
menu->exec(button->mapToGlobal(pos));
});
QFontMetrics metrics(fontMetrics()); QFontMetrics metrics(fontMetrics());
// Roughly 10-16 lines depending on padding size, no need to calculate more precisely // Roughly 10-16 lines depending on padding size, no need to calculate more precisely
@ -1115,15 +1091,12 @@ void MainWindow::initBackForwardMenu()
if (auto menu = prepareButtonMenu(ui->actionBackward)) { if (auto menu = prepareButtonMenu(ui->actionBackward)) {
menu->setObjectName("historyMenu"); menu->setObjectName("historyMenu");
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() { connect(menu, &QMenu::aboutToShow, menu,
updateHistoryMenu(menu, false); [this, menu]() { updateHistoryMenu(menu, false); });
});
} }
if (auto menu = prepareButtonMenu(ui->actionForward)) { if (auto menu = prepareButtonMenu(ui->actionForward)) {
menu->setObjectName("forwardHistoryMenu"); menu->setObjectName("forwardHistoryMenu");
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() { connect(menu, &QMenu::aboutToShow, menu, [this, menu]() { updateHistoryMenu(menu, true); });
updateHistoryMenu(menu, true);
});
} }
} }
@ -1147,7 +1120,8 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
if (history != redo || current) { // Include current in both directions if (history != redo || current) { // Include current in both directions
QString addressString = RAddressString(offset); QString addressString = RAddressString(offset);
QString toolTip = QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip QString toolTip =
QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip
name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function
QString label = QString("%1 (%2)").arg(name, addressString); QString label = QString("%1 (%2)").arg(name, addressString);
@ -1186,7 +1160,6 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
} }
++steps; ++steps;
} }
} }
void MainWindow::updateLayoutsMenu() void MainWindow::updateLayoutsMenu()
@ -1198,9 +1171,8 @@ void MainWindow::updateLayoutsMenu()
continue; continue;
} }
auto action = new QAction(it.key(), ui->menuLayouts); auto action = new QAction(it.key(), ui->menuLayouts);
connect(action, &QAction::triggered, this, [this, name]() { connect(action, &QAction::triggered, this,
setViewLayout(getViewLayout(name)); [this, name]() { setViewLayout(getViewLayout(name)); });
});
ui->menuLayouts->addAction(action); ui->menuLayouts->addAction(action);
} }
} }
@ -1214,9 +1186,11 @@ void MainWindow::saveNamedLayout()
names.removeAll(LAYOUT_DEFAULT); names.removeAll(LAYOUT_DEFAULT);
while (name.isEmpty() || isBuiltinLayoutName(name)) { while (name.isEmpty() || isBuiltinLayoutName(name)) {
if (ok) { if (ok) {
QMessageBox::warning(this, tr("Save layout error"), tr("'%1' is not a valid name.").arg(name)); QMessageBox::warning(this, tr("Save layout error"),
tr("'%1' is not a valid name.").arg(name));
} }
name = QInputDialog::getItem(this, tr("Save layout"), tr("Enter name"), names, -1, true, &ok); name = QInputDialog::getItem(this, tr("Save layout"), tr("Enter name"), names, -1, true,
&ok);
if (!ok) { if (!ok) {
return; return;
} }
@ -1261,17 +1235,12 @@ void MainWindow::removeWidget(CutterDockWidget *widget)
void MainWindow::showZenDocks() void MainWindow::showZenDocks()
{ {
const QList<QDockWidget *> zenDocks = { functionsDock, const QList<QDockWidget *> zenDocks = { functionsDock, dashboardDock, stringsDock, searchDock,
dashboardDock, importsDock };
stringsDock,
searchDock,
importsDock
};
functionDockWidthToRestore = functionsDock->maximumWidth(); functionDockWidthToRestore = functionsDock->maximumWidth();
functionsDock->setMaximumWidth(200); functionsDock->setMaximumWidth(200);
for (auto w : dockWidgets) { for (auto w : dockWidgets) {
if (zenDocks.contains(w) || if (zenDocks.contains(w) || isExtraMemoryWidget(w)) {
isExtraMemoryWidget(w)) {
w->show(); w->show();
} }
} }
@ -1280,24 +1249,16 @@ void MainWindow::showZenDocks()
void MainWindow::showDebugDocks() void MainWindow::showDebugDocks()
{ {
const QList<QDockWidget *> debugDocks = { functionsDock, const QList<QDockWidget *> debugDocks = { functionsDock, stringsDock, searchDock,
stringsDock, stackDock, registersDock, backtraceDock,
searchDock, threadsDock, memoryMapDock, breakpointDock };
stackDock,
registersDock,
backtraceDock,
threadsDock,
memoryMapDock,
breakpointDock
};
functionDockWidthToRestore = functionsDock->maximumWidth(); functionDockWidthToRestore = functionsDock->maximumWidth();
functionsDock->setMaximumWidth(200); functionsDock->setMaximumWidth(200);
auto registerWidth = qhelpers::forceWidth(registersDock, std::min(500, this->width() / 4)); auto registerWidth = qhelpers::forceWidth(registersDock, std::min(500, this->width() / 4));
auto registerHeight = qhelpers::forceHeight(registersDock, std::max(100, height() / 2)); auto registerHeight = qhelpers::forceHeight(registersDock, std::max(100, height() / 2));
QDockWidget *widgetToFocus = nullptr; QDockWidget *widgetToFocus = nullptr;
for (auto w : dockWidgets) { for (auto w : dockWidgets) {
if (debugDocks.contains(w) || if (debugDocks.contains(w) || isExtraMemoryWidget(w)) {
isExtraMemoryWidget(w)) {
w->show(); w->show();
} }
if (qobject_cast<DisassemblyWidget *>(w)) { if (qobject_cast<DisassemblyWidget *>(w)) {
@ -1317,8 +1278,8 @@ void MainWindow::dockOnMainArea(QDockWidget *widget)
float bestScore = 1; float bestScore = 1;
// choose best existing area for placing the new widget // choose best existing area for placing the new widget
for (auto dock : dockWidgets) { for (auto dock : dockWidgets) {
if (dock->isHidden() || dock == widget || if (dock->isHidden() || dock == widget || dock->isFloating()
dock->isFloating() || // tabifying onto floating dock using code doesn't work well || // tabifying onto floating dock using code doesn't work well
dock->parentWidget() != this) { // floating group isn't considered floating dock->parentWidget() != this) { // floating group isn't considered floating
continue; continue;
} }
@ -1392,12 +1353,9 @@ void MainWindow::setViewLayout(const CutterLayout &layout)
QStringList docksToCreate; QStringList docksToCreate;
if (isDefault) { if (isDefault) {
docksToCreate = QStringList { docksToCreate =
DisassemblyWidget::getWidgetType(), QStringList { DisassemblyWidget::getWidgetType(), GraphWidget::getWidgetType(),
GraphWidget::getWidgetType(), HexdumpWidget::getWidgetType(), DecompilerWidget::getWidgetType() };
HexdumpWidget::getWidgetType(),
DecompilerWidget::getWidgetType()
};
} else { } else {
docksToCreate = layout.viewProperties.keys(); docksToCreate = layout.viewProperties.keys();
} }
@ -1490,7 +1448,8 @@ void MainWindow::saveLayouts(QSettings &settings)
settings.setValue("state", layout.state); settings.setValue("state", layout.state);
settings.setValue("geometry", layout.geometry); settings.setValue("geometry", layout.geometry);
QVariantMap properties; QVariantMap properties;
for (auto it = layout.viewProperties.begin(), end = layout.viewProperties.end(); it != end; ++it) { for (auto it = layout.viewProperties.begin(), end = layout.viewProperties.end(); it != end;
++it) {
properties.insert(it.key(), it.value()); properties.insert(it.key(), it.value());
} }
settings.setValue("docks", properties); settings.setValue("docks", properties);
@ -1498,7 +1457,6 @@ void MainWindow::saveLayouts(QSettings &settings)
settings.endArray(); settings.endArray();
} }
void MainWindow::on_actionDefault_triggered() void MainWindow::on_actionDefault_triggered()
{ {
if (core->currentlyDebugging) { if (core->currentlyDebugging) {
@ -1510,7 +1468,6 @@ void MainWindow::on_actionDefault_triggered()
} }
} }
/** /**
* @brief MainWindow::on_actionNew_triggered * @brief MainWindow::on_actionNew_triggered
* Open a new Cutter session. * Open a new Cutter session.
@ -1538,8 +1495,8 @@ void MainWindow::on_actionRun_Script_triggered()
dialog.setViewMode(QFileDialog::Detail); dialog.setViewMode(QFileDialog::Detail);
dialog.setDirectory(QDir::home()); dialog.setDirectory(QDir::home());
const QString &fileName = QDir::toNativeSeparators(dialog.getOpenFileName(this, const QString &fileName =
tr("Select Rizin script"))); QDir::toNativeSeparators(dialog.getOpenFileName(this, tr("Select Rizin script")));
if (fileName.isEmpty()) // Cancel was pressed if (fileName.isEmpty()) // Cancel was pressed
return; return;
@ -1581,9 +1538,8 @@ void MainWindow::on_actionTabs_on_Top_triggered()
void MainWindow::on_actionReset_settings_triggered() void MainWindow::on_actionReset_settings_triggered()
{ {
QMessageBox::StandardButton ret = QMessageBox::StandardButton ret = (QMessageBox::StandardButton)QMessageBox::question(
(QMessageBox::StandardButton)QMessageBox::question(this, APPNAME, this, APPNAME, tr("Do you really want to clear all settings?"),
tr("Do you really want to clear all settings?"),
QMessageBox::Ok | QMessageBox::Cancel); QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Ok) { if (ret == QMessageBox::Ok) {
Config()->resetAll(); Config()->resetAll();
@ -1810,13 +1766,13 @@ bool MainWindow::eventFilter(QObject *, QEvent *event)
bool MainWindow::event(QEvent *event) bool MainWindow::event(QEvent *event)
{ {
if (event->type() == QEvent::FontChange if (event->type() == QEvent::FontChange || event->type() == QEvent::StyleChange
|| event->type() == QEvent::StyleChange
|| event->type() == QEvent::PaletteChange) { || event->type() == QEvent::PaletteChange) {
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
QMetaObject::invokeMethod(Config(), "refreshFont", Qt::ConnectionType::QueuedConnection); QMetaObject::invokeMethod(Config(), "refreshFont", Qt::ConnectionType::QueuedConnection);
#else #else
QMetaObject::invokeMethod(Config(), &Configuration::refreshFont, Qt::ConnectionType::QueuedConnection); QMetaObject::invokeMethod(Config(), &Configuration::refreshFont,
Qt::ConnectionType::QueuedConnection);
#endif #endif
} }
return QMainWindow::event(event); return QMainWindow::event(event);
@ -1848,7 +1804,6 @@ void MainWindow::chooseThemeIcons()
{ ui->actionBackward, QStringLiteral("arrow_left.svg") }, { ui->actionBackward, QStringLiteral("arrow_left.svg") },
}; };
// Set the correct icon for the QAction // Set the correct icon for the QAction
qhelpers::setThemeIcons(kSupportedIconsNames, [](void *obj, const QIcon &icon) { qhelpers::setThemeIcons(kSupportedIconsNames, [](void *obj, const QIcon &icon) {
static_cast<QAction *>(obj)->setIcon(icon); static_cast<QAction *>(obj)->setIcon(icon);

View File

@ -90,10 +90,14 @@ public:
void addMemoryDockWidget(MemoryDockWidget *widget); void addMemoryDockWidget(MemoryDockWidget *widget);
void removeWidget(CutterDockWidget *widget); void removeWidget(CutterDockWidget *widget);
void addExtraWidget(CutterDockWidget *extraDock); void addExtraWidget(CutterDockWidget *extraDock);
MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address, bool synchronized = true); MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address,
bool synchronized = true);
CUTTER_DEPRECATED("Action will be ignored. Use addPluginDockWidget(CutterDockWidget*) instead.") CUTTER_DEPRECATED("Action will be ignored. Use addPluginDockWidget(CutterDockWidget*) instead.")
void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *) { addPluginDockWidget(dockWidget); } void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *)
{
addPluginDockWidget(dockWidget);
}
void addPluginDockWidget(CutterDockWidget *dockWidget); void addPluginDockWidget(CutterDockWidget *dockWidget);
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins }; enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
/** /**
@ -104,17 +108,15 @@ public:
QMenu *getMenuByType(MenuType type); QMenu *getMenuByType(MenuType type);
void addMenuFileAction(QAction *action); void addMenuFileAction(QAction *action);
QString getFilename() const QString getFilename() const { return filename; }
{
return filename;
}
void messageBoxWarning(QString title, QString message); void messageBoxWarning(QString title, QString message);
QString getUniqueObjectName(const QString &widgetType) const; QString getUniqueObjectName(const QString &widgetType) const;
void showMemoryWidget(); void showMemoryWidget();
void showMemoryWidget(MemoryWidgetType type); void showMemoryWidget(MemoryWidgetType type);
enum class AddressTypeHint { Function, Data, Unknown }; enum class AddressTypeHint { Function, Data, Unknown };
QMenu *createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType = AddressTypeHint::Unknown); QMenu *createShowInMenu(QWidget *parent, RVA address,
AddressTypeHint addressType = AddressTypeHint::Unknown);
void setCurrentMemoryWidget(MemoryDockWidget *memoryWidget); void setCurrentMemoryWidget(MemoryDockWidget *memoryWidget);
MemoryDockWidget *getLastMemoryWidget(); MemoryDockWidget *getLastMemoryWidget();
@ -202,6 +204,7 @@ private slots:
void onZoomReset(); void onZoomReset();
void setAvailableIOModeOptions(); void setAvailableIOModeOptions();
private: private:
CutterCore *core; CutterCore *core;
@ -266,7 +269,8 @@ private:
void initToolBar(); void initToolBar();
void initDocks(); void initDocks();
void initBackForwardMenu(); void initBackForwardMenu();
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false); void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(),
bool skipOptionsDialog = false);
Cutter::CutterLayout getViewLayout(); Cutter::CutterLayout getViewLayout();
Cutter::CutterLayout getViewLayout(const QString &name); Cutter::CutterLayout getViewLayout(const QString &name);
@ -275,7 +279,6 @@ private:
void loadLayouts(QSettings &settings); void loadLayouts(QSettings &settings);
void saveLayouts(QSettings &settings); void saveLayouts(QSettings &settings);
void updateMemberPointers(); void updateMemberPointers();
void restoreDocks(); void restoreDocks();
void showZenDocks(); void showZenDocks();
@ -309,7 +312,8 @@ private:
MemoryWidgetType getMemoryWidgetTypeToRestore(); MemoryWidgetType getMemoryWidgetTypeToRestore();
/** /**
* @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective contructor of the widget * @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective
* contructor of the widget
*/ */
QMap<QString, std::function<CutterDockWidget *(MainWindow *)>> widgetTypeToConstructorMap; QMap<QString, std::function<CutterDockWidget *(MainWindow *)>> widgetTypeToConstructorMap;

View File

@ -18,26 +18,25 @@
#include "CutterConfig.h" #include "CutterConfig.h"
AboutDialog::AboutDialog(QWidget *parent) : AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
QDialog(parent),
ui(new Ui::AboutDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
ui->logoSvgWidget->load(Config()->getLogoFile()); ui->logoSvgWidget->load(Config()->getLogoFile());
QString aboutString(tr("Version") + " " CUTTER_VERSION_FULL "<br/>" QString aboutString(
+ tr("Using rizin-") + RZ_GITTAP + "<br/>" tr("Version") + " " CUTTER_VERSION_FULL "<br/>" + tr("Using rizin-") + RZ_GITTAP
+ buildQtVersionString() + "<br/>" + buildQtVersionString() + "<p><b>" + tr("Optional Features:") + "</b><br/>"
+ "<p><b>" + tr("Optional Features:") + "</b><br/>" + QString("Python: %1<br/>")
+ QString("Python: %1<br/>").arg( .arg(
#ifdef CUTTER_ENABLE_PYTHON #ifdef CUTTER_ENABLE_PYTHON
"ON" "ON"
#else #else
"OFF" "OFF"
#endif #endif
) )
+ QString("Python Bindings: %2</p>").arg( + QString("Python Bindings: %2</p>")
.arg(
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS #ifdef CUTTER_ENABLE_PYTHON_BINDINGS
"ON" "ON"
#else #else
@ -45,10 +44,13 @@ AboutDialog::AboutDialog(QWidget *parent) :
#endif #endif
) )
+ "<h2>" + tr("License") + "</h2>" + "<h2>" + tr("License") + "</h2>"
+ tr("This Software is released under the GNU General Public License v3.0") + tr("This Software is released under the GNU General Public License v3.0") + "<h2>"
+ "<h2>" + tr("Authors") + "</h2>" + tr("Authors") + "</h2>"
+ tr("Cutter is developed by the community and maintained by its core and development teams.<br/>") + tr("Cutter is developed by the community and maintained by its core and development "
+ tr("Check our <a href='https://github.com/rizinorg/cutter/graphs/contributors'>contributors page</a> for the full list of contributors.")); "teams.<br/>")
+ tr("Check our <a "
"href='https://github.com/rizinorg/cutter/graphs/contributors'>contributors "
"page</a> for the full list of contributors."));
ui->label->setText(aboutString); ui->label->setText(aboutString);
QSignalBlocker s(ui->updatesCheckBox); QSignalBlocker s(ui->updatesCheckBox);
@ -102,7 +104,8 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
QMessageBox::critical(nullptr, tr("Error!"), error); QMessageBox::critical(nullptr, tr("Error!"), error);
} else { } else {
if (version <= UpdateWorker::currentVersionNumber()) { if (version <= UpdateWorker::currentVersionNumber()) {
QMessageBox::information(nullptr, tr("Version control"), tr("Cutter is up to date!")); QMessageBox::information(nullptr, tr("Version control"),
tr("Cutter is up to date!"));
} else { } else {
updateWorker.showUpdateDialog(false); updateWorker.showUpdateDialog(false);
} }
@ -143,7 +146,6 @@ static QString compilerString()
QString AboutDialog::buildQtVersionString(void) QString AboutDialog::buildQtVersionString(void)
{ {
return tr("Based on Qt %1 (%2, %3 bit)").arg(QLatin1String(qVersion()), return tr("Based on Qt %1 (%2, %3 bit)")
compilerString(), .arg(QLatin1String(qVersion()), compilerString(), QString::number(QSysInfo::WordSize));
QString::number(QSysInfo::WordSize));
} }

View File

@ -4,11 +4,8 @@
#include "ui_AsyncTaskDialog.h" #include "ui_AsyncTaskDialog.h"
AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent) AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
: QDialog(parent), : QDialog(parent), ui(new Ui::AsyncTaskDialog), task(task)
ui(new Ui::AsyncTaskDialog),
task(task)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -18,9 +15,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
} }
connect(task.data(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog); connect(task.data(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog);
connect(task.data(), &AsyncTask::finished, this, [this]() { connect(task.data(), &AsyncTask::finished, this, [this]() { close(); });
close();
});
updateLog(task->getLog()); updateLog(task->getLog());
@ -32,9 +27,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent)
updateProgressTimer(); updateProgressTimer();
} }
AsyncTaskDialog::~AsyncTaskDialog() AsyncTaskDialog::~AsyncTaskDialog() {}
{
}
void AsyncTaskDialog::updateLog(const QString &log) void AsyncTaskDialog::updateLog(const QString &log)
{ {

View File

@ -10,8 +10,7 @@
// ------------ // ------------
// ProcessModel // ProcessModel
// ------------ // ------------
ProcessModel::ProcessModel(QObject *parent) ProcessModel::ProcessModel(QObject *parent) : QAbstractListModel(parent)
: QAbstractListModel(parent)
{ {
updateData(); updateData();
} }
@ -125,7 +124,8 @@ QString ProcessBeingAnalysedProxyModel::processPathToFilename(const QString &pat
bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
{ {
QModelIndex index = sourceModel()->index(row, 0, parent); QModelIndex index = sourceModel()->index(row, 0, parent);
ProcessDescription item = index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); ProcessDescription item =
index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
QString procFilename = processPathToFilename(item.path); QString procFilename = processPathToFilename(item.path);
return procFilename == processBeingAnalysedFilename; return procFilename == processBeingAnalysedFilename;
@ -134,10 +134,10 @@ bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex
bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left, bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const const QModelIndex &right) const
{ {
ProcessDescription leftProc = left.data( ProcessDescription leftProc =
ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
ProcessDescription rightProc = right.data( ProcessDescription rightProc =
ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
return ProcessModel::lessThan(leftProc, rightProc, left.column()); return ProcessModel::lessThan(leftProc, rightProc, left.column());
} }
@ -154,16 +154,17 @@ ProcessProxyModel::ProcessProxyModel(ProcessModel *sourceModel, QObject *parent)
bool ProcessProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const bool ProcessProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
{ {
QModelIndex index = sourceModel()->index(row, 0, parent); QModelIndex index = sourceModel()->index(row, 0, parent);
ProcessDescription item = index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); ProcessDescription item =
index.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
return item.path.contains(filterRegExp()); return item.path.contains(filterRegExp());
} }
bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{ {
ProcessDescription leftProc = left.data( ProcessDescription leftProc =
ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); left.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
ProcessDescription rightProc = right.data( ProcessDescription rightProc =
ProcessModel::ProcDescriptionRole).value<ProcessDescription>(); right.data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>();
return ProcessModel::lessThan(leftProc, rightProc, left.column()); return ProcessModel::lessThan(leftProc, rightProc, left.column());
} }
@ -171,9 +172,7 @@ bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig
// ---------------- // ----------------
// AttachProcDialog // AttachProcDialog
// ---------------- // ----------------
AttachProcDialog::AttachProcDialog(QWidget *parent) : AttachProcDialog::AttachProcDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AttachProcDialog)
QDialog(parent),
ui(new Ui::AttachProcDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
@ -232,13 +231,19 @@ void AttachProcDialog::updateModelData()
if (allViewHadSelection) { if (allViewHadSelection) {
allViewPrevScrollPos = allView->verticalScrollBar()->value(); allViewPrevScrollPos = allView->verticalScrollBar()->value();
allViewPrevPID = allView->selectionModel()->currentIndex().data( allViewPrevPID = allView->selectionModel()
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid; ->currentIndex()
.data(ProcessModel::ProcDescriptionRole)
.value<ProcessDescription>()
.pid;
} }
if (smallViewHadSelection) { if (smallViewHadSelection) {
smallViewPrevScrollPos = smallView->verticalScrollBar()->value(); smallViewPrevScrollPos = smallView->verticalScrollBar()->value();
smallViewPrevPID = smallView->selectionModel()->currentIndex().data( smallViewPrevPID = smallView->selectionModel()
ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid; ->currentIndex()
.data(ProcessModel::ProcDescriptionRole)
.value<ProcessDescription>()
.pid;
} }
// Let the model update // Let the model update
@ -246,16 +251,18 @@ void AttachProcDialog::updateModelData()
// Restore the selection and scroll position // Restore the selection and scroll position
if (allViewHadSelection) { if (allViewHadSelection) {
QModelIndexList idx = allView->model()->match( QModelIndexList idx =
allView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(allViewPrevPID)); allView->model()->match(allView->model()->index(0, 0), Qt::DisplayRole,
QVariant::fromValue(allViewPrevPID));
if (!idx.isEmpty()) { if (!idx.isEmpty()) {
allView->setCurrentIndex(idx.first()); allView->setCurrentIndex(idx.first());
allView->verticalScrollBar()->setValue(allViewPrevScrollPos); allView->verticalScrollBar()->setValue(allViewPrevScrollPos);
} }
} }
if (smallViewHadSelection) { if (smallViewHadSelection) {
QModelIndexList idx = smallView->model()->match( QModelIndexList idx =
smallView->model()->index(0, 0), Qt::DisplayRole, QVariant::fromValue(smallViewPrevPID)); smallView->model()->match(smallView->model()->index(0, 0), Qt::DisplayRole,
QVariant::fromValue(smallViewPrevPID));
if (!idx.isEmpty()) { if (!idx.isEmpty()) {
smallView->setCurrentIndex(idx.first()); smallView->setCurrentIndex(idx.first());
@ -265,14 +272,13 @@ void AttachProcDialog::updateModelData()
// Init selection if nothing was ever selected yet, and a new process with the same name // Init selection if nothing was ever selected yet, and a new process with the same name
// as the one being analysed was launched. // as the one being analysed was launched.
if (!allView->selectionModel()->hasSelection() && !smallView->selectionModel()->hasSelection()) { if (!allView->selectionModel()->hasSelection()
&& !smallView->selectionModel()->hasSelection()) {
smallView->setCurrentIndex(smallView->model()->index(0, 0)); smallView->setCurrentIndex(smallView->model()->index(0, 0));
} }
} }
void AttachProcDialog::on_buttonBox_accepted() void AttachProcDialog::on_buttonBox_accepted() {}
{
}
void AttachProcDialog::on_buttonBox_rejected() void AttachProcDialog::on_buttonBox_rejected()
{ {
@ -302,12 +308,18 @@ int AttachProcDialog::getPID()
// Here we need to know which table was selected last to get the proper PID // Here we need to know which table was selected last to get the proper PID
if (wasAllProcViewLastPressed && ui->allProcView->selectionModel()->hasSelection()) { if (wasAllProcViewLastPressed && ui->allProcView->selectionModel()->hasSelection()) {
pid = ui->allProcView->selectionModel()->currentIndex(). pid = ui->allProcView->selectionModel()
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid; ->currentIndex()
.data(ProcessModel::ProcDescriptionRole)
.value<ProcessDescription>()
.pid;
} else if (!wasAllProcViewLastPressed } else if (!wasAllProcViewLastPressed
&& ui->procBeingAnalyzedView->selectionModel()->hasSelection()) { && ui->procBeingAnalyzedView->selectionModel()->hasSelection()) {
pid = ui->procBeingAnalyzedView->selectionModel()->currentIndex(). pid = ui->procBeingAnalyzedView->selectionModel()
data(ProcessModel::ProcDescriptionRole).value<ProcessDescription>().pid; ->currentIndex()
.data(ProcessModel::ProcDescriptionRole)
.value<ProcessDescription>()
.pid;
} else { } else {
// Error attaching. No process selected! Happens when you press ENTER but // Error attaching. No process selected! Happens when you press ENTER but
// there was no process with the same name as the one being analyzed. // there was no process with the same name as the one being analyzed.

View File

@ -15,7 +15,6 @@ class MainWindow;
class QTreeWidget; class QTreeWidget;
class QTreeWidgetItem; class QTreeWidgetItem;
class ProcessModel : public QAbstractListModel class ProcessModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
@ -34,14 +33,13 @@ public:
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
static bool lessThan(const ProcessDescription &left, const ProcessDescription &right, int column); static bool lessThan(const ProcessDescription &left, const ProcessDescription &right,
int column);
public slots: public slots:
void updateData(); void updateData();
}; };
class ProcessProxyModel : public QSortFilterProxyModel class ProcessProxyModel : public QSortFilterProxyModel
{ {
Q_OBJECT Q_OBJECT
@ -54,7 +52,6 @@ protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
}; };
class ProcessBeingAnalysedProxyModel : public QSortFilterProxyModel class ProcessBeingAnalysedProxyModel : public QSortFilterProxyModel
{ {
Q_OBJECT Q_OBJECT
@ -71,8 +68,6 @@ private:
QString processPathToFilename(const QString &path) const; QString processPathToFilename(const QString &path) const;
}; };
class AttachProcDialog : public QDialog class AttachProcDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT

View File

@ -7,15 +7,14 @@
#include <QCompleter> #include <QCompleter>
#include <QCheckBox> #include <QCheckBox>
BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) : BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::BreakpointsDialog), editMode(editMode)
ui(new Ui::BreakpointsDialog),
editMode(editMode)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
connect(ui->breakpointPosition, &QLineEdit::textChanged, this, &BreakpointsDialog::refreshOkButton); connect(ui->breakpointPosition, &QLineEdit::textChanged, this,
&BreakpointsDialog::refreshOkButton);
refreshOkButton(); refreshOkButton();
if (editMode) { if (editMode) {
@ -24,13 +23,14 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
setWindowTitle(tr("New breakpoint")); setWindowTitle(tr("New breakpoint"));
} }
struct
struct { {
QString label; QString label;
QString tooltip; QString tooltip;
BreakpointDescription::PositionType type; BreakpointDescription::PositionType type;
} positionTypes[] = { } positionTypes[] = {
{tr("Address"), tr("Address or expression calculated when creating breakpoint"), BreakpointDescription::Address}, { tr("Address"), tr("Address or expression calculated when creating breakpoint"),
BreakpointDescription::Address },
{ tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named }, { tr("Named"), tr("Expression - stored as expression"), BreakpointDescription::Named },
{ tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module }, { tr("Module offset"), tr("Offset relative to module"), BreakpointDescription::Module },
}; };
@ -41,8 +41,9 @@ BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) :
index++; index++;
} }
connect(ui->positionType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), connect(ui->positionType,
this, &BreakpointsDialog::onTypeChanged); static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&BreakpointsDialog::onTypeChanged);
onTypeChanged(); onTypeChanged();
auto modules = Core()->getMemoryMap(); auto modules = Core()->getMemoryMap();
@ -111,7 +112,8 @@ BreakpointsDialog::~BreakpointsDialog() {}
BreakpointDescription BreakpointsDialog::getDescription() BreakpointDescription BreakpointsDialog::getDescription()
{ {
BreakpointDescription breakpoint; BreakpointDescription breakpoint;
auto positionType = ui->positionType->currentData().value<BreakpointDescription::PositionType>(); auto positionType =
ui->positionType->currentData().value<BreakpointDescription::PositionType>();
switch (positionType) { switch (positionType) {
case BreakpointDescription::Address: case BreakpointDescription::Address:
breakpoint.addr = Core()->math(ui->breakpointPosition->text()); breakpoint.addr = Core()->math(ui->breakpointPosition->text());
@ -167,7 +169,8 @@ void BreakpointsDialog::onTypeChanged()
bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module); bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module);
ui->moduleLabel->setEnabled(moduleEnabled); ui->moduleLabel->setEnabled(moduleEnabled);
ui->moduleName->setEnabled(moduleEnabled); ui->moduleName->setEnabled(moduleEnabled);
ui->breakpointPosition->setPlaceholderText(ui->positionType->currentData(Qt::ToolTipRole).toString()); ui->breakpointPosition->setPlaceholderText(
ui->positionType->currentData(Qt::ToolTipRole).toString());
} }
void BreakpointsDialog::configureCheckboxRestrictions() void BreakpointsDialog::configureCheckboxRestrictions()

View File

@ -22,6 +22,7 @@ public:
static void createNewBreakpoint(RVA address = RVA_INVALID, QWidget *parent = nullptr); static void createNewBreakpoint(RVA address = RVA_INVALID, QWidget *parent = nullptr);
static void editBreakpoint(const BreakpointDescription &breakpoint, QWidget *parent = nullptr); static void editBreakpoint(const BreakpointDescription &breakpoint, QWidget *parent = nullptr);
private: private:
std::unique_ptr<Ui::BreakpointsDialog> ui; std::unique_ptr<Ui::BreakpointsDialog> ui;
bool editMode = false; bool editMode = false;

View File

@ -3,9 +3,7 @@
#include "core/Cutter.h" #include "core/Cutter.h"
CommentsDialog::CommentsDialog(QWidget *parent) : CommentsDialog::CommentsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CommentsDialog)
QDialog(parent),
ui(new Ui::CommentsDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
@ -16,9 +14,7 @@ CommentsDialog::CommentsDialog(QWidget *parent) :
CommentsDialog::~CommentsDialog() {} CommentsDialog::~CommentsDialog() {}
void CommentsDialog::on_buttonBox_accepted() void CommentsDialog::on_buttonBox_accepted() {}
{
}
void CommentsDialog::on_buttonBox_rejected() void CommentsDialog::on_buttonBox_rejected()
{ {
@ -66,8 +62,8 @@ bool CommentsDialog::eventFilter(QObject */*obj*/, QEvent *event)
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
// Confirm comment by pressing Ctrl/Cmd+Return // Confirm comment by pressing Ctrl/Cmd+Return
if ((keyEvent -> modifiers() & Qt::ControlModifier) && if ((keyEvent->modifiers() & Qt::ControlModifier)
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return))) { && ((keyEvent->key() == Qt::Key_Enter) || (keyEvent->key() == Qt::Key_Return))) {
this->accept(); this->accept();
return true; return true;
} }

View File

@ -1,9 +1,8 @@
#include "EditFunctionDialog.h" #include "EditFunctionDialog.h"
#include "ui_EditFunctionDialog.h" #include "ui_EditFunctionDialog.h"
EditFunctionDialog::EditFunctionDialog(QWidget *parent) : EditFunctionDialog::EditFunctionDialog(QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::EditFunctionDialog)
ui(new Ui::EditFunctionDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
@ -44,21 +43,22 @@ void EditFunctionDialog::setStackSizeText(const QString &stackSize)
ui->stackSizeLineEdit->setText(stackSize); ui->stackSizeLineEdit->setText(stackSize);
} }
void EditFunctionDialog::setCallConList(const QStringList &callConList) { void EditFunctionDialog::setCallConList(const QStringList &callConList)
{
ui->callConComboBox->addItems(callConList); ui->callConComboBox->addItems(callConList);
} }
void EditFunctionDialog::setCallConSelected(const QString &selected) { void EditFunctionDialog::setCallConSelected(const QString &selected)
{
ui->callConComboBox->setCurrentText(selected); ui->callConComboBox->setCurrentText(selected);
} }
QString EditFunctionDialog::getCallConSelected() { QString EditFunctionDialog::getCallConSelected()
{
return ui->callConComboBox->currentText(); return ui->callConComboBox->currentText();
} }
void EditFunctionDialog::on_buttonBox_accepted() void EditFunctionDialog::on_buttonBox_accepted() {}
{
}
void EditFunctionDialog::on_buttonBox_rejected() void EditFunctionDialog::on_buttonBox_rejected()
{ {

View File

@ -2,10 +2,8 @@
#include "ui_EditInstructionDialog.h" #include "ui_EditInstructionDialog.h"
#include "core/Cutter.h" #include "core/Cutter.h"
EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent) : EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::EditInstructionDialog), editMode(editMode)
ui(new Ui::EditInstructionDialog),
editMode(editMode)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->lineEdit->setMinimumWidth(400); ui->lineEdit->setMinimumWidth(400);
@ -17,9 +15,7 @@ EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidg
EditInstructionDialog::~EditInstructionDialog() {} EditInstructionDialog::~EditInstructionDialog() {}
void EditInstructionDialog::on_buttonBox_accepted() void EditInstructionDialog::on_buttonBox_accepted() {}
{
}
void EditInstructionDialog::on_buttonBox_rejected() void EditInstructionDialog::on_buttonBox_rejected()
{ {

View File

@ -8,9 +8,7 @@ namespace Ui {
class EditInstructionDialog; class EditInstructionDialog;
} }
enum InstructionEditMode { enum InstructionEditMode { EDIT_NONE, EDIT_BYTES, EDIT_TEXT };
EDIT_NONE, EDIT_BYTES, EDIT_TEXT
};
class EditInstructionDialog : public QDialog class EditInstructionDialog : public QDialog
{ {
@ -32,7 +30,8 @@ private slots:
private: private:
std::unique_ptr<Ui::EditInstructionDialog> ui; std::unique_ptr<Ui::EditInstructionDialog> ui;
InstructionEditMode editMode; // true if editing intruction **bytes**; false if editing instruction **text** InstructionEditMode
editMode; // true if editing intruction **bytes**; false if editing instruction **text**
}; };
#endif // EDITINSTRUCTIONDIALOG_H #endif // EDITINSTRUCTIONDIALOG_H

View File

@ -3,9 +3,8 @@
#include <QComboBox> #include <QComboBox>
EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) : EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::EditMethodDialog)
ui(new Ui::EditMethodDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
@ -24,15 +23,14 @@ EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) :
updateVirtualUI(); updateVirtualUI();
validateInput(); validateInput();
connect(ui->virtualCheckBox, &QCheckBox::stateChanged, this, &EditMethodDialog::updateVirtualUI); connect(ui->virtualCheckBox, &QCheckBox::stateChanged, this,
&EditMethodDialog::updateVirtualUI);
connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput); connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput);
} }
EditMethodDialog::~EditMethodDialog() {} EditMethodDialog::~EditMethodDialog() {}
void EditMethodDialog::on_buttonBox_accepted() void EditMethodDialog::on_buttonBox_accepted() {}
{
}
void EditMethodDialog::on_buttonBox_rejected() void EditMethodDialog::on_buttonBox_rejected()
{ {
@ -131,7 +129,8 @@ AnalMethodDescription EditMethodDialog::getMethod() const
return ret; return ret;
} }
bool EditMethodDialog::showDialog(const QString &title, bool classFixed, QString *className, AnalMethodDescription *desc, QWidget *parent) bool EditMethodDialog::showDialog(const QString &title, bool classFixed, QString *className,
AnalMethodDescription *desc, QWidget *parent)
{ {
EditMethodDialog dialog(classFixed, parent); EditMethodDialog dialog(classFixed, parent);
dialog.setWindowTitle(title); dialog.setWindowTitle(title);

View File

@ -17,7 +17,8 @@ class EditMethodDialog : public QDialog
public: public:
/** /**
* @param classFixed whether the user should be able to change the class. If false, a QComboBox will be shown, otherwise a plain QLabel. * @param classFixed whether the user should be able to change the class. If false, a QComboBox
* will be shown, otherwise a plain QLabel.
*/ */
explicit EditMethodDialog(bool classFixed, QWidget *parent = nullptr); explicit EditMethodDialog(bool classFixed, QWidget *parent = nullptr);
~EditMethodDialog(); ~EditMethodDialog();
@ -37,17 +38,20 @@ public:
* @param desc initial data for the method information * @param desc initial data for the method information
* @return whether the dialog was accepted by the user * @return whether the dialog was accepted by the user
*/ */
static bool showDialog(const QString &title, bool classFixed, QString *className, AnalMethodDescription *desc, QWidget *parent = nullptr); static bool showDialog(const QString &title, bool classFixed, QString *className,
AnalMethodDescription *desc, QWidget *parent = nullptr);
/** /**
* @brief Show the dialog to add a new method a given class * @brief Show the dialog to add a new method a given class
*/ */
static void newMethod(QString className = nullptr, const QString &meth = QString(), QWidget *parent = nullptr); static void newMethod(QString className = nullptr, const QString &meth = QString(),
QWidget *parent = nullptr);
/** /**
* @brief Show the dialog to edit a given method of a given class * @brief Show the dialog to edit a given method of a given class
*/ */
static void editMethod(const QString &className, const QString &meth, QWidget *parent = nullptr); static void editMethod(const QString &className, const QString &meth,
QWidget *parent = nullptr);
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
@ -62,7 +66,8 @@ private:
QComboBox *classComboBox = nullptr; QComboBox *classComboBox = nullptr;
QLabel *classLabel = nullptr; QLabel *classLabel = nullptr;
/** /**
* This will only be used when the dialog was created with classFixed = true in order to remember the class name. * This will only be used when the dialog was created with classFixed = true in order to
* remember the class name.
*/ */
QString fixedClass; QString fixedClass;

View File

@ -2,8 +2,7 @@
#include "ui_EditStringDialog.h" #include "ui_EditStringDialog.h"
EditStringDialog::EditStringDialog(QWidget *parent) EditStringDialog::EditStringDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent), ui(new Ui::EditStringDialog {})
, ui(new Ui::EditStringDialog{})
{ {
ui->setupUi(this); ui->setupUi(this);
ui->spinBox_size->setMinimum(0); ui->spinBox_size->setMinimum(0);
@ -45,18 +44,14 @@ EditStringDialog::StringType EditStringDialog::getStringType() const
{ {
const int indexVal = ui->comboBox_type->currentIndex(); const int indexVal = ui->comboBox_type->currentIndex();
switch(indexVal) switch (indexVal) {
{ case 0: {
case 0:
{
return EditStringDialog::StringType::Auto; return EditStringDialog::StringType::Auto;
} }
case 1: case 1: {
{
return EditStringDialog::StringType::ASCII_LATIN1; return EditStringDialog::StringType::ASCII_LATIN1;
} }
case 2: case 2: {
{
return EditStringDialog::StringType::UTF8; return EditStringDialog::StringType::UTF8;
} }
default: default:

View File

@ -31,7 +31,6 @@ public:
*/ */
bool getStringStartAddress(uint64_t &returnValue) const; bool getStringStartAddress(uint64_t &returnValue) const;
/** /**
* @brief Sets the size of string in the dialog * @brief Sets the size of string in the dialog
* *

View File

@ -6,16 +6,13 @@
#include <QMetaType> #include <QMetaType>
#include <QPushButton> #include <QPushButton>
EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget *parent)
EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget *parent) : : QDialog(parent), ui(new Ui::EditVariablesDialog), functionAddress(RVA_INVALID)
QDialog(parent),
ui(new Ui::EditVariablesDialog),
functionAddress(RVA_INVALID)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditVariablesDialog::applyFields); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditVariablesDialog::applyFields);
connect<void(QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged, connect<void (QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged, this,
this, &EditVariablesDialog::updateFields); &EditVariablesDialog::updateFields);
QString fcnName = Core()->cmdRawAt("afn.", offset).trimmed(); QString fcnName = Core()->cmdRawAt("afn.", offset).trimmed();
functionAddress = offset; functionAddress = offset;
@ -61,7 +58,8 @@ void EditVariablesDialog::applyFields()
Core()->cmdRaw(QString("afvt %1 %2").arg(desc.name).arg(ui->typeComboBox->currentText())); Core()->cmdRaw(QString("afvt %1 %2").arg(desc.name).arg(ui->typeComboBox->currentText()));
// TODO Remove all those replace once rizin command parser is fixed // TODO Remove all those replace once rizin command parser is fixed
QString newName = ui->nameEdit->text().replace(QLatin1Char(' '), QLatin1Char('_')) QString newName = ui->nameEdit->text()
.replace(QLatin1Char(' '), QLatin1Char('_'))
.replace(QLatin1Char('\\'), QLatin1Char('_')) .replace(QLatin1Char('\\'), QLatin1Char('_'))
.replace(QLatin1Char('/'), QLatin1Char('_')); .replace(QLatin1Char('/'), QLatin1Char('_'));
if (newName != desc.name) { if (newName != desc.name) {
@ -86,7 +84,6 @@ void EditVariablesDialog::updateFields()
ui->typeComboBox->setCurrentText(desc.type); ui->typeComboBox->setCurrentText(desc.type);
} }
void EditVariablesDialog::populateTypesComboBox() void EditVariablesDialog::populateTypesComboBox()
{ {
// gets all loaded types, structures and enums and puts them in a list // gets all loaded types, structures and enums and puts them in a list

View File

@ -13,7 +13,8 @@ class EditVariablesDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit EditVariablesDialog(RVA offset, QString initialVar = QString(), QWidget *parent = nullptr); explicit EditVariablesDialog(RVA offset, QString initialVar = QString(),
QWidget *parent = nullptr);
~EditVariablesDialog(); ~EditVariablesDialog();
bool empty() const; bool empty() const;

View File

@ -4,13 +4,8 @@
#include <QIntValidator> #include <QIntValidator>
#include "core/Cutter.h" #include "core/Cutter.h"
FlagDialog::FlagDialog(RVA offset, QWidget *parent)
FlagDialog::FlagDialog(RVA offset, QWidget *parent) : : QDialog(parent), ui(new Ui::FlagDialog), offset(offset), flagName(""), flagOffset(RVA_INVALID)
QDialog(parent),
ui(new Ui::FlagDialog),
offset(offset),
flagName(""),
flagOffset(RVA_INVALID)
{ {
// Setup UI // Setup UI
ui->setupUi(this); ui->setupUi(this);
@ -32,10 +27,8 @@ FlagDialog::FlagDialog(RVA offset, QWidget *parent) :
} }
// Connect slots // Connect slots
connect(ui->buttonBox, &QDialogButtonBox::accepted, connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &FlagDialog::buttonBoxAccepted);
this, &FlagDialog::buttonBoxAccepted); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &FlagDialog::buttonBoxRejected);
connect(ui->buttonBox, &QDialogButtonBox::rejected,
this, &FlagDialog::buttonBoxRejected);
} }
FlagDialog::~FlagDialog() {} FlagDialog::~FlagDialog() {}

View File

@ -5,7 +5,6 @@
#include <memory> #include <memory>
#include "core/CutterCommon.h" #include "core/CutterCommon.h"
namespace Ui { namespace Ui {
class FlagDialog; class FlagDialog;
} }

View File

@ -6,26 +6,25 @@
#include <cstdint> #include <cstdint>
#include "core/Cutter.h" #include "core/Cutter.h"
HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent, bool allowEmpty) : HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent, bool allowEmpty)
QDialog(parent), : QDialog(parent), ui(new Ui::HexdumpRangeDialog), allowEmpty(allowEmpty)
ui(new Ui::HexdumpRangeDialog),
allowEmpty(allowEmpty)
{ {
ui->setupUi(this); ui->setupUi(this);
QRegularExpressionValidator *v = new QRegularExpressionValidator(QRegularExpression("(?:0[xX])?[0-9a-fA-F]+"), this); QRegularExpressionValidator *v =
new QRegularExpressionValidator(QRegularExpression("(?:0[xX])?[0-9a-fA-F]+"), this);
ui->lengthLineEdit->setValidator(v); ui->lengthLineEdit->setValidator(v);
ui->startAddressLineEdit->setValidator(v); ui->startAddressLineEdit->setValidator(v);
ui->endAddressLineEdit->setValidator(v); ui->endAddressLineEdit->setValidator(v);
// subscribe to a text change slot // subscribe to a text change slot
connect(ui->startAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited); connect(ui->startAddressLineEdit, &QLineEdit::textEdited, this,
&HexdumpRangeDialog::textEdited);
connect(ui->endAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited); connect(ui->endAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
connect(ui->lengthLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited); connect(ui->lengthLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
connect(ui->endAddressRadioButton, &QRadioButton::clicked, this, connect(ui->endAddressRadioButton, &QRadioButton::clicked, this,
&HexdumpRangeDialog::on_radioButtonClicked); &HexdumpRangeDialog::on_radioButtonClicked);
connect(ui->lengthRadioButton, &QRadioButton::clicked, this, connect(ui->lengthRadioButton, &QRadioButton::clicked, this,
&HexdumpRangeDialog::on_radioButtonClicked); &HexdumpRangeDialog::on_radioButtonClicked);
} }
HexdumpRangeDialog::~HexdumpRangeDialog() HexdumpRangeDialog::~HexdumpRangeDialog()
@ -60,8 +59,7 @@ bool HexdumpRangeDialog::getLengthRadioButtonChecked() const
void HexdumpRangeDialog::setStartAddress(ut64 start) void HexdumpRangeDialog::setStartAddress(ut64 start)
{ {
ui->startAddressLineEdit->setText( ui->startAddressLineEdit->setText(QString("0x%1").arg(start, 0, 16));
QString("0x%1").arg(start, 0, 16));
} }
void HexdumpRangeDialog::open(ut64 start) void HexdumpRangeDialog::open(ut64 start)
@ -84,8 +82,7 @@ bool HexdumpRangeDialog::validate()
endAddress = Core()->math(ui->endAddressLineEdit->text()); endAddress = Core()->math(ui->endAddressLineEdit->text());
if (endAddress > startAddress) { if (endAddress > startAddress) {
length = endAddress - startAddress; length = endAddress - startAddress;
ui->lengthLineEdit->setText( ui->lengthLineEdit->setText(QString("0x%1").arg(length, 0, 16));
QString("0x%1").arg(length, 0, 16));
this->endAddress = endAddress - 1; this->endAddress = endAddress - 1;
emptyRange = false; emptyRange = false;
} else if (endAddress == startAddress) { } else if (endAddress == startAddress) {
@ -108,11 +105,9 @@ bool HexdumpRangeDialog::validate()
endAddress = startAddress + length - 1; endAddress = startAddress + length - 1;
emptyRange = false; emptyRange = false;
if (endAddress == UINT64_MAX) { if (endAddress == UINT64_MAX) {
ui->endAddressLineEdit->setText( ui->endAddressLineEdit->setText(QString("2^64"));
QString("2^64"));
} else { } else {
ui->endAddressLineEdit->setText( ui->endAddressLineEdit->setText(QString("0x%1").arg(endAddress + 1, 0, 16));
QString("0x%1").arg(endAddress + 1, 0, 16));
} }
} }
} }

View File

@ -4,7 +4,6 @@
#include "core/CutterCommon.h" #include "core/CutterCommon.h"
#include <QDialog> #include <QDialog>
namespace Ui { namespace Ui {
class HexdumpRangeDialog; class HexdumpRangeDialog;
} }
@ -39,7 +38,6 @@ private:
private slots: private slots:
void on_radioButtonClicked(bool checked); void on_radioButtonClicked(bool checked);
}; };
#endif // HEXDUMPRANGEDIALOG_H #endif // HEXDUMPRANGEDIALOG_H

View File

@ -15,9 +15,8 @@
#include "core/Cutter.h" #include "core/Cutter.h"
#include "common/AnalTask.h" #include "common/AnalTask.h"
InitialOptionsDialog::InitialOptionsDialog(MainWindow *main)
InitialOptionsDialog::InitialOptionsDialog(MainWindow *main): : QDialog(nullptr), // parent must not be main
QDialog(nullptr), // parent must not be main
ui(new Ui::InitialOptionsDialog), ui(new Ui::InitialOptionsDialog),
main(main), main(main),
core(Core()) core(Core())
@ -65,9 +64,14 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main):
{ { "aaft", tr("Type and Argument matching analysis") }, new QCheckBox(), false }, { { "aaft", tr("Type and Argument matching analysis") }, new QCheckBox(), false },
{ { "aaT", tr("Analyze code after trap-sleds") }, new QCheckBox(), false }, { { "aaT", tr("Analyze code after trap-sleds") }, new QCheckBox(), false },
{ { "aap", tr("Analyze function preludes") }, new QCheckBox(), false }, { { "aap", tr("Analyze function preludes") }, new QCheckBox(), false },
{ { "e! analysis.jmp.tbl", tr("Analyze jump tables in switch statements") }, new QCheckBox(), false }, { { "e! analysis.jmp.tbl", tr("Analyze jump tables in switch statements") },
new QCheckBox(),
false },
{ { "e! analysis.pushret", tr("Analyze PUSH+RET as JMP") }, new QCheckBox(), false }, { { "e! analysis.pushret", tr("Analyze PUSH+RET as JMP") }, new QCheckBox(), false },
{ { "e! analysis.hasnext", tr("Continue analysis after each function") }, new QCheckBox(), false }}; { { "e! analysis.hasnext", tr("Continue analysis after each function") },
new QCheckBox(),
false }
};
// Per each checkbox, set a tooltip desccribing it // Per each checkbox, set a tooltip desccribing it
AnalysisCommands item; AnalysisCommands item;
@ -78,18 +82,19 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main):
ui->verticalLayout_7->addWidget(item.checkbox); ui->verticalLayout_7->addWidget(item.checkbox);
} }
ui->hideFrame->setVisible(false); ui->hideFrame->setVisible(false);
ui->analoptionsFrame->setVisible(false); ui->analoptionsFrame->setVisible(false);
ui->advancedAnlysisLine->setVisible(false); ui->advancedAnlysisLine->setVisible(false);
updatePDBLayout(); updatePDBLayout();
connect(ui->pdbCheckBox, &QCheckBox::stateChanged, this, &InitialOptionsDialog::updatePDBLayout); connect(ui->pdbCheckBox, &QCheckBox::stateChanged, this,
&InitialOptionsDialog::updatePDBLayout);
updateScriptLayout(); updateScriptLayout();
connect(ui->scriptCheckBox, &QCheckBox::stateChanged, this, &InitialOptionsDialog::updateScriptLayout); connect(ui->scriptCheckBox, &QCheckBox::stateChanged, this,
&InitialOptionsDialog::updateScriptLayout);
connect(ui->cancelButton, &QPushButton::clicked, this, &InitialOptionsDialog::reject); connect(ui->cancelButton, &QPushButton::clicked, this, &InitialOptionsDialog::reject);
@ -106,9 +111,9 @@ void InitialOptionsDialog::updateCPUComboBox()
QString arch = getSelectedArch(); QString arch = getSelectedArch();
QStringList cpus; QStringList cpus;
if (!arch.isEmpty()) { if (!arch.isEmpty()) {
auto pluginDescr = std::find_if(asmPlugins.begin(), asmPlugins.end(), [&](const RzAsmPluginDescription &plugin) { auto pluginDescr = std::find_if(
return plugin.name == arch; asmPlugins.begin(), asmPlugins.end(),
}); [&](const RzAsmPluginDescription &plugin) { return plugin.name == arch; });
if (pluginDescr != asmPlugins.end()) { if (pluginDescr != asmPlugins.end()) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
cpus = pluginDescr->cpus.split(",", Qt::SkipEmptyParts); cpus = pluginDescr->cpus.split(",", Qt::SkipEmptyParts);
@ -124,7 +129,8 @@ void InitialOptionsDialog::updateCPUComboBox()
ui->cpuComboBox->lineEdit()->setText(currentText); ui->cpuComboBox->lineEdit()->setText(currentText);
} }
QList<QString> InitialOptionsDialog::getAnalysisCommands(const InitialOptions &options) { QList<QString> InitialOptionsDialog::getAnalysisCommands(const InitialOptions &options)
{
QList<QString> commands; QList<QString> commands;
for (auto &commandDesc : options.analCmd) { for (auto &commandDesc : options.analCmd) {
commands << commandDesc.command; commands << commandDesc.command;
@ -175,18 +181,14 @@ void InitialOptionsDialog::loadOptions(const InitialOptions &options)
ui->writeCheckBox->setChecked(options.writeEnabled); ui->writeCheckBox->setChecked(options.writeEnabled);
// TODO: all other options should also be applied to the ui // TODO: all other options should also be applied to the ui
} }
void InitialOptionsDialog::setTooltipWithConfigHelp(QWidget *w, const char *config)
void InitialOptionsDialog::setTooltipWithConfigHelp(QWidget *w, const char *config) { {
w->setToolTip(QString("%1 (%2)") w->setToolTip(QString("%1 (%2)").arg(core->getConfigDescription(config)).arg(config));
.arg(core->getConfigDescription(config))
.arg(config));
} }
QString InitialOptionsDialog::getSelectedArch() const QString InitialOptionsDialog::getSelectedArch() const
{ {
QVariant archValue = ui->archComboBox->currentData(); QVariant archValue = ui->archComboBox->currentData();
@ -259,8 +261,8 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
options.binLoadAddr = Core()->math(ui->entry_loadOffset->text()); options.binLoadAddr = Core()->math(ui->entry_loadOffset->text());
} }
options.mapAddr = Core()->math( options.mapAddr =
ui->entry_mapOffset->text()); // Where to map the file once loaded (-m) Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m)
options.arch = getSelectedArch(); options.arch = getSelectedArch();
options.cpu = getSelectedCPU(); options.cpu = getSelectedCPU();
options.bits = getSelectedBits(); options.bits = getSelectedBits();
@ -280,7 +282,6 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
options.script = ui->scriptLineEdit->text(); options.script = ui->scriptLineEdit->text();
} }
options.endian = getSelectedEndianness(); options.endian = getSelectedEndianness();
int level = ui->analSlider->value(); int level = ui->analSlider->value();
@ -299,7 +300,6 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
break; break;
} }
AnalTask *analTask = new AnalTask(); AnalTask *analTask = new AnalTask();
analTask->setOptions(options); analTask->setOptions(options);
@ -417,7 +417,6 @@ void InitialOptionsDialog::on_pdbSelectButton_clicked()
} }
} }
void InitialOptionsDialog::updateScriptLayout() void InitialOptionsDialog::updateScriptLayout()
{ {
ui->scriptWidget->setEnabled(ui->scriptCheckBox->isChecked()); ui->scriptWidget->setEnabled(ui->scriptCheckBox->isChecked());
@ -440,7 +439,6 @@ void InitialOptionsDialog::on_scriptSelectButton_clicked()
} }
} }
void InitialOptionsDialog::reject() void InitialOptionsDialog::reject()
{ {
done(0); done(0);

View File

@ -48,9 +48,9 @@ private:
int analLevel; int analLevel;
QList<RzAsmPluginDescription> asmPlugins; QList<RzAsmPluginDescription> asmPlugins;
void updateCPUComboBox(); void updateCPUComboBox();
struct AnalysisCommands { struct AnalysisCommands
{
CommandDescription commandDesc; CommandDescription commandDesc;
QCheckBox *checkbox; QCheckBox *checkbox;
bool checked; bool checked;

View File

@ -5,21 +5,18 @@
using namespace Cutter; using namespace Cutter;
LayoutManager::LayoutManager(QMap<QString, Cutter::CutterLayout> &layouts, QWidget *parent) : LayoutManager::LayoutManager(QMap<QString, Cutter::CutterLayout> &layouts, QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::LayoutManager), layouts(layouts)
ui(new Ui::LayoutManager),
layouts(layouts)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(ui->renameButton, &QPushButton::clicked, this, &LayoutManager::renameCurrentLayout); connect(ui->renameButton, &QPushButton::clicked, this, &LayoutManager::renameCurrentLayout);
connect(ui->deleteButton, &QPushButton::clicked, this, &LayoutManager::deleteLayout); connect(ui->deleteButton, &QPushButton::clicked, this, &LayoutManager::deleteLayout);
connect(ui->layoutSelector, &QComboBox::currentTextChanged, this, &LayoutManager::updateButtons); connect(ui->layoutSelector, &QComboBox::currentTextChanged, this,
&LayoutManager::updateButtons);
refreshNameList(); refreshNameList();
} }
LayoutManager::~LayoutManager() LayoutManager::~LayoutManager() {}
{
}
void LayoutManager::refreshNameList(QString selection) void LayoutManager::refreshNameList(QString selection)
{ {
@ -42,10 +39,11 @@ void LayoutManager::renameCurrentLayout()
QString newName; QString newName;
while (newName.isEmpty() || isBuiltinLayoutName(newName) || layouts.contains(newName)) { while (newName.isEmpty() || isBuiltinLayoutName(newName) || layouts.contains(newName)) {
if (!newName.isEmpty()) { if (!newName.isEmpty()) {
QMessageBox::warning(this, tr("Rename layout error"), tr("'%1' is already used.").arg(newName)); QMessageBox::warning(this, tr("Rename layout error"),
tr("'%1' is already used.").arg(newName));
} }
newName = QInputDialog::getText(this, tr("Save layout"), tr("Enter name"), QLineEdit::Normal, newName = QInputDialog::getText(this, tr("Save layout"), tr("Enter name"),
current); QLineEdit::Normal, current);
if (newName.isEmpty()) { if (newName.isEmpty()) {
return; return;
} }

View File

@ -1,9 +1,7 @@
#include "LinkTypeDialog.h" #include "LinkTypeDialog.h"
#include "ui_LinkTypeDialog.h" #include "ui_LinkTypeDialog.h"
LinkTypeDialog::LinkTypeDialog(QWidget *parent) : LinkTypeDialog::LinkTypeDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LinkTypeDialog)
QDialog(parent),
ui(new Ui::LinkTypeDialog)
{ {
addrValid = false; addrValid = false;
@ -49,7 +47,6 @@ bool LinkTypeDialog::setDefaultAddress(const QString &address)
return true; return true;
} }
void LinkTypeDialog::done(int r) void LinkTypeDialog::done(int r)
{ {
if (r == QDialog::Accepted) { if (r == QDialog::Accepted) {

View File

@ -5,9 +5,7 @@
#include <QFileDialog> #include <QFileDialog>
MapFileDialog::MapFileDialog(QWidget *parent): MapFileDialog::MapFileDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MapFileDialog)
QDialog(parent),
ui(new Ui::MapFileDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
} }

View File

@ -4,9 +4,7 @@
#include <QMessageBox> #include <QMessageBox>
MultitypeFileSaveDialog::MultitypeFileSaveDialog(QWidget *parent, const QString &caption,
MultitypeFileSaveDialog::MultitypeFileSaveDialog(QWidget *parent,
const QString &caption,
const QString &directory) const QString &directory)
: QFileDialog(parent, caption, directory) : QFileDialog(parent, caption, directory)
{ {
@ -16,8 +14,8 @@ MultitypeFileSaveDialog::MultitypeFileSaveDialog(QWidget *parent,
connect(this, &QFileDialog::filterSelected, this, &MultitypeFileSaveDialog::onFilterSelected); connect(this, &QFileDialog::filterSelected, this, &MultitypeFileSaveDialog::onFilterSelected);
} }
void MultitypeFileSaveDialog::setTypes(const QVector<MultitypeFileSaveDialog::TypeDescription> void MultitypeFileSaveDialog::setTypes(
types, bool useDetection) const QVector<MultitypeFileSaveDialog::TypeDescription> types, bool useDetection)
{ {
this->hasTypeDetection = useDetection; this->hasTypeDetection = useDetection;
this->types.clear(); this->types.clear();
@ -43,7 +41,8 @@ MultitypeFileSaveDialog::TypeDescription MultitypeFileSaveDialog::selectedType()
if (hasTypeDetection && filterIt == this->types.begin()) { if (hasTypeDetection && filterIt == this->types.begin()) {
QFileInfo info(this->selectedFiles().first()); QFileInfo info(this->selectedFiles().first());
QString currentSuffix = info.suffix(); QString currentSuffix = info.suffix();
filterIt = std::find_if(types.begin(), types.end(), [&currentSuffix](const TypeDescription & v) { filterIt = std::find_if(types.begin(), types.end(),
[&currentSuffix](const TypeDescription &v) {
return currentSuffix == v.extension; return currentSuffix == v.extension;
}); });
if (filterIt != types.end()) { if (filterIt != types.end()) {
@ -96,8 +95,7 @@ void MultitypeFileSaveDialog::onFilterSelected(const QString &filter)
QVector<MultitypeFileSaveDialog::TypeDescription>::const_iterator QVector<MultitypeFileSaveDialog::TypeDescription>::const_iterator
MultitypeFileSaveDialog::findType(const QString &description) const MultitypeFileSaveDialog::findType(const QString &description) const
{ {
return std::find_if(types.begin(), types.end(), return std::find_if(types.begin(), types.end(), [&description](const TypeDescription &v) {
[&description](const TypeDescription & v) {
return v.description == description; return v.description == description;
}); });
} }

View File

@ -10,20 +10,22 @@ class MultitypeFileSaveDialog : public QFileDialog
Q_OBJECT Q_OBJECT
public: public:
struct TypeDescription { struct TypeDescription
{
QString description; QString description;
QString extension; QString extension;
QVariant data; QVariant data;
}; };
explicit MultitypeFileSaveDialog(QWidget *parent = nullptr, explicit MultitypeFileSaveDialog(QWidget *parent = nullptr, const QString &caption = QString(),
const QString &caption = QString(),
const QString &directory = QString()); const QString &directory = QString());
void setTypes(const QVector<TypeDescription> types, bool useDetection = true); void setTypes(const QVector<TypeDescription> types, bool useDetection = true);
TypeDescription selectedType() const; TypeDescription selectedType() const;
protected: protected:
void done(int r) override; void done(int r) override;
private: private:
void onFilterSelected(const QString &filter); void onFilterSelected(const QString &filter);
QVector<TypeDescription>::const_iterator findType(const QString &description) const; QVector<TypeDescription>::const_iterator findType(const QString &description) const;

View File

@ -3,9 +3,8 @@
#include <QMessageBox> #include <QMessageBox>
NativeDebugDialog::NativeDebugDialog(QWidget *parent) : NativeDebugDialog::NativeDebugDialog(QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::NativeDebugDialog)
ui(new Ui::NativeDebugDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));

Some files were not shown because too many files have changed in this diff Show More