Refactor code to match new style (#3612)

* Refactor code to match coding style
* NULL to nullptr
* clang format 16
* Remove unused header
* Fix ordering of headers
* QtResImporter: Don't ignore return value of file.open()
* Add missing memory header
* GraphGridLayout: Remove <ranges>
* GraphGridLayout: no views::reverse
* Fix typos
* Console widget cmd fix
This commit is contained in:
Premade 2026-05-21 14:26:49 +05:00 committed by GitHub
parent fbf2c156d3
commit 1e6782de48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
371 changed files with 8027 additions and 6727 deletions

View file

@ -24,7 +24,6 @@ set(SOURCES
dialogs/XrefsDialog.cpp
core/MainWindow.cpp
common/Helpers.cpp
common/Highlighter.cpp
common/MdHighlighter.cpp
common/DirectionalComboBox.cpp
dialogs/preferences/AsmOptionsWidget.cpp
@ -75,7 +74,6 @@ set(SOURCES
widgets/CutterDockWidget.cpp
widgets/GraphWidget.cpp
widgets/OverviewWidget.cpp
common/JsonModel.cpp
dialogs/VersionInfoDialog.cpp
widgets/FlirtWidget.cpp
common/AsyncTask.cpp
@ -87,7 +85,7 @@ set(SOURCES
widgets/BacktraceWidget.cpp
dialogs/MapFileDialog.cpp
common/CommandTask.cpp
common/ProgressIndicator.cpp
widgets/ProgressIndicator.cpp
common/RizinTask.cpp
dialogs/RizinTaskDialog.cpp
widgets/DebugActions.cpp
@ -172,6 +170,7 @@ set(SOURCES
widgets/ItemCountLineEdit.cpp
widgets/AbstractFilterView.cpp
dialogs/preferences/InterfaceOptionsWidget.cpp
common/Json.cpp
)
set(HEADER_FILES
core/Cutter.h
@ -197,7 +196,6 @@ set(HEADER_FILES
dialogs/XrefsDialog.h
common/Helpers.h
core/MainWindow.h
common/Highlighter.h
common/MdHighlighter.h
common/DirectionalComboBox.h
dialogs/InitialOptionsDialog.h
@ -247,7 +245,6 @@ set(HEADER_FILES
widgets/CutterDockWidget.h
widgets/GraphWidget.h
widgets/OverviewWidget.h
common/JsonModel.h
dialogs/VersionInfoDialog.h
widgets/FlirtWidget.h
common/AsyncTask.h
@ -261,7 +258,7 @@ set(HEADER_FILES
common/StringsTask.h
common/FunctionsTask.h
common/CommandTask.h
common/ProgressIndicator.h
widgets/ProgressIndicator.h
plugins/CutterPlugin.h
common/RizinTask.h
dialogs/RizinTaskDialog.h

View file

@ -1,24 +1,26 @@
#include "common/PythonManager.h"
#include "CutterApplication.h"
#include "plugins/PluginManager.h"
#include "CutterConfig.h"
#include "common/Decompiler.h"
#include "common/Decompiler.h" // IWYU pragma: keep
#include "common/PythonManager.h" // IWYU pragma: keep
#include "common/ResourcePaths.h"
#include "core/Cutter.h"
#include "plugins/PluginManager.h"
#include <QApplication>
#include <QFileOpenEvent>
#include <QCommandLineParser>
#include <QDir>
#include <QEvent>
#include <QFileOpenEvent>
#include <QFontDatabase>
#include <QLibraryInfo>
#include <QMenu>
#include <QMessageBox>
#include <QCommandLineParser>
#include <QTextCodec>
#include <QStringList>
#include <QProcess>
#include <QPluginLoader>
#include <QDir>
#include <QProcess>
#include <QStringList>
#include <QTextCodec>
#include <QTranslator>
#include <QLibraryInfo>
#include <QFontDatabase>
#ifdef Q_OS_WIN
# include <QtNetwork/QtNetwork>
#endif // Q_OS_WIN
@ -88,8 +90,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
}
// Check rizin version
QString rzversion = rz_core_version();
QString localVersion = CUTTER_COMPILE_TIME_RZ_VERSION;
const QString rzversion = rz_core_version();
const QString localVersion = CUTTER_COMPILE_TIME_RZ_VERSION;
qDebug() << rzversion << localVersion;
if (rzversion != localVersion) {
QMessageBox msg;
@ -147,7 +149,7 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
}
mainWindow->displayNewFileDialog();
} else { // filename specified as positional argument
bool askOptions = (clOptions.analysisLevel != AutomaticAnalysisLevel::Ask)
const bool askOptions = (clOptions.analysisLevel != AutomaticAnalysisLevel::Ask)
|| !clOptions.fileOpenOptions.projectFile.isEmpty();
mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions);
}
@ -213,16 +215,16 @@ void CutterApplication::launchNewInstance(const QStringList &args)
bool CutterApplication::event(QEvent *e)
{
if (e->type() == QEvent::FileOpen) {
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(e);
const auto *openEvent = static_cast<QFileOpenEvent *>(e);
if (openEvent) {
if (m_FileAlreadyDropped) {
if (fileAlreadyDropped) {
// We already dropped a file in macOS, let's spawn another instance
// (Like the File -> Open)
QString fileName = openEvent->file();
const QString fileName = openEvent->file();
launchNewInstance({ fileName });
} else {
QString fileName = openEvent->file();
m_FileAlreadyDropped = true;
const QString fileName = openEvent->file();
fileAlreadyDropped = true;
mainWindow->closeNewFileDialog();
InitialOptions options;
options.filename = fileName;
@ -246,9 +248,9 @@ bool CutterApplication::loadTranslations()
QApplication::setLayoutDirection(locale.textDirection());
QLocale::setDefault(locale);
QTranslator *trCutter = new QTranslator;
QTranslator *trQtBase = new QTranslator;
QTranslator *trQt = new QTranslator;
auto *trCutter = new QTranslator;
auto *trQtBase = new QTranslator;
auto *trQt = new QTranslator;
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
@ -361,11 +363,11 @@ QStringList CutterApplication::getArgs() const
}
if (options.binLoadAddr != RVA_INVALID) {
args.push_back("-B");
args.push_back(RzAddressString(options.binLoadAddr));
args.push_back(rzAddressString(options.binLoadAddr));
}
if (options.mapAddr != RVA_INVALID) {
args.push_back("-m");
args.push_back(RzAddressString(options.mapAddr));
args.push_back(rzAddressString(options.mapAddr));
}
if (!options.filename.isEmpty()) {
args.push_back(options.filename);
@ -377,104 +379,104 @@ bool CutterApplication::parseCommandLineOptions()
{
// Keep this function in sync with documentation
QCommandLineParser cmd_parser;
cmd_parser.setApplicationDescription(
QCommandLineParser cmdParser;
cmdParser.setApplicationDescription(
QObject::tr("A Qt and C++ GUI for rizin reverse engineering framework"));
cmd_parser.addHelpOption();
cmd_parser.addVersionOption();
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
cmdParser.addHelpOption();
cmdParser.addVersionOption();
cmdParser.addPositionalArgument("filename", QObject::tr("Filename to open."));
QCommandLineOption analOption(
const QCommandLineOption analOption(
{ "A", "analysis" },
QObject::tr("Automatically open file and optionally start analysis. "
"Needs filename to be specified. May be a value between 0 and 2:"
" 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"),
QObject::tr("level"));
cmd_parser.addOption(analOption);
cmdParser.addOption(analOption);
QCommandLineOption archOption({ "a", "arch" }, QObject::tr("Sets a specific architecture name"),
QObject::tr("arch"));
cmd_parser.addOption(archOption);
const QCommandLineOption archOption(
{ "a", "arch" }, QObject::tr("Sets a specific architecture name"), QObject::tr("arch"));
cmdParser.addOption(archOption);
QCommandLineOption bitsOption({ "b", "bits" }, QObject::tr("Sets a specific architecture bits"),
QObject::tr("bits"));
cmd_parser.addOption(bitsOption);
const QCommandLineOption bitsOption(
{ "b", "bits" }, QObject::tr("Sets a specific architecture bits"), QObject::tr("bits"));
cmdParser.addOption(bitsOption);
QCommandLineOption cpuOption({ "c", "cpu" }, QObject::tr("Sets a specific CPU"),
QObject::tr("cpu"));
cmd_parser.addOption(cpuOption);
const QCommandLineOption cpuOption({ "c", "cpu" }, QObject::tr("Sets a specific CPU"),
QObject::tr("cpu"));
cmdParser.addOption(cpuOption);
QCommandLineOption osOption({ "o", "os" }, QObject::tr("Sets a specific operating system"),
QObject::tr("os"));
cmd_parser.addOption(osOption);
const QCommandLineOption osOption(
{ "o", "os" }, QObject::tr("Sets a specific operating system"), QObject::tr("os"));
cmdParser.addOption(osOption);
QCommandLineOption endianOption({ "e", "endian" },
QObject::tr("Sets the endianness (big or little)"),
QObject::tr("big|little"));
cmd_parser.addOption(endianOption);
const QCommandLineOption endianOption({ "e", "endian" },
QObject::tr("Sets the endianness (big or little)"),
QObject::tr("big|little"));
cmdParser.addOption(endianOption);
QCommandLineOption formatOption({ "F", "format" },
QObject::tr("Force using a specific file format (bin plugin)"),
QObject::tr("name"));
cmd_parser.addOption(formatOption);
const QCommandLineOption formatOption(
{ "F", "format" }, QObject::tr("Force using a specific file format (bin plugin)"),
QObject::tr("name"));
cmdParser.addOption(formatOption);
QCommandLineOption baddrOption({ "B", "base" },
QObject::tr("Load binary at a specific base address"),
QObject::tr("base address"));
cmd_parser.addOption(baddrOption);
const QCommandLineOption baddrOption({ "B", "base" },
QObject::tr("Load binary at a specific base address"),
QObject::tr("base address"));
cmdParser.addOption(baddrOption);
QCommandLineOption maddrOption({ "m", "map" },
QObject::tr("Map the binary at a specific address"),
QObject::tr("map address"));
cmd_parser.addOption(maddrOption);
const QCommandLineOption maddrOption({ "m", "map" },
QObject::tr("Map the binary at a specific address"),
QObject::tr("map address"));
cmdParser.addOption(maddrOption);
QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
cmd_parser.addOption(scriptOption);
const QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
cmdParser.addOption(scriptOption);
QCommandLineOption projectOption({ "p", "project" }, QObject::tr("Load project file"),
QObject::tr("project file"));
cmd_parser.addOption(projectOption);
const QCommandLineOption projectOption({ "p", "project" }, QObject::tr("Load project file"),
QObject::tr("project file"));
cmdParser.addOption(projectOption);
QCommandLineOption writeModeOption({ "w", "writemode" },
QObject::tr("Open file in write mode"));
cmd_parser.addOption(writeModeOption);
const QCommandLineOption writeModeOption({ "w", "writemode" },
QObject::tr("Open file in write mode"));
cmdParser.addOption(writeModeOption);
QCommandLineOption phyModeOption({ "P", "phymode" },
QObject::tr("Disables virtual addressing"));
cmd_parser.addOption(phyModeOption);
const QCommandLineOption phyModeOption({ "P", "phymode" },
QObject::tr("Disables virtual addressing"));
cmdParser.addOption(phyModeOption);
QCommandLineOption pythonHomeOption(
const QCommandLineOption pythonHomeOption(
"pythonhome", QObject::tr("PYTHONHOME to use for embedded python interpreter"),
"PYTHONHOME");
cmd_parser.addOption(pythonHomeOption);
cmdParser.addOption(pythonHomeOption);
QCommandLineOption disableRedirectOption(
const QCommandLineOption disableRedirectOption(
"no-output-redirect",
QObject::tr("Disable output redirection."
" Some of the output in console widget will not be visible."
" Use this option when debuging a crash or freeze and output "
" redirection is causing some messages to be lost."));
cmd_parser.addOption(disableRedirectOption);
cmdParser.addOption(disableRedirectOption);
QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
cmd_parser.addOption(disablePlugins);
const QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
cmdParser.addOption(disablePlugins);
QCommandLineOption disableCutterPlugins("no-cutter-plugins",
QObject::tr("Do not load Cutter plugins"));
cmd_parser.addOption(disableCutterPlugins);
const QCommandLineOption disableCutterPlugins("no-cutter-plugins",
QObject::tr("Do not load Cutter plugins"));
cmdParser.addOption(disableCutterPlugins);
QCommandLineOption disableRizinPlugins("no-rizin-plugins",
QObject::tr("Do not load rizin plugins"));
cmd_parser.addOption(disableRizinPlugins);
const QCommandLineOption disableRizinPlugins("no-rizin-plugins",
QObject::tr("Do not load rizin plugins"));
cmdParser.addOption(disableRizinPlugins);
cmd_parser.process(*this);
cmdParser.process(*this);
CutterCommandLineOptions opts;
opts.args = cmd_parser.positionalArguments();
opts.args = cmdParser.positionalArguments();
if (cmd_parser.isSet(analOption)) {
if (cmdParser.isSet(analOption)) {
bool analysisLevelSpecified = false;
int analysisLevel = cmd_parser.value(analOption).toInt(&analysisLevelSpecified);
const int analysisLevel = cmdParser.value(analOption).toInt(&analysisLevelSpecified);
if (!analysisLevelSpecified || analysisLevel < 0 || analysisLevel > 2) {
fprintf(stderr, "%s\n",
@ -506,17 +508,17 @@ bool CutterApplication::parseCommandLineOptions()
if (!opts.args.isEmpty()) {
opts.fileOpenOptions.filename = opts.args[0];
opts.fileOpenOptions.forceBinPlugin = cmd_parser.value(formatOption);
if (cmd_parser.isSet(baddrOption)) {
opts.fileOpenOptions.forceBinPlugin = cmdParser.value(formatOption);
if (cmdParser.isSet(baddrOption)) {
bool ok = false;
RVA baddr = cmd_parser.value(baddrOption).toULongLong(&ok, 0);
const RVA baddr = cmdParser.value(baddrOption).toULongLong(&ok, 0);
if (ok) {
opts.fileOpenOptions.binLoadAddr = baddr;
}
}
if (cmd_parser.isSet(maddrOption)) {
if (cmdParser.isSet(maddrOption)) {
bool ok = false;
RVA maddr = cmd_parser.value(maddrOption).toULongLong(&ok, 0);
const RVA maddr = cmdParser.value(maddrOption).toULongLong(&ok, 0);
if (ok) {
opts.fileOpenOptions.mapAddr = maddr;
}
@ -539,19 +541,19 @@ bool CutterApplication::parseCommandLineOptions()
};
break;
}
opts.fileOpenOptions.script = cmd_parser.value(scriptOption);
opts.fileOpenOptions.arch = cmd_parser.value(archOption);
opts.fileOpenOptions.cpu = cmd_parser.value(cpuOption);
opts.fileOpenOptions.os = cmd_parser.value(osOption);
if (cmd_parser.isSet(bitsOption)) {
opts.fileOpenOptions.script = cmdParser.value(scriptOption);
opts.fileOpenOptions.arch = cmdParser.value(archOption);
opts.fileOpenOptions.cpu = cmdParser.value(cpuOption);
opts.fileOpenOptions.os = cmdParser.value(osOption);
if (cmdParser.isSet(bitsOption)) {
bool ok = false;
int bits = cmd_parser.value(bitsOption).toInt(&ok, 10);
const int bits = cmdParser.value(bitsOption).toInt(&ok, 10);
if (ok && bits > 0) {
opts.fileOpenOptions.bits = bits;
}
}
if (cmd_parser.isSet(endianOption)) {
QString endian = cmd_parser.value(endianOption).toLower();
if (cmdParser.isSet(endianOption)) {
const QString endian = cmdParser.value(endianOption).toLower();
opts.fileOpenOptions.endian = InitialOptions::Endianness::Auto;
if (endian == "little") {
opts.fileOpenOptions.endian = InitialOptions::Endianness::Little;
@ -568,27 +570,27 @@ bool CutterApplication::parseCommandLineOptions()
opts.fileOpenOptions.endian = InitialOptions::Endianness::Auto;
}
opts.fileOpenOptions.writeEnabled = cmd_parser.isSet(writeModeOption);
opts.fileOpenOptions.useVA = !cmd_parser.isSet(phyModeOption);
opts.fileOpenOptions.writeEnabled = cmdParser.isSet(writeModeOption);
opts.fileOpenOptions.useVA = !cmdParser.isSet(phyModeOption);
}
opts.fileOpenOptions.projectFile = cmd_parser.value(projectOption);
opts.fileOpenOptions.projectFile = cmdParser.value(projectOption);
if (cmd_parser.isSet(pythonHomeOption)) {
opts.pythonHome = cmd_parser.value(pythonHomeOption);
if (cmdParser.isSet(pythonHomeOption)) {
opts.pythonHome = cmdParser.value(pythonHomeOption);
}
opts.outputRedirectionEnabled = !cmd_parser.isSet(disableRedirectOption);
if (cmd_parser.isSet(disablePlugins)) {
opts.outputRedirectionEnabled = !cmdParser.isSet(disableRedirectOption);
if (cmdParser.isSet(disablePlugins)) {
opts.enableCutterPlugins = false;
opts.enableRizinPlugins = false;
}
if (cmd_parser.isSet(disableCutterPlugins)) {
if (cmdParser.isSet(disableCutterPlugins)) {
opts.enableCutterPlugins = false;
}
if (cmd_parser.isSet(disableRizinPlugins)) {
if (cmdParser.isSet(disableRizinPlugins)) {
opts.enableRizinPlugins = false;
}

View file

@ -1,14 +1,14 @@
#ifndef CUTTERAPPLICATION_H
#define CUTTERAPPLICATION_H
#include <QEvent>
#include "core/MainWindow.h"
#include <QApplication>
#include <QEvent>
#include <QList>
#include <QProxyStyle>
#include "core/MainWindow.h"
enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA };
enum class AutomaticAnalysisLevel : ut8 { Ask, None, AAA, AAAA };
struct CutterCommandLineOptions
{
@ -21,6 +21,9 @@ struct CutterCommandLineOptions
bool enableRizinPlugins = true;
};
/**
* @brief Main application class for Cutter
*/
class CutterApplication : public QApplication
{
Q_OBJECT
@ -53,7 +56,7 @@ private:
bool parseCommandLineOptions();
private:
bool m_FileAlreadyDropped;
bool fileAlreadyDropped;
CutterCore core;
MainWindow *mainWindow;
CutterCommandLineOptions clOptions;

View file

@ -1,13 +1,11 @@
#include "CutterApplication.h"
#include "core/MainWindow.h"
#include "common/UpdateWorker.h"
#include "CutterConfig.h"
#include "common/SettingsUpgrade.h"
#include "common/UpdateWorker.h"
#include "core/MainWindow.h" // IWYU pragma: keep
#include <QJsonObject>
#include <QJsonArray>
#include <iostream>
#include <QJsonObject>
/**
* @brief Attempt to connect to a parent console and configure outputs.
@ -85,13 +83,13 @@ int main(int argc, char *argv[])
# endif
#endif
CutterApplication a(argc, argv);
const CutterApplication a(argc, argv);
Cutter::migrateThemes();
if (Config()->getAutoUpdateEnabled()) {
#if CUTTER_UPDATE_WORKER_AVAILABLE
UpdateWorker *updateWorker = new UpdateWorker;
auto *updateWorker = new UpdateWorker;
QObject::connect(updateWorker, &UpdateWorker::checkComplete,
[=](const QVersionNumber &version, const QString &error) {
if (error.isEmpty()
@ -104,7 +102,7 @@ int main(int argc, char *argv[])
#endif
}
int ret = a.exec();
const int ret = a.exec();
return ret;
}

View file

@ -4,11 +4,11 @@
#define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
#include "../core/Cutter.h"
#include "../common/Configuration.h"
#include "../core/Cutter.h"
#include "../core/MainWindow.h"
#include "../widgets/CutterDockWidget.h"
#include "../plugins/CutterPlugin.h"
#include "../menus/AddressableItemContextMenu.h"
#include "../plugins/CutterPlugin.h"
#include "../widgets/CutterDockWidget.h"
#endif // CUTTER_BINDINGS_H

View file

@ -1,14 +1,12 @@
#include <stdexcept>
#include "AddressableItemModel.h"
#include <stdexcept>
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
QObject *parent)
: AddressableItemModel<QSortFilterProxyModel>(parent)
: AddressableItemModel<QSortFilterProxyModel>(parent), addressableSourceModel(sourceModel)
{
setSourceModel(sourceModel);
addressableSourceModel = sourceModel;
}
RVA AddressableFilterProxyModel::address(const QModelIndex &index) const

View file

@ -1,13 +1,14 @@
#ifndef ADDRESSABLEITEMMODEL_H
#define ADDRESSABLEITEMMODEL_H
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QAbstractItemModel>
#include "core/CutterCommon.h"
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
/**
* @brief An interface for QAbstractItemModel containing an address field for each index
*/
class CUTTER_EXPORT AddressableItemModelI
{
public:
@ -17,14 +18,13 @@ public:
* @param index item intex
* @return Item name or empty QString if item doesn't have short descriptive name.
*/
virtual QString name(const QModelIndex &index) const
{
Q_UNUSED(index)
return QString();
}
virtual QString name(const QModelIndex & /*index*/) const { return QString(); }
virtual QAbstractItemModel *asItemModel() = 0;
};
/**
* @brief A wrapper class for QAbstractItemModel containing an address field for each index
*/
template<class ParentModel = QAbstractItemModel>
class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
{
@ -37,6 +37,10 @@ public:
QAbstractItemModel *asItemModel() { return this; }
};
/**
* @brief A wrapper class for QSortFilterProxyModel with @ref AddressableItemModelI as source
* model
*/
class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
{
using ParentClass = AddressableItemModel<QSortFilterProxyModel>;

View file

@ -1,10 +1,12 @@
#include "core/Cutter.h"
#include "common/AnalysisTask.h"
#include "core/Cutter.h"
#include "core/MainWindow.h"
#include "dialogs/InitialOptionsDialog.h"
#include <QJsonArray>
#include <QDebug>
#include <QCheckBox>
#include <QDebug>
#include <QJsonArray>
AnalysisTask::AnalysisTask() : AsyncTask() {}
@ -16,12 +18,9 @@ void AnalysisTask::interrupt()
rz_cons_singleton()->context->breaked = true;
}
QString AnalysisTask::getTitle()
QString AnalysisTask::getTitle() const
{
// If no file is loaded we consider it's Initial Analysis
RzCoreLocked core(Core());
RzList *descs = rz_id_storage_list(core->io->files);
if (rz_list_empty(descs)) {
if (Core()->isFileLoaded()) {
return tr("Initial Analysis");
}
return tr("Analyzing Program");
@ -34,17 +33,18 @@ void AnalysisTask::runTask()
perms |= RZ_PERM_W;
emit Core()->ioModeChanged();
}
// Need to lock Core here, so avoid the use of Core()-> functions as much as possible
RzCoreLocked core(Core());
// Demangle (must be before file Core()->loadFile)
Core()->setConfig("bin.demangle", options.demangle);
// recursive mutex Demangle (must be before file Core()->loadFile)
rz_config_set_b(core->config, "bin.demangle", options.demangle);
// Do not reload the file if already loaded
RzCoreLocked core(Core());
RzList *descs = rz_id_storage_list(core->io->files);
const RzList *descs = rz_id_storage_list(core->io->files);
if (rz_list_empty(descs) && options.filename.length()) {
log(tr("Loading the file..."));
openFailed = false;
bool fileLoaded =
const bool fileLoaded =
Core()->loadFile(options.filename, options.binLoadAddr, options.mapAddr, perms,
options.useVA, options.loadBinInfo, options.forceBinPlugin);
if (!fileLoaded) {
@ -64,17 +64,17 @@ void AnalysisTask::runTask()
}
if (!options.os.isNull()) {
RzCoreLocked core(Core());
rz_config_set(core->config, "asm.os", options.os.toUtf8().constData());
}
if (!options.pdbFile.isNull()) {
log(tr("Loading PDB file..."));
Core()->loadPDB(options.pdbFile);
rz_core_bin_pdb_load(core, options.pdbFile.toUtf8().constData());
}
if (Core()->getConfigb("bin.dbginfo.debuginfod")) {
Core()->applyDwarf();
log(tr("Applying Dwarf..."));
rz_core_bin_apply_dwarf(core, rz_bin_cur(core->bin));
}
if (isInterrupted()) {
@ -87,7 +87,8 @@ void AnalysisTask::runTask()
}
if (options.endian != InitialOptions::Endianness::Auto) {
Core()->setEndianness(options.endian == InitialOptions::Endianness::Big);
rz_config_set_b(core->config, "cfg.bigendian",
options.endian == InitialOptions::Endianness::Big);
}
rz_flag_space_set(core->flags, "*");
@ -103,7 +104,7 @@ void AnalysisTask::runTask()
if (!options.analysisCmd.empty()) {
log(tr("Executing analysis..."));
for (const CommandDescription &cmd : options.analysisCmd) {
for (const CommandDescription &cmd : std::as_const(options.analysisCmd)) {
if (isInterrupted()) {
return;
}

View file

@ -1,14 +1,17 @@
#ifndef ANALTHREAD_H
#define ANALTHREAD_H
#ifndef ANALYSISTASK_H
#define ANALYSISTASK_H
#include "common/AsyncTask.h"
#include "core/Cutter.h"
#include "common/InitialOptions.h"
// #include "core/Cutter.h"
class CutterCore;
class MainWindow;
class InitialOptionsDialog;
/**
* @brief Background task for initial binary analysis and file loading
*/
class AnalysisTask : public AsyncTask
{
Q_OBJECT
@ -17,13 +20,13 @@ public:
explicit AnalysisTask();
~AnalysisTask();
QString getTitle() override;
QString getTitle() const override;
void setOptions(const InitialOptions &options) { this->options = options; }
void interrupt() override;
bool getOpenFileFailed() { return openFailed; }
bool getOpenFileFailed() const { return openFailed; }
protected:
void runTask() override;
@ -37,4 +40,4 @@ private:
bool openFailed = false;
};
#endif // ANALTHREAD_H
#endif // ANALYSISTASK_H

View file

@ -1,10 +1,9 @@
#include "AsyncTask.h"
AsyncTask::AsyncTask() : QObject(nullptr), QRunnable()
AsyncTask::AsyncTask() : QObject(nullptr), QRunnable(), running(false)
{
setAutoDelete(false);
running = false;
}
AsyncTask::~AsyncTask()
@ -20,7 +19,7 @@ void AsyncTask::wait()
bool AsyncTask::wait(int timeout)
{
bool r = runningMutex.tryLock(timeout);
const bool r = runningMutex.tryLock(timeout);
if (r) {
runningMutex.unlock();
}
@ -62,24 +61,24 @@ void AsyncTask::log(QString s)
emit logChanged(logBuffer);
}
AsyncTaskManager::AsyncTaskManager(QObject *parent) : QObject(parent)
AsyncTaskManager::AsyncTaskManager(QObject *parent)
: QObject(parent), threadPool(new QThreadPool(this))
{
threadPool = new QThreadPool(this);
}
AsyncTaskManager::~AsyncTaskManager() {}
void AsyncTaskManager::start(AsyncTask::Ptr task)
void AsyncTaskManager::start(const AsyncTask::Ptr &task)
{
tasks.append(task);
task->prepareRun();
QWeakPointer<AsyncTask> weakPtr = task;
connect(task.data(), &AsyncTask::finished, this, [this, weakPtr]() {
tasks.removeOne(weakPtr);
const std::weak_ptr<AsyncTask> weakPtr = task;
connect(task.get(), &AsyncTask::finished, this, [this, weakPtr]() {
tasks.removeOne(weakPtr.lock());
emit tasksChanged();
});
threadPool->start(task.data());
threadPool->start(task.get());
emit tasksChanged();
}

View file

@ -1,18 +1,22 @@
#ifndef ASYNCTASK_H
#define ASYNCTASK_H
#include "core/CutterCommon.h"
#include <QElapsedTimer>
#include <QList>
#include <QMutex>
#include <QRunnable>
#include <QThreadPool>
#include <QMutex>
#include <QElapsedTimer>
#include <QSharedPointer>
#include <QList>
#include <memory>
class AsyncTaskManager;
/**
* @brief Wrapper class for QRunnable that provides timing and logging, intended to be used
* with @ref AsyncTaskManager
*/
class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable
{
Q_OBJECT
@ -20,7 +24,7 @@ class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable
friend class AsyncTaskManager;
public:
using Ptr = QSharedPointer<AsyncTask>;
using Ptr = std::shared_ptr<AsyncTask>;
AsyncTask();
~AsyncTask();
@ -30,14 +34,14 @@ public:
void wait();
bool wait(int timeout);
virtual void interrupt();
bool isInterrupted() { return interrupted; }
bool isRunning() { return running; }
bool isInterrupted() const { return interrupted; }
bool isRunning() const { return running; }
const QString &getLog() { return logBuffer; }
const QElapsedTimer &getTimer() { return timer; }
qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; }
virtual QString getTitle() { return QString(); }
virtual QString getTitle() const { return QString(); }
protected:
virtual void runTask() = 0;
@ -59,6 +63,10 @@ private:
void prepareRun();
};
/**
* @brief Wrapper class for QThreadPool, used for starting @ref AsyncTask objects on separate
* threads
*/
class AsyncTaskManager : public QObject
{
Q_OBJECT
@ -71,11 +79,11 @@ public:
explicit AsyncTaskManager(QObject *parent = nullptr);
~AsyncTaskManager();
void start(AsyncTask::Ptr task);
void start(const AsyncTask::Ptr &task);
bool getTasksRunning();
signals:
void tasksChanged();
};
#endif // ASYNCTASK_H
#endif // ASYNCTASK_H

View file

@ -2,9 +2,6 @@
BasicBlockHighlighter::BasicBlockHighlighter() {}
/**
* @brief Highlight the basic block at address
*/
void BasicBlockHighlighter::highlight(RVA address, const QColor &color)
{
BasicBlock block;
@ -13,22 +10,14 @@ void BasicBlockHighlighter::highlight(RVA address, const QColor &color)
bbMap[address] = block;
}
/**
* @brief Clear the basic block highlighting
*/
void BasicBlockHighlighter::clear(RVA address)
{
bbMap.erase(address);
}
/**
* @brief Return a highlighted basic block
*
* If there is nothing to highlight at specified address, returns nullptr
*/
BasicBlockHighlighter::BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address)
const BasicBlockHighlighter::BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address) const
{
auto it = bbMap.find(address);
const auto it = bbMap.find(address);
if (it != bbMap.end()) {
return &it->second;
}

View file

@ -4,8 +4,12 @@
class BasicBlockHighlighter;
#include "Cutter.h"
#include <map>
/**
* @brief Contains a highlight map for basic blocks
*/
class BasicBlockHighlighter
{
public:
@ -17,9 +21,21 @@ public:
BasicBlockHighlighter();
/**
* @brief Highlight the basic block at address
*/
void highlight(RVA address, const QColor &color);
/**
* @brief Clear the basic block highlighting
*/
void clear(RVA address);
BasicBlock *getBasicBlock(RVA address);
/**
* @brief Return a highlighted basic block
* If there is nothing to highlight at specified address, returns nullptr
*/
const BasicBlock *getBasicBlock(RVA address) const;
private:
std::map<RVA, BasicBlock> bbMap;

View file

@ -1,12 +1,10 @@
#include "BasicInstructionHighlighter.h"
#include <vector>
/**
* @brief Clear the basic instruction highlighting
*/
void BasicInstructionHighlighter::clear(RVA address, RVA size)
{
BasicInstructionIt it = biMap.lower_bound(address);
auto it = biMap.lower_bound(address);
if (it != biMap.begin()) {
--it;
}
@ -34,40 +32,33 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
}
}
for (RVA addr : addrs) {
for (const RVA addr : addrs) {
const BasicInstruction &bi = biMap[addr];
if (std::max(bi.address, address) < std::min(bi.address + bi.size, address + size)) {
biMap.erase(addr);
}
}
for (BasicInstruction newInstr : newInstructions) {
for (const auto &newInstr : newInstructions) {
biMap[newInstr.address] = newInstr;
}
}
/**
* @brief Highlight the basic instruction at address
*/
void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color)
{
clear(address, size);
biMap[address] = { address, size, color };
}
/**
* @brief Return a highlighted basic instruction
*
* If there is nothing to highlight at specified address, returns nullptr
*/
BasicInstruction *BasicInstructionHighlighter::getBasicInstruction(RVA address)
const BasicInstructionHighlighter::BasicInstruction *
BasicInstructionHighlighter::getBasicInstruction(RVA address) const
{
BasicInstructionIt it = biMap.upper_bound(address);
auto it = biMap.upper_bound(address);
if (it == biMap.begin()) {
return nullptr;
}
BasicInstruction *bi = &(--it)->second;
const BasicInstruction *bi = &(--it)->second;
if (bi->address <= address && address < bi->address + bi->size) {
return bi;
}

View file

@ -2,24 +2,41 @@
#define BASICINSTRUCTIONHIGHLIGHTER_H
#include "CutterCommon.h"
#include <map>
#include <QColor>
struct BasicInstruction
{
RVA address;
RVA size;
QColor color;
};
typedef std::map<RVA, BasicInstruction>::iterator BasicInstructionIt;
#include <map>
/**
* @brief Contains a highlight map for basic instructions
*/
class BasicInstructionHighlighter
{
public:
struct BasicInstruction
{
RVA address;
RVA size;
QColor color;
};
typedef std::map<RVA, BasicInstruction>::iterator BasicInstructionIt;
/**
* @brief Clear the basic instruction highlighting
*/
void clear(RVA address, RVA size);
/**
* @brief Highlight the basic instruction at address
*/
void highlight(RVA address, RVA size, QColor color);
BasicInstruction *getBasicInstruction(RVA address);
/**
* @brief Return a highlighted basic instruction
* If there is nothing to highlight at specified address, returns nullptr
*/
const BasicInstruction *getBasicInstruction(RVA address) const;
private:
std::map<RVA, BasicInstruction> biMap;

View file

@ -1,15 +1,16 @@
#ifndef BINARY_TREES_H
#define BINARY_TREES_H
/** \file BinaryTrees.h
* \brief Utilities to simplify creation of specialized augmented binary trees.
/**
* @file BinaryTrees.h
* @brief Utilities to simplify creation of specialized augmented binary trees.
*/
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <climits>
#include <cstdint>
#include <algorithm>
#include <cstdlib>
#include <vector>
/**
* Not really a segment tree for storing segments as referred in academic literature. Can be
@ -19,8 +20,8 @@
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left,
* NodeType& right) method which calculates inner node values from children nodes.
*
* \tparam NodeTypeT type of each tree element
* \tparam FinalType final child class used for curiously recurring template pattern
* @tparam NodeTypeT type of each tree element
* @tparam FinalType final child class used for curiously recurring template pattern
*/
template<class NodeTypeT, class FinalType>
class SegmentTreeBase
@ -86,7 +87,7 @@ protected:
};
/**
* \brief Tree for point modification and range queries.
* @brief Tree for point modification and range queries.
*/
template<class NodeType, class FinalType>
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
@ -221,17 +222,17 @@ 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.
*
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies
* the applies the operation stored in \a promise for nodePosition to the direct children nodes.
* the applies the operation stored in @a promise for nodePosition to the direct children nodes.
*
* \tparam NodeType type of tree nodes
* \tparam PromiseType type describing operation that needs to be applied to subtree
* \tparam FinalType child class type for CRTP. See SegmentTreeBase
* @tparam NodeType type of tree nodes
* @tparam PromiseType type describing operation that needs to be applied to subtree
* @tparam FinalType child class type for CRTP. See SegmentTreeBase
*/
template<class NodeType, class PromiseType, class FinalType>
class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType>
@ -244,9 +245,9 @@ public:
* @param neutralPromise Promise value that doesn't modify tree nodes.
*/
LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise)
: BaseType(size), neutralPromiseElement(neutralPromise), promise(size, neutralPromise)
: BaseType(size), h(0), neutralPromiseElement(neutralPromise), promise(size, neutralPromise)
{
h = 0;
size_t v = size;
while (v) {
v >>= 1;
@ -339,8 +340,8 @@ public:
void pushDown(size_t parent)
{
if (promise[parent]) {
size_t left = (parent << 1);
size_t right = (parent << 1) | 1;
const size_t left = (parent << 1);
const size_t right = (parent << 1) | 1;
nodes[left] = nodes[right] = nodes[parent];
if (left < size) {
promise[left] = promise[parent];
@ -428,46 +429,46 @@ class MinMaxAccumulateTree : public LazySegmentTreeBase<std::pair<IntegerType, I
using NodeType = typename BaseType::NodeType;
using NodePosition = typename BaseType::NodePosition;
static constexpr MinMax LIMITS()
static constexpr MinMax limits()
{
return { std::numeric_limits<IntegerType>::max(), std::numeric_limits<IntegerType>::min() };
}
static MinMax Combine(const MinMax &a, const MinMax &b)
static MinMax combine(const MinMax &a, const MinMax &b)
{
return { std::min(a.first, b.first), std::max(a.second, b.second) };
}
void UpdateNode(NodePosition nodePos, ValueType value)
void updateNode(NodePosition nodePos, ValueType value)
{
this->nodes[nodePos] = Combine(this->nodes[nodePos], value);
this->nodes[nodePos] = combine(this->nodes[nodePos], value);
if (!this->isLeave(nodePos)) {
this->promise[nodePos] = Combine(this->promise[nodePos], value);
this->promise[nodePos] = combine(this->promise[nodePos], value);
}
}
public:
MinMaxAccumulateTree(size_t size, ValueType initialValue = LIMITS())
: BaseType(size, initialValue, LIMITS())
MinMaxAccumulateTree(size_t size, ValueType initialValue = limits())
: BaseType(size, initialValue, limits())
{
}
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
{
parent = Combine(left, right);
parent = combine(left, right);
}
void pushDown(NodePosition parent)
{
size_t left = (parent << 1);
size_t right = (parent << 1) | 1;
this->UpdateNode(left, this->promise[parent]);
this->UpdateNode(right, this->promise[parent]);
const size_t left = (parent << 1);
const size_t right = (parent << 1) | 1;
this->updateNode(left, this->promise[parent]);
this->updateNode(right, this->promise[parent]);
this->promise[parent] = this->neutralPromiseElement;
}
/**
* @brief Update min and max values in the range [\a left, \a right) with number \a value.
* @brief Update min and max values in the range [@a left, @a right) with number @a value.
* @param left inclusive range left side
* @param right exclusive right side of range
* @param value number to be used for updating minimum and maximum
@ -478,15 +479,15 @@ public:
right = this->leaveIndexToPosition(right);
this->pushDownFromRoot(left);
this->pushDownFromRoot(right - 1);
MinMax pairValue { value, value };
const MinMax pairValue { value, value };
for (size_t l = left, r = right; l < r; l >>= 1, r >>= 1) {
if (l & 1) {
UpdateNode(l, pairValue);
updateNode(l, pairValue);
l += 1;
}
if (r & 1) {
r -= 1;
UpdateNode(r, pairValue);
updateNode(r, pairValue);
}
}
this->updateUntilRoot(left);

View file

@ -1,10 +1,11 @@
#include "BugReporting.h"
#include "Cutter.h"
#include <QUrl>
#include <QJsonObject>
#include "CutterConfig.h"
#include <QDesktopServices>
#include <QJsonObject>
#include <QUrl>
void openIssue()
{
@ -12,7 +13,7 @@ void openIssue()
RzBinFile *bf = rz_bin_cur(core->bin);
RzBinObject *bobj = rz_bin_cur_object(core->bin);
const RzBinInfo *info = bobj ? rz_bin_object_get_info(bobj) : nullptr;
RzBinPlugin *plugin = rz_bin_file_cur_plugin(bf);
const RzBinPlugin *plugin = rz_bin_file_cur_plugin(bf);
QString url, osInfo, format, arch, type;
// Pull in info needed for git issue

View file

@ -1,5 +1,5 @@
#ifndef CRASHREPORTING_H
#define CRASHREPORTING_H
#ifndef BUGREPORTING_H
#define BUGREPORTING_H
/**
* @brief Opens issue on Cutter's github page
@ -7,4 +7,4 @@
*/
void openIssue();
#endif // CRASHREPORTING_H
#endif // BUGREPORTING_H

View file

@ -3,34 +3,42 @@
#include "common/Metrics.h"
#include <QObject>
#include <QFont>
#include <QFontMetrics>
#include <QObject>
/**
* @brief A cache class for font measurements
*
* Stores calculated widths in an array so when asking for a character's width
* second time, it is returned instantly without any calculation
*
* @tparam T The type used for dimensions, such as int or qreal
*/
template<typename T>
class CachedFontMetrics
{
public:
explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font)
explicit CachedFontMetrics(const QFont &font)
: fontMetrics(font), charWidths {}, fontHeight(fontMetrics.height())
{
memset(mWidths, 0, sizeof(mWidths));
mHeight = mFontMetrics.height();
}
T width(const QChar &ch)
{
// return mFontMetrics.width(ch);
auto unicode = ch.unicode();
if (unicode >= 0xD800) {
if (unicode >= 0xE000)
if (unicode >= 0xD800) [[unlikely]] {
if (unicode >= 0xE000) {
unicode -= 0xE000 - 0xD800;
else
} else {
// is lonely surrogate
return fetchWidth(ch);
}
}
if (!mWidths[unicode])
return mWidths[unicode] = fetchWidth(ch);
return mWidths[unicode];
if (!charWidths[unicode]) [[unlikely]] {
return charWidths[unicode] = fetchWidth(ch);
}
return charWidths[unicode];
}
T width(const QString &text)
@ -38,17 +46,18 @@ public:
T result = 0;
QChar temp;
for (const QChar &ch : text) {
if (ch.isHighSurrogate())
if (ch.isHighSurrogate()) [[unlikely]] {
temp = ch;
else if (ch.isLowSurrogate())
} else if (ch.isLowSurrogate()) [[unlikely]] {
result += fetchWidth(QString(temp) + ch);
else
} else [[likely]] {
result += width(ch);
}
}
return result;
}
T height() { return mHeight; }
T height() { return fontHeight; }
T position(const QString &text, T offset)
{
@ -56,15 +65,15 @@ public:
QChar temp;
for (int i = 0; i < text.length(); i++) {
QChar ch = text[i];
const QChar ch = text[i];
if (ch.isHighSurrogate())
if (ch.isHighSurrogate()) [[unlikely]] {
temp = ch;
else if (ch.isLowSurrogate())
} else if (ch.isLowSurrogate()) [[unlikely]] {
curWidth += fetchWidth(QString(temp) + ch);
else
} else [[likely]] {
curWidth += width(ch);
}
if (curWidth >= offset) {
return i;
}
@ -74,25 +83,25 @@ public:
}
private:
typename Metrics<T>::FontMetrics mFontMetrics;
T mWidths[0x10000 - 0xE000 + 0xD800];
T mHeight;
typename Metrics<T>::FontMetrics fontMetrics;
T charWidths[0x10000 - 0xE000 + 0xD800];
T fontHeight;
T fetchWidth(QChar c)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
return mFontMetrics.width(c);
return fontMetrics.width(c);
#else
return mFontMetrics.horizontalAdvance(c);
return fontMetrics.horizontalAdvance(c);
#endif
}
T fetchWidth(const QString &s)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
return mFontMetrics.width(s);
return fontMetrics.width(s);
#else
return mFontMetrics.horizontalAdvance(s);
return fontMetrics.horizontalAdvance(s);
#endif
}
};

View file

@ -1,14 +1,15 @@
#include "ColorThemeWorker.h"
#include "common/Configuration.h"
#include <QColor>
#include <QDir>
#include <QFile>
#include <QColor>
#include <QJsonArray>
#include <QStandardPaths>
#include <QRegularExpression>
#include <rz_util/rz_path.h>
#include <QStandardPaths>
#include "common/Configuration.h"
#include <rz_util/rz_path.h>
const QStringList ColorThemeWorker::cutterSpecificOptions = {
"wordHighlight",
@ -55,9 +56,9 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
QDir().mkpath(customRzThemesLocationPath);
}
RzPath *sys_path = rz_path_new();
const char *theme_dir = rz_path_system(sys_path, RZ_THEMES);
QDir currDir { theme_dir };
RzPath *sysPath = rz_path_new();
const char *themeDir = rz_path_system(sysPath, RZ_THEMES);
const QDir currDir { themeDir };
if (currDir.exists()) {
standardRzThemesLocationPath = currDir.absolutePath();
} else {
@ -66,7 +67,7 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
"Most likely, Rizin is not properly installed.")
.arg(currDir.path()));
}
rz_path_free(sys_path);
rz_path_free(sysPath);
}
QColor ColorThemeWorker::mergeColors(const QColor &upper, const QColor &lower) const
@ -128,14 +129,14 @@ bool ColorThemeWorker::isCustomTheme(const QString &themeName) const
bool ColorThemeWorker::isThemeExist(const QString &name) const
{
QStringList themes = Core()->getColorThemes();
const QStringList themes = Core()->getColorThemes();
return themes.contains(name);
}
ColorThemeWorker::Theme ColorThemeWorker::getTheme(const QString &themeName) const
{
Theme theme;
QString curr = Config()->getColorTheme();
const QString curr = Config()->getColorTheme();
if (themeName != curr) {
RzCoreLocked core(Core());
@ -206,13 +207,13 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const
QString ColorThemeWorker::importTheme(const QString &file) const
{
QFileInfo src(file);
const QFileInfo src(file);
if (!src.exists()) {
return tr("File <b>%1</b> does not exist.").arg(file);
}
bool ok;
bool isTheme = isFileTheme(file, &ok);
const bool isTheme = isFileTheme(file, &ok);
if (!ok) {
return tr("File <b>%1</b> could not be opened. "
"Please make sure you have access to it and try again.")
@ -221,7 +222,7 @@ QString ColorThemeWorker::importTheme(const QString &file) const
return tr("File <b>%1</b> is not a Cutter color theme").arg(file);
}
QString name = src.fileName();
const QString name = src.fileName();
if (isThemeExist(name)) {
return tr("A color theme named <b>%1</b> already exists.").arg(name);
}
@ -246,8 +247,8 @@ QString ColorThemeWorker::renameTheme(const QString &themeName, const QString &n
return tr("You can not rename standard Rizin themes.");
}
QDir dir = customRzThemesLocationPath;
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
const QDir dir = customRzThemesLocationPath;
const bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
if (!ok) {
return tr("Something went wrong during renaming. "
"Please make sure you have access to the directory <b>\"%1\"</b>.")
@ -265,13 +266,13 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
}
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
QString options =
const QString options =
(Core()->getThemeKeys() << cutterSpecificOptions).join('|').replace(".", "\\.");
QString pattern =
const QString pattern =
QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options, colors);
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
const QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
for (auto &line : QString(f.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
line.replace("#~", "ec ");
@ -287,11 +288,11 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
QStringList ColorThemeWorker::customThemes() const
{
QStringList themes = Core()->getColorThemes();
const QStringList themes = Core()->getColorThemes();
QStringList ret;
for (int i = 0; i < themes.size(); i++) {
if (isCustomTheme(themes[i])) {
ret.push_back(themes[i]);
for (const auto &theme : themes) {
if (isCustomTheme(theme)) {
ret.push_back(theme);
}
}
return ret;

View file

@ -1,18 +1,19 @@
#ifndef COLORTHEMEWORKER_H
#define COLORTHEMEWORKER_H
#include <QFile>
#include <QColor>
#include <QObject>
#include "Cutter.h"
#include <QColor>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QObject>
#define ThemeWorker() (ColorThemeWorker::instance())
/**
* @brief The ColorThemeWorker class is a singletone that provides API for working with
* color themes.
* @brief The ColorThemeWorker class is a singleton that provides API for working with
* color themes
*/
class ColorThemeWorker : public QObject
{
@ -40,20 +41,16 @@ public:
/**
* @brief Copies @a srcThemeName with name @a copyThemeName.
* @param srcThemeName
* Name of theme to be copied.
* @param copyThemeName
* Name of copy.
* @param srcThemeName Name of theme to be copied.
* @param copyThemeName Name of copy.
* @return "" on success or error message.
*/
QString copy(const QString &srcThemeName, const QString &copyThemeName) const;
/**
* @brief Saves @a theme as @a themeName theme.
* @param theme
* Theme to be saved.
* @param themeName
* Name of theme to save.
* @param theme Theme to be saved.
* @param themeName Name of theme to save.
* @return "" on success or error message.
*/
QString save(const Theme &theme, const QString &themeName) const;
@ -61,8 +58,7 @@ public:
/**
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or
* not.
* @param themeName
* Name of theme to check.
* @param themeName Name of theme to check.
*/
bool isCustomTheme(const QString &themeName) const;
@ -74,15 +70,13 @@ public:
/**
* @brief Returns theme as QHash where key is option name and value is QColor.
* @param themeName
* Theme to get.
* @param themeName Theme to get.
*/
Theme getTheme(const QString &themeName) const;
/**
* @brief Deletes theme named @a themeName.
* @param themeName
* Name of theme to be removed.
* @param themeName Name of theme to be removed.
* @return "" on success or error message.
*/
QString deleteTheme(const QString &themeName) const;
@ -101,11 +95,9 @@ public:
/**
* @brief Returns whether or not file at @a filePath is a color theme.
* @param filePath
* Path to file to check.
* @param ok
* Output parameter. Indicates wheter or not check was successful.
* @return true if given file is color theme and ok == true, otherwise returns false.
* @param filePath Path to file to check.
* @param ok Output parameter. Indicates wheter or not check was successful.
* @return true if given file is a valid color theme and ok == true, otherwise returns false.
*/
bool isFileTheme(const QString &filePath, bool *ok) const;
@ -114,8 +106,8 @@ public:
*/
QStringList customThemes() const;
QString getStandardThemesPath() { return standardRzThemesLocationPath; }
QString getCustomThemesPath() { return customRzThemesLocationPath; }
QString getStandardThemesPath() const { return standardRzThemesLocationPath; }
QString getCustomThemesPath() const { return customRzThemesLocationPath; }
const QStringList &getRizinSpecificOptions();

View file

@ -1,106 +1,26 @@
#include "Colors.h"
#include "common/Configuration.h"
Colors::Colors() {}
#include <utility>
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 typeNum)
{
RichTextPainter::CustomRichText_t assembly;
RichTextPainter::CustomRichText assembly;
assembly.highlight = false;
assembly.flags = RichTextPainter::FlagColor;
// TODO cut opcode and use op["ptr"] to colorate registers and immediate values
assembly.text = opcode;
assembly.text = std::move(opcode);
QString colorName = Colors::getColor(type_num);
const QString colorName = Core()->getColorNameFromOp(typeNum);
assembly.textColor = ConfigColor(colorName);
list.push_back(assembly);
}
// Temporary solution
// Copied from RZ_API const char* r_print_color_op_type(RPrint *p, ut64 analysis_type) {
QString Colors::getColor(ut64 type)
{
switch (type & RZ_ANALYSIS_OP_TYPE_MASK) {
case RZ_ANALYSIS_OP_TYPE_NOP:
return "nop";
case RZ_ANALYSIS_OP_TYPE_ADD:
case RZ_ANALYSIS_OP_TYPE_SUB:
case RZ_ANALYSIS_OP_TYPE_MUL:
case RZ_ANALYSIS_OP_TYPE_DIV:
case RZ_ANALYSIS_OP_TYPE_MOD:
case RZ_ANALYSIS_OP_TYPE_LENGTH:
return "math";
case RZ_ANALYSIS_OP_TYPE_AND:
case RZ_ANALYSIS_OP_TYPE_OR:
case RZ_ANALYSIS_OP_TYPE_XOR:
case RZ_ANALYSIS_OP_TYPE_NOT:
case RZ_ANALYSIS_OP_TYPE_SHL:
case RZ_ANALYSIS_OP_TYPE_SAL:
case RZ_ANALYSIS_OP_TYPE_SAR:
case RZ_ANALYSIS_OP_TYPE_SHR:
case RZ_ANALYSIS_OP_TYPE_ROL:
case RZ_ANALYSIS_OP_TYPE_ROR:
case RZ_ANALYSIS_OP_TYPE_CPL:
return "bin";
case RZ_ANALYSIS_OP_TYPE_IO:
return "swi";
case RZ_ANALYSIS_OP_TYPE_JMP:
case RZ_ANALYSIS_OP_TYPE_UJMP:
case RZ_ANALYSIS_OP_TYPE_IJMP:
case RZ_ANALYSIS_OP_TYPE_RJMP:
case RZ_ANALYSIS_OP_TYPE_IRJMP:
case RZ_ANALYSIS_OP_TYPE_MJMP:
return "jmp";
case RZ_ANALYSIS_OP_TYPE_CJMP:
case RZ_ANALYSIS_OP_TYPE_UCJMP:
case RZ_ANALYSIS_OP_TYPE_SWITCH:
return "cjmp";
case RZ_ANALYSIS_OP_TYPE_CMP:
case RZ_ANALYSIS_OP_TYPE_ACMP:
return "cmp";
case RZ_ANALYSIS_OP_TYPE_UCALL:
case RZ_ANALYSIS_OP_TYPE_ICALL:
case RZ_ANALYSIS_OP_TYPE_RCALL:
case RZ_ANALYSIS_OP_TYPE_IRCALL:
case RZ_ANALYSIS_OP_TYPE_UCCALL:
case RZ_ANALYSIS_OP_TYPE_CALL:
case RZ_ANALYSIS_OP_TYPE_CCALL:
return "call";
case RZ_ANALYSIS_OP_TYPE_NEW:
case RZ_ANALYSIS_OP_TYPE_SWI:
return "swi";
case RZ_ANALYSIS_OP_TYPE_ILL:
case RZ_ANALYSIS_OP_TYPE_TRAP:
return "trap";
case RZ_ANALYSIS_OP_TYPE_CRET:
case RZ_ANALYSIS_OP_TYPE_RET:
return "ret";
case RZ_ANALYSIS_OP_TYPE_CAST:
case RZ_ANALYSIS_OP_TYPE_MOV:
case RZ_ANALYSIS_OP_TYPE_LEA:
case RZ_ANALYSIS_OP_TYPE_CMOV: // TODO: add cmov cathegory?
return "mov";
case RZ_ANALYSIS_OP_TYPE_PUSH:
case RZ_ANALYSIS_OP_TYPE_UPUSH:
case RZ_ANALYSIS_OP_TYPE_LOAD:
return "push";
case RZ_ANALYSIS_OP_TYPE_POP:
case RZ_ANALYSIS_OP_TYPE_STORE:
return "pop";
case RZ_ANALYSIS_OP_TYPE_CRYPTO:
return "crypto";
case RZ_ANALYSIS_OP_TYPE_NULL:
return "other";
case RZ_ANALYSIS_OP_TYPE_UNK:
default:
return "invalid";
}
}
QColor Colors::overlayColor(const QColor &base, const QColor &overlay)
{
int alpha = overlay.alpha();
const int alpha = overlay.alpha();
if (alpha == 255) {
return overlay;
}
@ -108,9 +28,9 @@ QColor Colors::overlayColor(const QColor &base, const QColor &overlay)
return base;
}
int r = (overlay.red() * alpha + base.red() * (255 - alpha)) / 255;
int g = (overlay.green() * alpha + base.green() * (255 - alpha)) / 255;
int b = (overlay.blue() * alpha + base.blue() * (255 - alpha)) / 255;
const int r = (overlay.red() * alpha + base.red() * (255 - alpha)) / 255;
const int g = (overlay.green() * alpha + base.green() * (255 - alpha)) / 255;
const int b = (overlay.blue() * alpha + base.blue() * (255 - alpha)) / 255;
return QColor(r, g, b);
}

View file

@ -1,23 +1,29 @@
#ifndef COLORS_H
#define COLORS_H
#include "core/Cutter.h"
#include "common/RichTextPainter.h"
#include <rz_analysis.h>
#include "core/Cutter.h"
class Colors
{
public:
Colors();
static void colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num);
static QString getColor(ut64 type);
/**
* @brief Blends an overlay color onto an existing base color
* @param base The original color (assumes base color is solid)
* @param overlay The overlay color with alpha transparency
* @return The resulting blended color
*/
static QColor overlayColor(const QColor &base, const QColor &overlay);
};
/**
* @brief Utilities for handling color logic and syntax highlighting for assembly
*/
namespace Colors {
/**
* @brief Colorize asssembly text
* @param list RichTextPainter::List to add the opcode to
* @param opcode Opcode to colorize
* @param typeNum Type of opcode
*/
void colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 typeNum);
/**
* @brief Blends an overlay color onto an existing base color
* @param base The original color (assumes base color is solid)
* @param overlay The overlay color with alpha transparency
* @return The resulting blended color
*/
QColor overlayColor(const QColor &base, const QColor &overlay);
}
#endif // COLORS_H

View file

@ -1,5 +1,6 @@
#include "CommandTask.h"
#include "Cutter.h"
#include "TempConfig.h"
CommandTask::CommandTask(const QString &cmd, ColorMode colorMode) : cmd(cmd), colorMode(colorMode)

View file

@ -1,16 +1,17 @@
#ifndef COMMANDTASK_H
#define COMMANDTASK_H
#include "common/AsyncTask.h"
#include "core/Cutter.h"
/**
* @brief Background task for running a command in rizin
*/
class CUTTER_EXPORT CommandTask : public AsyncTask
{
Q_OBJECT
public:
enum ColorMode {
enum ColorMode : ut8 {
DISABLED = COLOR_MODE_DISABLED,
MODE_16 = COLOR_MODE_16,
MODE_256 = COLOR_MODE_256,
@ -19,7 +20,7 @@ public:
CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED);
QString getTitle() override { return tr("Running Command"); }
QString getTitle() const override { return tr("Running Command"); }
signals:
void finished(const QString &result);

View file

@ -1,21 +1,24 @@
#include "Configuration.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QFontDatabase>
#include <QFile>
#include <QApplication>
#include <QDir>
#include <QFile>
#include <QFontDatabase>
#include <QHash>
#include <QJsonArray>
#include <QJsonObject>
#include <utility>
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
# include <KSyntaxHighlighting/Definition>
# include <KSyntaxHighlighting/Repository>
# include <KSyntaxHighlighting/Theme>
# include <KSyntaxHighlighting/Definition>
#endif
#include "common/ColorThemeWorker.h"
#include "common/SyntaxHighlighter.h"
#include "common/ResourcePaths.h"
#include "common/SyntaxHighlighter.h"
/* Map with names of themes associated with its color palette
* (Dark or Light), so for dark interface themes will be shown only Dark color themes
@ -37,8 +40,8 @@ const QHash<QString, ColorFlags> Configuration::relevantThemes = {
{ "cutter", LightFlag }, { "matrix", LightFlag }, { "white", LightFlag },
};
static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter";
static const QString DEFAULT_DARK_COLOR_THEME = "ayu";
static const QString defaultLightColorTheme = "cutter";
static const QString defaultDarkColorTheme = "ayu";
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
{ "gui.cflow",
@ -114,7 +117,7 @@ const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColor
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x50) } } }
};
Configuration *Configuration::mPtr = nullptr;
Configuration *Configuration::ptr = nullptr;
/**
* @brief All asm.* options saved as settings. Values are the default values.
@ -157,7 +160,7 @@ static const QHash<QString, QVariant> asmOptions = { { "asm.esil", false },
Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
{
mPtr = this;
ptr = this;
if (!s.isWritable()) {
QMessageBox::critical(
nullptr, tr("Critical Error!"),
@ -171,9 +174,10 @@ Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
Configuration *Configuration::instance()
{
if (!mPtr)
mPtr = new Configuration();
return mPtr;
if (!ptr) {
ptr = new Configuration();
}
return ptr;
}
void Configuration::loadInitial()
@ -189,7 +193,7 @@ void Configuration::loadInitial()
QString Configuration::getRecentFolder()
{
QString recentFolder = s.value("dir.recentFolder", QDir::homePath()).toString();
const QString recentFolder = s.value("dir.recentFolder", QDir::homePath()).toString();
return QDir::toNativeSeparators(recentFolder);
}
@ -279,7 +283,7 @@ bool Configuration::setLocaleByName(const QString &language)
bool Configuration::windowColorIsDark()
{
ColorFlags currentThemeColorFlags = getCurrentTheme()->flag;
const ColorFlags currentThemeColorFlags = getCurrentTheme()->flag;
if (currentThemeColorFlags == ColorFlags::LightFlag) {
return false;
} else if (currentThemeColorFlags == ColorFlags::DarkFlag) {
@ -301,15 +305,13 @@ void Configuration::loadNativeStylesheet()
QFile f(":native/native.qss");
if (!f.exists()) {
qWarning() << "Can't find Native theme stylesheet.";
} else {
f.open(QFile::ReadOnly | QFile::Text);
} else if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
QString stylesheet = ts.readAll();
QString stylesheet = ts.readAll(); // NOLINT
#ifdef Q_OS_MACOS
QFile mf(nativeWindowIsDark() ? ":native/native-macos-dark.qss"
: ":native/native-macos-light.qss");
if (mf.exists()) {
mf.open(QFile::ReadOnly | QFile::Text);
if (mf.exists() && mf.open(QFile::ReadOnly | QFile::Text)) {
QTextStream mts(&mf);
stylesheet += "\n" + mts.readAll();
}
@ -336,10 +338,9 @@ void Configuration::loadLightStylesheet()
QFile f(":lightstyle/light.qss");
if (!f.exists()) {
qWarning() << "Can't find Light theme stylesheet.";
} else {
f.open(QFile::ReadOnly | QFile::Text);
} else if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
QString stylesheet = ts.readAll();
const QString stylesheet = ts.readAll();
QPalette p = qApp->palette();
p.setColor(QPalette::Text, Qt::black);
@ -355,10 +356,9 @@ void Configuration::loadDarkStylesheet()
QFile f(":qdarkstyle/style.qss");
if (!f.exists()) {
qWarning() << "Can't find Dark theme stylesheet.";
} else {
f.open(QFile::ReadOnly | QFile::Text);
} else if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
QString stylesheet = ts.readAll();
QString stylesheet = ts.readAll(); // NOLINT
#ifdef Q_OS_MACX
// see https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529
stylesheet += "QDockWidget::title"
@ -381,10 +381,9 @@ void Configuration::loadMidnightStylesheet()
QFile f(":midnight/style.css");
if (!f.exists()) {
qWarning() << "Can't find Midnight theme stylesheet.";
} else {
f.open(QFile::ReadOnly | QFile::Text);
} else if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
QString stylesheet = ts.readAll();
const QString stylesheet = ts.readAll();
QPalette p = qApp->palette();
p.setColor(QPalette::Text, Qt::white);
@ -396,7 +395,7 @@ void Configuration::loadMidnightStylesheet()
const QFont Configuration::getBaseFont() const
{
QFont font = s.value("font", QFont("Inconsolata", 11)).value<QFont>();
const auto font = s.value("font", QFont("Inconsolata", 11)).value<QFont>();
return font;
}
@ -420,7 +419,7 @@ void Configuration::refreshFont()
qreal Configuration::getZoomFactor() const
{
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
const auto fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
return qMax(fontZoom, 0.1);
}
@ -442,7 +441,7 @@ void Configuration::setInterfaceTheme(int theme)
}
s.setValue("ColorPalette", theme);
CutterInterfaceTheme interfaceTheme = cutterInterfaceThemesList()[theme];
const CutterInterfaceTheme interfaceTheme = cutterInterfaceThemesList()[theme];
if (interfaceTheme.name == "Native") {
loadNativeStylesheet();
@ -517,11 +516,6 @@ QString Configuration::getLogoFile()
: QString(":/img/cutter_plain.svg");
}
/**
* @brief Configuration::setColor sets the local Cutter configuration color
* @param name Color Name
* @param color The color you want to set
*/
void Configuration::setColor(const QString &name, const QColor &color)
{
s.setValue("colors." + name, color);
@ -553,7 +547,7 @@ void Configuration::setColorTheme(const QString &theme)
s.setValue("theme", theme);
}
ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme);
const ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme);
for (auto it = colorTheme.constBegin(); it != colorTheme.constEnd(); it++) {
setColor(it.key(), it.value());
}
@ -563,12 +557,12 @@ void Configuration::setColorTheme(const QString &theme)
void Configuration::adjustColorThemeDarkness()
{
bool windowIsDark = windowColorIsDark();
int windowDarkness = windowIsDark ? DarkFlag : LightFlag;
int currentColorThemeDarkness = colorThemeDarkness(getColorTheme());
const bool windowIsDark = windowColorIsDark();
const int windowDarkness = windowIsDark ? DarkFlag : LightFlag;
const int currentColorThemeDarkness = colorThemeDarkness(getColorTheme());
if ((currentColorThemeDarkness & windowDarkness) == 0) {
setColorTheme(windowIsDark ? DEFAULT_DARK_COLOR_THEME : DEFAULT_LIGHT_COLOR_THEME);
setColorTheme(windowIsDark ? defaultDarkColorTheme : defaultLightColorTheme);
}
}
@ -608,8 +602,18 @@ const QList<CutterInterfaceTheme> &Configuration::cutterInterfaceThemesList()
QVariant Configuration::getConfigVar(const QString &key)
{
QHash<QString, QVariant>::const_iterator it = asmOptions.find(key);
const QHash<QString, QVariant>::const_iterator it = asmOptions.find(key);
if (it != asmOptions.end()) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
switch (it.value().typeId()) {
case QMetaType::Type::Bool:
return Core()->getConfigb(key);
case QMetaType::Type::Int:
return Core()->getConfigi(key);
default:
return Core()->getConfig(key);
}
#else
switch (it.value().type()) {
case QVariant::Type::Bool:
return Core()->getConfigb(key);
@ -618,6 +622,7 @@ QVariant Configuration::getConfigVar(const QString &key)
default:
return Core()->getConfig(key);
}
#endif
}
return QVariant();
}
@ -637,12 +642,6 @@ QString Configuration::getConfigString(const QString &key)
return getConfigVar(key).toString();
}
/**
* @brief Configuration::setConfig
* Set Rizin configuration value (e.g. "asm.lines")
* @param key
* @param value
*/
void Configuration::setConfig(const QString &key, const QVariant &value)
{
if (asmOptions.contains(key)) {
@ -652,17 +651,13 @@ void Configuration::setConfig(const QString &key, const QVariant &value)
Core()->setConfig(key, value);
}
/**
* @brief this function will gather and return available translation for Cutter
* @return a list of locales and their names
*/
std::vector<Configuration::LangInfo> Configuration::getAvailableTranslations()
{
const auto &trDirs = Cutter::getTranslationsDirectories();
QSet<QString> fileNamesSet;
for (const auto &trDir : trDirs) {
QDir dir(trDir);
const QDir dir(trDir);
if (!dir.exists()) {
continue;
}
@ -678,20 +673,20 @@ std::vector<Configuration::LangInfo> Configuration::getAvailableTranslations()
QString currLanguageName;
std::vector<Configuration::LangInfo> result;
QHash<QString, int> langCount;
for (const auto &translationFile : fileNames) {
for (const auto &translationFile : std::as_const(fileNames)) {
auto name = QFileInfo(translationFile).baseName();
auto parts = name.split("_");
if (parts.length() < 2) {
continue;
}
auto langCode = parts[1];
const auto &langCode = parts[1];
++langCount[langCode];
}
for (auto &i : fileNames) {
auto name = QFileInfo(i).baseName();
QString localeName = name.mid(sizeof("cutter_") - 1);
QLocale locale(localeName);
const QString localeName = name.mid(sizeof("cutter_") - 1);
const QLocale locale(localeName);
if (locale.language() == QLocale::C) {
continue;
}
@ -704,7 +699,7 @@ std::vector<Configuration::LangInfo> Configuration::getAvailableTranslations()
if (langCount[langCode] <= 1
&& locale.language() != QLocale::Chinese) { // Always distinguish Chinese Traditional,
// Chinese simplified
QLocale localSimple(locale.language());
const QLocale localSimple(locale.language());
auto simpleName = localSimple.nativeLanguageName();
if (!simpleName.isEmpty()) {
currLanguageName = simpleName;
@ -848,10 +843,10 @@ QList<RecentFileEntry> Configuration::getRecentFiles() const
const QStringList list = s.value("recentFileList").toStringList();
for (const QString &file : list) {
int sep = file.indexOf("://");
const int sep = file.indexOf("://");
if (sep != -1) {
QString ioMode = file.left(sep + 3);
QString path = file.mid(sep + 3);
const QString ioMode = file.left(sep + 3);
const QString path = file.mid(sep + 3);
recentFiles.append({ ioMode, path });
} else {
recentFiles.append({ "file://", file });
@ -892,7 +887,7 @@ void Configuration::setRecentProjects(const QList<RecentFileEntry> &list)
void Configuration::addRecentProject(QString file)
{
RecentFileEntry project = { "", file };
const RecentFileEntry project = { "", std::move(file) };
QList<RecentFileEntry> files = getRecentProjects();
files.removeAll(project);
files.prepend(project);

View file

@ -1,8 +1,9 @@
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include <QSettings>
#include <QFont>
#include <QSettings>
#include <core/Cutter.h>
#define Config() (Configuration::instance())
@ -18,7 +19,7 @@ class Theme;
class QSyntaxHighlighter;
class QTextDocument;
enum ColorFlags {
enum ColorFlags : ut8 {
LightFlag = 1,
DarkFlag = 2,
DualColor = LightFlag | DarkFlag,
@ -41,13 +42,16 @@ struct RecentFileEntry
}
};
/**
* @brief Singleton class to save and load all of the configuration values
*/
class CUTTER_EXPORT Configuration : public QObject
{
Q_OBJECT
private:
QPalette nativePalette;
QSettings s;
static Configuration *mPtr;
static Configuration *ptr;
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
KSyntaxHighlighting::Repository *kSyntaxHighlightingRepository;
@ -91,6 +95,10 @@ public:
QString name;
QLocale locale;
};
/**
* @brief this function will gather and return available translation for Cutter
* @return a list of locales and their names
*/
std::vector<LangInfo> getAvailableTranslations();
// Fonts
@ -147,6 +155,11 @@ public:
void adjustColorThemeDarkness();
int colorThemeDarkness(const QString &colorTheme) const;
/**
* @brief Configuration::setColor sets the local Cutter configuration color
* @param name Color Name
* @param color The color you want to set
*/
void setColor(const QString &name, const QColor &color);
const QColor getColor(const QString &name) const;
@ -232,12 +245,16 @@ public:
void setPreviewValue(bool checked);
bool getPreviewValue() const;
// Tooltip
/**
* @brief Show tooltips for known values of registers, variables, and memory when debugging
*/
void setShowVarTooltips(bool enabled);
bool getShowVarTooltips() const;
// Recent Items
/**
* @brief Recently opened binaries, as shown in NewFileDialog.
*/
@ -274,7 +291,7 @@ public:
*/
void removeRecentRegProfile(const QString &profile);
// Functions Widget Layout
// Interface
/**
* @brief Get the layout of the Functions widget.

View file

@ -4,5 +4,5 @@ using namespace Cutter;
bool Cutter::isBuiltinLayoutName(const QString &name)
{
return name == LAYOUT_DEFAULT || name == LAYOUT_DEBUG;
return name == layoutDefault || name == layoutDebug;
}

View file

@ -6,6 +6,9 @@
#include <QString>
#include <QVariantMap>
/**
* @namespace Utilities related to cutter layout
*/
namespace Cutter {
struct CutterLayout
@ -15,8 +18,8 @@ struct CutterLayout
QMap<QString, QVariantMap> viewProperties;
};
const QString LAYOUT_DEFAULT = "Default";
const QString LAYOUT_DEBUG = "Debug";
const QString layoutDefault = "Default";
const QString layoutDebug = "Debug";
bool isBuiltinLayoutName(const QString &name);

View file

@ -1,14 +1,15 @@
#include "CutterSearchable.h"
#include "SearchBarWidget.h"
#include "shortcuts/ShortcutManager.h"
#include <QObject>
#include <QAbstractScrollArea>
#include <QObject>
#include <QScrollBar>
void CutterSearchableHelper::setupConnections(QWidget *parent, SearchBarWidget *searchBar)
{
CutterSearchable *searchable = dynamic_cast<CutterSearchable *>(parent);
auto *searchable = dynamic_cast<CutterSearchableI *>(parent);
if (!searchBar || !parent || !searchable) {
return;
}
@ -49,8 +50,8 @@ void CutterSearchableHelper::setupConnections(QWidget *parent, SearchBarWidget *
searchBar->showSearchBar();
QWidget *searchArea = searchable->searchableArea();
int hPadding = searchable->searchHPadding();
int vPadding = searchable->searchVPadding();
const int hPadding = searchable->searchHPadding();
const int vPadding = searchable->searchVPadding();
positionSearchBar(parent, searchBar, searchArea, hPadding, vPadding);
}
@ -66,13 +67,14 @@ void CutterSearchableHelper::positionSearchBar(QWidget *parent, SearchBarWidget
int searchBarWidth = 0;
if (auto *scrollArea = qobject_cast<QAbstractScrollArea *>(searchArea)) {
QScrollBar *scrollBar = scrollArea->verticalScrollBar();
const QScrollBar *scrollBar = scrollArea->verticalScrollBar();
searchBarWidth = (scrollBar && scrollBar->isVisible()) ? scrollBar->width() : 0;
}
QPoint areaPos = searchArea->mapTo(parent, QPoint(0, 0));
int x = areaPos.x() + searchArea->width() - searchBarWidth - searchBar->width() - hPadding;
int y = areaPos.y() + vPadding;
const QPoint areaPos = searchArea->mapTo(parent, QPoint(0, 0));
const int x =
areaPos.x() + searchArea->width() - searchBarWidth - searchBar->width() - hPadding;
const int y = areaPos.y() + vPadding;
searchBar->move(x, y);
}

View file

@ -1,11 +1,13 @@
#ifndef CUTTERSEARCHABLE_H
#define CUTTERSEARCHABLE_H
#include "CutterCommon.h"
class QString;
class SearchBarWidget;
class QWidget;
enum SearchOption {
enum SearchOption : ut8 {
CaseSensitive = 1,
WholeWords = 1 << 1,
RegExp = 1 << 2,
@ -15,10 +17,10 @@ enum SearchOption {
/**
* @brief Interface for any widget that needs a search bar
*/
class CutterSearchable
class CutterSearchableI
{
public:
virtual ~CutterSearchable() = default;
virtual ~CutterSearchableI() = default;
/**
* @brief Widget which the search bar will be shown relative to

View file

@ -1,6 +1,7 @@
#include "core/MainWindow.h"
#include "CutterSeekable.h"
#include "core/MainWindow.h"
#include <QPlainTextEdit>
CutterSeekable::CutterSeekable(QObject *parent) : QObject(parent)
@ -44,7 +45,7 @@ void CutterSeekable::seekPrev()
}
}
RVA CutterSeekable::getOffset()
RVA CutterSeekable::getOffset() const
{
return (synchronized) ? Core()->getOffset() : widgetOffset;
}
@ -54,7 +55,7 @@ void CutterSeekable::toggleSynchronization()
setSynchronization(!synchronized);
}
bool CutterSeekable::isSynchronized()
bool CutterSeekable::isSynchronized() const
{
return synchronized;
}
@ -65,7 +66,7 @@ void CutterSeekable::seekToReference(RVA offset)
return;
}
QList<XrefDescription> refs = Core()->getXRefs(offset, false, false);
const QList<XrefDescription> refs = Core()->getXRefs(offset, false, false);
if (refs.length()) {
if (refs.length() > 1) {

View file

@ -4,6 +4,9 @@
class MainWindow;
/**
* @brief Class to synchronize seeks with other widgets
*/
class CUTTER_EXPORT CutterSeekable : public QObject
{
Q_OBJECT
@ -39,19 +42,19 @@ public:
* If it's not synchronized, it will return the seekable current seek.
* @return the seekable current offset.
*/
RVA getOffset();
RVA getOffset() const;
/**
* @brief isSynchronized tells whether the seekable
* is synchronized with Core or not.
* @return boolean
* @return true if synchronized, false otherwise
*/
bool isSynchronized();
bool isSynchronized() const;
/**
* @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);
@ -62,15 +65,11 @@ public slots:
void seekPrev();
/**
* @brief toggleSyncWithCore toggles
* Core seek synchronization.
* @brief toggleSyncWithCore toggles Core seek synchronization.
*/
void toggleSynchronization();
private slots:
/**
* @brief onCoreSeekChanged
*/
void onCoreSeekChanged(RVA addr, CutterCore::SeekHistoryType type);
private:

View file

@ -1,17 +1,17 @@
#include "Decompiler.h"
#include "Cutter.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonObject>
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
: QObject(parent), id(id), name(name)
{
}
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
RzAnnotatedCode *Decompiler::makeWarning(const QString &warningMessage)
{
std::string temporary = warningMessage.toStdString();
const std::string temporary = warningMessage.toStdString();
return rz_annotated_code_new(strdup(temporary.c_str()));
}

View file

@ -2,14 +2,14 @@
#define DECOMPILER_H
#include "CutterCommon.h"
#include "RizinTask.h"
#include <QObject>
#include <QString>
#include <rz_util/rz_annotated_code.h>
#include <QString>
#include <QObject>
/**
* Implements a decompiler that can be registered using CutterCore::registerDecompiler()
* @brief Implements a decompiler that can be registered using CutterCore::registerDecompiler()
*/
class CUTTER_EXPORT Decompiler : public QObject
{
@ -23,7 +23,7 @@ public:
Decompiler(const QString &id, const QString &name, QObject *parent = nullptr);
virtual ~Decompiler() = default;
static RzAnnotatedCode *makeWarning(QString warningMessage);
static RzAnnotatedCode *makeWarning(const QString &warningMessage);
QString getId() const { return id; }
QString getName() const { return name; }

View file

@ -1,5 +1,5 @@
#include "DecompilerHighlighter.h"
#include "common/Configuration.h"
#include <memory>
@ -20,7 +20,7 @@ void DecompilerHighlighter::setAnnotations(RzAnnotatedCode *code)
void DecompilerHighlighter::setupTheme()
{
struct
const struct
{
RSyntaxHighlightType type;
QString name;
@ -46,19 +46,17 @@ void DecompilerHighlighter::highlightBlock(const QString &)
return;
}
auto block = currentBlock();
size_t start = block.position();
size_t end = block.position() + block.length();
const size_t start = block.position();
const size_t end = block.position() + block.length();
auto annotations = fromOwned(rz_annotated_code_annotations_range(code, start, end));
void **iter;
rz_pvector_foreach(annotations.get(), iter)
{
RzCodeAnnotation *annotation = static_cast<RzCodeAnnotation *>(*iter);
for (const auto *annotation : CutterPVector<RzCodeAnnotation>(annotations.get())) {
if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
continue;
}
auto type = annotation->syntax_highlight.type;
if (size_t(type) >= HIGHLIGHT_COUNT) {
if (size_t(type) >= highlightCount) {
continue;
}
auto annotationStart = annotation->start;

View file

@ -2,14 +2,16 @@
#define DECOMPILER_HIGHLIGHTER_H
#include "CutterCommon.h"
#include <rz_util/rz_annotated_code.h>
#include <QSyntaxHighlighter>
#include <QTextDocument>
#include <QTextCharFormat>
#include <QTextDocument>
#include <array>
#include <rz_util/rz_annotated_code.h>
/**
* \brief SyntaxHighlighter based on annotations from decompiled code.
* @brief SyntaxHighlighter based on annotations from decompiled code.
* Can be only used in combination with DecompilerWidget.
*/
class CUTTER_EXPORT DecompilerHighlighter : public QSyntaxHighlighter
@ -36,8 +38,8 @@ protected:
private:
void setupTheme();
static const int HIGHLIGHT_COUNT = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE + 1;
std::array<QTextCharFormat, HIGHLIGHT_COUNT> format;
static const int highlightCount = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE + 1;
std::array<QTextCharFormat, highlightCount> format;
RzAnnotatedCode *code = nullptr;
};

View file

@ -3,8 +3,8 @@
#include <QComboBox>
/**
* @brief Custom QComboBox created to prevent the menu popup from opening up at different
* offsets for different items, which may result in list items being rendered outside
* of the screen/containing widget.
* offsets for different items, which may result in list items being rendered outside
* of the screen/containing widget.
*/
class DirectionalComboBox : public QComboBox
{

View file

@ -1,18 +1,19 @@
#include "DisassemblyHelper.h"
#include "Cutter.h"
#include "rz_types_base.h"
typedef struct mmio_lookup_context
typedef struct MmioLookupContext
{
QString selected;
RVA mmio_address;
RVA mmioAddress;
} mmio_lookup_context_t;
static bool lookup_mmio_addr_cb(void *user, const ut64 key, const void *value)
static bool lookupMmioAddrCb(void *user, const ut64 key, const void *value)
{
mmio_lookup_context_t *ctx = (mmio_lookup_context_t *)user;
if (ctx->selected == (const char *)value) {
ctx->mmio_address = key;
auto *ctx = static_cast<mmio_lookup_context_t *>(user);
if (ctx->selected == static_cast<const char *>(value)) {
ctx->mmioAddress = key;
return false;
}
return true;
@ -35,8 +36,8 @@ DisassemblyTextBlockUserData *DisassemblyHelper::getUserData(const QTextBlock &b
RVA DisassemblyHelper::getXRefFromWord(RVA offset, const QString &selectedWord)
{
RVA selectedOffset = Core()->num(selectedWord);
auto xrefsTo = Core()->getXRefs(offset, true, false);
const RVA selectedOffset = Core()->num(selectedWord);
const auto xrefsTo = Core()->getXRefs(offset, true, false);
for (const auto &xref : xrefsTo) {
if (xref.from == selectedOffset) {
return xref.from;
@ -50,7 +51,7 @@ bool DisassemblyHelper::isXRefFromComment(RVA offset, const QString &line)
return Core()->getXRefCommentAt(offset).simplified().contains(line.simplified());
}
RVA DisassemblyHelper::readDisassemblyOffset(QTextCursor tc)
RVA DisassemblyHelper::readDisassemblyOffset(const QTextCursor &tc)
{
auto userData = DisassemblyHelper::getUserData(tc.block());
if (!userData) {
@ -60,7 +61,7 @@ RVA DisassemblyHelper::readDisassemblyOffset(QTextCursor tc)
return userData->line.offset;
}
RVA DisassemblyHelper::readDisassemblyArrow(QTextCursor tc)
RVA DisassemblyHelper::readDisassemblyArrow(const QTextCursor &tc)
{
auto userData = getUserData(tc.block());
if (!userData) {
@ -74,8 +75,8 @@ DisassemblyHelper::BracketResult DisassemblyHelper::findBracketRange(const QStri
int posInLine)
{
BracketResult res;
int openBracket = line.lastIndexOf('[', posInLine);
int closeBracket = line.indexOf(']', posInLine);
const int openBracket = line.lastIndexOf('[', posInLine);
const int closeBracket = line.indexOf(']', posInLine);
if (openBracket != -1 && closeBracket != -1) {
bool isInside = true;
@ -106,12 +107,12 @@ DisassemblyHelper::BracketResult DisassemblyHelper::findBracketRange(const QStri
DisassemblyHelper::TargetContext DisassemblyHelper::getContextFromCursor(QTextCursor tc)
{
int originalPos = tc.position();
const int originalPos = tc.position();
tc.select(QTextCursor::WordUnderCursor);
QString word = tc.selectedText();
QString line = tc.block().text();
int lineStart = tc.block().position();
int posInLine = originalPos - lineStart;
const QString line = tc.block().text();
const int lineStart = tc.block().position();
const int posInLine = originalPos - lineStart;
auto bracketRes = findBracketRange(line, posInLine);
if (bracketRes.found) {
@ -135,7 +136,7 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon
// Xref comments need special handling to show preview for each caller offset
if (filter & TargetFilter::XRefComments) {
bool showXRefComments = Core()->getConfigb("asm.xrefs");
const bool showXRefComments = Core()->getConfigb("asm.xrefs");
if (showXRefComments && isXRefFromComment(ctx.offset, ctx.line)) {
res.value = getXRefFromWord(ctx.offset, ctx.word);
res.type = TargetType::XRefComment;
@ -162,8 +163,8 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon
}
if (filter & TargetFilter::VariableXrefs) {
XrefDescription xref = Core()->getFirstXRefForVariable(ctx.word, ctx.offset);
if (!xref.from_str.isEmpty() || !xref.to_str.isEmpty()) {
const XrefDescription xref = Core()->getFirstXRefForVariable(ctx.word, ctx.offset);
if (!xref.fromStr.isEmpty() || !xref.toStr.isEmpty()) {
res.value = xref.from;
res.type = TargetType::VariableXRef;
return res;
@ -196,16 +197,16 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon
}
if (filter & TargetFilter::MMIO) {
mmio_lookup_context_t mmio_ctx;
mmio_ctx.selected = ctx.word;
mmio_ctx.mmio_address = RVA_INVALID;
mmio_lookup_context_t mmioCtx;
mmioCtx.selected = ctx.word;
mmioCtx.mmioAddress = RVA_INVALID;
auto core = Core()->lock();
RzPlatformTarget *arch_target = rz_analysis_get_arch_target(core->analysis);
if (arch_target && arch_target->profile) {
ht_up_foreach(arch_target->profile->registers_mmio, lookup_mmio_addr_cb, &mmio_ctx);
const RzPlatformTarget *archTarget = rz_analysis_get_arch_target(core->analysis);
if (archTarget && archTarget->profile) {
ht_up_foreach(archTarget->profile->registers_mmio, lookupMmioAddrCb, &mmioCtx);
}
if (mmio_ctx.mmio_address != RVA_INVALID) {
res.value = mmio_ctx.mmio_address;
if (mmioCtx.mmioAddress != RVA_INVALID) {
res.value = mmioCtx.mmioAddress;
res.type = TargetType::MMIO;
return res;
}

View file

@ -1,9 +1,10 @@
#ifndef DISASSEMBLYHELPER_H
#define DISASSEMBLYHELPER_H
#include <QTextBlockUserData>
#include "core/CutterDescriptions.h"
#include <QTextBlockUserData>
/**
* @brief Metadata container attached to each QTextBlock in the disassembly view
*
@ -25,7 +26,7 @@ namespace DisassemblyHelper {
/**
* @brief Identifies what kind of item was clicked or hovered
*/
enum class TargetType {
enum class TargetType : ut8 {
VariableXRef,
VariableValue,
TypeName,
@ -60,7 +61,7 @@ struct TargetAction
/**
* @brief Filter to control how deep the search goes
*/
enum TargetFilter {
enum TargetFilter : ut8 {
XRefComments = 1 << 0,
VariableXrefs = 1 << 1,
VariableValues = 1 << 2,
@ -116,13 +117,13 @@ bool isXRefFromComment(RVA offset, const QString &line);
* @brief Reads the offset for the cursor position
* @return The disassembly offset of the hovered asm text
*/
RVA readDisassemblyOffset(QTextCursor tc);
RVA readDisassemblyOffset(const QTextCursor &tc);
/*!
* @brief Reads the arrow offset for the cursor position
* @return Offset the arrow points to
*/
RVA readDisassemblyArrow(QTextCursor tc);
RVA readDisassemblyArrow(const QTextCursor &tc);
/**
* @brief Gets the text and address at the current cursor position

View file

@ -1,12 +1,12 @@
#include "DisassemblyPreview.h"
#include "Configuration.h"
#include "rz_types_base.h"
#include "widgets/GraphView.h"
#include <QCoreApplication>
#include <QWidget>
#include <QToolTip>
#include <QProcessEnvironment>
#include <QToolTip>
#include <QWidget>
namespace DH = DisassemblyHelper;
@ -15,15 +15,14 @@ QString DisassemblyPreview::getToolTipStyleSheet()
return QString { "QToolTip { border-width: 1px; max-width: %1px;"
"opacity: 230; background-color: %2;"
"color: %3; border-color: %3;}" }
.arg(400)
.arg(Config()->getColor("gui.tooltip.background").name())
.arg(Config()->getColor("gui.tooltip.foreground").name());
.arg(QString::number(400), Config()->getColor("gui.tooltip.background").name(),
Config()->getColor("gui.tooltip.foreground").name());
}
bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOfEvent,
const RVA offsetFrom)
{
QList<XrefDescription> refs = Core()->getXRefs(offsetFrom, false, false);
const QList<XrefDescription> refs = Core()->getXRefs(offsetFrom, false, false);
if (refs.length()) {
if (refs.length() > 1) {
qWarning() << QObject::tr(
@ -31,7 +30,7 @@ bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOf
.arg(refs.length());
}
RVA offsetTo = refs.at(0).to; // This is the offset we want to preview
const RVA offsetTo = refs.at(0).to; // This is the offset we want to preview
/*
* Only if the offset we point *to* is different from the one the cursor is currently
* on *and* the former is a valid offset, we are allowed to get a preview of offsetTo
@ -46,16 +45,15 @@ bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOf
bool DisassemblyPreview::showDisasPreviewAt(QWidget *parent, const QPoint &pointOfEvent,
const RVA offset)
{
QStringList disasmPreview = Core()->getDisassemblyPreview(offset, 10);
const QStringList disasmPreview = Core()->getDisassemblyPreview(offset, 10);
if (!disasmPreview.isEmpty()) {
const QFont &fnt = Config()->getFont();
QString tooltip = QString("<html><div style=\"font-family: '%1'; font-size: %2pt; "
"white-space: nowrap;\"><div style=\"margin-bottom: "
"10px;\"><strong>Disassembly Preview</strong>:</div>"
"%3</div></html>")
.arg(fnt.family().toHtmlEscaped())
.arg(qMax(8, fnt.pointSize() - 1))
.arg(disasmPreview.join("<br>"));
const QString tooltip = QString("<html><div style=\"font-family: %1; font-size: %2pt; "
"white-space: nowrap;\"><div style=\"margin-bottom: "
"10px;\"><strong>Disassembly Preview</strong>:<br>%3<div>")
.arg(fnt.family())
.arg(qMax(8, fnt.pointSize() - 1))
.arg(disasmPreview.join("<br>"));
QToolTip::showText(pointOfEvent, tooltip, parent, QRect {}, 3500);
return true;
@ -83,7 +81,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po
break;
}
case DH::TargetType::MMIO: {
int len = 8; // TODO: Determine proper len of mmio address for the cpu
const int len = 8; // TODO: Determine proper len of mmio address for the cpu
auto core = Core()->lock();
if (char *r = rz_core_print_hexdump_or_hexdiff_str(core, RZ_OUTPUT_MODE_STANDARD, ta.value,
len, false)) {
@ -93,7 +91,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po
break;
}
case DH::TargetType::Memory: {
ut64 addr = Core()->math(ctx.word.mid(1, ctx.word.length() - 2));
const ut64 addr = Core()->math(ctx.word.mid(1, ctx.word.length() - 2));
msg = QString("%1 = 0x%2 -> 0x%3").arg(ctx.word).arg(addr, 0, 16).arg(ta.value, 0, 16);
break;
}
@ -113,7 +111,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po
bool DisassemblyPreview::showTooltip(QWidget *parent, const QPoint &globalPos,
const DH::TargetContext &ctx, bool hasPreview)
{
bool isWordEmpty = ctx.word.isEmpty();
const bool isWordEmpty = ctx.word.isEmpty();
if (hasPreview) {
auto ta = DH::resolveTarget(ctx, DH::XRefComments | DH::Arrows);

View file

@ -1,16 +1,15 @@
#ifndef DISASSEMBLYPREVIEW_H
#define DISASSEMBLYPREVIEW_H
#include <QTextBlockUserData>
#include "core/CutterDescriptions.h"
#include "DisassemblyHelper.h"
#include "core/CutterDescriptions.h"
#include <QTextBlockUserData>
class QWidget;
/**
* @brief Namespace to define relevant functions
*
* @ingroup DisassemblyPreview
* @namespace Namespace containing functions for showing tooltips in disassembly
*/
namespace DisassemblyPreview {
/*!

View file

@ -1,16 +1,18 @@
#ifndef FUNCTIONSTASK_H
#define FUNCTIONSTASK_H
#include "common/AsyncTask.h"
#include "core/Cutter.h"
/**
* @brief Async task for fetching functions through rizin
*/
class FunctionsTask : public AsyncTask
{
Q_OBJECT
public:
QString getTitle() override { return tr("Fetching Functions"); }
QString getTitle() const override { return tr("Fetching Functions"); }
signals:
void fetchFinished(const QList<FunctionDescription> &strings);

View file

@ -1,30 +1,25 @@
#include "common/Helpers.h"
#include "Configuration.h"
#include <cmath>
#include <QPlainTextEdit>
#include <QTextEdit>
#include <QFileInfo>
#include <QtCore>
#include <QCryptographicHash>
#include <QTreeWidget>
#include <QString>
#include <QAbstractItemView>
#include <QAbstractButton>
#include <QDockWidget>
#include <QMenu>
#include <QAbstractItemView>
#include <QComboBox>
#include <QCryptographicHash>
#include <QDockWidget>
#include <QFileInfo>
#include <QMenu>
#include <QPlainTextEdit>
#include <QString>
#include <QTextEdit>
#include <QTreeWidget>
#include <QtCore>
static QAbstractItemView::ScrollMode scrollMode()
{
const bool use_scrollperpixel = true;
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
: QAbstractItemView::ScrollPerItem;
}
#include <cmath>
namespace qhelpers {
QString formatBytecount(const uint64_t bytecount)
QString formatByteCount(ut64 bytecount)
{
if (bytecount == 0) {
return "0";
@ -54,7 +49,7 @@ void adjustColumns(QTreeView *tv, int startIndex, int endIndex, int padding)
for (int i = startIndex; i < endIndex; ++i) {
tv->resizeColumnToContents(i);
if (padding > 0) {
int width = tv->columnWidth(i);
const int width = tv->columnWidth(i);
tv->setColumnWidth(i, width + padding);
}
}
@ -80,29 +75,28 @@ void adjustColumn(QTreeView *tv, int columnIndex, int width)
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
const QString &str3, const QString &str4, const QString &str5)
{
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
auto *tempItem = new QTreeWidgetItem();
// Fill dummy hidden column
tempItem->setText(0, "0");
tempItem->setText(1, str);
if (!str2.isNull())
if (!str2.isNull()) {
tempItem->setText(2, str2);
if (!str3.isNull())
}
if (!str3.isNull()) {
tempItem->setText(3, str3);
if (!str4.isNull())
}
if (!str4.isNull()) {
tempItem->setText(4, str4);
if (!str5.isNull())
}
if (!str5.isNull()) {
tempItem->setText(5, str5);
}
tw->insertTopLevelItem(0, tempItem);
return tempItem;
}
/**
* @brief Select first item of a QAbstractItemView if not empty
* @param itemView
* @return true if first item was selected
*/
bool selectFirstItem(QAbstractItemView *itemView)
{
if (!itemView) {
@ -121,12 +115,12 @@ bool selectFirstItem(QAbstractItemView *itemView)
void setVerticalScrollMode(QAbstractItemView *tw)
{
tw->setVerticalScrollMode(scrollMode());
tw->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}
void setCheckedWithoutSignals(QAbstractButton *button, bool checked)
{
bool blocked = button->signalsBlocked();
const bool blocked = button->signalsBlocked();
button->blockSignals(true);
button->setChecked(checked);
button->blockSignals(blocked);
@ -164,14 +158,14 @@ SizePolicyMinMax forceHeight(QWidget *widget, int height)
return r;
}
void SizePolicyMinMax::restoreWidth(QWidget *widget)
void SizePolicyMinMax::restoreWidth(QWidget *widget) const
{
widget->setSizePolicy(sizePolicy.horizontalPolicy(), widget->sizePolicy().verticalPolicy());
widget->setMinimumWidth(min);
widget->setMaximumWidth(max);
}
void SizePolicyMinMax::restoreHeight(QWidget *widget)
void SizePolicyMinMax::restoreHeight(QWidget *widget) const
{
widget->setSizePolicy(widget->sizePolicy().horizontalPolicy(), sizePolicy.verticalPolicy());
widget->setMinimumHeight(min);
@ -180,7 +174,7 @@ void SizePolicyMinMax::restoreHeight(QWidget *widget)
int getMaxFullyDisplayedLines(QTextEdit *textEdit)
{
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
const QFontMetrics fontMetrics(textEdit->document()->defaultFont());
return (textEdit->height()
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
+ (int)(textEdit->document()->documentMargin() * 2)))
@ -189,7 +183,7 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit)
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
{
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
const QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
return (plainTextEdit->height()
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
@ -201,19 +195,19 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color)
static const QRegularExpression styleRegExp(
"(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
int replaceStrLen = replaceStr.length();
const QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
const int replaceStrLen = replaceStr.length();
QString xml = QString::fromUtf8(data);
int offset = 0;
while (true) {
QRegularExpressionMatch match = styleRegExp.match(xml, offset);
const QRegularExpressionMatch match = styleRegExp.match(xml, offset);
if (!match.hasMatch()) {
break;
}
int captureIndex = match.captured(1).isNull() ? 2 : 1;
const int captureIndex = match.captured(1).isNull() ? 2 : 1;
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex),
replaceStr);
offset = match.capturedStart(captureIndex) + replaceStrLen;
@ -225,21 +219,15 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color)
QByteArray applyColorToSvg(const QString &filename, QColor color)
{
QFile file(filename);
file.open(QIODevice::ReadOnly);
if (!file.open(QIODevice::ReadOnly)) {
return QByteArray();
}
return applyColorToSvg(file.readAll(), color);
}
/**
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an
* object which has to be used and loaded icon
* @param supportedIconsNames list of <object ptr, icon name>
* @param setter functor which has to be called
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon
* &icon) { static_cast<QAction*>(o)->setIcon(icon); }
*/
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
std::function<void(void *, const QIcon &)> setter)
void setThemeIcons(const QList<QPair<void *, QString>> &supportedIconsNames,
const std::function<void(void *, const QIcon &)> &setter)
{
if (supportedIconsNames.isEmpty() || !setter) {
return;
@ -280,7 +268,7 @@ qreal devicePixelRatio(const QPaintDevice *p)
#endif
}
void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex)
void selectIndexByData(QComboBox *widget, const QVariant &data, int defaultIndex)
{
for (int i = 0; i < widget->count(); i++) {
if (widget->itemData(i) == data) {

View file

@ -3,9 +3,10 @@
#include "core/CutterCommon.h"
#include <QString>
#include <QColor>
#include <QSizePolicy>
#include <QString>
#include <functional>
class QIcon;
@ -32,8 +33,11 @@ class QMouseEvent;
# define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
#endif
/**
* @namespace Helpers for QT related objects
*/
namespace qhelpers {
CUTTER_EXPORT QString formatBytecount(const uint64_t bytecount);
CUTTER_EXPORT QString formatByteCount(ut64 bytecount);
CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding);
CUTTER_EXPORT void adjustColumns(QTreeView *tw, int startIndex, int endIndex, int padding);
CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
@ -49,6 +53,11 @@ CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
*/
CUTTER_EXPORT void adjustColumn(QTreeView *tv, int columnIndex, int width = -1);
/**
* @brief Select first item of a QAbstractItemView if not empty
* @param itemView
* @return true if first item was selected
*/
CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str,
const QString &str2 = QString(),
@ -66,8 +75,8 @@ struct CUTTER_EXPORT SizePolicyMinMax
int min;
int max;
void restoreWidth(QWidget *widget);
void restoreHeight(QWidget *widget);
void restoreWidth(QWidget *widget) const;
void restoreHeight(QWidget *widget) const;
};
CUTTER_EXPORT SizePolicyMinMax forceWidth(QWidget *widget, int width);
@ -79,8 +88,16 @@ CUTTER_EXPORT int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color);
CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color);
CUTTER_EXPORT void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
std::function<void(void *, const QIcon &)> setter);
/**
* @brief Finds the theme-specific icon path and calls `setter` functor providing a pointer of an
* object which has to be used and loaded icon
* @param supportedIconsNames list of <object ptr, icon name>
* @param setter functor which has to be called
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon
* &icon) { static_cast<QAction*>(o)->setIcon(icon); }
*/
CUTTER_EXPORT void setThemeIcons(const QList<QPair<void *, QString>> &supportedIconsNames,
const std::function<void(void *, const QIcon &)> &setter);
CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu);
CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
@ -90,7 +107,8 @@ CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
* @param data - value to search in combobox item data
* @param defaultIndex - item to select in case no match
*/
CUTTER_EXPORT void selectIndexByData(QComboBox *comboBox, QVariant data, int defaultIndex = -1);
CUTTER_EXPORT void selectIndexByData(QComboBox *comboBox, const QVariant &data,
int defaultIndex = -1);
/**
* @brief Emit data change signal in a model's column (DisplayRole)
* @param model - model containing data with changes

View file

@ -3,7 +3,7 @@
#include <QGuiApplication>
#include <QScreen>
static qreal GetDevicePixelRatio(qreal devicePixelRatio)
static qreal getDevicePixelRatio(qreal devicePixelRatio)
{
if (devicePixelRatio > 0) {
return devicePixelRatio;
@ -16,8 +16,8 @@ static qreal GetDevicePixelRatio(qreal devicePixelRatio)
}
HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio)
: QPixmap(int(width * GetDevicePixelRatio(devicePixelRatio)),
int(height * GetDevicePixelRatio(devicePixelRatio)))
: QPixmap(int(width * getDevicePixelRatio(devicePixelRatio)),
int(height * getDevicePixelRatio(devicePixelRatio)))
{
setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio));
setDevicePixelRatio(getDevicePixelRatio(devicePixelRatio));
}

View file

@ -2,6 +2,10 @@
#define HIGHDPIPIXMAP_H
#include <QPixmap>
/**
* @brief A QPixmap wrapper that automatically scales for high density displays
*/
class HighDpiPixmap : public QPixmap
{
public:

View file

@ -1,64 +0,0 @@
#include "Highlighter.h"
#include "core/MainWindow.h"
#include <QtGui>
Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
{
HighlightingRule rule;
core = Core();
regFormat.setForeground(QColor(236, 100, 75));
for (const QString &pattern : this->core->regs) {
rule.pattern.setPattern("\\b" + pattern + "\\b");
rule.pattern.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
rule.format = regFormat;
highlightingRules.append(rule);
}
singleLineCommentFormat.setFontWeight(QFont::Bold);
singleLineCommentFormat.setForeground(QColor(63, 195, 128));
rule.pattern.setPattern(";[^\n]*");
rule.format = singleLineCommentFormat;
highlightingRules.append(rule);
commentStartRegularExpression.setPattern("/\\*");
commentEndRegularExpression.setPattern("\\*/");
}
void Highlighter::highlightBlock(const QString &text)
{
for (const HighlightingRule &rule : highlightingRules) {
QRegularExpression expression(rule.pattern);
int index = expression.match(text).capturedStart();
while (index >= 0) {
int length = expression.match(text).capturedLength();
setFormat(index, length, rule.format);
index = expression.match(text.mid(index + length)).capturedStart();
}
}
setCurrentBlockState(0);
int startIndex = 0;
if (previousBlockState() != 1)
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
while (startIndex >= 0) {
QRegularExpressionMatch commentEndMatch =
QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
int endIndex = commentEndMatch.capturedStart();
int commentLength;
if (endIndex == -1) {
setCurrentBlockState(1);
commentLength = text.length() - startIndex;
} else {
commentLength = endIndex - startIndex + commentEndMatch.capturedLength();
}
setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = QRegularExpression(commentStartRegularExpression)
.match(text.mid(startIndex + commentLength))
.capturedStart();
}
}

View file

@ -1,46 +0,0 @@
#ifndef HIGHLIGHTER_H
#define HIGHLIGHTER_H
#include "core/Cutter.h"
#include <QSyntaxHighlighter>
#include <QHash>
#include <QTextCharFormat>
#include <QRegularExpression>
class QTextDocument;
class MainWindow;
class Highlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
Highlighter(QTextDocument *parent = nullptr);
protected:
void highlightBlock(const QString &text);
private:
CutterCore *core;
struct HighlightingRule
{
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;
QRegularExpression commentStartRegularExpression;
QRegularExpression commentEndRegularExpression;
QTextCharFormat keywordFormat;
QTextCharFormat regFormat;
QTextCharFormat classFormat;
QTextCharFormat singleLineCommentFormat;
QTextCharFormat multiLineCommentFormat;
QTextCharFormat quotationFormat;
QTextCharFormat functionFormat;
};
#endif // HIGHLIGHTER_H

View file

@ -1,11 +1,12 @@
#include "IOModesController.h"
#include "Cutter.h"
#include <QJsonArray>
#include <QPushButton>
#include <QObject>
#include <QMessageBox>
#include <QJsonObject>
#include <QMessageBox>
#include <QObject>
#include <QPushButton>
#include <qwidget.h>
IOModesController::IOModesController(QWidget *parentWindow)
@ -64,9 +65,9 @@ bool IOModesController::prepareForWriting()
"For safety, please consider using Cache mode and then commit the changes manually "
"via File -> Commit modifications to disk."));
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
QAbstractButton *reopenButton =
const QAbstractButton *reopenButton =
msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole);
QAbstractButton *iocacheButton =
const QAbstractButton *iocacheButton =
msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole);
msgBox.exec();
@ -81,22 +82,11 @@ bool IOModesController::prepareForWriting()
return true;
}
bool IOModesController::allChangesComitted()
{
RzCoreLocked core(Core());
for (auto c : CutterPVector<RzIOCache>(&core->io->cache)) {
if (!c->written) {
return false;
}
}
return true;
}
bool IOModesController::askCommitUnsavedChanges()
{
// Check if there are uncommitted changes
if (!allChangesComitted()) {
QMessageBox::StandardButton ret = QMessageBox::question(
if (!Core()->hasUncommitedChanges()) {
const QMessageBox::StandardButton ret = QMessageBox::question(
parentWindow, QObject::tr("Uncommitted changes"),
QObject::tr("It seems that you have changes or patches that are not committed to "
"the file.\n"

View file

@ -2,8 +2,14 @@
#define IOMODESCONTROLLER_H
#include "core/Cutter.h"
#include <qwidget.h>
/**
* @brief Manages switching between Read-Only, Cache, and Write modes
*
* Handles the logic required when changing how Cutter interacts with the underlying file on disk
*/
class IOModesController : public QObject
{
@ -13,7 +19,6 @@ public:
enum class Mode { READ_ONLY, CACHE, WRITE };
bool prepareForWriting();
bool canWrite();
bool allChangesComitted();
Mode getIOMode();
void setIOMode(Mode mode);

View file

@ -1,8 +1,7 @@
#ifndef CUTTER_INITIALOPTIONS_H
#define CUTTER_INITIALOPTIONS_H
#include "core/Cutter.h"
#include "core/Cutter.h" // IWYU pragma: keep
/**
* @brief The CommandDescription struct is a pair of a Rizin command and its description
@ -15,9 +14,12 @@ struct CommandDescription
QString translatedDescription() const;
};
/**
* @brief Struct to hold the options set when opening a file/project
*/
struct InitialOptions
{
enum class Endianness { Auto, Little, Big };
enum class Endianness : ut8 { Auto, Little, Big };
QString filename;
QString projectFile;

View file

@ -1,4 +1,8 @@
#include "JsonModel.h"
#include "Json.h"
#include "CutterJson.h"
#include <QTreeWidgetItem>
QTreeWidgetItem *Cutter::jsonTreeWidgetItem(const QString &key, const CutterJson &json)
{

View file

@ -1,19 +1,32 @@
#ifndef JSON_H
#define JSON_H
#ifndef CUTTER_JSON_H
#define CUTTER_JSON_H
#include "core/Cutter.h"
#include "CutterCommon.h"
#include <QJsonValue>
#include <QVariant>
static inline RVA JsonValueGetRVA(const QJsonValue &value, RVA defaultValue = RVA_INVALID)
class QTreeWidgetItem;
class CutterJson;
/**
* @file Json.h
* @brief Helpers for Json objects
*/
namespace Cutter {
inline RVA jsonValueToRVA(const QJsonValue &value, RVA defaultValue = RVA_INVALID)
{
bool ok;
RVA ret = value.toVariant().toULongLong(&ok);
const RVA ret = value.toVariant().toULongLong(&ok);
if (!ok) {
return defaultValue;
}
return ret;
}
#endif // CUTTER_JSON_H
QTreeWidgetItem *jsonTreeWidgetItem(const QString &key, const CutterJson &json);
}
#endif // JSON_H

View file

@ -1,14 +0,0 @@
#ifndef JSONMODEL_H
#define JSONMODEL_H
#include <QTreeWidgetItem>
#include "CutterJson.h"
namespace Cutter {
QTreeWidgetItem *jsonTreeWidgetItem(const QString &key, const CutterJson &json);
};
#endif // JSONMODEL_H

View file

@ -1,9 +1,8 @@
#ifndef LINKED_LIST_POOL_H
#define LINKED_LIST_POOL_H
#include <vector>
#include <cstdint>
#include <iterator>
#include <vector>
/**
* @brief Pool of singly linked lists.
@ -92,7 +91,7 @@ public:
};
/**
* @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.
*/
LinkedListPool(size_t initialCapacity) : data(1)
@ -110,7 +109,7 @@ public:
*/
List makeList(const T &value)
{
size_t position = data.size();
const size_t position = data.size();
data.push_back(Item { 0, value });
return { position, position };
}
@ -122,8 +121,8 @@ public:
* items. Modifying them will affect both lists.
*
* @param list The list that needs to be split.
* @param head Iterator to the first item in new list. Needs to be within \a list .
* @return Returns suffix of \a list.
* @param head Iterator to the first item in new list. Needs to be within @a list .
* @return Returns suffix of @a list.
*/
List splitTail(const List &list, const ListIterator &head)
{
@ -135,8 +134,8 @@ public:
*
* @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 .
* @return Returns prefix of \a list.
* be within @a list .
* @return Returns prefix of @a list.
*/
List splitHead(const List &list, const ListIterator &end)
{

View file

@ -1,7 +1,7 @@
#include <QtGui>
#include "common/MdHighlighter.h"
#include <QtGui>
MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
{
HighlightingRule rule;
@ -16,7 +16,7 @@ MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
<< "\\_([^\\\\]+)\\_"
<< "\\_\\_([^\\\\]+)\\_\\_";
for (const QString &pattern : keywordPatterns) {
for (const QString &pattern : std::as_const(keywordPatterns)) {
rule.pattern.setPattern(pattern);
rule.format = keywordFormat;
highlightingRules.append(rule);
@ -31,11 +31,11 @@ MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
void MdHighlighter::highlightBlock(const QString &text)
{
for (const HighlightingRule &rule : highlightingRules) {
QRegularExpression expression(rule.pattern);
for (const HighlightingRule &rule : std::as_const(highlightingRules)) {
const QRegularExpression expression(rule.pattern);
int index = expression.match(text).capturedStart();
while (index >= 0) {
int length = expression.match(text).capturedLength();
const int length = expression.match(text).capturedLength();
setFormat(index, length, rule.format);
index = expression.match(text.mid(index + length)).capturedStart();
}

View file

@ -1,14 +1,16 @@
#ifndef MDHIGHLIGHTER_H
#define MDHIGHLIGHTER_H
#include <QSyntaxHighlighter>
#include <QHash>
#include <QTextCharFormat>
#include <QRegularExpression>
#include <QSyntaxHighlighter>
#include <QTextCharFormat>
class QTextDocument;
/**
* @brief Wrapper of QSyntaxHighlighter for Markdown
*/
class MdHighlighter : public QSyntaxHighlighter
{
Q_OBJECT

View file

@ -1,4 +1,3 @@
#ifndef METRICS_H
#define METRICS_H

View file

@ -1,7 +1,7 @@
#include "PythonAPI.h"
#include "core/Cutter.h"
#include "CutterConfig.h"
#include "core/Cutter.h"
#include <QFile>

View file

@ -1,18 +1,20 @@
#include <cassert>
// clang-format off
#include "PythonAPI.h"
#include "PythonManager.h"
// clang-format on
#include "Cutter.h"
#include <QDebug>
#include <QFile>
#include <QDebug>
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <cassert>
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
# include <shiboken.h>
# include <pyside.h>
# include <shiboken.h>
# ifdef HAVE_PYSIDECLEANUP
// This header is introduced in PySide 6
# include <pysidecleanup.h>

View file

@ -1,8 +1,10 @@
// clang-format off
#include "PythonAPI.h"
#include "QtResImporter.h"
// clang-format on
#include <QFile>
#include <QDebug>
#include <QFile>
bool QtResExists(const char *name, QFile &file)
{
@ -19,7 +21,10 @@ PyObject *QtResGetCode(const char *name)
return nullptr;
}
moduleFile.open(QIODevice::ReadOnly);
if (!moduleFile.open(QIODevice::ReadOnly)) {
return nullptr;
}
QByteArray data = moduleFile.readAll();
moduleFile.close();
@ -50,8 +55,9 @@ PyObject *qtres_exists(PyObject *self, PyObject *args)
Q_UNUSED(self)
char *name;
QFile resFile;
if (!PyArg_ParseTuple(args, "s", &name))
if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}
return PyBool_FromLong(QtResExists(name, resFile));
}
@ -59,11 +65,13 @@ PyObject *qtres_get_code(PyObject *self, PyObject *args)
{
Q_UNUSED(self)
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}
PyObject *ret = QtResGetCode(name);
if (ret)
if (ret) {
return ret;
}
Py_RETURN_NONE;
}

View file

@ -1,5 +1,5 @@
#include "RefreshDeferrer.h"
#include "widgets/CutterDockWidget.h"
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent)

View file

@ -58,7 +58,7 @@ private:
public:
/**
* \param Determines whether, if nullptr is passed, the current value should be replaced or
* @param Determines whether, if nullptr is passed, the current value should be replaced or
* kept.
*/
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)

View file

@ -1,10 +1,10 @@
#include "common/ResourcePaths.h"
#include <QLibraryInfo>
#include <QDir>
#include <QFileInfo>
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QLibraryInfo>
#include <QStandardPaths>
#ifdef APPIMAGE
@ -30,7 +30,7 @@ static QString substitutePath(QString path)
/**
* @brief Substitute or filter paths returned by standardLocations based on Cutter package kind.
* @param paths list of paths to process
* @return
* @return List of substituted path strings
*/
static QStringList substitutePaths(const QStringList &paths)
{
@ -50,8 +50,8 @@ QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QStri
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs
// to be done after substitutions
QStringList result;
for (auto path : standardLocations(type)) {
QString filePath = path + QLatin1Char('/') + fileName;
for (const auto &path : standardLocations(type)) {
const QString filePath = path + QLatin1Char('/') + fileName;
bool exists = false;
if (options & QStandardPaths::LocateDirectory) {
exists = QDir(filePath).exists();
@ -79,6 +79,10 @@ QStringList Cutter::getTranslationsDirectories()
{
auto result = locateAll(QStandardPaths::AppDataLocation, "translations",
QStandardPaths::LocateDirectory);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
result << QLibraryInfo::path(QLibraryInfo::TranslationsPath);
#else
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
#endif
return result;
}

View file

@ -4,7 +4,7 @@
#include <QStandardPaths>
/**
* \file ResourcePaths.h
* @file ResourcePaths.h
* Set of functions for obtaining various paths. Some of the functions are wrappers around
* QStandardPaths functions having the same name but with modifications specific to way
* Cutter is packaged.

View file

@ -1,7 +1,9 @@
/* x64dbg RichTextPainter */
#include "RichTextPainter.h"
#include "CachedFontMetrics.h"
#include "common/Configuration.h"
#include <QPainter>
#include <QTextBlock>
#include <QTextFragment>
@ -15,13 +17,15 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
QPen pen;
QPen highlightPen;
QBrush brush(Qt::cyan);
for (const CustomRichText_t &curRichText : richText) {
for (const CustomRichText &curRichText : richText) {
T textWidth = fontMetrics->width(curRichText.text);
T backgroundWidth = textWidth;
if (backgroundWidth + xinc > w)
if (backgroundWidth + xinc > w) {
backgroundWidth = w - xinc;
if (backgroundWidth <= 0) // stop drawing when going outside the specified width
}
if (backgroundWidth <= 0) { // stop drawing when going outside the specified width
break;
}
switch (curRichText.flags) {
case FlagNone: // defaults
pen.setColor(ConfigColor("btext").name());
@ -46,7 +50,7 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin
painter->setPen(pen);
break;
}
int flags = 0;
int flags = 0; // NOLINT
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
flags = Qt::TextBypassShaping;
#endif
@ -69,18 +73,9 @@ template void RichTextPainter::paintRichText<qreal>(QPainter *painter, qreal x,
qreal h, qreal xinc, const List &richText,
CachedFontMetrics<qreal> *fontMetrics);
/**
* @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other
* applications
* @param richText The rich text to be converted to HTML format
* @param textHtml The HTML source. Any previous content will be preserved and new content will be
* appended at the end.
* @param textPlain The plain text. Any previous content will be preserved and new content will be
* appended at the end.
*/
void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain)
{
for (const CustomRichText_t &curRichText : richText) {
for (const CustomRichText &curRichText : richText) {
if (curRichText.text == " ") { // blank
textHtml += " ";
textPlain += " ";
@ -95,29 +90,33 @@ void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QStr
break;
case FlagBackground: // background only
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.
// That's not desired. Leave it blank.
textHtml += QString("<span style=\"background-color:%1\">")
.arg(curRichText.textBackground.name());
else
} else {
textHtml += QString("<span>");
}
break;
case FlagAll: // color+background
if (curRichText.textBackground
!= Qt::transparent) // QColor::name() returns "#000000" for transparent color.
// That's not desired. Leave it blank.
!= Qt::transparent) { // QColor::name() returns "#000000" for transparent color.
// That's not desired. Leave it blank.
textHtml += QString("<span style=\"color:%1; background-color:%2\">")
.arg(curRichText.textColor.name(),
curRichText.textBackground.name());
else
} else {
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
}
break;
}
if (curRichText.highlight) // Underline highlighted token
if (curRichText.highlight) { // Underline highlighted token
textHtml += "<u>";
}
textHtml += curRichText.text.toHtmlEscaped();
if (curRichText.highlight)
if (curRichText.highlight) {
textHtml += "</u>";
}
textHtml += "</span>"; // Close the tag
textPlain += curRichText.text;
}
@ -129,16 +128,16 @@ RichTextPainter::List RichTextPainter::fromTextDocument(const QTextDocument &doc
for (QTextBlock block = doc.begin(); block != doc.end(); block = block.next()) {
for (QTextBlock::iterator it = block.begin(); it != block.end(); ++it) {
QTextFragment fragment = it.fragment();
QTextCharFormat format = fragment.charFormat();
const QTextFragment fragment = it.fragment();
const QTextCharFormat format = fragment.charFormat();
CustomRichText_t text;
CustomRichText text;
text.text = fragment.text();
text.textColor = format.foreground().color();
text.textBackground = format.background().color();
bool hasForeground = format.hasProperty(QTextFormat::ForegroundBrush);
bool hasBackground = format.hasProperty(QTextFormat::BackgroundBrush);
const bool hasForeground = format.hasProperty(QTextFormat::ForegroundBrush);
const bool hasBackground = format.hasProperty(QTextFormat::BackgroundBrush);
if (hasForeground && !hasBackground) {
text.flags = FlagColor;
@ -166,14 +165,14 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
int cols = 0;
bool cropped = false;
for (const auto &text : richText) {
int textLength = text.text.size();
const int textLength = text.text.size();
if (cols + textLength <= maxCols) {
r.push_back(text);
cols += textLength;
} else if (cols == maxCols) {
break;
} else {
CustomRichText_t croppedText = text;
CustomRichText croppedText = text;
croppedText.text.truncate(maxCols - cols);
r.push_back(croppedText);
cropped = true;

View file

@ -2,11 +2,12 @@
#ifndef RICHTEXTPAINTER_H
#define RICHTEXTPAINTER_H
#include "common/Metrics.h"
#include "CutterDescriptions.h" // IWYU pragma: keep
#include <QColor>
#include <QString>
#include <QTextDocument>
#include <QColor>
#include <vector>
class QFontMetricsF;
@ -14,36 +15,57 @@ template<typename T>
class CachedFontMetrics;
class QPainter;
class RichTextPainter
/**
* @namespace For efficient painting of text
*/
namespace RichTextPainter {
// structures
enum CustomRichTextFlags : ut8 { FlagNone, FlagColor, FlagBackground, FlagAll };
struct CustomRichText
{
public:
// structures
enum CustomRichTextFlags { FlagNone, FlagColor, FlagBackground, FlagAll };
struct CustomRichText_t
{
QString text;
QColor textColor;
QColor textBackground;
CustomRichTextFlags flags;
bool highlight = false;
QColor highlightColor;
int highlightWidth = 2;
bool highlightConnectPrev = false;
};
typedef std::vector<CustomRichText_t> List;
// functions
template<typename T = qreal>
static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText,
CachedFontMetrics<T> *fontMetrics);
static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
static List fromTextDocument(const QTextDocument &doc);
static List cropped(const List &richText, int maxCols, const QString &indicator = nullptr,
bool *croppedOut = nullptr);
QString text;
QColor textColor;
QColor textBackground;
CustomRichTextFlags flags;
bool highlight = false;
QColor highlightColor;
int highlightWidth = 2;
bool highlightConnectPrev = false;
};
typedef std::vector<CustomRichText> List;
// functions
template<typename T = qreal>
void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText,
CachedFontMetrics<T> *fontMetrics);
/**
* @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[out] textHtml The HTML source. Any previous content will be preserved and new content will
* be appended at the end.
* @param[out] textPlain The plain text. Any previous content will be preserved and new content will
* be appended at the end.
*/
void htmlRichText(const List &richText, QString &textHtml, QString &textPlain);
List fromTextDocument(const QTextDocument &doc);
/**
* @brief Crops a list of rich text elements to a maximum column width.
*
* @param richText The input list of rich text segments.
* @param maxCols The maximum character width allowed.
* @param indicator String to append if text is cropped (e.g., "...").
* @param[out] croppedOut Set to true if the text was actually truncated.
* @return A new list containing the cropped segments.
*/
List cropped(const List &richText, int maxCols, const QString &indicator = nullptr,
bool *croppedOut = nullptr);
}
#endif // RICHTEXTPAINTER_H

View file

@ -1,6 +1,7 @@
#include "RizinTask.h"
#include <rz_core.h>
#include <utility>
RizinTask::~RizinTask()
{
@ -11,17 +12,17 @@ RizinTask::~RizinTask()
void RizinTask::startTask()
{
rz_core_task_enqueue(&Core()->core_->tasks, task);
rz_core_task_enqueue(&Core()->rzCore->tasks, task);
}
void RizinTask::breakTask()
{
rz_core_task_break(&Core()->core_->tasks, task->id);
rz_core_task_break(&Core()->rzCore->tasks, task->id);
}
void RizinTask::joinTask()
{
rz_core_task_join(&Core()->core_->tasks, nullptr, task->id);
rz_core_task_join(&Core()->rzCore->tasks, nullptr, task->id);
}
void RizinTask::taskFinished()
@ -74,7 +75,7 @@ const char *RizinCmdTask::getResultRaw()
// RizinFunctionTask
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
: fcn(fcn), res(nullptr)
: fcn(std::move(fcn)), res(nullptr)
{
auto core = Core()->lock();
task = rz_core_function_task_new(
@ -85,7 +86,7 @@ RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool t
void *RizinFunctionTask::runner(RzCore *core, void *user)
{
RizinFunctionTask *task = reinterpret_cast<RizinFunctionTask *>(user);
auto *task = reinterpret_cast<RizinFunctionTask *>(user);
task->res = task->fcn(core);
task->taskFinished();
return nullptr;

View file

@ -1,9 +1,13 @@
#ifndef RZTASK_H
#define RZTASK_H
#include "core/Cutter.h"
#include <memory>
/**
* @brief Base class for managing background tasks via the Rizin core task API
*/
class CUTTER_EXPORT RizinTask : public QObject
{
Q_OBJECT
@ -15,7 +19,7 @@ protected:
void taskFinished();
public:
using Ptr = QSharedPointer<RizinTask>;
using Ptr = std::shared_ptr<RizinTask>;
virtual ~RizinTask();
@ -27,6 +31,9 @@ signals:
void finished();
};
/**
* @brief AsyncTask for executing individual Rizin commands and fetching their output
*/
class CUTTER_EXPORT RizinCmdTask : public RizinTask
{
Q_OBJECT

View file

@ -1,5 +1,6 @@
#include "core/Cutter.h"
#include "common/RunScriptTask.h"
#include "core/Cutter.h"
#include "core/MainWindow.h"
RunScriptTask::RunScriptTask() : AsyncTask() {}

View file

@ -1,9 +1,11 @@
#ifndef RUNSCRIPTTHREAD_H
#define RUNSCRIPTTHREAD_H
#ifndef RUNSCRIPTTASK_H
#define RUNSCRIPTTASK_H
#include "common/AsyncTask.h"
#include "core/Cutter.h"
/**
* @brief Async task for running rizin scripts
*/
class RunScriptTask : public AsyncTask
{
Q_OBJECT
@ -12,7 +14,7 @@ public:
explicit RunScriptTask();
~RunScriptTask();
QString getTitle() override { return tr("Run Script"); }
QString getTitle() const override { return tr("Run Script"); }
void setFileName(const QString &fileName) { this->fileName = fileName; }
@ -25,4 +27,4 @@ private:
QString fileName;
};
#endif // RUNSCRIPTTHREAD_H
#endif // RUNSCRIPTTASK_H

View file

@ -1,22 +1,22 @@
#include "SelectionHighlight.h"
#include "Configuration.h"
#include "Colors.h"
#include <QList>
#include <QTextEdit>
#include "Colors.h"
#include "Configuration.h"
#include <QColor>
#include <QTextCursor>
#include <QList>
#include <QPlainTextEdit>
#include <QRegularExpression>
#include <QTextCursor>
#include <QTextEdit>
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
const QString &word)
{
QList<QTextEdit::ExtraSelection> selections;
QTextEdit::ExtraSelection highlightSelection;
QTextDocument *document = textEdit->document();
QColor highlightWordColor = ConfigColor("wordHighlight");
const QTextDocument *document = textEdit->document();
const QColor highlightWordColor = ConfigColor("wordHighlight");
if (word.isEmpty()) {
return QList<QTextEdit::ExtraSelection>();
@ -85,18 +85,18 @@ QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor)
{
QColor highlightColor = ConfigColor("lineHighlight");
const QColor highlightColor = ConfigColor("lineHighlight");
return createLineHighlight(cursor, highlightColor);
}
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
{
QColor highlightColor = ConfigColor("highlightPC");
const QColor highlightColor = ConfigColor("highlightPC");
return createLineHighlight(cursor, highlightColor);
}
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor)
{
QColor highlightColor = ConfigColor("gui.breakpoint_background");
const QColor highlightColor = ConfigColor("gui.breakpoint_background");
return createLineHighlight(cursor, highlightColor);
}

View file

@ -7,40 +7,43 @@ class QPlainTextEdit;
class QString;
/**
* @brief createSameWordsSelections se
* @param textEdit
* @param word
* @return
* @brief Create selections for any occurences of the given word
* @param textEdit TextEdit object to make selections in
* @param word Word to make selections of
* @return List of ExtraSelection with highlighted words
*/
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit,
const QString &word);
/**
* @brief createLineHighlight
* @param cursor - a Cursor object represents the line to be highlighted
* @param highlightColor - the color to be used for highlighting. The color is decided by the callee
* @brief Highlight the currently selected line with given color
* @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, ...)
* @return ExtraSelection with highlighted line
*/
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);
/**
* @brief This function responsible to highlight the currently selected line
* @param cursor - a Cursor object represents the line to be highlighted
* @brief This function is responsible for highlighting the currently selected line
*
* Similar to @ref createLineHighlight() but uses "lineHighlght" value from config
*
* @param cursor A Cursor object represents the line to be highlighted
* @return ExtraSelection with highlighted line
*/
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor);
/**
* @brief This function responsible to highlight the program counter line
* @param cursor - a Cursor object represents the line to be highlighted
* @brief This function is responsible for highlighting the program counter line
* @param cursor A Cursor object represents the line to be highlighted
* @return ExtraSelection with highlighted line
*/
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor);
/**
* @brief This function responsible to highlight a line with breakpoint
* @param cursor - a Cursor object represents the line to be highlighted
* @brief This function is responsible for highlighting a line that contains a breakpoint
* @param cursor A Cursor object represents the line to be highlighted
* @return ExtraSelection with highlighted line
*/
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor);

View file

@ -1,22 +1,44 @@
#include "SettingsUpgrade.h"
#include <QApplication>
#include <QMessageBox>
#include "Configuration.h"
#include "common/ColorThemeWorker.h"
#include <QApplication>
#include <QMessageBox>
#define CUTTER_SETTINGS_VERSION_CURRENT 7
#define CUTTER_SETTINGS_VERSION_KEY "version"
#define THEME_VERSION_CURRENT 2
#define THEME_VERSION_KEY "theme_version"
/*
* How Settings migrations work:
*
* Every time settings are changed in a way that needs migration,
* CUTTER_SETTINGS_VERSION_CURRENT is raised by 1 and a function migrateSettingsToX
* is implemented and added to initializeSettings().
* This function takes care of migrating from EXACTLY version X-1 to X.
*/
namespace {
const char preRizinOrg[] = "RadareOrg";
const char preRizinApp[] = "Cutter";
const int lastR2CutterSettingVersion = 6;
/**
* @brief Migrate Settings used before Cutter 1.8
*
* @return whether any settings have been migrated
*/
static bool migrateSettingsPre18(QSettings &newSettings)
bool migrateSettingsPre18(QSettings &newSettings)
{
if (newSettings.value("settings_migrated", false).toBool()) {
return false;
}
QSettings oldSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, "Cutter", "Cutter");
QStringList allKeys = oldSettings.allKeys();
const QStringList allKeys = oldSettings.allKeys();
if (allKeys.isEmpty()) {
return false;
}
@ -31,32 +53,20 @@ static bool migrateSettingsPre18(QSettings &newSettings)
return true;
}
#define CUTTER_SETTINGS_VERSION_CURRENT 7
#define CUTTER_SETTINGS_VERSION_KEY "version"
/*
* How Settings migrations work:
*
* Every time settings are changed in a way that needs migration,
* CUTTER_SETTINGS_VERSION_CURRENT is raised by 1 and a function migrateSettingsToX
* is implemented and added to initializeSettings().
* This function takes care of migrating from EXACTLY version X-1 to X.
*/
static void migrateSettingsTo1(QSettings &settings)
void migrateSettingsTo1(QSettings &settings)
{
settings.remove("settings_migrated"); // now handled by version
settings.remove("updated_custom_themes"); // now handled by theme_version
}
static void migrateSettingsTo2(QSettings &settings)
void migrateSettingsTo2(QSettings &settings)
{
QStringList docks = settings.value("docks").toStringList(); // get current list of docks
// replace occurences of "PseudocodeWidget" with "DecompilerWidget"
settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget"));
}
static void migrateSettingsTo3(QSettings &settings)
void migrateSettingsTo3(QSettings &settings)
{
auto defaultGeometry = settings.value("geometry").toByteArray();
auto defaultState = settings.value("state").toByteArray();
@ -69,7 +79,7 @@ static void migrateSettingsTo3(QSettings &settings)
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QSet<QString> unsyncDocks = unsyncList.toSet();
#else
QSet<QString> unsyncDocks(unsyncList.begin(), unsyncList.end());
const QSet<QString> unsyncDocks(unsyncList.begin(), unsyncList.end());
#endif
QVariantMap viewProperties;
@ -108,7 +118,7 @@ static void migrateSettingsTo3(QSettings &settings)
settings.remove("unsync");
}
static void renameAsmOption(QSettings &settings, const QString &oldName, const QString &newName)
void renameAsmOption(QSettings &settings, const QString &oldName, const QString &newName)
{
if (settings.contains(oldName)) {
auto value = settings.value(oldName);
@ -117,23 +127,23 @@ static void renameAsmOption(QSettings &settings, const QString &oldName, const Q
}
}
static void migrateSettingsTo4(QSettings &settings)
void migrateSettingsTo4(QSettings &settings)
{
renameAsmOption(settings, "asm.var.subonly", "asm.sub.varonly");
renameAsmOption(settings, "asm.bytespace", "asm.bytes.space");
}
static void migrateSettingsTo5(QSettings &settings)
void migrateSettingsTo5(QSettings &settings)
{
renameAsmOption(settings, "asm.var.sub", "asm.sub.var");
}
static void migrateSettingsTo6(QSettings &settings)
void migrateSettingsTo6(QSettings &settings)
{
settings.remove("dir.projects");
}
static void migrateSettingsTo7(QSettings &settings)
void migrateSettingsTo7(QSettings &settings)
{
auto list = settings.value("recentFileList").toStringList();
for (auto &file : list) {
@ -142,12 +152,120 @@ static void migrateSettingsTo7(QSettings &settings)
settings.setValue("recentFileList", list);
}
void removeObsoleteOptionsFromCustomThemes()
{
const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
const QStringList themes = Core()->getColorThemes();
for (const auto &themeName : themes) {
if (!ThemeWorker().isCustomTheme(themeName)) {
continue;
}
const ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName);
ColorThemeWorker::Theme updatedTheme;
for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) {
if (options.contains(it.key())) {
updatedTheme.insert(it.key(), it.value());
}
}
ThemeWorker().save(updatedTheme, themeName);
}
}
void syncCustomThemes()
{
const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
const QStringList themes = Core()->getColorThemes();
const ColorThemeWorker::Theme lightTheme =
ThemeWorker().getTheme("cutter"); // default light theme
const ColorThemeWorker::Theme darkTheme = ThemeWorker().getTheme("ayu"); // default dark theme
// note that there was no entry for angui.navbar.str (as it was a typo) so the
// default color for it will most likely be black instead of the color defined
// in config, unless changed by the user
QHash<QString, QString> renames = {
{ "angui.navbar.str", "gui.navbar.str" },
{ "gui.navbar.empty", "gui.navbar.unexplored" },
};
const QStringList forceDefaultKeys = { "gui.navbar.signature", "gui.navbar.data" };
for (const auto &themeName : themes) {
if (!ThemeWorker().isCustomTheme(themeName)) {
continue;
}
const ColorThemeWorker::Theme originalTheme = ThemeWorker().getTheme(themeName);
ColorThemeWorker::Theme updatedTheme;
for (auto it = renames.begin(); it != renames.end(); ++it) {
if (originalTheme.contains(it.key())) {
updatedTheme.insert(it.value(), originalTheme.value(it.key()));
}
}
const QColor bg = originalTheme.value("gui.background", QColor(Qt::white));
const QStringList renameValues = renames.values();
for (const auto &option : options) {
if (renameValues.contains(option)) {
continue;
}
if (originalTheme.contains(option) && !forceDefaultKeys.contains(option)) {
updatedTheme.insert(option, originalTheme.value(option));
} else {
const QColor color =
bg.lightness() > 128 ? lightTheme.value(option) : darkTheme.value(option);
updatedTheme.insert(option, color);
}
}
ThemeWorker().save(updatedTheme, themeName);
if (Config()->getColorTheme() == themeName) {
Config()->setColorTheme(themeName);
}
}
}
void importOldSettings()
{
// QSettings
QSettings::setDefaultFormat(QSettings::IniFormat);
const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg,
preRizinApp);
QSettings newSettings;
for (const auto &key : r2CutterSettings.allKeys()) {
newSettings.setValue(key, r2CutterSettings.value(key));
}
// Color Themes
char *szThemes = rz_str_home(".local/share/radare2/cons");
const QString r2ThemesPath = szThemes;
rz_mem_free(szThemes);
const QDir r2ThemesDir(r2ThemesPath);
if (QFileInfo(r2ThemesPath).isDir()) {
const QDir rzThemesDir(ThemeWorker().getCustomThemesPath());
if (!rzThemesDir.exists()) {
QDir().mkpath(rzThemesDir.absolutePath());
}
for (const auto &f : r2ThemesDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) {
auto dst = rzThemesDir.absoluteFilePath(f.fileName());
if (QDir(dst).exists()) {
qInfo() << "Theme" << dst << "already exists. Not overwriting with"
<< f.absoluteFilePath();
continue;
}
qInfo() << "Copying Theme" << f.absoluteFilePath() << "to" << dst;
QFile::copy(f.absoluteFilePath(), dst);
}
}
}
} // End Anonymous namespace
void Cutter::initializeSettings()
{
QSettings::setDefaultFormat(QSettings::IniFormat);
QSettings settings;
int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt();
const int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt();
if (settingsVersion == 0) {
migrateSettingsPre18(settings);
}
@ -189,84 +307,10 @@ void Cutter::initializeSettings()
settings.setValue(CUTTER_SETTINGS_VERSION_KEY, CUTTER_SETTINGS_VERSION_CURRENT);
}
#define THEME_VERSION_CURRENT 2
#define THEME_VERSION_KEY "theme_version"
static void removeObsoleteOptionsFromCustomThemes()
{
const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
QStringList themes = Core()->getColorThemes();
for (const auto &themeName : themes) {
if (!ThemeWorker().isCustomTheme(themeName)) {
continue;
}
ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName);
ColorThemeWorker::Theme updatedTheme;
for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) {
if (options.contains(it.key())) {
updatedTheme.insert(it.key(), it.value());
}
}
ThemeWorker().save(updatedTheme, themeName);
}
}
static void syncCustomThemes()
{
const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
QStringList themes = Core()->getColorThemes();
ColorThemeWorker::Theme lightTheme = ThemeWorker().getTheme("cutter"); // default light theme
ColorThemeWorker::Theme darkTheme = ThemeWorker().getTheme("ayu"); // default dark theme
// note that there was no entry for angui.navbar.str (as it is a typo) so the
// default color for it will most likely be black instead of the color defined
// in config, unless changed by the user
QHash<QString, QString> renames = {
{ "angui.navbar.str", "gui.navbar.str" },
{ "gui.navbar.empty", "gui.navbar.unexplored" },
};
const QStringList forceDefaultKeys = { "gui.navbar.signature", "gui.navbar.data" };
for (const auto &themeName : themes) {
if (!ThemeWorker().isCustomTheme(themeName)) {
continue;
}
ColorThemeWorker::Theme originalTheme = ThemeWorker().getTheme(themeName);
ColorThemeWorker::Theme updatedTheme;
for (auto it = renames.begin(); it != renames.end(); ++it) {
if (originalTheme.contains(it.key())) {
updatedTheme.insert(it.value(), originalTheme.value(it.key()));
}
}
QColor bg = originalTheme.value("gui.background", QColor(Qt::white));
const QStringList renameValues = renames.values();
for (const auto &option : options) {
if (renameValues.contains(option)) {
continue;
}
if (originalTheme.contains(option) && !forceDefaultKeys.contains(option)) {
updatedTheme.insert(option, originalTheme.value(option));
} else {
QColor color =
bg.lightness() > 128 ? lightTheme.value(option) : darkTheme.value(option);
updatedTheme.insert(option, color);
}
}
ThemeWorker().save(updatedTheme, themeName);
if (Config()->getColorTheme() == themeName) {
Config()->setColorTheme(themeName);
}
}
}
void Cutter::migrateThemes()
{
QSettings settings;
int themeVersion = settings.value(THEME_VERSION_KEY, 0).toInt();
const int themeVersion = settings.value(THEME_VERSION_KEY, 0).toInt();
if (themeVersion >= THEME_VERSION_CURRENT) {
qWarning() << "Themes have a higher version than current! Skipping migration.";
return;
@ -288,73 +332,35 @@ void Cutter::migrateThemes()
settings.setValue(THEME_VERSION_KEY, THEME_VERSION_CURRENT);
}
static const char PRE_RIZIN_ORG[] = "RadareOrg";
static const char PRE_RIZIN_APP[] = "Cutter";
const int LAST_R2_CUTTER_SETTING_VERSION = 6;
bool Cutter::shouldOfferSettingImport()
{
QSettings::setDefaultFormat(QSettings::IniFormat);
QSettings settings;
const QSettings settings;
if (settings.contains("firstExecution")) {
return false;
}
QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG,
PRE_RIZIN_APP);
QString f = r2CutterSettings.fileName();
const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg,
preRizinApp);
const QString f = r2CutterSettings.fileName();
if (r2CutterSettings.value("firstExecution", true) != QVariant(false)) {
return false; // no Cutter <= 1.12 settings to import
}
int version = r2CutterSettings.value("version", -1).toInt();
if (version < 1 || version > LAST_R2_CUTTER_SETTING_VERSION) {
const int version = r2CutterSettings.value("version", -1).toInt();
if (version < 1 || version > lastR2CutterSettingVersion) {
return false; // version too new maybe it's from r2Cutter fork instead of pre-rizin Cutter.
}
return true;
}
static void importOldSettings()
{
// QSettings
QSettings::setDefaultFormat(QSettings::IniFormat);
QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG,
PRE_RIZIN_APP);
QSettings newSettings;
for (auto key : r2CutterSettings.allKeys()) {
newSettings.setValue(key, r2CutterSettings.value(key));
}
// Color Themes
char *szThemes = rz_str_home(".local/share/radare2/cons");
QString r2ThemesPath = szThemes;
rz_mem_free(szThemes);
QDir r2ThemesDir(r2ThemesPath);
if (QFileInfo(r2ThemesPath).isDir()) {
QDir rzThemesDir(ThemeWorker().getCustomThemesPath());
if (!rzThemesDir.exists()) {
QDir().mkpath(rzThemesDir.absolutePath());
}
for (auto f : r2ThemesDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) {
auto dst = rzThemesDir.absoluteFilePath(f.fileName());
if (QDir(dst).exists()) {
qInfo() << "Theme" << dst << "already exists. Not overwriting with"
<< f.absoluteFilePath();
continue;
}
qInfo() << "Copying Theme" << f.absoluteFilePath() << "to" << dst;
QFile::copy(f.absoluteFilePath(), dst);
}
}
}
void Cutter::showSettingImportDialog(int &argc, char **argv)
{
// Creating temporary QApplication because this happens before anything else in Cutter is
// initialized
QApplication temporaryApp(argc, argv);
QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG,
PRE_RIZIN_APP);
QString oldFile = r2CutterSettings.fileName();
const QApplication temporaryApp(argc, argv);
const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg,
preRizinApp);
const QString oldFile = r2CutterSettings.fileName();
// Can't use message translations because settings have not been imported
auto result =
QMessageBox::question(nullptr, "Setting import",

View file

@ -1,9 +1,15 @@
#ifndef COMMON_SETTINGS_UPGRADE_H
#define COMMON_SETTINGS_UPGRADE_H
#ifndef SETTINGS_UPGRADE_H
#define SETTINGS_UPGRADE_H
#include <QSettings>
#include <core/Cutter.h>
/**
* @file SettingsUpgrade.h
* @brief Logic for migrating and importing Cutter settings from older versions
*/
namespace Cutter {
void initializeSettings();
/**
@ -21,4 +27,4 @@ void showSettingImportDialog(int &argc, char **argv);
void migrateThemes();
}
#endif // COMMON_SETTINGS_UPGRADE_H
#endif // SETTINGS_UPGRADE_H

View file

@ -1,16 +1,18 @@
#ifndef STRINGSASYNCTASK_H
#define STRINGSASYNCTASK_H
#ifndef STRINGSTASK_H
#define STRINGSTASK_H
#include "common/AsyncTask.h"
#include "core/Cutter.h"
/**
* @brief AsyncTask for querying all strings in binary
*/
class StringsTask : public AsyncTask
{
Q_OBJECT
public:
QString getTitle() override { return tr("Searching for Strings"); }
QString getTitle() const override { return tr("Searching for Strings"); }
signals:
void stringSearchFinished(const QList<StringDescription> &strings);
@ -23,4 +25,4 @@ protected:
}
};
#endif // STRINGSASYNCTASK_H
#endif // STRINGSTASK_H

View file

@ -1,17 +1,17 @@
#include "SvgIconEngine.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QFile>
#include "Helpers.h"
#include <QFile>
#include <QPainter>
#include <QSvgRenderer>
SvgIconEngine::SvgIconEngine(const QString &filename)
{
QFile file(filename);
file.open(QFile::ReadOnly);
this->svgData = file.readAll();
if (file.open(QFile::ReadOnly)) {
this->svgData = file.readAll();
}
}
SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor)
@ -44,7 +44,7 @@ QPixmap SvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State
QPixmap pix = QPixmap::fromImage(img, Qt::NoFormatConversion);
{
QPainter painter(&pix);
QRect r(QPoint(0, 0), size);
const QRect r(QPoint(0, 0), size);
this->paint(&painter, r, mode, state);
}
return pix;

View file

@ -1,10 +1,12 @@
#ifndef SVGICONENGINE_H
#define SVGICONENGINE_H
#include <QIconEngine>
#include <QPalette>
/**
* @brief QIconEngine wrapper for rendering Svg's
*/
class SvgIconEngine : public QIconEngine
{
private:

View file

@ -66,7 +66,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
QTextCharFormat keywordFormat;
keywordFormat.setForeground(QColor(80, 200, 215));
for (const auto &pattern : keywordPatterns) {
for (const auto &pattern : std::as_const(keywordPatterns)) {
rule.pattern.setPattern(pattern);
rule.format = keywordFormat;
highlightingRules.append(rule);
@ -99,7 +99,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent)
void FallbackSyntaxHighlighter::highlightBlock(const QString &text)
{
for (const auto &it : highlightingRules) {
for (const auto &it : std::as_const(highlightingRules)) {
auto matchIterator = it.pattern.globalMatch(text);
while (matchIterator.hasNext()) {
const auto match = matchIterator.next();

View file

@ -2,11 +2,12 @@
#define SYNTAXHIGHLIGHTER_H
#include "CutterCommon.h"
#include <QSyntaxHighlighter>
#include <QVector>
#include <QTextDocument>
#include <QRegularExpression>
#include <QSyntaxHighlighter>
#include <QTextCharFormat>
#include <QTextDocument>
#include <QVector>
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
@ -26,7 +27,7 @@ private slots:
#endif
/**
* SyntaxHighlighter to be used when KSyntaxHighlighting is not available
* @brief SyntaxHighlighter to be used when KSyntaxHighlighting is not available
*/
class CUTTER_EXPORT FallbackSyntaxHighlighter : public QSyntaxHighlighter
{

View file

@ -1,12 +1,28 @@
#include <cassert>
#include "TempConfig.h"
#include "core/Cutter.h"
#include "TempConfig.h"
#include <cassert>
TempConfig::~TempConfig()
{
for (auto i = resetValues.constBegin(); i != resetValues.constEnd(); ++i) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
switch (i.value().typeId()) {
case QMetaType::Type::QString:
Core()->setConfig(i.key(), i.value().toString());
break;
case QMetaType::Type::Int:
Core()->setConfig(i.key(), i.value().toInt());
break;
case QMetaType::Type::Bool:
Core()->setConfig(i.key(), i.value().toBool());
break;
default:
assert(false);
break;
}
#else
switch (i.value().type()) {
case QVariant::String:
Core()->setConfig(i.key(), i.value().toString());
@ -21,6 +37,7 @@ TempConfig::~TempConfig()
assert(false);
break;
}
#endif
}
}

View file

@ -15,13 +15,13 @@
* calls can be chained. If a command or Rizin method accepts arguments directly it is preferred to
* use those instead of temporary modifying global configuration.
*
* \code
* @code
* {
* TempConfig tempConfig;
* tempConfig.set("asm.arch", "x86").set("asm.comments", false);
* // config automatically restored at the end of scope
* }
* \endcode
* @endcode
*/
class CUTTER_EXPORT TempConfig
{

View file

@ -1,25 +1,25 @@
#include "UpdateWorker.h"
#if CUTTER_UPDATE_WORKER_AVAILABLE
# include <QUrl>
# include <QFile>
# include <QTimer>
# include <QEventLoop>
# include <QDataStream>
# include <QJsonObject>
# include <QApplication>
# include <QJsonDocument>
# include <QDesktopServices>
# include <QtNetwork/QNetworkReply>
# include <QtNetwork/QNetworkRequest>
# include <QStandardPaths>
# include "CutterConfig.h"
# include "common/Configuration.h"
# include <QApplication>
# include <QDataStream>
# include <QDesktopServices>
# include <QEventLoop>
# include <QFile>
# include <QFileDialog>
# include <QJsonDocument>
# include <QJsonObject>
# include <QMessageBox>
# include <QProgressDialog>
# include <QPushButton>
# include <QFileDialog>
# include <QMessageBox>
# include "common/Configuration.h"
# include "CutterConfig.h"
# include <QStandardPaths>
# include <QTimer>
# include <QUrl>
# include <QtNetwork/QNetworkReply>
# include <QtNetwork/QNetworkRequest>
#endif
#if CUTTER_UPDATE_WORKER_AVAILABLE
@ -39,7 +39,7 @@ UpdateWorker::UpdateWorker(QObject *parent) : QObject(parent), pending(false)
void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
{
QUrl url("https://api.github.com/repos/rizinorg/cutter/releases/latest");
const QUrl url("https://api.github.com/repos/rizinorg/cutter/releases/latest");
QNetworkRequest request;
request.setUrl(url);
@ -70,7 +70,7 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
mb.setStandardButtons(QMessageBox::Ok);
}
mb.setDefaultButton(QMessageBox::Ok);
int ret = mb.exec();
const int ret = mb.exec();
if (ret == QMessageBox::Reset) {
Config()->setAutoUpdateEnabled(false);
}
@ -90,7 +90,7 @@ void UpdateWorker::serveVersionCheckReply()
.toString();
versionReplyStr.remove('v');
}
QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
const QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr);
if (!versionReply.isNull()) {
latestVersion = versionReply;
}

View file

@ -11,21 +11,19 @@
#if CUTTER_UPDATE_WORKER_AVAILABLE
# include <QDir>
# include <QTimer>
# include <QObject>
# include <QtNetwork/QNetworkAccessManager>
# include <QTimer>
# include <QVersionNumber>
# include <QtNetwork/QNetworkAccessManager>
#endif
#if CUTTER_UPDATE_WORKER_AVAILABLE
class QNetworkReply;
/**
* @class UpdateWorker
* @brief The UpdateWorker class is a class providing API to check for current Cutter version.
* @brief The UpdateWorker class is a class providing API to check for current/latest Cutter
* version.
*/
class UpdateWorker : public QObject
{
Q_OBJECT
@ -43,7 +41,6 @@ public:
*
* @sa checkComplete(const QString& verson, const QString& errorMsg)
*/
void checkCurrentVersion(time_t timeoutMs);
/**

View file

@ -1,15 +1,16 @@
#include "Basefind.h"
#include "Cutter.h"
bool Basefind::threadCallback(const RzBaseFindThreadInfo *info, void *user)
{
auto th = reinterpret_cast<Basefind *>(user);
return th->updateProgress(info);
}
Basefind::Basefind(CutterCore *core)
: core(core),
scores(nullptr),
continue_run(true)
Basefind::Basefind()
: scores(nullptr),
continueRun(true)
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
,
mutex(QMutex::Recursive)
@ -61,14 +62,13 @@ void Basefind::run()
mutex.lock();
rz_list_free(scores);
scores = nullptr;
continue_run = true;
continueRun = true;
mutex.unlock();
core->coreMutex.lock();
auto core = Core()->lock();
options.callback = threadCallback;
options.user = this;
scores = rz_basefind(core->core_, &options);
core->coreMutex.unlock();
scores = rz_basefind(core, &options);
emit complete();
}
@ -76,7 +76,7 @@ void Basefind::run()
void Basefind::cancel()
{
mutex.lock();
continue_run = false;
continueRun = false;
mutex.unlock();
}
@ -103,7 +103,7 @@ bool Basefind::updateProgress(const RzBaseFindThreadInfo *info)
status.percentage = info->percentage;
emit progress(status);
bool ret = continue_run;
const bool ret = continueRun;
mutex.unlock();
return ret;
}

View file

@ -1,21 +1,25 @@
#ifndef CUTTER_BASEFIND_CORE_H
#define CUTTER_BASEFIND_CORE_H
#ifndef BASEFIND_H
#define BASEFIND_H
#include <QThread>
#include <QMutex>
#include "Cutter.h"
#include "CutterDescriptions.h"
#include <QMutex>
#include <QThread>
#include <rz_basefind.h>
class CutterCore;
/**
* @brief Threaded wrapper for Rizin's basefind functionality to identify the base address of a
* binary
*/
class Basefind : public QThread
{
Q_OBJECT
public:
explicit Basefind(CutterCore *core);
explicit Basefind();
virtual ~Basefind();
void run();
@ -30,9 +34,8 @@ signals:
void complete();
private:
CutterCore *const core;
RzList *scores;
bool continue_run;
bool continueRun;
RzBaseFindOpt options;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QMutex mutex;
@ -44,4 +47,4 @@ private:
static bool threadCallback(const RzBaseFindThreadInfo *info, void *user);
};
#endif // CUTTER_BASEFIND_CORE_H
#endif // BASEFIND_H

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,25 @@
#ifndef CUTTER_H
#define CUTTER_H
#include "RizinCpp.h"
#include "common/BasicInstructionHighlighter.h"
#include "core/Basefind.h"
#include "core/CutterCommon.h"
#include "core/CutterDescriptions.h"
#include "core/CutterJson.h"
#include "core/Basefind.h"
#include "common/BasicInstructionHighlighter.h"
#include <QDebug>
#include <QDir>
#include <QErrorMessage>
#include <QMap>
#include <QMenu>
#include <QDebug>
#include <QObject>
#include <QSharedPointer>
#include <QStringList>
#include <QMessageBox>
#include <QErrorMessage>
#include <QMutex>
#include <QDir>
#include <QObject>
#include <QStringList>
#include <functional>
#include <memory>
// #include <memory>
class AsyncTaskManager;
class BasicInstructionHighlighter;
@ -32,9 +33,9 @@ class RizinTaskDialog;
#include "common/BasicBlockHighlighter.h"
#include "common/Helpers.h"
#include <memory>
#include <rz_heap_glibc.h>
#include <rz_project.h>
#include <memory>
#define Core() (CutterCore::instance())
@ -48,12 +49,12 @@ struct CUTTER_EXPORT AddrRefs
QString reg;
QString fcn;
QString type;
QString asm_op;
QString asmOp;
QString perms;
ut64 value;
bool has_value;
bool hasValue;
QString string;
QSharedPointer<AddrRefs> ref;
std::shared_ptr<AddrRefs> ref;
};
struct CUTTER_EXPORT RegisterRef
@ -63,7 +64,7 @@ struct CUTTER_EXPORT RegisterRef
QString name;
};
enum class SearchKind {
enum class SearchKind : ut8 {
AsmCode,
HexString,
ROPGadgets,
@ -79,8 +80,13 @@ enum class SearchKind {
MagicSignature,
};
enum class AddressTypeHint { Function, Code, Data, Unknown };
enum class AddressTypeHint : ut8 { Function, Code, Data, Unknown };
/**
* @brief Core class that talks to rizin.
*
* Prefer the use of this class when functionality from rizin is needed
*/
class CUTTER_EXPORT CutterCore : public QObject
{
Q_OBJECT
@ -101,7 +107,7 @@ public:
AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; }
RVA getOffset() const { return core_->offset; }
RVA getOffset() const { return rzCore->offset; }
/* Core functions (commands) */
/* Almost the same as core_cmd_raw,
@ -123,7 +129,7 @@ public:
* @param fcn the task you want to execute
* @return execute successful?
*/
bool asyncTask(std::function<void *(RzCore *)> fcn, QSharedPointer<RizinTask> &task);
bool asyncTask(std::function<void *(RzCore *)> fcn, std::shared_ptr<RizinTask> &task);
void functionTask(std::function<void *(RzCore *)> fcn);
/**
@ -174,7 +180,7 @@ public:
Core()->seekSilent(returnAddress);
}
}
SeekReturn(SeekReturn &&from)
SeekReturn(SeekReturn &&from) noexcept
{
if (this != &from) {
returnAddress = from.returnAddress;
@ -191,7 +197,7 @@ public:
return returner;
}
enum class SeekHistoryType { New, Undo, Redo };
enum class SeekHistoryType : ut8 { New, Undo, Redo };
CutterJson cmdj(const char *str);
CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
@ -211,7 +217,7 @@ public:
/* Functions methods */
void renameFunction(const RVA offset, const QString &newName);
void delFunction(RVA addr);
void renameFlag(QString old_name, QString new_name);
void renameFlag(const QString &old_name, const QString &new_name);
/**
* @brief Renames the specified local variable in the function specified by the
* address given.
@ -220,7 +226,8 @@ public:
* @param oldName Specifies the current name of the function variable.
* @param functionAddress Specifies the exact address of the function.
*/
void renameFunctionVariable(QString newName, QString oldName, RVA functionAddress);
void renameFunctionVariable(const QString &newName, const QString &oldName,
RVA functionAddress);
/**
* @param addr
@ -234,19 +241,45 @@ public:
*/
RzAnalysisFunction *functionAt(ut64 addr);
/**
* @brief finds the start address of a function in a given address
* @param addr - an address which belongs to a function
* @returns if function exists, return its start address. Otherwise return RVA_INVALID
*/
RVA getFunctionStart(RVA addr);
/**
* @brief finds the end address of a function in a given address
* @param addr - an address which belongs to a function
* @returns if function exists, return its end address. Otherwise return RVA_INVALID
*/
RVA getFunctionEnd(RVA addr);
/**
* @brief finds the last instruction of a function in a given address
* @param addr - an address which belongs to a function
* @returns if function exists, return the address of its last instruction. Otherwise return
* RVA_INVALID
*/
RVA getLastFunctionInstruction(RVA addr);
QString flagAt(RVA addr, bool getClosestFlag = true);
AddressTypeHint getAddressType(RVA addr);
void createFunctionAt(RVA addr);
void createFunctionAt(RVA addr, QString name);
/**
* @brief get a compact disassembly preview for tooltips
* @param address - the address from which to print the disassembly
* @param num_of_lines - number of instructions to print
*/
QStringList getDisassemblyPreview(RVA address, int num_of_lines);
/* Flags */
void delFlag(RVA addr);
void delFlag(const QString &name);
void addFlag(RVA offset, QString name, RVA size);
/**
* @brief Gets all the flags present at a specific address
* @param addr The address to be checked
* @return String containing all the flags which are comma-separated
*/
QString listFlagsAsStringAt(RVA addr);
/**
* @brief Get nearest flag at or before offset.
@ -258,7 +291,8 @@ public:
void triggerFlagsChanged();
/* Marks */
void addMark(RVA from, RVA to, QString name, QString comment = {}, QColor color = {});
void addMark(RVA from, RVA to, const QString &name, const QString &comment = {},
QColor color = {});
void delMark(const QString &name);
QList<MarkDescription> getMarks();
QList<MarkDescription> getMarksAt(RVA addr);
@ -271,10 +305,10 @@ public:
QColor getBlendedMarksColorAt(RVA addr);
/* Global Variables */
void addGlobalVariable(RVA offset, QString name, QString typ);
void addGlobalVariable(RVA offset, QString name, const QString &typ);
void delGlobalVariable(QString name);
void delGlobalVariable(RVA offset);
void modifyGlobalVariable(RVA offset, QString name, QString typ);
void modifyGlobalVariable(RVA offset, QString name, const QString &typ);
QString getGlobalVariableType(QString name);
QString getGlobalVariableType(RVA offset);
@ -290,13 +324,13 @@ public:
/* Code/Data */
void setToCode(RVA addr);
enum class StringTypeFormats { None, ASCII_LATIN1, UTF8 };
enum class StringTypeFormats : ut8 { None, ASCII_LATIN1, UTF8 };
/**
* @brief Adds string at address
* That function calls the 'Cs' command
* \param addr The address of the array where the string will be applied
* \param size The size of string
* \param type The type of string
* @param addr The address of the array where the string will be applied
* @param size The size of string
* @param type The type of string
*/
void setAsString(RVA addr, int size = 0, StringTypeFormats type = StringTypeFormats::None);
/**
@ -308,14 +342,14 @@ public:
/**
* @brief Gets string at address
* That function correspond the 'Cs.' command
* \param addr The address of the string
* @param addr The address of the string
* @return string at requested address
*/
QString getMetaString(RVA addr);
/**
* @brief Gets string at address
* That function calls the 'ps' command
* \param addr The address of the first byte of the array
* @param addr The address of the first byte of the array
* @return string at requested address
*/
QString getString(RVA addr);
@ -326,6 +360,11 @@ public:
/* Comments */
void setComment(RVA addr, const QString &cmt);
void delComment(RVA addr);
/**
* @brief Gets the comment present at a specific address
* @param addr The address to be checked
* @return String containing comment
*/
QString getCommentAt(RVA addr);
void setImmediateBase(const QString &rzBaseName, RVA offset = RVA_INVALID);
void setCurrentBits(int bits, RVA offset = RVA_INVALID);
@ -334,8 +373,8 @@ public:
* @brief Changes immediate displacement to structure offset
* This function makes use of the "aht" command of Rizin to apply structure
* offset to the immediate displacement used in the given instruction
* \param structureOffset The name of struct which will be applied
* \param offset The address of the instruction where the struct will be applied
* @param structureOffset The name of struct which will be applied
* @param offset The address of the instruction where the struct will be applied
*/
void applyStructureOffset(const QString &structureOffset, RVA offset = RVA_INVALID);
@ -354,17 +393,41 @@ public:
void setAnalysisMethod(const QString &cls, const AnalysisMethodDescription &meth);
/* File related methods */
bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = RZ_PERM_R,
/**
* @brief CutterCore::loadFile
* Load initial file.
* @param path File path
* @param baddr Base (RzBin) address
* @param mapaddr Map address
* @param perms
* @param va
* @param loadbin Load RzBin information
* @param forceBinPlugin
* @return
*/
bool loadFile(const QString &path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = RZ_PERM_R,
int va = 0, bool loadbin = false, const QString &forceBinPlugin = QString());
bool tryFile(QString path, bool rw);
bool mapFile(QString path, RVA mapaddr);
bool tryFile(const QString &path, bool rw);
/**
* @brief Maps a file using Rizin API
* @param path Path to file
* @param mapaddr Map Address
* @return bool
*/
bool mapFile(const QString &path, RVA mapaddr);
void loadScript(const QString &scriptname);
/**
* @brief Check whether any file is loaded
* @return True if any file is loaded, false otherwise
*/
bool isFileLoaded();
/* Seek functions */
void seek(QString thing);
void seek(const QString &thing);
void seek(ut64 offset);
void seekSilent(ut64 offset);
void seekSilent(QString thing) { seekSilent(math(thing)); }
void seekSilent(const QString &thing) { seekSilent(math(thing)); }
void seekPrev();
void seekNext();
void updateSeek(SeekHistoryType type = SeekHistoryType::New);
@ -374,15 +437,15 @@ public:
*/
void showMemoryWidget();
/**
* @brief Seek to \p offset and raise a memory widget showing it.
* @brief Seek to @p offset and raise a memory widget showing it.
* @param offset
*/
void seekAndShow(ut64 offset);
/**
* @brief \see CutterCore::show(ut64)
* @brief @see CutterCore::show(ut64)
* @param thing - addressable expression
*/
void seekAndShow(QString thing);
void seekAndShow(const QString &thing);
RVA getOffset();
RVA prevOpAddr(RVA startAddr, int count);
RVA nextOpAddr(RVA startAddr, int count);
@ -426,6 +489,7 @@ public:
QHash<QString, QColor> getTheme();
QStringList getThemeKeys();
bool setColor(const QString &key, const QString &color);
QString getColorNameFromOp(ut32 opType);
QStringList getConfigVariableSpaces(const QString &key = "");
/* Assembly\Hexdump related methods */
@ -436,23 +500,34 @@ public:
static QByteArray hexStringToBytes(const QString &hex);
static QString bytesToHexString(const QByteArray &bytes);
enum class HexdumpFormats { Normal, Half, Word, Quad, Signed, Octal };
enum class HexdumpFormats : ut8 { Normal, Half, Word, Quad, Signed, Octal };
/**
* @brief return hexdump of <size> from an <offset> by a given formats
* @param address - the address from which to print the hexdump
* @param size - number of bytes to print
* @param format - the type of hexdump (qwords, words. decimal, etc)
*/
QString hexdump(RVA offset, int size, HexdumpFormats format);
/**
* @brief get a compact hexdump preview for tooltips
* @param address - the address from which to print the hexdump
* @param size - number of bytes to print
*/
QString getHexdumpPreview(RVA offset, int size);
void setCPU(QString arch, QString cpu, int bits);
void setCPU(const QString &arch, const QString &cpu, int bits);
void setEndianness(bool big);
/* SDB */
QList<QString> sdbList(QString path);
QList<QString> sdbListKeys(QString path);
QString sdbGet(QString path, QString key);
bool sdbSet(QString path, QString key, QString val);
QList<QString> sdbList(const QString &path);
QList<QString> sdbListKeys(const QString &path);
QString sdbGet(const QString &path, const QString &key);
bool sdbSet(const QString &path, const QString &key, const QString &val);
/* Debug */
QString getRegisterName(QString registerRole);
QString getRegisterName(const QString &registerRole);
RVA getProgramCounterValue();
void setRegister(QString regName, QString regValue);
void setRegister(const QString &regName, const QString &regValue);
void setCurrentDebugThread(int tid);
/**
* @brief Attach to a given pid from a debug session
@ -475,7 +550,7 @@ public:
* @brief return a RefDescription with a formatted ref string and configured colors
* @param ref the "ref" JSON node from getAddrRefs
*/
RefDescription formatRefDesc(const QSharedPointer<AddrRefs> &ref);
RefDescription formatRefDesc(const std::shared_ptr<AddrRefs> &ref);
/**
* @brief Get a list of a given process's threads
* @param pid The pid of the process, -1 for the currently debugged process
@ -587,7 +662,7 @@ public:
* @param profilePath Path to the GDB profile
* @return Converted profile string
*/
QString convertGDBProfile(const QString &profilePath);
QString convertGdbProfile(const QString &profilePath);
/**
* @brief Retrieves the current register profile string
@ -601,12 +676,12 @@ public:
QList<RVA> getBreakpointsInFunction(RVA funcAddr);
QString getActiveDebugPlugin();
QStringList getDebugPlugins();
void setDebugPlugin(QString plugin);
void setDebugPlugin(const QString &plugin);
bool isDebugTaskInProgress();
/**
* @brief Check if we can use output/input redirection with the currently debugged process
*/
bool isRedirectableDebugee();
bool isRedirectableDebugee() const;
bool currentlyDebugging = false;
bool currentlyEmulating = false;
bool currentlyTracing = false;
@ -633,7 +708,7 @@ public:
CutterJson getSignatureInfo();
bool existsFileInfo();
void setGraphEmpty(bool empty);
bool isGraphEmpty();
bool isGraphEmpty() const;
void getRegs();
QList<QString> regs;
@ -672,7 +747,7 @@ public:
QList<RelocDescription> getAllRelocs();
QList<StringDescription> getAllStrings();
QList<FlagspaceDescription> getAllFlagspaces();
QList<FlagDescription> getAllFlags(QString flagspace = QString());
QList<FlagDescription> getAllFlags(const QString &flagspace = QString());
QList<SectionDescription> getAllSections();
QList<SegmentDescription> getAllSegments();
QList<EntrypointDescription> getAllEntrypoint();
@ -717,7 +792,7 @@ public:
* @param name - the name or the type of the given Type
* @return The type decleration as C output
*/
QString getTypeAsC(QString name);
QString getTypeAsC(const QString &name);
/**
* @brief Check if a type exists using its name
@ -740,7 +815,7 @@ public:
bool isAddressMapped(RVA addr);
QList<MemoryMapDescription> getMemoryMap();
QList<SearchDescription> getAllSearch(QString searchFor, SearchKind kind, QString in);
QList<SearchDescription> getAllSearch(QString searchFor, SearchKind kind, const QString &in);
QList<BreakpointDescription> getBreakpoints();
/**
* @brief Get list of processes attachable by debugger
@ -776,7 +851,8 @@ public:
* @return A list of XrefDescriptions that contains details of all the writes or reads that
* happen to the variable 'variableName'.
*/
QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset);
QList<XrefDescription> getXRefsForVariable(const QString &variableName, bool findWrites,
RVA offset);
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
const QString &filterType = QString());
/**
@ -849,6 +925,12 @@ public:
*/
bool isWriteModeEnabled();
/**
* @brief Check if there are modified blocks in the IO cache that haven't been saved
* @return true if the cache contains "dirty" (unwritten) data, false otherwise.
*/
bool hasUncommitedChanges();
/**
* @brief Returns the textual version of global or specific graph.
* @param type Graph type, example RZ_CORE_GRAPH_TYPE_FUNCALL or RZ_CORE_GRAPH_TYPE_IMPORT
@ -866,7 +948,8 @@ public:
* RZ_CORE_GRAPH_TYPE_IMPORT
* @param address The object address (if global set it to RVA_INVALID)
*/
void writeGraphvizGraphToFile(QString path, QString format, RzCoreGraphType type, RVA address);
void writeGraphvizGraphToFile(const QString &path, const QString &format, RzCoreGraphType type,
RVA address);
signals:
void refreshAll();
@ -924,10 +1007,10 @@ signals:
/**
* @brief seekChanged is emitted each time Rizin's seek value is modified
* @param offset
* @param historyType
* @param offset Offset to seek at
* @param historyType Type of seek history
*/
void seekChanged(RVA offset, SeekHistoryType type = SeekHistoryType::New);
void seekChanged(RVA offset, CutterCore::SeekHistoryType type = SeekHistoryType::New);
void toggleDebugView();
@ -947,7 +1030,7 @@ private:
* Internal reference to the RzCore.
* NEVER use this directly! Always use the CORE_LOCK(); macro and access it like core->...
*/
RzCore *core_ = nullptr;
RzCore *rzCore = nullptr;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QMutex coreMutex;
#else
@ -967,12 +1050,13 @@ private:
bool iocache = false;
BasicInstructionHighlighter biHighlighter;
QSharedPointer<RizinTask> debugTask;
std::shared_ptr<RizinTask> debugTask;
RizinTaskDialog *debugTaskDialog;
QVector<QString> getCutterRCFilePaths() const;
QList<TypeDescription> getBaseType(RzBaseTypeKind kind, const char *category);
QList<SearchDescription> getAllSearchCommand(QString searchFor, SearchKind kind, QString in);
QList<SearchDescription> getAllSearchCommand(const QString &searchFor, SearchKind kind,
const QString &in);
QList<MarkDescription> convertMarks(RzList *marks);
/**
* @brief Collect cross-references for the specified local variable
@ -994,7 +1078,7 @@ public:
explicit RzCoreLocked(CutterCore *core);
RzCoreLocked(const RzCoreLocked &) = delete;
RzCoreLocked &operator=(const RzCoreLocked &) = delete;
RzCoreLocked(RzCoreLocked &&);
RzCoreLocked(RzCoreLocked &&) noexcept;
~RzCoreLocked();
operator RzCore *() &;
RzCore *operator->() &;

View file

@ -1,13 +1,13 @@
/** \file CutterCommon.h
/** @file CutterCommon.h
* This file contains any definition that is useful in the whole project.
* For example, it may contain custom types (RVA, ut64), list iterators, etc.
*/
#ifndef CUTTERCORE_H
#define CUTTERCORE_H
#include "rz_core.h"
#include "rz_core.h" // IWYU pragma: keep
#include <QString>
#include "RizinCpp.h"
// Workaround for compile errors on Windows
#ifdef Q_OS_WIN
@ -46,19 +46,19 @@ typedef quint64 RVA;
*/
#define RVA_INVALID RVA_MAX
inline QString RzAddressString(RVA addr)
inline QString rzAddressString(RVA addr)
{
return QString::asprintf("%#010" PFMT64x, addr);
return QString::asprintf("%#010llx", static_cast<unsigned long long>(addr));
}
inline QString RzSizeString(RVA size)
inline QString rzSizeString(RVA size)
{
return QString::asprintf("%#" PFMT64x, size);
return QString::asprintf("%#llx", static_cast<unsigned long long>(size));
}
inline QString RzHexString(RVA size)
inline QString rzHexString(RVA size)
{
return QString::asprintf("%#" PFMT64x, size);
return QString::asprintf("%#llx", static_cast<unsigned long long>(size));
}
#ifdef CUTTER_SOURCE_BUILD

View file

@ -1,17 +1,18 @@
/** \file CutterDescriptions.h
/** @file CutterDescriptions.h
* This file contains every structure description that are used in widgets.
* The descriptions are used for the Qt metatypes.
*/
#ifndef DESCRIPTIONS_H
#define DESCRIPTIONS_H
#include <QString>
#include <QList>
#include <QStringList>
#include <QMetaType>
#include <QColor>
#include "core/CutterCommon.h"
#include <QColor>
#include <QList>
#include <QMetaType>
#include <QString>
#include <QStringList>
struct FunctionDescription
{
RVA offset;
@ -49,7 +50,7 @@ struct ExportDescription
RVA size;
QString type;
QString name;
QString flag_name;
QString flagName;
};
struct HeaderDescription
@ -62,14 +63,14 @@ struct HeaderDescription
struct FlirtDescription
{
QString bin_name;
QString arch_name;
QString arch_bits;
QString base_name;
QString short_path;
QString file_path;
QString binName;
QString archName;
QString archBits;
QString baseName;
QString shortPath;
QString filePath;
QString details;
QString n_modules;
QString nModules;
};
struct TypeDescription
@ -168,9 +169,9 @@ struct EntrypointDescription
struct XrefDescription
{
RVA from;
QString from_str;
QString fromStr;
RVA to;
QString to_str;
QString toStr;
QString type;
};
@ -318,7 +319,7 @@ struct MemoryMapDescription
struct BreakpointDescription
{
enum PositionType {
enum PositionType : ut8 {
Address,
Named,
Module,
@ -401,11 +402,11 @@ struct Arena
RVA offset;
QString type;
quint64 top;
quint64 last_remainder;
quint64 lastRemainder;
quint64 next;
quint64 next_free;
quint64 system_mem;
quint64 max_system_mem;
quint64 nextFree;
quint64 systemMem;
quint64 maxSystemMem;
};
struct BasefindCoreStatusDescription

View file

@ -2,7 +2,7 @@
CutterJson CutterJson::last() const
{
if (!has_children()) {
if (!hasChildren()) {
return CutterJson();
}

View file

@ -3,29 +3,34 @@
#include "core/CutterCommon.h"
#include <QSharedPointer>
#include <QString>
#include <QStringList>
#include <memory>
#include <rz_project.h>
#include <utility>
class CutterJsonOwner;
/**
* @brief Cutter wrapper for handling Json
*/
class CUTTER_EXPORT CutterJson
{
public:
class iterator
class Iterator
{
public:
iterator(const RzJson *value, QSharedPointer<CutterJsonOwner> owner)
: value(value), owner(owner)
Iterator(const RzJson *value, std::shared_ptr<CutterJsonOwner> owner)
: value(value), owner(std::move(owner))
{
}
CutterJson operator*() const { return CutterJson(value, owner); }
bool operator!=(const iterator &other) const { return value != other.value; }
bool operator!=(const Iterator &other) const { return value != other.value; }
iterator &operator++()
Iterator &operator++()
{
value = value->next;
return *this;
@ -33,19 +38,19 @@ public:
private:
const RzJson *value;
QSharedPointer<CutterJsonOwner> owner;
std::shared_ptr<CutterJsonOwner> owner;
};
CutterJson() : value(nullptr), owner(nullptr) {}
CutterJson() : value(nullptr) {}
CutterJson(const RzJson *value, QSharedPointer<CutterJsonOwner> owner)
: value(value), owner(owner)
CutterJson(const RzJson *value, std::shared_ptr<CutterJsonOwner> owner)
: value(value), owner(std::move(owner))
{
}
CutterJson first() const
{
return CutterJson(has_children() ? value->children.first : nullptr, owner);
return CutterJson(hasChildren() ? value->children.first : nullptr, owner);
}
CutterJson last() const;
@ -62,12 +67,12 @@ public:
value && value->type == RZ_JSON_OBJECT ? rz_json_get(value, key) : nullptr, owner);
}
iterator begin() const
Iterator begin() const
{
return iterator(has_children() ? value->children.first : nullptr, owner);
return Iterator(hasChildren() ? value->children.first : nullptr, owner);
}
iterator end() const { return iterator(nullptr, nullptr); }
Iterator end() const { return Iterator(nullptr, nullptr); }
bool toBool() const { return value && value->type == RZ_JSON_BOOLEAN && value->num.u_value; }
st64 toSt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.s_value : 0; }
@ -85,19 +90,19 @@ public:
QString key() const { return value ? value->key : QString(); }
QStringList keys() const;
size_t size() const { return has_children() ? value->children.count : 0; }
size_t size() const { return hasChildren() ? value->children.count : 0; }
RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; }
bool valid() const { return value ? true : false; }
const RzJson *lowLevelValue() const { return value; }
private:
bool has_children() const
bool hasChildren() const
{
return value && (value->type == RZ_JSON_OBJECT || value->type == RZ_JSON_ARRAY);
}
const RzJson *value;
QSharedPointer<CutterJsonOwner> owner;
std::shared_ptr<CutterJsonOwner> owner;
};
class CUTTER_EXPORT CutterJsonOwner

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,20 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "core/Cutter.h" // only needed for ut64
// #include "core/Cutter.h" // only needed for ut64
#include "dialogs/NewFileDialog.h"
#include "dialogs/WelcomeDialog.h"
#include "common/Configuration.h"
#include "common/InitialOptions.h"
#include "common/IOModesController.h"
#include "common/CutterLayout.h"
// #include "dialogs/WelcomeDialog.h"
#include "MemoryDockWidget.h"
#include "common/Configuration.h"
#include "common/CutterLayout.h"
#include "common/IOModesController.h"
#include "common/InitialOptions.h"
#include <QList>
#include <QMainWindow>
#include <memory>
#include <QMainWindow>
#include <QList>
class CutterCore;
class Omnibar;
class ProgressIndicator;
@ -61,6 +61,9 @@ namespace Ui {
class MainWindow;
}
/**
* @brief Cutter main window
*/
class CUTTER_EXPORT MainWindow : public QMainWindow
{
Q_OBJECT
@ -73,6 +76,11 @@ public:
void openNewFile(InitialOptions &options, bool skipOptionsDialog = false);
void displayNewFileDialog();
/**
* @brief displays the WelocmeDialog
* Upon first execution of Cutter, the WelcomeDialog would be showed to the user.
* The Welcome dialog would be showed after a reset of Cutter's preferences by the user.
*/
void displayWelcomeDialog();
void closeNewFileDialog();
bool openProject(const QString &project_name);
@ -100,7 +108,7 @@ public:
addPluginDockWidget(dockWidget);
}
void addPluginDockWidget(CutterDockWidget *dockWidget);
enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
enum class MenuType : ut8 { File, Edit, View, Windows, Debug, Help, Plugins };
/**
* @brief Getter for MainWindow's different menus
* @param type The type which represents the desired menu
@ -110,7 +118,11 @@ public:
void addMenuFileAction(QAction *action);
QString getFilename() const { return filename; }
void messageBoxWarning(QString title, QString message);
/**
* @brief Show a warning message box.
* This API can either be used in Cutter internals, or by Python plugins.
*/
void messageBoxWarning(const QString &title, const QString &message);
QString getUniqueObjectName(const QString &widgetType) const;
void showMemoryWidget();
@ -123,7 +135,7 @@ public:
bool synchronized = true);
/* Context menu plugins */
enum class ContextMenuType { Disassembly, Addressable };
enum class ContextMenuType : ut8 { Disassembly, Addressable };
/**
* @brief Fetches the pointer to a context menu extension of type
* @param type - the type of the context menu
@ -140,13 +152,16 @@ public slots:
void seekToFunctionStart();
void setTabLocation();
void on_actionTabs_triggered();
void onActionTabsTriggered();
void on_actionAnalyze_triggered();
/**
* @brief A signal that creates an AsyncTask to re-analyze the current file
*/
void onActionAnalyzeTriggered() const;
void lockDocks(bool lock);
void on_actionRun_Script_triggered();
void onActionRunScriptTriggered();
void toggleResponsive(bool maybe);
@ -154,50 +169,58 @@ public slots:
void toggleOverview(bool visibility, GraphWidget *targetGraph);
private slots:
void on_actionBaseFind_triggered();
void on_actionAbout_triggered();
void on_actionIssue_triggered();
void onActionBaseFindTriggered();
void onActionAboutTriggered();
void onActionIssueTriggered();
void documentationClicked();
void addExtraGraph();
void addExtraHexdump();
void addExtraDisassembly();
void addExtraDecompiler();
void on_actionRefresh_Panels_triggered();
void onActionRefreshPanelsTriggered();
void on_actionDisasAdd_comment_triggered();
void onActionDisasAddCommentTriggered();
void on_actionDefault_triggered();
void onActionDefaultTriggered();
void on_actionNew_triggered();
/**
* @brief MainWindow::on_actionNew_triggered
* Open a new Cutter session.
*/
void onActionNewTriggered();
void on_actionSave_triggered();
void on_actionSaveAs_triggered();
void onActionSaveTriggered();
void onActionSaveAsTriggered();
void on_actionBackward_triggered();
void on_actionForward_triggered();
void onActionBackwardTriggered();
void onActionForwardTriggered();
void on_actionMap_triggered();
/**
* @brief MainWindow::on_actionOpen_triggered
* Open a file as in "load (add) a file in current session".
*/
void onActionMapTriggered();
void on_actionTabs_on_Top_triggered();
void onActionTabsOnTopTriggered();
void on_actionReset_settings_triggered();
void onActionResetSettingsTriggered();
void on_actionQuit_triggered();
void onActionQuitTriggered();
void on_actionRefresh_contents_triggered();
void onActionRefreshContentsTriggered();
void on_actionPreferences_triggered();
void onActionPreferencesTriggered();
void on_actionImportPDB_triggered();
void onActionImportPdbTriggered();
void on_actionExport_as_code_triggered();
void onActionExportAsCodeTriggered();
void on_actionApplySigFromFile_triggered();
void onActionApplySigFromFileTriggered();
void on_actionCreateNewSig_triggered();
void onActionCreateNewSigTriggered();
void on_actionGrouped_dock_dragging_triggered(bool checked);
void onActionGroupedDockDraggingTriggered(bool checked);
void updateTasksIndicator();
@ -205,6 +228,9 @@ private slots:
bool eventFilter(QObject *object, QEvent *event) override;
bool event(QEvent *event) override;
void toggleDebugView();
/**
* @brief When theme changed, change icons which have a special version for the theme.
*/
void chooseThemeIcons();
void onZoomIn();
@ -301,7 +327,7 @@ private:
void enableDebugWidgetsMenu(bool enable);
/**
* @brief Fill menu with seek history entries.
* @param menu
* @param menu Menu to update
* @param redo set to false for undo history, true for redo.
*/
void updateHistoryMenu(QMenu *menu, bool redo = false);
@ -313,7 +339,7 @@ private:
bool isOverviewActive();
/**
* @brief Check if a widget is one of debug specific dock widgets.
* @param dock
* @param dock DockWidget to check
* @return true for debug specific widgets, false for all other including common dock widgets.
*/
bool isDebugWidget(QDockWidget *dock) const;

View file

@ -53,8 +53,8 @@
<rect>
<x>2024</x>
<y>127</y>
<width>151</width>
<height>312</height>
<width>196</width>
<height>389</height>
</rect>
</property>
<property name="title">
@ -74,7 +74,7 @@
<addaction name="actionNew"/>
<addaction name="actionMap"/>
<addaction name="separator"/>
<addaction name="actionImportPDB"/>
<addaction name="actionImportPdb"/>
<addaction name="actionAnalyze"/>
<addaction name="separator"/>
<addaction name="actionApplySigFromFile"/>
@ -85,9 +85,9 @@
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="actionExport_as_code"/>
<addaction name="actionExportAsCode"/>
<addaction name="separator"/>
<addaction name="actionRun_Script"/>
<addaction name="actionRunScript"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
<addaction name="separator"/>
@ -113,14 +113,14 @@
<string>Layouts</string>
</property>
</widget>
<addaction name="actionRefresh_contents"/>
<addaction name="actionRefreshContents"/>
<addaction name="separator"/>
<addaction name="actionDefault"/>
<addaction name="actionReset_settings"/>
<addaction name="actionDefaultLayout"/>
<addaction name="actionResetSettings"/>
<addaction name="separator"/>
<addaction name="actionUnlock"/>
<addaction name="actionTabs_on_Top"/>
<addaction name="actionGrouped_dock_dragging"/>
<addaction name="actionTabsOnTop"/>
<addaction name="actionGroupedDockDragging"/>
<addaction name="separator"/>
<addaction name="menuZoom"/>
<addaction name="separator"/>
@ -201,7 +201,7 @@
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
<enum>Qt::ContextMenuPolicy::DefaultContextMenu</enum>
</property>
<property name="windowTitle">
<string>Main toolbar</string>
@ -216,7 +216,7 @@
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
<enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
@ -227,7 +227,7 @@
<addaction name="actionBackward"/>
<addaction name="actionForward"/>
</widget>
<action name="actionDefault">
<action name="actionDefaultLayout">
<property name="text">
<string>Reset to default layout</string>
</property>
@ -268,7 +268,7 @@
<string>Close</string>
</property>
</action>
<action name="actionSave_workspace">
<action name="actionSaveWorkspace">
<property name="text">
<string>Save layout</string>
</property>
@ -317,7 +317,7 @@
<string>Delete</string>
</property>
</action>
<action name="actionSelect_all">
<action name="actionSelectAll">
<property name="text">
<string>Select all</string>
</property>
@ -330,7 +330,7 @@
<string>Find</string>
</property>
</action>
<action name="actionFind_next">
<action name="actionFindNext">
<property name="text">
<string>Find next</string>
</property>
@ -338,7 +338,7 @@
<string>Find next</string>
</property>
</action>
<action name="actionFind_previous">
<action name="actionFindPrevious">
<property name="text">
<string>Find previous</string>
</property>
@ -348,7 +348,7 @@
</action>
<action name="actionBackward">
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/arrow_left.svg</normaloff>:/img/icons/arrow_left.svg</iconset>
</property>
<property name="text">
@ -360,7 +360,7 @@
</action>
<action name="actionForward">
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/arrow_right.svg</normaloff>:/img/icons/arrow_right.svg</iconset>
</property>
<property name="text">
@ -374,16 +374,17 @@
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/lock</normaloff>
<normalon>:/unlock</normalon>:/lock</iconset>
</property>
<property name="text">
<string>Unlock Panels</string>
</property>
<property name="toolTip">
<string>Toggle panel locks</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/lock</normaloff><normalon>:/unlock</normalon>:/unlock</iconset>
</property>
<property name="iconVisibleInMenu">
<bool>false</bool>
</property>
@ -393,7 +394,7 @@
<bool>false</bool>
</property>
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/themes.svg</normaloff>:/img/icons/themes.svg</iconset>
</property>
<property name="text">
@ -403,12 +404,12 @@
<bool>false</bool>
</property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
<enum>QAction::MenuRole::PreferencesRole</enum>
</property>
</action>
<action name="actionTabs">
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/tabs.svg</normaloff>:/img/icons/tabs.svg</iconset>
</property>
<property name="text">
@ -418,16 +419,16 @@
<string>Tabs up/down</string>
</property>
</action>
<action name="actionRefresh_Panels">
<action name="actionRefreshPanels">
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/spin.svg</normaloff>:/img/icons/spin.svg</iconset>
</property>
<property name="text">
<string>Refresh</string>
</property>
</action>
<action name="actionTabs_on_Top">
<action name="actionTabsOnTop">
<property name="checkable">
<bool>true</bool>
</property>
@ -438,12 +439,12 @@
<string>Toggle tab position</string>
</property>
</action>
<action name="actionDark_Theme">
<action name="actionDarkTheme">
<property name="text">
<string>Dark Theme</string>
</property>
</action>
<action name="actionLoad_workspace">
<action name="actionLoadWorkspace">
<property name="text">
<string>Load layout</string>
</property>
@ -451,7 +452,7 @@
<string>Load layout</string>
</property>
</action>
<action name="actionWhite_Theme">
<action name="actionWhiteTheme">
<property name="text">
<string>Default Theme</string>
</property>
@ -466,12 +467,12 @@
<string>Analysis</string>
</property>
</action>
<action name="actionTest_menu">
<action name="actionTestMenu">
<property name="text">
<string>Test menu</string>
</property>
</action>
<action name="actionHexCopy_Hexpair">
<action name="actionHexCopyHexpair">
<property name="text">
<string>Copy hexpair</string>
</property>
@ -479,7 +480,7 @@
<string>Copy hexpair</string>
</property>
</action>
<action name="actionHexCopy_Text">
<action name="actionHexCopyText">
<property name="text">
<string>Copy text</string>
</property>
@ -487,12 +488,12 @@
<string>Copy text</string>
</property>
</action>
<action name="actionHexCopy_ASCII">
<action name="actionHexCopyAscii">
<property name="text">
<string>Copy ASCII</string>
</property>
</action>
<action name="actionHexInsert_String">
<action name="actionHexInsertString">
<property name="text">
<string>Insert string</string>
</property>
@ -500,7 +501,7 @@
<string>Insert string</string>
</property>
</action>
<action name="actionHexInsert_Hex">
<action name="actionHexInsertHex">
<property name="text">
<string>Insert hex</string>
</property>
@ -518,17 +519,17 @@
<string>Paste</string>
</property>
</action>
<action name="actionDisas_ShowHideBytes">
<action name="actionDisasShowHideBytes">
<property name="text">
<string>Show/Hide bytes</string>
</property>
</action>
<action name="actionDisasSwitch_case">
<action name="actionDisasSwitchCase">
<property name="text">
<string>Switch case</string>
</property>
</action>
<action name="actionDisasCopy_All">
<action name="actionDisasCopyAll">
<property name="text">
<string>Copy all</string>
</property>
@ -536,7 +537,7 @@
<string>Copy all</string>
</property>
</action>
<action name="actionDisasCopy_Bytes">
<action name="actionDisasCopyBytes">
<property name="text">
<string>Copy bytes</string>
</property>
@ -544,7 +545,7 @@
<string>Copy bytes</string>
</property>
</action>
<action name="actionDisasCopy_Disasm">
<action name="actionDisasCopyDisasm">
<property name="text">
<string>Copy disasm</string>
</property>
@ -560,12 +561,12 @@
<string>Copy disasm</string>
</property>
</action>
<action name="actionStart_Web_Server">
<action name="actionStartWebServer">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/cloud.svg</normaloff>:/img/icons/cloud.svg</iconset>
</property>
<property name="text">
@ -610,7 +611,7 @@
<string>64</string>
</property>
</action>
<action name="actionSyntax_AT_T_Intel">
<action name="actionSyntaxATTIntel">
<property name="text">
<string>Syntax AT&amp;T/Intel</string>
</property>
@ -635,17 +636,17 @@
<string>Undefine</string>
</property>
</action>
<action name="actionDisasAdd_comment">
<action name="actionDisasAddComment">
<property name="text">
<string>Add comment</string>
</property>
</action>
<action name="actionhide_bottomPannel">
<action name="actionhideBottomPannel">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset>
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/down.svg</normaloff>:/img/icons/down.svg</iconset>
</property>
<property name="text">
@ -655,12 +656,12 @@
<string>Show/Hide bottom panel</string>
</property>
</action>
<action name="actionRun_Script">
<action name="actionRunScript">
<property name="text">
<string>Run Rizin script</string>
</property>
</action>
<action name="actionReset_settings">
<action name="actionResetSettings">
<property name="text">
<string>Reset Settings</string>
</property>
@ -687,7 +688,7 @@
<string>Show/Hide Exports panel</string>
</property>
</action>
<action name="actionRefresh_contents">
<action name="actionRefreshContents">
<property name="text">
<string>Refresh Contents</string>
</property>
@ -695,7 +696,7 @@
<string>Refresh contents</string>
</property>
</action>
<action name="actionDisplay_Esil">
<action name="actionDisplayEsil">
<property name="checkable">
<bool>true</bool>
</property>
@ -703,7 +704,7 @@
<string>Show ESIL rather than assembly</string>
</property>
</action>
<action name="actionDisplay_Decompiler">
<action name="actionDisplayDecompiler">
<property name="checkable">
<bool>true</bool>
</property>
@ -711,7 +712,7 @@
<string>Show pseudocode rather than assembly</string>
</property>
</action>
<action name="actionDisplay_Offsets">
<action name="actionDisplayOffsets">
<property name="checkable">
<bool>true</bool>
</property>
@ -740,7 +741,7 @@
<string>Graph</string>
</property>
</action>
<action name="actionImportPDB">
<action name="actionImportPdb">
<property name="text">
<string>Import PDB</string>
</property>
@ -750,7 +751,7 @@
<string>Analyze Program</string>
</property>
</action>
<action name="actionExport_as_code">
<action name="actionExportAsCode">
<property name="text">
<string>Export as code</string>
</property>
@ -785,7 +786,7 @@
<string>Add Graph</string>
</property>
</action>
<action name="actionGrouped_dock_dragging">
<action name="actionGroupedDockDragging">
<property name="checkable">
<bool>true</bool>
</property>
@ -804,7 +805,7 @@
<string>Ctrl++</string>
</property>
<property name="shortcutContext">
<enum>Qt::ApplicationShortcut</enum>
<enum>Qt::ShortcutContext::ApplicationShortcut</enum>
</property>
</action>
<action name="actionZoomOut">
@ -815,7 +816,7 @@
<string>Ctrl+-</string>
</property>
<property name="shortcutContext">
<enum>Qt::ApplicationShortcut</enum>
<enum>Qt::ShortcutContext::ApplicationShortcut</enum>
</property>
</action>
<action name="actionZoomReset">
@ -826,7 +827,7 @@
<string>Ctrl+=</string>
</property>
<property name="shortcutContext">
<enum>Qt::ApplicationShortcut</enum>
<enum>Qt::ShortcutContext::ApplicationShortcut</enum>
</property>
</action>
<action name="actionCommitChanges">
@ -880,7 +881,7 @@
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="resources.qrc"/>
<include location="../resources.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -1,4 +1,4 @@
/** \file RizinCpp.h
/** @file RizinCpp.h
* Various utilities for easier and safer interactions with Rizin
* from C++ code.
*/
@ -6,7 +6,9 @@
#define RIZINCPP_H
#include "rz_core.h"
#include <QString>
#include <memory>
static inline QString fromOwnedCharPtr(char *str)
@ -59,9 +61,9 @@ static inline auto fromOwned(RZ_OWN RzList *data) -> UniquePtrCP<decltype(data),
#define CutterRzVectorForeach(vec, it, type) \
if ((vec) && (vec)->a) \
for (it = (type *)(vec)->a; \
(char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); \
it = (type *)((char *)it + (vec)->elem_size))
for (it = static_cast<type *>((vec)->a); reinterpret_cast<char *>(it) \
!= static_cast<char *>((vec)->a) + ((vec)->len * (vec)->elem_size); \
it = reinterpret_cast<type *>(reinterpret_cast<char *>(it) + (vec)->elem_size))
template<typename T>
class CutterPVector
@ -70,7 +72,7 @@ private:
const RzPVector *const vec;
public:
class iterator
class Iterator
{
public:
using iterator_category = std::input_iterator_tag;
@ -83,27 +85,27 @@ public:
T **p;
public:
iterator(T **p) : p(p) {}
iterator(const iterator &o) : p(o.p) {}
iterator &operator++()
Iterator(T **p) : p(p) {}
Iterator(const Iterator &o) : p(o.p) {}
Iterator &operator++()
{
p++;
return *this;
}
iterator operator++(int)
Iterator operator++(int)
{
iterator tmp(*this);
Iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const iterator &rhs) const { return p == rhs.p; }
bool operator!=(const iterator &rhs) const { return p != rhs.p; }
bool operator==(const Iterator &rhs) const { return p == rhs.p; }
bool operator!=(const Iterator &rhs) const { return p != rhs.p; }
T *operator*() { return *p; }
};
CutterPVector(const RzPVector *vec) : vec(vec) {}
iterator begin() const { return iterator(reinterpret_cast<T **>(vec->v.a)); }
iterator end() const { return iterator(reinterpret_cast<T **>(vec->v.a) + vec->v.len); }
Iterator begin() const { return Iterator(reinterpret_cast<T **>(vec->v.a)); }
Iterator end() const { return Iterator(reinterpret_cast<T **>(vec->v.a) + vec->v.len); }
};
template<typename T>
@ -113,7 +115,7 @@ private:
const RzList *const list;
public:
class iterator
class Iterator
{
public:
using iterator_category = std::input_iterator_tag;
@ -126,9 +128,9 @@ public:
RzListIter *iter;
public:
explicit iterator(RzListIter *iter) : iter(iter) {}
iterator(const iterator &o) : iter(o.iter) {}
iterator &operator++()
explicit Iterator(RzListIter *iter) : iter(iter) {}
Iterator(const Iterator &o) : iter(o.iter) {}
Iterator &operator++()
{
if (!iter) {
return *this;
@ -136,14 +138,14 @@ public:
iter = iter->next;
return *this;
}
iterator operator++(int)
Iterator operator++(int)
{
iterator tmp(*this);
Iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const iterator &rhs) const { return iter == rhs.iter; }
bool operator!=(const iterator &rhs) const { return iter != rhs.iter; }
bool operator==(const Iterator &rhs) const { return iter == rhs.iter; }
bool operator!=(const Iterator &rhs) const { return iter != rhs.iter; }
T *operator*()
{
if (!iter) {
@ -154,14 +156,14 @@ public:
};
explicit CutterRzList(const RzList *l) : list(l) {}
iterator begin() const
Iterator begin() const
{
if (!list) {
return iterator(nullptr);
return Iterator(nullptr);
}
return iterator(list->head);
return Iterator(list->head);
}
iterator end() const { return iterator(nullptr); }
Iterator end() const { return Iterator(nullptr); }
};
template<typename T>

View file

@ -1,22 +1,22 @@
#include "core/Cutter.h"
#include "AboutDialog.h"
#include "ui_AboutDialog.h"
#include "CutterConfig.h"
#include "RizinPluginsDialog.h"
#include "common/Configuration.h"
#include "common/BugReporting.h"
#include "common/Configuration.h"
#include "core/Cutter.h"
#include "ui_AboutDialog.h"
#include <QUrl>
#include <QTimer>
#include <QEventLoop>
#include <QJsonObject>
#include <QProgressBar>
#include <QProgressDialog>
#include <UpdateWorker.h>
#include <QtNetwork/QNetworkRequest>
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include "CutterConfig.h"
#include <UpdateWorker.h>
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
{
@ -24,7 +24,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
ui->logoSvgWidget->load(Config()->getLogoFile());
QString aboutString(
const QString aboutString(
tr("Version") + " " CUTTER_VERSION_FULL "<br/>" + tr("Using rizin ")
+ Core()->getRizinVersionReadable() + "<br/>" + buildQtVersionString() + "<p><b>"
+ tr("Optional Features:") + "</b><br/>"
@ -55,23 +55,42 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
"page</a> for the full list of contributors."));
ui->label->setText(aboutString);
QSignalBlocker s(ui->updatesCheckBox);
const QSignalBlocker s(ui->updatesCheckBox);
ui->updatesCheckBox->setChecked(Config()->getAutoUpdateEnabled());
if (!CUTTER_UPDATE_WORKER_AVAILABLE) {
ui->updatesCheckBox->hide();
ui->checkForUpdatesButton->hide();
}
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &AboutDialog::onButtonBoxRejected);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(ui->showVersionButton, &QPushButton::clicked, this,
&AboutDialog::onShowVersionButtonClicked);
connect(ui->showPluginsButton, &QPushButton::clicked, this,
&AboutDialog::onShowPluginsButtonClicked);
connect(ui->issueButton, &QPushButton::clicked, this, &AboutDialog::onIssueClicked);
connect(ui->checkForUpdatesButton, &QPushButton::clicked, this,
&AboutDialog::onCheckForUpdatesButtonClicked);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
connect(ui->updatesCheckBox, &QCheckBox::checkStateChanged, this,
&AboutDialog::onUpdatesCheckBoxStateChanged);
#else
connect(ui->updatesCheckBox, &QCheckBox::stateChanged, this,
&AboutDialog::onUpdatesCheckBoxStateChanged);
#endif
}
AboutDialog::~AboutDialog() {}
void AboutDialog::on_buttonBox_rejected()
void AboutDialog::onButtonBoxRejected()
{
close();
}
void AboutDialog::on_showVersionButton_clicked()
void AboutDialog::onShowVersionButtonClicked()
{
QMessageBox popup(this);
popup.setWindowTitle(tr("Rizin version information"));
@ -81,17 +100,17 @@ void AboutDialog::on_showVersionButton_clicked()
popup.exec();
}
void AboutDialog::on_showPluginsButton_clicked()
void AboutDialog::onShowPluginsButtonClicked()
{
RizinPluginsDialog dialog(this);
dialog.exec();
}
void AboutDialog::on_Issue_clicked()
void AboutDialog::onIssueClicked()
{
openIssue();
}
void AboutDialog::on_checkForUpdatesButton_clicked()
void AboutDialog::onCheckForUpdatesButtonClicked()
{
#if CUTTER_UPDATE_WORKER_AVAILABLE
UpdateWorker updateWorker;
@ -99,7 +118,7 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
auto parentWindow = this;
QProgressDialog waitDialog(parentWindow);
QProgressBar *bar = new QProgressBar(&waitDialog);
auto *bar = new QProgressBar(&waitDialog);
bar->setMaximum(0);
waitDialog.setBar(bar);
@ -125,7 +144,7 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
#endif
}
void AboutDialog::on_updatesCheckBox_stateChanged(int)
void AboutDialog::onUpdatesCheckBoxStateChanged(int)
{
Config()->setAutoUpdateEnabled(!Config()->getAutoUpdateEnabled());
}
@ -133,7 +152,7 @@ void AboutDialog::on_updatesCheckBox_stateChanged(int)
static QString compilerString()
{
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
QString isAppleString;
QString isAppleString; // NOLINT
# if defined(__apple_build_version__) // Apple clang has other version numbers
isAppleString = QLatin1String(" (Apple)");
# endif
@ -142,12 +161,15 @@ static QString compilerString()
#elif defined(Q_CC_GNU)
return QLatin1String("GCC ") + QLatin1String(__VERSION__);
#elif defined(Q_CC_MSVC)
if (_MSC_VER > 1999)
if (_MSC_VER > 1999) {
return QLatin1String("MSVC <unknown>");
if (_MSC_VER >= 1910)
}
if (_MSC_VER >= 1910) {
return QLatin1String("MSVC 2017");
if (_MSC_VER >= 1900)
}
if (_MSC_VER >= 1900) {
return QLatin1String("MSVC 2015");
}
#endif
return QLatin1String("<unknown compiler>");
}

View file

@ -2,13 +2,17 @@
#define ABOUTDIALOG_H
#include <QDialog>
#include <memory>
#include <QtNetwork/QNetworkReply>
#include <memory>
namespace Ui {
class AboutDialog;
}
/**
* @brief Dialog that displays memory allocation details and offsets for a specific Arena.
*/
class AboutDialog : public QDialog
{
Q_OBJECT
@ -18,24 +22,20 @@ public:
~AboutDialog();
private slots:
void on_buttonBox_rejected();
void on_showVersionButton_clicked();
void on_showPluginsButton_clicked();
void on_Issue_clicked();
void onButtonBoxRejected();
void onShowVersionButtonClicked();
void onShowPluginsButtonClicked();
void onIssueClicked();
/**
* @fn AboutDialog::on_checkForUpdatesButton_clicked()
*
* @brief Initiates process of checking for updates.
*/
void on_checkForUpdatesButton_clicked();
void onCheckForUpdatesButtonClicked();
/**
* @fn AboutDialog::on_updatesCheckBox_stateChanged(int state)
*
* @brief Changes value of autoUpdateEnabled option in settings.
*/
void on_updatesCheckBox_stateChanged(int state);
void onUpdatesCheckBoxStateChanged(int state);
private:
std::unique_ptr<Ui::AboutDialog> ui;

View file

@ -17,7 +17,7 @@
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -30,7 +30,7 @@
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
<set>QDialogButtonBox::StandardButton::Close</set>
</property>
</widget>
</item>
@ -68,7 +68,7 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="4" alignment="Qt::AlignHCenter">
<item row="2" column="1" colspan="4" alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -81,7 +81,7 @@
</property>
</widget>
</item>
<item row="1" column="2" colspan="2" alignment="Qt::AlignHCenter">
<item row="1" column="2" colspan="2" alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:28pt; font-weight:600;&quot;&gt;Cutter&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -89,7 +89,7 @@
</widget>
</item>
<item row="3" column="4">
<widget class="QPushButton" name="Issue">
<widget class="QPushButton" name="issueButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
@ -144,7 +144,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="margin">
<number>5</number>
@ -153,11 +153,11 @@
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignHCenter">
<item row="0" column="0" alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QSvgWidget" name="logoSvgWidget" native="true">
<property name="enabled">
<bool>true</bool>
@ -181,10 +181,10 @@
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
<enum>Qt::ContextMenuPolicy::DefaultContextMenu</enum>
</property>
<property name="toolTipDuration">
<number>0</number>

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