mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 10:56:11 +00:00
Changing coding style
This commit is contained in:
parent
b06725e1d3
commit
3cd71f75e1
@ -35,10 +35,14 @@ Make sure to connect the `CutterCore::seekChanged(RVA offset)` signal so your wi
|
||||
|
||||
### Code formatting
|
||||
|
||||
We use [AStyle 2.06](https://sourceforge.net/projects/astyle/files/astyle/astyle%202.06/) to format the code. The command line for formatting the code according to the style is:
|
||||
We follow [these guidelines](https://wiki.qt.io/Qt_Coding_Style) to format the code.
|
||||
If in doubt, you can use [AStyle 2.06](https://sourceforge.net/projects/astyle/files/astyle/astyle%202.06/) to format the code. The command line for formatting the code according to the style is:
|
||||
|
||||
```bash
|
||||
AStyle --style=allman --convert-tabs --align-pointer=name --align-reference=name --indent=spaces --indent-namespaces --indent-col1-comments --pad-oper --pad-header --unpad-paren --keep-one-line-blocks --close-templates $(git ls-files *.cpp *.h *.c *.hpp)
|
||||
astyle --style=kr --indent=spaces=4 --align-pointer=name --align-reference=name --convert-tabs --attach-namespaces --max-code-length=100 --max-instatement-indent=120 --pad-header --pad-oper filename.cpp
|
||||
```
|
||||
|
||||
**If in doubt, check the source around you and follow that style!**
|
||||
### Functions documentation
|
||||
|
||||
It's good to add some documentation to your functions when needed. To do so we follow these [rules](http://doc.qt.io/qt-5/qdoc-guide-writing.html).
|
||||
|
||||
|
@ -16,8 +16,7 @@ AnalThread::AnalThread(OptionsDialog *parent) :
|
||||
|
||||
AnalThread::~AnalThread()
|
||||
{
|
||||
if (isRunning())
|
||||
{
|
||||
if (isRunning()) {
|
||||
quit();
|
||||
wait();
|
||||
}
|
||||
@ -36,8 +35,7 @@ void AnalThread::interruptAndWait()
|
||||
{
|
||||
interrupted = true;
|
||||
|
||||
while(isRunning())
|
||||
{
|
||||
while (isRunning()) {
|
||||
r_cons_singleton()->breaked = true;
|
||||
r_sys_usleep(10000);
|
||||
}
|
||||
@ -58,25 +56,22 @@ void AnalThread::run()
|
||||
// Advanced Options
|
||||
//
|
||||
|
||||
core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits());
|
||||
core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(),
|
||||
optionsDialog->getSelectedBits());
|
||||
|
||||
int perms = R_IO_READ | R_IO_EXEC;
|
||||
if (ui->writeCheckBox->isChecked())
|
||||
perms |= R_IO_WRITE;
|
||||
bool loadBinInfo = !ui->binCheckBox->isChecked();
|
||||
|
||||
if (loadBinInfo)
|
||||
{
|
||||
if (!va)
|
||||
{
|
||||
if (loadBinInfo) {
|
||||
if (!va) {
|
||||
va = 2;
|
||||
loadaddr = UT64_MAX;
|
||||
r_config_set_i(core->core()->config, "bin.laddr", loadaddr);
|
||||
mapaddr = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Core()->setConfig("file.info", "false");
|
||||
va = false;
|
||||
loadaddr = mapaddr = 0;
|
||||
@ -88,8 +83,7 @@ void AnalThread::run()
|
||||
|
||||
QString forceBinPlugin = nullptr;
|
||||
QVariant forceBinPluginData = ui->formatComboBox->currentData();
|
||||
if (!forceBinPluginData.isNull())
|
||||
{
|
||||
if (!forceBinPluginData.isNull()) {
|
||||
RBinPluginDescription pluginDesc = forceBinPluginData.value<RBinPluginDescription>();
|
||||
forceBinPlugin = pluginDesc.name;
|
||||
}
|
||||
@ -97,25 +91,22 @@ void AnalThread::run()
|
||||
core->setConfig("bin.demangle", ui->demangleCheckBox->isChecked());
|
||||
|
||||
QJsonArray openedFiles = Core()->getOpenedFiles();
|
||||
if (!openedFiles.size())
|
||||
{
|
||||
core->loadFile(main->getFilename(), loadaddr, mapaddr, perms, va, binidx, loadBinInfo, forceBinPlugin);
|
||||
if (!openedFiles.size()) {
|
||||
core->loadFile(main->getFilename(), loadaddr, mapaddr, perms, va, binidx, loadBinInfo,
|
||||
forceBinPlugin);
|
||||
}
|
||||
emit updateProgress("Analysis in progress.");
|
||||
|
||||
QString os = optionsDialog->getSelectedOS();
|
||||
if (!os.isNull())
|
||||
{
|
||||
if (!os.isNull()) {
|
||||
core->cmd("e asm.os=" + os);
|
||||
}
|
||||
|
||||
if (ui->pdbCheckBox->isChecked())
|
||||
{
|
||||
if (ui->pdbCheckBox->isChecked()) {
|
||||
core->loadPDB(ui->pdbLineEdit->text());
|
||||
}
|
||||
|
||||
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto)
|
||||
{
|
||||
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto) {
|
||||
core->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,10 @@ public:
|
||||
void start(MainWindow *main, int level, QList<QString> advanced);
|
||||
void interruptAndWait();
|
||||
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isInterrupted()
|
||||
{
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
282
src/Cutter.cpp
282
src/Cutter.cpp
@ -67,12 +67,10 @@ QList<QString> CutterCore::sdbList(QString path)
|
||||
CORE_LOCK();
|
||||
QList<QString> list = QList<QString>();
|
||||
Sdb *root = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
|
||||
if (root)
|
||||
{
|
||||
if (root) {
|
||||
void *vsi;
|
||||
ls_iter_t *iter;
|
||||
ls_foreach(root->ns, iter, vsi)
|
||||
{
|
||||
ls_foreach(root->ns, iter, vsi) {
|
||||
SdbNs *nsi = (SdbNs *)vsi;
|
||||
list << nsi->name;
|
||||
}
|
||||
@ -85,13 +83,11 @@ QList<QString> CutterCore::sdbListKeys(QString path)
|
||||
CORE_LOCK();
|
||||
QList<QString> list = QList<QString>();
|
||||
Sdb *root = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
|
||||
if (root)
|
||||
{
|
||||
if (root) {
|
||||
void *vsi;
|
||||
ls_iter_t *iter;
|
||||
SdbList *l = sdb_foreach_list(root, false);
|
||||
ls_foreach(l, iter, vsi)
|
||||
{
|
||||
ls_foreach(l, iter, vsi) {
|
||||
SdbKv *nsi = (SdbKv *)vsi;
|
||||
list << nsi->key;
|
||||
}
|
||||
@ -103,8 +99,7 @@ QString CutterCore::sdbGet(QString path, QString key)
|
||||
{
|
||||
CORE_LOCK();
|
||||
Sdb *db = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
|
||||
if (db)
|
||||
{
|
||||
if (db) {
|
||||
const char *val = sdb_const_get(db, key.toUtf8().constData(), 0);
|
||||
if (val && *val)
|
||||
return val;
|
||||
@ -147,13 +142,11 @@ QString CutterCore::cmd(const QString &str)
|
||||
char *res = r_core_cmd_str(this->core_, cmd.constData());
|
||||
QString o = QString(res ? res : "");
|
||||
r_mem_free(res);
|
||||
if (offset != core_->offset)
|
||||
{
|
||||
if (offset != core_->offset) {
|
||||
emit seekChanged(core_->offset);
|
||||
|
||||
// Switch from graph to disassembly if there is no function
|
||||
if (this->cmd("afi.").trimmed().isEmpty() && memoryWidgetPriority == MemoryWidgetType::Graph)
|
||||
{
|
||||
if (this->cmd("afi.").trimmed().isEmpty() && memoryWidgetPriority == MemoryWidgetType::Graph) {
|
||||
memoryWidgetPriority = MemoryWidgetType::Disassembly;
|
||||
}
|
||||
|
||||
@ -178,8 +171,7 @@ QJsonDocument CutterCore::cmdj(const QString &str)
|
||||
|
||||
QString resString = QString(res);
|
||||
|
||||
if (resString.isEmpty())
|
||||
{
|
||||
if (resString.isEmpty()) {
|
||||
r_mem_free(res);
|
||||
return QJsonDocument();
|
||||
}
|
||||
@ -187,9 +179,9 @@ QJsonDocument CutterCore::cmdj(const QString &str)
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument doc = res ? QJsonDocument::fromJson(resString.toUtf8(), &jsonError) : QJsonDocument();
|
||||
|
||||
if (jsonError.error != QJsonParseError::NoError)
|
||||
{
|
||||
eprintf("Failed to parse JSON for command \"%s\": %s\n", str.toLocal8Bit().constData(), jsonError.errorString().toLocal8Bit().constData());
|
||||
if (jsonError.error != QJsonParseError::NoError) {
|
||||
eprintf("Failed to parse JSON for command \"%s\": %s\n", str.toLocal8Bit().constData(),
|
||||
jsonError.errorString().toLocal8Bit().constData());
|
||||
eprintf("%s\n", resString.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
@ -197,7 +189,8 @@ QJsonDocument CutterCore::cmdj(const QString &str)
|
||||
return doc;
|
||||
}
|
||||
|
||||
bool CutterCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, int perms, int va, int idx, bool loadbin, const QString &forceBinPlugin)
|
||||
bool CutterCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, int perms, int va,
|
||||
int idx, bool loadbin, const QString &forceBinPlugin)
|
||||
{
|
||||
Q_UNUSED(loadaddr);
|
||||
Q_UNUSED(idx);
|
||||
@ -208,63 +201,50 @@ bool CutterCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, int
|
||||
r_config_set_i(core_->config, "io.va", va);
|
||||
|
||||
f = r_core_file_open(core_, path.toUtf8().constData(), perms, mapaddr);
|
||||
if (!f)
|
||||
{
|
||||
if (!f) {
|
||||
eprintf("r_core_file_open failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!forceBinPlugin.isNull())
|
||||
{
|
||||
if (!forceBinPlugin.isNull()) {
|
||||
r_bin_force_plugin(r_core_get_bin(core_), forceBinPlugin.toUtf8().constData());
|
||||
}
|
||||
|
||||
if (loadbin)
|
||||
{
|
||||
if (va == 1)
|
||||
{
|
||||
if (!r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX))
|
||||
{
|
||||
if (loadbin) {
|
||||
if (va == 1) {
|
||||
if (!r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX)) {
|
||||
eprintf("CANNOT GET RBIN INFO\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX))
|
||||
{
|
||||
} else {
|
||||
if (!r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX)) {
|
||||
eprintf("CANNOT GET RBIN INFO\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_MULTIPLE_RBIN_FILES_INSIDE_SELECT_WHICH_ONE
|
||||
if (!r_core_file_open(core, path.toUtf8(), R_IO_READ | (rw ? R_IO_WRITE : 0, mapaddr)))
|
||||
{
|
||||
if (!r_core_file_open(core, path.toUtf8(), R_IO_READ | (rw ? R_IO_WRITE : 0, mapaddr))) {
|
||||
eprintf("Cannot open file\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// load RBin information
|
||||
// XXX only for sub-bins
|
||||
r_core_bin_load(core, path.toUtf8(), loadaddr);
|
||||
r_bin_select_idx(core_->bin, NULL, idx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Not loading RBin info coz va = false
|
||||
}
|
||||
|
||||
auto iod = core_->io ? core_->io->desc : NULL;
|
||||
auto debug = core_->file && iod && (core_->file->fd == iod->fd) && iod->plugin && \
|
||||
iod->plugin->isdbg;
|
||||
iod->plugin->isdbg;
|
||||
|
||||
if (!debug && r_flag_get (core_->flags, "entry0")) {
|
||||
r_core_cmd0 (core_, "s entry0");
|
||||
r_core_cmd0 (core_, "s entry0");
|
||||
}
|
||||
|
||||
if (perms & R_IO_WRITE) {
|
||||
r_core_cmd0 (core_, "omfg+w");
|
||||
r_core_cmd0 (core_, "omfg+w");
|
||||
}
|
||||
|
||||
setDefaultCPU();
|
||||
@ -283,18 +263,12 @@ void CutterCore::analyze(int level, QList<QString> advanced)
|
||||
* Level 2: aaaa
|
||||
*/
|
||||
|
||||
if (level == 1)
|
||||
{
|
||||
if (level == 1) {
|
||||
r_core_cmd0(core_, "aaa");
|
||||
}
|
||||
else if (level == 2)
|
||||
{
|
||||
} else if (level == 2) {
|
||||
r_core_cmd0(core_, "aaaa");
|
||||
}
|
||||
else if (level == 3)
|
||||
{
|
||||
foreach (QString option, advanced)
|
||||
{
|
||||
} else if (level == 3) {
|
||||
foreach (QString option, advanced) {
|
||||
r_core_cmd0(core_, option.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
@ -368,8 +342,7 @@ void CutterCore::delComment(RVA addr)
|
||||
|
||||
void CutterCore::setImmediateBase(const QString &r2BaseName, RVA offset)
|
||||
{
|
||||
if (offset == RVA_INVALID)
|
||||
{
|
||||
if (offset == RVA_INVALID) {
|
||||
offset = getOffset();
|
||||
}
|
||||
|
||||
@ -379,8 +352,7 @@ void CutterCore::setImmediateBase(const QString &r2BaseName, RVA offset)
|
||||
|
||||
void CutterCore::setCurrentBits(int bits, RVA offset)
|
||||
{
|
||||
if (offset == RVA_INVALID)
|
||||
{
|
||||
if (offset == RVA_INVALID) {
|
||||
offset = getOffset();
|
||||
}
|
||||
|
||||
@ -394,8 +366,7 @@ void CutterCore::seek(ut64 offset)
|
||||
// which means we either have to duplicate code from radare2
|
||||
// here, or refactor radare2 API.
|
||||
CORE_LOCK();
|
||||
if (offset == RVA_INVALID)
|
||||
{
|
||||
if (offset == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
cmd(QString("s %1").arg(offset));
|
||||
@ -425,7 +396,8 @@ RVA CutterCore::prevOpAddr(RVA startAddr, int count)
|
||||
{
|
||||
CORE_LOCK();
|
||||
bool ok;
|
||||
RVA offset = cmd("/O " + QString::number(count) + " @ " + QString::number(startAddr)).toULongLong(&ok, 16);
|
||||
RVA offset = cmd("/O " + QString::number(count) + " @ " + QString::number(startAddr)).toULongLong(
|
||||
&ok, 16);
|
||||
return ok ? offset : startAddr - count;
|
||||
}
|
||||
|
||||
@ -433,22 +405,20 @@ RVA CutterCore::nextOpAddr(RVA startAddr, int count)
|
||||
{
|
||||
CORE_LOCK();
|
||||
|
||||
QJsonArray array = Core()->cmdj("pdj " + QString::number(count+1) + "@" + QString::number(startAddr)).array();
|
||||
if (array.isEmpty())
|
||||
{
|
||||
QJsonArray array = Core()->cmdj("pdj " + QString::number(count + 1) + "@" + QString::number(
|
||||
startAddr)).array();
|
||||
if (array.isEmpty()) {
|
||||
return startAddr + 1;
|
||||
}
|
||||
|
||||
QJsonValue instValue = array.last();
|
||||
if (!instValue.isObject())
|
||||
{
|
||||
if (!instValue.isObject()) {
|
||||
return startAddr + 1;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
RVA offset = instValue.toObject()["offset"].toVariant().toULongLong(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
if (!ok) {
|
||||
return startAddr + 1;
|
||||
}
|
||||
|
||||
@ -467,8 +437,7 @@ bool CutterCore::tryFile(QString path, bool rw)
|
||||
int flags = R_IO_READ;
|
||||
if (rw) flags |= R_IO_WRITE;
|
||||
cf = r_core_file_open(this->core_, path.toUtf8().constData(), flags, 0LL);
|
||||
if (!cf)
|
||||
{
|
||||
if (!cf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -600,8 +569,7 @@ void CutterCore::setCPU(QString arch, QString cpu, int bits, bool temporary)
|
||||
setConfig("asm.arch", arch);
|
||||
setConfig("asm.cpu", cpu);
|
||||
setConfig("asm.bits", bits);
|
||||
if (!temporary)
|
||||
{
|
||||
if (!temporary) {
|
||||
default_arch = arch;
|
||||
default_cpu = cpu;
|
||||
default_bits = bits;
|
||||
@ -706,13 +674,10 @@ QList<QList<QString>> CutterCore::get_exec_sections()
|
||||
QList<QList<QString>> ret;
|
||||
|
||||
QString text = cmd("S*~^S");
|
||||
for (QString line : text.split("\n"))
|
||||
{
|
||||
for (QString line : text.split("\n")) {
|
||||
QStringList fields = line.split(" ");
|
||||
if (fields.length() == 7)
|
||||
{
|
||||
if (fields[6].contains("x"))
|
||||
{
|
||||
if (fields.length() == 7) {
|
||||
if (fields[6].contains("x")) {
|
||||
QList<QString> tmp = QList<QString>();
|
||||
tmp << fields[2];
|
||||
tmp << fields[3];
|
||||
@ -732,10 +697,10 @@ QString CutterCore::getOffsetInfo(QString addr)
|
||||
RVA CutterCore::getOffsetJump(RVA addr)
|
||||
{
|
||||
bool ok;
|
||||
RVA value = cmdj("aoj @" + QString::number(addr)).array().first().toObject().value("jump").toVariant().toULongLong(&ok);
|
||||
RVA value = cmdj("aoj @" + QString::number(
|
||||
addr)).array().first().toObject().value("jump").toVariant().toULongLong(&ok);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
if (!ok) {
|
||||
return RVA_INVALID;
|
||||
}
|
||||
|
||||
@ -784,7 +749,8 @@ QString CutterCore::getSimpleGraph(QString function)
|
||||
{
|
||||
// New styles
|
||||
QString graph = "graph [bgcolor=invis, splines=polyline];";
|
||||
QString node = "node [style=\"filled\" fillcolor=\"#4183D7\" shape=box fontname=\"Courier\" fontsize=\"8\" color=\"#4183D7\" fontcolor=\"white\"];";
|
||||
QString node =
|
||||
"node [style=\"filled\" fillcolor=\"#4183D7\" shape=box fontname=\"Courier\" fontsize=\"8\" color=\"#4183D7\" fontcolor=\"white\"];";
|
||||
QString arrow = "edge [arrowhead=\"normal\";]";
|
||||
|
||||
// Old styles
|
||||
@ -863,8 +829,7 @@ QStringList CutterCore::getAsmPluginNames()
|
||||
QStringList ret;
|
||||
|
||||
RAsmPlugin *ap;
|
||||
CutterRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap)
|
||||
{
|
||||
CutterRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap) {
|
||||
ret << ap->name;
|
||||
}
|
||||
|
||||
@ -878,8 +843,7 @@ QStringList CutterCore::getAnalPluginNames()
|
||||
QStringList ret;
|
||||
|
||||
RAnalPlugin *ap;
|
||||
CutterRListForeach(core_->anal->plugins, it, RAnalPlugin, ap)
|
||||
{
|
||||
CutterRListForeach(core_->anal->plugins, it, RAnalPlugin, ap) {
|
||||
ret << ap->name;
|
||||
}
|
||||
|
||||
@ -903,15 +867,13 @@ QList<RBinPluginDescription> CutterCore::getRBinPluginDescriptions(const QString
|
||||
QList<RBinPluginDescription> ret;
|
||||
|
||||
QJsonObject jsonRoot = cmdj("iLj").object();
|
||||
for (const QString &key : jsonRoot.keys())
|
||||
{
|
||||
for (const QString &key : jsonRoot.keys()) {
|
||||
if (!type.isNull() && key != type)
|
||||
continue;
|
||||
|
||||
QJsonArray pluginArray = jsonRoot[key].toArray();
|
||||
|
||||
for (const auto &pluginValue : pluginArray)
|
||||
{
|
||||
for (const auto &pluginValue : pluginArray) {
|
||||
QJsonObject pluginObject = pluginValue.toObject();
|
||||
RBinPluginDescription desc;
|
||||
desc.name = pluginObject["name"].toString();
|
||||
@ -930,8 +892,7 @@ QList<RIOPluginDescription> CutterCore::getRIOPluginDescriptions()
|
||||
QList<RIOPluginDescription> ret;
|
||||
|
||||
QJsonArray plugins = cmdj("oLj").object()["IO_Plugins"].toArray();
|
||||
for(QJsonValueRef pluginValue : plugins)
|
||||
{
|
||||
for (QJsonValueRef pluginValue : plugins) {
|
||||
QJsonObject pluginObject = pluginValue.toObject();
|
||||
RIOPluginDescription plugin;
|
||||
|
||||
@ -951,8 +912,7 @@ QList<RCorePluginDescription> CutterCore::getRCorePluginDescriptions()
|
||||
QList<RCorePluginDescription> ret;
|
||||
|
||||
QJsonArray plugins = cmdj("Lsj").array();
|
||||
for(QJsonValueRef pluginValue : plugins)
|
||||
{
|
||||
for (QJsonValueRef pluginValue : plugins) {
|
||||
QJsonObject pluginObject = pluginValue.toObject();
|
||||
RCorePluginDescription plugin;
|
||||
|
||||
@ -972,8 +932,7 @@ QList<RAsmPluginDescription> CutterCore::getRAsmPluginDescriptions()
|
||||
QList<RAsmPluginDescription> ret;
|
||||
|
||||
RAsmPlugin *ap;
|
||||
CutterRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap)
|
||||
{
|
||||
CutterRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap) {
|
||||
RAsmPluginDescription plugin;
|
||||
|
||||
plugin.name = ap->name;
|
||||
@ -997,8 +956,7 @@ QList<FunctionDescription> CutterCore::getAllFunctions()
|
||||
|
||||
QJsonArray jsonArray = cmdj("aflj").array();
|
||||
|
||||
foreach (QJsonValue value, jsonArray)
|
||||
{
|
||||
foreach (QJsonValue value, jsonArray) {
|
||||
QJsonObject jsonObject = value.toObject();
|
||||
|
||||
FunctionDescription function;
|
||||
@ -1020,8 +978,7 @@ QList<ImportDescription> CutterCore::getAllImports()
|
||||
|
||||
QJsonArray importsArray = cmdj("iij").array();
|
||||
|
||||
foreach (QJsonValue value, importsArray)
|
||||
{
|
||||
foreach (QJsonValue value, importsArray) {
|
||||
QJsonObject importObject = value.toObject();
|
||||
|
||||
ImportDescription import;
|
||||
@ -1045,8 +1002,7 @@ QList<ExportDescription> CutterCore::getAllExports()
|
||||
|
||||
QJsonArray importsArray = cmdj("iEj").array();
|
||||
|
||||
foreach (QJsonValue value, importsArray)
|
||||
{
|
||||
foreach (QJsonValue value, importsArray) {
|
||||
QJsonObject importObject = value.toObject();
|
||||
|
||||
ExportDescription exp;
|
||||
@ -1072,10 +1028,8 @@ QList<SymbolDescription> CutterCore::getAllSymbols()
|
||||
QList<SymbolDescription> ret;
|
||||
|
||||
RBinSymbol *bs;
|
||||
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o)
|
||||
{
|
||||
CutterRListForeach(core_->bin->cur->o->symbols, it, RBinSymbol, bs)
|
||||
{
|
||||
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o) {
|
||||
CutterRListForeach(core_->bin->cur->o->symbols, it, RBinSymbol, bs) {
|
||||
QString type = QString(bs->bind) + " " + QString(bs->type);
|
||||
SymbolDescription symbol;
|
||||
symbol.vaddr = bs->vaddr;
|
||||
@ -1088,8 +1042,7 @@ QList<SymbolDescription> CutterCore::getAllSymbols()
|
||||
/* list entrypoints as symbols too */
|
||||
int n = 0;
|
||||
RBinAddr *entry;
|
||||
CutterRListForeach(core_->bin->cur->o->entries, it, RBinAddr, entry)
|
||||
{
|
||||
CutterRListForeach(core_->bin->cur->o->entries, it, RBinAddr, entry) {
|
||||
SymbolDescription symbol;
|
||||
symbol.vaddr = entry->vaddr;
|
||||
symbol.name = QString("entry") + QString::number(n++);
|
||||
@ -1108,8 +1061,7 @@ QList<CommentDescription> CutterCore::getAllComments(const QString &filterType)
|
||||
QList<CommentDescription> ret;
|
||||
|
||||
QJsonArray commentsArray = cmdj("CCj").array();
|
||||
for (QJsonValue value : commentsArray)
|
||||
{
|
||||
for (QJsonValue value : commentsArray) {
|
||||
QJsonObject commentObject = value.toObject();
|
||||
|
||||
QString type = commentObject["type"].toString();
|
||||
@ -1132,10 +1084,8 @@ QList<RelocDescription> CutterCore::getAllRelocs()
|
||||
QList<RelocDescription> ret;
|
||||
|
||||
RBinReloc *br;
|
||||
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o)
|
||||
{
|
||||
CutterRListForeach(core_->bin->cur->o->relocs, it, RBinReloc, br)
|
||||
{
|
||||
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o) {
|
||||
CutterRListForeach(core_->bin->cur->o->relocs, it, RBinReloc, br) {
|
||||
RelocDescription reloc;
|
||||
|
||||
reloc.vaddr = br->vaddr;
|
||||
@ -1161,8 +1111,7 @@ QList<StringDescription> CutterCore::getAllStrings()
|
||||
QJsonDocument stringsDoc = cmdj("izzj");
|
||||
QJsonObject stringsObj = stringsDoc.object();
|
||||
QJsonArray stringsArray = stringsObj["strings"].toArray();
|
||||
for (QJsonValue value : stringsArray)
|
||||
{
|
||||
for (QJsonValue value : stringsArray) {
|
||||
QJsonObject stringObject = value.toObject();
|
||||
|
||||
StringDescription string;
|
||||
@ -1184,8 +1133,7 @@ QList<FlagspaceDescription> CutterCore::getAllFlagspaces()
|
||||
QList<FlagspaceDescription> ret;
|
||||
|
||||
QJsonArray flagspacesArray = cmdj("fsj").array();
|
||||
for (QJsonValue value : flagspacesArray)
|
||||
{
|
||||
for (QJsonValue value : flagspacesArray) {
|
||||
QJsonObject flagspaceObject = value.toObject();
|
||||
|
||||
FlagspaceDescription flagspace;
|
||||
@ -1207,8 +1155,7 @@ QList<FlagDescription> CutterCore::getAllFlags(QString flagspace)
|
||||
cmd("fs *");
|
||||
|
||||
QJsonArray flagsArray = cmdj("fj").array();
|
||||
for (QJsonValue value : flagsArray)
|
||||
{
|
||||
for (QJsonValue value : flagsArray) {
|
||||
QJsonObject flagObject = value.toObject();
|
||||
|
||||
FlagDescription flag;
|
||||
@ -1227,8 +1174,7 @@ QList<SectionDescription> CutterCore::getAllSections()
|
||||
QList<SectionDescription> ret;
|
||||
|
||||
QJsonArray sectionsArray = cmdj("Sj").array();
|
||||
for (QJsonValue value : sectionsArray)
|
||||
{
|
||||
for (QJsonValue value : sectionsArray) {
|
||||
QJsonObject sectionObject = value.toObject();
|
||||
|
||||
QString name = sectionObject["name"].toString();
|
||||
@ -1254,8 +1200,7 @@ QList<EntrypointDescription> CutterCore::getAllEntrypoint()
|
||||
QList<EntrypointDescription> ret;
|
||||
|
||||
QJsonArray entrypointsArray = cmdj("iej").array();
|
||||
for (QJsonValue value : entrypointsArray)
|
||||
{
|
||||
for (QJsonValue value : entrypointsArray) {
|
||||
QJsonObject entrypointObject = value.toObject();
|
||||
|
||||
EntrypointDescription entrypoint;
|
||||
@ -1277,8 +1222,7 @@ QList<ClassDescription> CutterCore::getAllClassesFromBin()
|
||||
QList<ClassDescription> ret;
|
||||
|
||||
QJsonArray classesArray = cmdj("icj").array();
|
||||
for (QJsonValueRef value : classesArray)
|
||||
{
|
||||
for (QJsonValueRef value : classesArray) {
|
||||
QJsonObject classObject = value.toObject();
|
||||
|
||||
ClassDescription cls;
|
||||
@ -1286,8 +1230,7 @@ QList<ClassDescription> CutterCore::getAllClassesFromBin()
|
||||
cls.addr = classObject["addr"].toVariant().toULongLong();
|
||||
cls.index = classObject["index"].toVariant().toULongLong();
|
||||
|
||||
for(QJsonValueRef value2 : classObject["methods"].toArray())
|
||||
{
|
||||
for (QJsonValueRef value2 : classObject["methods"].toArray()) {
|
||||
QJsonObject methObject = value2.toObject();
|
||||
|
||||
ClassMethodDescription meth;
|
||||
@ -1296,8 +1239,7 @@ QList<ClassDescription> CutterCore::getAllClassesFromBin()
|
||||
cls.methods << meth;
|
||||
}
|
||||
|
||||
for(QJsonValueRef value2 : classObject["fields"].toArray())
|
||||
{
|
||||
for (QJsonValueRef value2 : classObject["fields"].toArray()) {
|
||||
QJsonObject fieldObject = value2.toObject();
|
||||
|
||||
ClassFieldDescription field;
|
||||
@ -1323,26 +1265,21 @@ QList<ClassDescription> CutterCore::getAllClassesFromFlags()
|
||||
QMap<QString, ClassDescription *> classesCache;
|
||||
|
||||
QJsonArray flagsArray = cmdj("fj@F:classes").array();
|
||||
for (QJsonValueRef value : flagsArray)
|
||||
{
|
||||
for (QJsonValueRef value : flagsArray) {
|
||||
QJsonObject flagObject = value.toObject();
|
||||
QString flagName = flagObject["name"].toString();
|
||||
|
||||
QRegularExpressionMatch match = classFlagRegExp.match(flagName);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
if (match.hasMatch()) {
|
||||
QString className = match.captured(1);
|
||||
ClassDescription *desc = nullptr;
|
||||
auto it = classesCache.find(className);
|
||||
if (it == classesCache.end())
|
||||
{
|
||||
if (it == classesCache.end()) {
|
||||
ClassDescription cls = {};
|
||||
ret << cls;
|
||||
desc = &ret.last();
|
||||
classesCache[className] = desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
desc = it.value();
|
||||
}
|
||||
desc->name = match.captured(1);
|
||||
@ -1352,13 +1289,11 @@ QList<ClassDescription> CutterCore::getAllClassesFromFlags()
|
||||
}
|
||||
|
||||
match = methodFlagRegExp.match(flagName);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
if (match.hasMatch()) {
|
||||
QString className = match.captured(1);
|
||||
ClassDescription *classDesc = nullptr;
|
||||
auto it = classesCache.find(className);
|
||||
if (it == classesCache.end())
|
||||
{
|
||||
if (it == classesCache.end()) {
|
||||
// add a new stub class, will be replaced if class flag comes after it
|
||||
ClassDescription cls;
|
||||
cls.name = tr("Unknown (%1)").arg(className);
|
||||
@ -1367,9 +1302,7 @@ QList<ClassDescription> CutterCore::getAllClassesFromFlags()
|
||||
ret << cls;
|
||||
classDesc = &ret.last();
|
||||
classesCache[className] = classDesc;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
classDesc = it.value();
|
||||
}
|
||||
|
||||
@ -1389,8 +1322,7 @@ QList<ResourcesDescription> CutterCore::getAllResources()
|
||||
QList<ResourcesDescription> ret;
|
||||
|
||||
QJsonArray resourcesArray = cmdj("iRj").array();
|
||||
for (QJsonValueRef value : resourcesArray)
|
||||
{
|
||||
for (QJsonValueRef value : resourcesArray) {
|
||||
QJsonObject resourceObject = value.toObject();
|
||||
|
||||
ResourcesDescription res;
|
||||
@ -1412,16 +1344,14 @@ QList<VTableDescription> CutterCore::getAllVTables()
|
||||
QList<VTableDescription> ret;
|
||||
|
||||
QJsonArray vTablesArray = cmdj("avj").array();
|
||||
for(QJsonValueRef vTableValue : vTablesArray)
|
||||
{
|
||||
for (QJsonValueRef vTableValue : vTablesArray) {
|
||||
QJsonObject vTableObject = vTableValue.toObject();
|
||||
|
||||
VTableDescription res;
|
||||
res.addr = vTableObject["offset"].toVariant().toULongLong();
|
||||
QJsonArray methodArray = vTableObject["methods"].toArray();
|
||||
|
||||
for(QJsonValueRef methodValue : methodArray)
|
||||
{
|
||||
for (QJsonValueRef methodValue : methodArray) {
|
||||
QJsonObject methodObject = methodValue.toObject();
|
||||
|
||||
ClassMethodDescription method;
|
||||
@ -1443,8 +1373,7 @@ QList<TypeDescription> CutterCore::getAllTypes()
|
||||
|
||||
QJsonArray typesArray = cmdj("tj").array();
|
||||
|
||||
foreach (QJsonValue value, typesArray)
|
||||
{
|
||||
foreach (QJsonValue value, typesArray) {
|
||||
QJsonObject typeObject = value.toObject();
|
||||
|
||||
TypeDescription exp;
|
||||
@ -1465,30 +1394,25 @@ QList<SearchDescription> CutterCore::getAllSearch(QString search_for, QString sp
|
||||
QList<SearchDescription> ret;
|
||||
|
||||
QJsonArray searchArray = cmdj(space + QString(" ") + search_for).array();
|
||||
|
||||
if (space == "/Rj")
|
||||
{
|
||||
foreach (QJsonValue value, searchArray)
|
||||
{
|
||||
|
||||
if (space == "/Rj") {
|
||||
foreach (QJsonValue value, searchArray) {
|
||||
QJsonObject searchObject = value.toObject();
|
||||
SearchDescription exp;
|
||||
exp.code = QString("");
|
||||
foreach (QJsonValue value2, searchObject["opcodes"].toArray())
|
||||
{
|
||||
foreach (QJsonValue value2, searchObject["opcodes"].toArray()) {
|
||||
QJsonObject gadget = value2.toObject();
|
||||
exp.code += gadget["opcode"].toString() + "; ";
|
||||
}
|
||||
|
||||
exp.offset = searchObject["opcodes"].toArray().first().toObject()["offset"].toVariant().toULongLong();
|
||||
exp.offset =
|
||||
searchObject["opcodes"].toArray().first().toObject()["offset"].toVariant().toULongLong();
|
||||
exp.size = searchObject["size"].toVariant().toULongLong();
|
||||
|
||||
ret << exp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QJsonValue value, searchArray)
|
||||
{
|
||||
} else {
|
||||
foreach (QJsonValue value, searchArray) {
|
||||
QJsonObject searchObject = value.toObject();
|
||||
SearchDescription exp;
|
||||
|
||||
@ -1503,7 +1427,8 @@ QList<SearchDescription> CutterCore::getAllSearch(QString search_for, QString sp
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType)
|
||||
QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_function,
|
||||
const QString &filterType)
|
||||
{
|
||||
QList<XrefDescription> ret = QList<XrefDescription>();
|
||||
|
||||
@ -1514,8 +1439,7 @@ QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_functi
|
||||
else
|
||||
xrefsArray = cmdj("axfj@" + QString::number(addr)).array();
|
||||
|
||||
for (QJsonValue value : xrefsArray)
|
||||
{
|
||||
for (QJsonValue value : xrefsArray) {
|
||||
QJsonObject xrefObject = value.toObject();
|
||||
|
||||
XrefDescription xref;
|
||||
@ -1592,11 +1516,11 @@ bool CutterCore::isProjectNameValid(const QString &name)
|
||||
|
||||
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
|
||||
{
|
||||
QJsonArray array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ") + QString::number(offset)).array();
|
||||
QJsonArray array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ") + QString::number(
|
||||
offset)).array();
|
||||
QList<DisassemblyLine> r;
|
||||
|
||||
for (QJsonValue value : array)
|
||||
{
|
||||
for (QJsonValue value : array) {
|
||||
QJsonObject object = value.toObject();
|
||||
|
||||
DisassemblyLine line;
|
||||
@ -1644,13 +1568,13 @@ QString CutterCore::getVersionInformation()
|
||||
{ "r_syscall", &r_syscall_version },
|
||||
{ "r_util", &r_util_version },
|
||||
/* ... */
|
||||
{NULL,NULL}
|
||||
{NULL, NULL}
|
||||
};
|
||||
ret.append(QString("%1 r2\n").arg(R2_GITTAP));
|
||||
for (i = 0; vcs[i].name; i++) {
|
||||
struct vcs_t *v = &vcs[i];
|
||||
const char *name = v->callback ();
|
||||
ret.append(QString("%1 %2\n").arg(name, v->name));
|
||||
struct vcs_t *v = &vcs[i];
|
||||
const char *name = v->callback ();
|
||||
ret.append(QString("%1 %2\n").arg(name, v->name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
119
src/Cutter.h
119
src/Cutter.h
@ -63,17 +63,18 @@ inline QString RSizeString(RVA size)
|
||||
return QString::asprintf("%lld", size);
|
||||
}
|
||||
|
||||
struct FunctionDescription
|
||||
{
|
||||
struct FunctionDescription {
|
||||
RVA offset;
|
||||
RVA size;
|
||||
QString name;
|
||||
|
||||
bool contains(RVA addr) const { return addr >= offset && addr < offset + size; }
|
||||
bool contains(RVA addr) const
|
||||
{
|
||||
return addr >= offset && addr < offset + size;
|
||||
}
|
||||
};
|
||||
|
||||
struct ImportDescription
|
||||
{
|
||||
struct ImportDescription {
|
||||
RVA plt;
|
||||
int ordinal;
|
||||
QString bind;
|
||||
@ -81,8 +82,7 @@ struct ImportDescription
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct ExportDescription
|
||||
{
|
||||
struct ExportDescription {
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA size;
|
||||
@ -91,45 +91,39 @@ struct ExportDescription
|
||||
QString flag_name;
|
||||
};
|
||||
|
||||
struct TypeDescription
|
||||
{
|
||||
struct TypeDescription {
|
||||
QString type;
|
||||
int size;
|
||||
QString format;
|
||||
};
|
||||
|
||||
struct SearchDescription
|
||||
{
|
||||
struct SearchDescription {
|
||||
RVA offset;
|
||||
int size;
|
||||
QString code;
|
||||
QString data;
|
||||
};
|
||||
|
||||
struct SymbolDescription
|
||||
{
|
||||
struct SymbolDescription {
|
||||
RVA vaddr;
|
||||
QString bind;
|
||||
QString type;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct CommentDescription
|
||||
{
|
||||
struct CommentDescription {
|
||||
RVA offset;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct RelocDescription
|
||||
{
|
||||
struct RelocDescription {
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
QString type;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct StringDescription
|
||||
{
|
||||
struct StringDescription {
|
||||
RVA vaddr;
|
||||
QString string;
|
||||
QString type;
|
||||
@ -137,20 +131,17 @@ struct StringDescription
|
||||
ut32 size;
|
||||
};
|
||||
|
||||
struct FlagspaceDescription
|
||||
{
|
||||
struct FlagspaceDescription {
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct FlagDescription
|
||||
{
|
||||
struct FlagDescription {
|
||||
RVA offset;
|
||||
RVA size;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct SectionDescription
|
||||
{
|
||||
struct SectionDescription {
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA size;
|
||||
@ -159,8 +150,7 @@ struct SectionDescription
|
||||
QString flags;
|
||||
};
|
||||
|
||||
struct EntrypointDescription
|
||||
{
|
||||
struct EntrypointDescription {
|
||||
RVA vaddr;
|
||||
RVA paddr;
|
||||
RVA baddr;
|
||||
@ -169,8 +159,7 @@ struct EntrypointDescription
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct XrefDescription
|
||||
{
|
||||
struct XrefDescription {
|
||||
RVA from;
|
||||
QString from_str;
|
||||
RVA to;
|
||||
@ -178,30 +167,26 @@ struct XrefDescription
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct RBinPluginDescription
|
||||
{
|
||||
struct RBinPluginDescription {
|
||||
QString name;
|
||||
QString description;
|
||||
QString license;
|
||||
QString type;
|
||||
};
|
||||
|
||||
struct RIOPluginDescription
|
||||
{
|
||||
struct RIOPluginDescription {
|
||||
QString name;
|
||||
QString description;
|
||||
QString license;
|
||||
QString permissions;
|
||||
};
|
||||
|
||||
struct RCorePluginDescription
|
||||
{
|
||||
struct RCorePluginDescription {
|
||||
QString name;
|
||||
QString description;
|
||||
};
|
||||
|
||||
struct RAsmPluginDescription
|
||||
{
|
||||
struct RAsmPluginDescription {
|
||||
QString name;
|
||||
QString architecture;
|
||||
QString author;
|
||||
@ -211,26 +196,22 @@ struct RAsmPluginDescription
|
||||
QString license;
|
||||
};
|
||||
|
||||
struct DisassemblyLine
|
||||
{
|
||||
struct DisassemblyLine {
|
||||
RVA offset;
|
||||
QString text;
|
||||
};
|
||||
|
||||
struct ClassMethodDescription
|
||||
{
|
||||
struct ClassMethodDescription {
|
||||
QString name;
|
||||
RVA addr;
|
||||
};
|
||||
|
||||
struct ClassFieldDescription
|
||||
{
|
||||
struct ClassFieldDescription {
|
||||
QString name;
|
||||
RVA addr;
|
||||
};
|
||||
|
||||
struct ClassDescription
|
||||
{
|
||||
struct ClassDescription {
|
||||
QString name;
|
||||
RVA addr;
|
||||
ut64 index;
|
||||
@ -238,8 +219,7 @@ struct ClassDescription
|
||||
QList<ClassFieldDescription> fields;
|
||||
};
|
||||
|
||||
struct ResourcesDescription
|
||||
{
|
||||
struct ResourcesDescription {
|
||||
int name;
|
||||
RVA vaddr;
|
||||
ut64 index;
|
||||
@ -248,8 +228,7 @@ struct ResourcesDescription
|
||||
QString lang;
|
||||
};
|
||||
|
||||
struct VTableDescription
|
||||
{
|
||||
struct VTableDescription {
|
||||
RVA addr;
|
||||
QList<ClassMethodDescription> methods;
|
||||
};
|
||||
@ -291,13 +270,21 @@ public:
|
||||
static CutterCore *getInstance();
|
||||
|
||||
/* Getters */
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
RVA getOffset() const
|
||||
{
|
||||
return core_->offset;
|
||||
}
|
||||
|
||||
static QString sanitizeStringForCommand(QString s);
|
||||
QString cmd(const QString &str);
|
||||
QString cmdRaw(const QString &str);
|
||||
QJsonDocument cmdj(const QString &str);
|
||||
QStringList cmdList(const QString &str) { auto l = cmd(str).split("\n"); l.removeAll(""); return l; }
|
||||
QStringList cmdList(const QString &str)
|
||||
{
|
||||
auto l = cmd(str).split("\n");
|
||||
l.removeAll("");
|
||||
return l;
|
||||
}
|
||||
|
||||
QList<DisassemblyLine> disassembleLines(RVA offset, int lines);
|
||||
|
||||
@ -310,7 +297,7 @@ public:
|
||||
void editInstruction(RVA addr, const QString &inst);
|
||||
void nopInstruction(RVA addr);
|
||||
void jmpReverse(RVA addr);
|
||||
|
||||
|
||||
void editBytes(RVA addr, const QString &inst);
|
||||
|
||||
void setComment(RVA addr, const QString &cmt);
|
||||
@ -319,7 +306,8 @@ public:
|
||||
void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID);
|
||||
void setCurrentBits(int bits, RVA offset = RVA_INVALID);
|
||||
|
||||
bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, int perms = R_IO_READ, int va = 0, int idx = 0, bool loadbin = false, const QString &forceBinPlugin = nullptr);
|
||||
bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, int perms = R_IO_READ,
|
||||
int va = 0, int idx = 0, bool loadbin = false, const QString &forceBinPlugin = nullptr);
|
||||
bool tryFile(QString path, bool rw);
|
||||
void analyze(int level, QList<QString> advanced);
|
||||
|
||||
@ -335,9 +323,18 @@ public:
|
||||
|
||||
// Disassembly/Graph/Hexdump/Pseudocode view priority
|
||||
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
|
||||
MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; }
|
||||
void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; }
|
||||
void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); }
|
||||
MemoryWidgetType getMemoryWidgetPriority() const
|
||||
{
|
||||
return memoryWidgetPriority;
|
||||
}
|
||||
void setMemoryWidgetPriority(MemoryWidgetType type)
|
||||
{
|
||||
memoryWidgetPriority = type;
|
||||
}
|
||||
void triggerRaisePrioritizedMemoryWidget()
|
||||
{
|
||||
emit raisePrioritizedMemoryWidget(memoryWidgetPriority);
|
||||
}
|
||||
|
||||
ut64 math(const QString &expr);
|
||||
QString itoa(ut64 num, int rdx = 16);
|
||||
@ -346,7 +343,10 @@ public:
|
||||
void setConfig(const QString &k, const QString &v);
|
||||
void setConfig(const QString &k, int v);
|
||||
void setConfig(const QString &k, bool v);
|
||||
void setConfig(const QString &k, const char *v) { setConfig(k, QString(v)); }
|
||||
void setConfig(const QString &k, const char *v)
|
||||
{
|
||||
setConfig(k, QString(v));
|
||||
}
|
||||
int getConfigi(const QString &k);
|
||||
bool getConfigb(const QString &k);
|
||||
QString getConfig(const QString &k);
|
||||
@ -358,7 +358,7 @@ public:
|
||||
void setCPU(QString arch, QString cpu, int bits, bool temporary = false);
|
||||
void setEndianness(bool big);
|
||||
void setBBSize(int size);
|
||||
|
||||
|
||||
RAnalFunction *functionAt(ut64 addr);
|
||||
QString cmdFunctionAt(QString addr);
|
||||
QString cmdFunctionAt(RVA addr);
|
||||
@ -423,7 +423,8 @@ public:
|
||||
QList<TypeDescription> getAllTypes();
|
||||
QList<SearchDescription> getAllSearch(QString search_for, QString space);
|
||||
|
||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null);
|
||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
|
||||
const QString &filterType = QString::null);
|
||||
|
||||
void addFlag(RVA offset, QString name, RVA size);
|
||||
void triggerFlagsChanged();
|
||||
|
@ -13,7 +13,8 @@
|
||||
#include "utils/JupyterConnection.h"
|
||||
#endif
|
||||
|
||||
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv){
|
||||
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
|
||||
{
|
||||
setOrganizationName("Cutter");
|
||||
setApplicationName("Cutter");
|
||||
setApplicationVersion(APP_VERSION);
|
||||
@ -26,18 +27,20 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
#endif
|
||||
QCommandLineParser cmd_parser;
|
||||
cmd_parser.setApplicationDescription(QObject::tr("A Qt and C++ GUI for radare2 reverse engineering framework"));
|
||||
cmd_parser.setApplicationDescription(
|
||||
QObject::tr("A Qt and C++ GUI for radare2 reverse engineering framework"));
|
||||
cmd_parser.addHelpOption();
|
||||
cmd_parser.addVersionOption();
|
||||
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
||||
|
||||
QCommandLineOption analOption({"A", "anal"},
|
||||
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"));
|
||||
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);
|
||||
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
QCommandLineOption pythonHomeOption("pythonhome", QObject::tr("PYTHONHOME to use for Jupyter"), "PYTHONHOME");
|
||||
QCommandLineOption pythonHomeOption("pythonhome", QObject::tr("PYTHONHOME to use for Jupyter"),
|
||||
"PYTHONHOME");
|
||||
cmd_parser.addOption(pythonHomeOption);
|
||||
#endif
|
||||
|
||||
@ -48,52 +51,48 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
||||
// Check r2 version
|
||||
QString r2version = r_core_version();
|
||||
QString localVersion = "" R2_GITTAP;
|
||||
if (r2version != localVersion)
|
||||
{
|
||||
if (r2version != localVersion) {
|
||||
QMessageBox msg;
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msg.setWindowTitle(QObject::tr("Version mismatch!"));
|
||||
msg.setText(QString(QObject::tr("The version used to compile Cutter (%1) does not match the binary version of radare2 (%2). This could result in unexpected behaviour. Are you sure you want to continue?")).arg(localVersion, r2version));
|
||||
msg.setText(QString(
|
||||
QObject::tr("The version used to compile Cutter (%1) does not match the binary version of radare2 (%2). This could result in unexpected behaviour. Are you sure you want to continue?")).arg(
|
||||
localVersion, r2version));
|
||||
if (msg.exec() == QMessageBox::No)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
if (cmd_parser.isSet(pythonHomeOption))
|
||||
{
|
||||
if (cmd_parser.isSet(pythonHomeOption)) {
|
||||
Jupyter()->setPythonHome(cmd_parser.value(pythonHomeOption));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool analLevelSpecified = false;
|
||||
int analLevel= 0;
|
||||
int analLevel = 0;
|
||||
|
||||
if (cmd_parser.isSet(analOption))
|
||||
{
|
||||
if (cmd_parser.isSet(analOption)) {
|
||||
analLevel = cmd_parser.value(analOption).toInt(&analLevelSpecified);
|
||||
|
||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 2)
|
||||
{
|
||||
printf("%s\n", QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData());
|
||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
|
||||
printf("%s\n",
|
||||
QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new MainWindow();
|
||||
|
||||
if (args.empty())
|
||||
{
|
||||
if (analLevelSpecified)
|
||||
{
|
||||
printf("%s\n", QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
||||
if (args.empty()) {
|
||||
if (analLevelSpecified) {
|
||||
printf("%s\n",
|
||||
QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mainWindow->displayNewFileDialog();
|
||||
}
|
||||
else // filename specified as positional argument
|
||||
{
|
||||
} else { // filename specified as positional argument
|
||||
mainWindow->openNewFile(args[0], analLevelSpecified ? analLevel : -1);
|
||||
}
|
||||
}
|
||||
@ -105,13 +104,10 @@ CutterApplication::~CutterApplication()
|
||||
|
||||
bool CutterApplication::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::FileOpen)
|
||||
{
|
||||
if (e->type() == QEvent::FileOpen) {
|
||||
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(e);
|
||||
if (openEvent)
|
||||
{
|
||||
if (m_FileAlreadyDropped)
|
||||
{
|
||||
if (openEvent) {
|
||||
if (m_FileAlreadyDropped) {
|
||||
// we already dropped a file in macOS, let's spawn another instance
|
||||
// (Like the File -> Open)
|
||||
QString fileName = openEvent->file();
|
||||
@ -119,9 +115,7 @@ bool CutterApplication::event(QEvent *e)
|
||||
process.setEnvironment(QProcess::systemEnvironment());
|
||||
QStringList args = QStringList(fileName);
|
||||
process.startDetached(qApp->applicationFilePath(), args);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QString fileName = openEvent->file();
|
||||
m_FileAlreadyDropped = true;
|
||||
mainWindow->closeNewFileDialog();
|
||||
|
@ -15,7 +15,10 @@ public:
|
||||
CutterApplication(int &argc, char **argv);
|
||||
~CutterApplication();
|
||||
|
||||
MainWindow *getMainWindow() { return mainWindow; }
|
||||
MainWindow *getMainWindow()
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e);
|
||||
|
@ -15,8 +15,7 @@ void set_appimage_symlink()
|
||||
*(i + 1) = '\0';
|
||||
char *dest = strcat(path, "../");
|
||||
struct stat buf;
|
||||
if (lstat(PREFIX, &buf) == 0 && S_ISLNK(buf.st_mode))
|
||||
{
|
||||
if (lstat(PREFIX, &buf) == 0 && S_ISLNK(buf.st_mode)) {
|
||||
remove(PREFIX);
|
||||
}
|
||||
symlink(dest, PREFIX);
|
||||
|
@ -267,8 +267,7 @@ void MainWindow::displayAnalysisOptionsDialog(int analLevel, QList<QString> adva
|
||||
o->setAttribute(Qt::WA_DeleteOnClose);
|
||||
o->show();
|
||||
|
||||
if (analLevel >= 0)
|
||||
{
|
||||
if (analLevel >= 0) {
|
||||
o->setupAndStartAnalysis(analLevel, advancedOptions);
|
||||
}
|
||||
}
|
||||
@ -308,12 +307,9 @@ void MainWindow::finalizeOpen()
|
||||
bool MainWindow::saveProject(bool quit)
|
||||
{
|
||||
QString projectName = core->getConfig("prj.name");
|
||||
if (projectName.isEmpty())
|
||||
{
|
||||
if (projectName.isEmpty()) {
|
||||
return saveProjectAs(quit);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
core->saveProject(projectName);
|
||||
return true;
|
||||
}
|
||||
@ -342,23 +338,17 @@ void MainWindow::setFilename(const QString &fn)
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(this, APPNAME,
|
||||
tr("Do you really want to exit?\nSave your project before closing!"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
if (ret == QMessageBox::Save)
|
||||
{
|
||||
if (saveProject(true))
|
||||
{
|
||||
tr("Do you really want to exit?\nSave your project before closing!"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
if (ret == QMessageBox::Save) {
|
||||
if (saveProject(true)) {
|
||||
saveSettings();
|
||||
}
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
else if (ret == QMessageBox::Discard)
|
||||
{
|
||||
} else if (ret == QMessageBox::Discard) {
|
||||
saveSettings();
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
@ -391,19 +381,14 @@ void MainWindow::saveSettings()
|
||||
|
||||
void MainWindow::setPanelLock()
|
||||
{
|
||||
if (panelLock)
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
if (panelLock) {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
||||
}
|
||||
|
||||
ui->actionLock->setChecked(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
} else {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
}
|
||||
|
||||
@ -413,14 +398,11 @@ void MainWindow::setPanelLock()
|
||||
|
||||
void MainWindow::setTabLocation()
|
||||
{
|
||||
if (tabsOnTop)
|
||||
{
|
||||
if (tabsOnTop) {
|
||||
ui->centralTabWidget->setTabPosition(QTabWidget::North);
|
||||
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
|
||||
ui->actionTabs_on_Top->setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->centralTabWidget->setTabPosition(QTabWidget::South);
|
||||
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
|
||||
ui->actionTabs_on_Top->setChecked(false);
|
||||
@ -434,17 +416,12 @@ void MainWindow::refreshAll()
|
||||
|
||||
void MainWindow::lockUnlock_Docks(bool what)
|
||||
{
|
||||
if (what)
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
if (what) {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
} else {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
}
|
||||
}
|
||||
@ -494,8 +471,7 @@ void MainWindow::restoreDocks()
|
||||
|
||||
void MainWindow::hideAllDocks()
|
||||
{
|
||||
for (auto w : dockWidgets)
|
||||
{
|
||||
for (auto w : dockWidgets) {
|
||||
removeDockWidget(w);
|
||||
}
|
||||
|
||||
@ -504,8 +480,7 @@ void MainWindow::hideAllDocks()
|
||||
|
||||
void MainWindow::updateDockActionsChecked()
|
||||
{
|
||||
for(auto i=dockWidgetActions.constBegin(); i!=dockWidgetActions.constEnd(); i++)
|
||||
{
|
||||
for (auto i = dockWidgetActions.constBegin(); i != dockWidgetActions.constEnd(); i++) {
|
||||
i.key()->setChecked(!i.value()->isHidden());
|
||||
}
|
||||
}
|
||||
@ -531,10 +506,8 @@ void MainWindow::showDefaultDocks()
|
||||
#endif
|
||||
};
|
||||
|
||||
for (auto w : dockWidgets)
|
||||
{
|
||||
if (defaultDocks.contains(w))
|
||||
{
|
||||
for (auto w : dockWidgets) {
|
||||
if (defaultDocks.contains(w)) {
|
||||
w->show();
|
||||
}
|
||||
}
|
||||
@ -581,18 +554,13 @@ void MainWindow::on_actionLock_triggered()
|
||||
|
||||
void MainWindow::on_actionLockUnlock_triggered()
|
||||
{
|
||||
if (ui->actionLockUnlock->isChecked())
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
if (ui->actionLockUnlock->isChecked()) {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
||||
}
|
||||
ui->actionLockUnlock->setIcon(QIcon(":/lock"));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>())
|
||||
{
|
||||
} else {
|
||||
foreach (QDockWidget *dockWidget, findChildren<QDockWidget *>()) {
|
||||
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
}
|
||||
ui->actionLockUnlock->setIcon(QIcon(":/unlock"));
|
||||
@ -665,10 +633,9 @@ void MainWindow::on_actionReset_settings_triggered()
|
||||
{
|
||||
QMessageBox::StandardButton ret =
|
||||
(QMessageBox::StandardButton)QMessageBox::question(this, APPNAME,
|
||||
tr("Do you really want to clear all settings?"),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if (ret == QMessageBox::Ok)
|
||||
{
|
||||
tr("Do you really want to clear all settings?"),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if (ret == QMessageBox::Ok) {
|
||||
Config()->resetAll();
|
||||
}
|
||||
}
|
||||
@ -744,15 +711,13 @@ void MainWindow::on_actionImportPDB_triggered()
|
||||
dialog.setWindowTitle(tr("Select PDB file"));
|
||||
dialog.setNameFilters({ tr("PDB file (*.pdb)"), tr("All files (*)") });
|
||||
|
||||
if (!dialog.exec())
|
||||
{
|
||||
if (!dialog.exec()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString pdbFile = dialog.selectedFiles().first();
|
||||
|
||||
if (!pdbFile.isEmpty())
|
||||
{
|
||||
if (!pdbFile.isEmpty()) {
|
||||
Core()->loadPDB(pdbFile);
|
||||
addOutput(tr("%1 loaded.").arg(pdbFile));
|
||||
}
|
||||
@ -763,10 +728,12 @@ void MainWindow::projectSaved(const QString &name)
|
||||
addOutput(tr("Project saved: ") + name);
|
||||
}
|
||||
|
||||
void MainWindow::addToDockWidgetList(QDockWidget *dockWidget) {
|
||||
void MainWindow::addToDockWidgetList(QDockWidget *dockWidget)
|
||||
{
|
||||
this->dockWidgets.push_back(dockWidget);
|
||||
}
|
||||
|
||||
void MainWindow::addDockWidgetAction(QDockWidget *dockWidget, QAction *action) {
|
||||
void MainWindow::addDockWidgetAction(QDockWidget *dockWidget, QAction *action)
|
||||
{
|
||||
this->dockWidgetActions[action] = dockWidget;
|
||||
}
|
||||
|
@ -46,9 +46,8 @@ class JupyterWidget;
|
||||
#endif
|
||||
class QDockWidget;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MainWindow;
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
|
||||
@ -62,7 +61,8 @@ public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
void openNewFile(const QString &fn, int analLevel = -1, QList<QString> advancedOptions = QList<QString>());
|
||||
void openNewFile(const QString &fn, int analLevel = -1,
|
||||
QList<QString> advancedOptions = QList<QString>());
|
||||
void displayNewFileDialog();
|
||||
void closeNewFileDialog();
|
||||
void displayAnalysisOptionsDialog(int analLevel, QList<QString> advancedOptions);
|
||||
@ -211,7 +211,10 @@ private:
|
||||
void toggleDockWidget(QDockWidget *dock_widget, bool show);
|
||||
|
||||
public:
|
||||
QString getFilename() const { return filename; }
|
||||
QString getFilename() const
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -24,19 +24,19 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
||||
"<h2>Authors</h2>"
|
||||
"xarkes, thestr4ng3r, ballessay<br/>"
|
||||
"Based on work by Hugo Teso <hugo.teso@gmail.org> (originally Iaito).")
|
||||
.arg(
|
||||
.arg(
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
"ON"
|
||||
"ON"
|
||||
#else
|
||||
"OFF"
|
||||
"OFF"
|
||||
#endif
|
||||
,
|
||||
,
|
||||
#ifdef CUTTER_ENABLE_QTWEBENGINE
|
||||
"ON"
|
||||
"ON"
|
||||
#else
|
||||
"OFF"
|
||||
"OFF"
|
||||
#endif
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
AboutDialog::~AboutDialog() {}
|
||||
|
@ -4,9 +4,8 @@
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AboutDialog;
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
|
@ -36,14 +36,12 @@ void CommentsDialog::setComment(const QString &comment)
|
||||
|
||||
bool CommentsDialog::eventFilter(QObject */*obj*/, QEvent *event)
|
||||
{
|
||||
if(event -> type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast <QKeyEvent*> (event);
|
||||
if (event -> type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast <QKeyEvent *> (event);
|
||||
|
||||
// Confirm comment by pressing Ctrl/Cmd+Return
|
||||
if((keyEvent -> modifiers() & Qt::ControlModifier) &&
|
||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return)))
|
||||
{
|
||||
if ((keyEvent -> modifiers() & Qt::ControlModifier) &&
|
||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return))) {
|
||||
this->accept();
|
||||
return true;
|
||||
}
|
||||
|
@ -4,9 +4,8 @@
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CommentsDialog;
|
||||
namespace Ui {
|
||||
class CommentsDialog;
|
||||
}
|
||||
|
||||
class CommentsDialog : public QDialog
|
||||
|
@ -38,14 +38,12 @@ bool EditInstructionDialog::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(obj);
|
||||
|
||||
if (event -> type() == QEvent::KeyPress)
|
||||
{
|
||||
if (event -> type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast <QKeyEvent *>(event);
|
||||
|
||||
// Confirm comment by pressing Ctrl/Cmd+Return
|
||||
if ((keyEvent -> modifiers() & Qt::ControlModifier) &&
|
||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return)))
|
||||
{
|
||||
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return))) {
|
||||
this->accept();
|
||||
return true;
|
||||
}
|
||||
|
@ -5,9 +5,8 @@
|
||||
#include <QKeyEvent>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditInstructionDialog;
|
||||
namespace Ui {
|
||||
class EditInstructionDialog;
|
||||
}
|
||||
|
||||
class EditInstructionDialog : public QDialog
|
||||
|
@ -6,9 +6,8 @@
|
||||
#include <memory>
|
||||
#include "Cutter.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FlagDialog;
|
||||
namespace Ui {
|
||||
class FlagDialog;
|
||||
}
|
||||
|
||||
class FlagDialog : public QDialog
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
const int NewFileDialog::MaxRecentFiles;
|
||||
|
||||
static QColor getColorFor(const QString& str, int pos)
|
||||
static QColor getColorFor(const QString &str, int pos)
|
||||
{
|
||||
Q_UNUSED(str);
|
||||
|
||||
@ -30,7 +30,7 @@ static QColor getColorFor(const QString& str, int pos)
|
||||
|
||||
}
|
||||
|
||||
static QIcon getIconFor(const QString& str, int pos)
|
||||
static QIcon getIconFor(const QString &str, int pos)
|
||||
{
|
||||
// Add to the icon list
|
||||
int w = 64;
|
||||
@ -51,8 +51,8 @@ static QIcon getIconFor(const QString& str, int pos)
|
||||
}
|
||||
|
||||
NewFileDialog::NewFileDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewFileDialog)
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewFileDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
@ -64,12 +64,9 @@ NewFileDialog::NewFileDialog(QWidget *parent) :
|
||||
fillRecentFilesList();
|
||||
bool projectsExist = fillProjectsList();
|
||||
|
||||
if(projectsExist)
|
||||
{
|
||||
if (projectsExist) {
|
||||
ui->tabWidget->setCurrentWidget(ui->projectsTab);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->tabWidget->setCurrentWidget(ui->filesTab);
|
||||
}
|
||||
|
||||
@ -90,8 +87,7 @@ void NewFileDialog::on_selectFileButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select file"), QDir::homePath());
|
||||
|
||||
if (!fileName.isEmpty())
|
||||
{
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->newFileEdit->setText(fileName);
|
||||
ui->loadFileButton->setFocus();
|
||||
}
|
||||
@ -103,22 +99,19 @@ void NewFileDialog::on_selectProjectsDirButton_clicked()
|
||||
dialog.setFileMode(QFileDialog::DirectoryOnly);
|
||||
|
||||
QString currentDir = CutterCore::getInstance()->getConfig("dir.projects");
|
||||
if(currentDir.startsWith("~"))
|
||||
{
|
||||
if (currentDir.startsWith("~")) {
|
||||
currentDir = QDir::homePath() + currentDir.mid(1);
|
||||
}
|
||||
dialog.setDirectory(currentDir);
|
||||
|
||||
dialog.setWindowTitle(tr("Select project path (dir.projects)"));
|
||||
|
||||
if(!dialog.exec())
|
||||
{
|
||||
if (!dialog.exec()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString dir = dialog.selectedFiles().first();
|
||||
if (!dir.isEmpty())
|
||||
{
|
||||
if (!dir.isEmpty()) {
|
||||
CutterCore::getInstance()->setConfig("dir.projects", dir);
|
||||
fillProjectsList();
|
||||
}
|
||||
@ -128,8 +121,7 @@ void NewFileDialog::on_loadProjectButton_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->projectsListWidget->currentItem();
|
||||
|
||||
if (item == nullptr)
|
||||
{
|
||||
if (item == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -160,8 +152,8 @@ void NewFileDialog::on_projectsListWidget_itemDoubleClicked(QListWidgetItem *ite
|
||||
|
||||
void NewFileDialog::on_aboutButton_clicked()
|
||||
{
|
||||
AboutDialog *a = new AboutDialog(this);
|
||||
a->open();
|
||||
AboutDialog *a = new AboutDialog(this);
|
||||
a->open();
|
||||
}
|
||||
|
||||
void NewFileDialog::on_actionRemove_item_triggered()
|
||||
@ -198,8 +190,7 @@ void NewFileDialog::on_actionClear_all_triggered()
|
||||
void NewFileDialog::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
// Accept drag & drop events only if they provide a URL
|
||||
if(event->mimeData()->hasUrls())
|
||||
{
|
||||
if (event->mimeData()->hasUrls()) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
@ -207,8 +198,7 @@ void NewFileDialog::dragEnterEvent(QDragEnterEvent *event)
|
||||
void NewFileDialog::dropEvent(QDropEvent *event)
|
||||
{
|
||||
// Accept drag & drop events only if they provide a URL
|
||||
if(event->mimeData()->urls().count() == 0)
|
||||
{
|
||||
if (event->mimeData()->urls().count() == 0) {
|
||||
qWarning() << "No URL in drop event, ignoring it.";
|
||||
return;
|
||||
}
|
||||
@ -226,8 +216,7 @@ bool NewFileDialog::fillRecentFilesList()
|
||||
|
||||
QMutableListIterator<QString> it(files);
|
||||
int i = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
while (it.hasNext()) {
|
||||
const QString &file = it.next();
|
||||
// Get stored files
|
||||
|
||||
@ -238,15 +227,13 @@ bool NewFileDialog::fillRecentFilesList()
|
||||
|
||||
// Get file info
|
||||
QFileInfo info(file);
|
||||
if (!info.exists())
|
||||
{
|
||||
if (!info.exists()) {
|
||||
it.remove();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QListWidgetItem *item = new QListWidgetItem(
|
||||
getIconFor(name, i++),
|
||||
file + "\nCreated: " + info.created().toString() + "\nSize: " + qhelpers::formatBytecount(info.size())
|
||||
getIconFor(name, i++),
|
||||
file + "\nCreated: " + info.created().toString() + "\nSize: " + qhelpers::formatBytecount(
|
||||
info.size())
|
||||
);
|
||||
//":/img/icons/target.svg"), name );
|
||||
item->setData(Qt::UserRole, file);
|
||||
@ -271,9 +258,8 @@ bool NewFileDialog::fillProjectsList()
|
||||
|
||||
ui->projectsListWidget->clear();
|
||||
|
||||
int i=0;
|
||||
for(const QString &project : projects)
|
||||
{
|
||||
int i = 0;
|
||||
for (const QString &project : projects) {
|
||||
QString info = core->cmd("Pi " + project);
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(getIconFor(project, i++), project + "\n" + info);
|
||||
@ -287,8 +273,7 @@ bool NewFileDialog::fillProjectsList()
|
||||
|
||||
void NewFileDialog::loadFile(const QString &filename)
|
||||
{
|
||||
if(!Core()->tryFile(filename, false))
|
||||
{
|
||||
if (!Core()->tryFile(filename, false)) {
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setText(tr("Select a new program or a previous one before continuing."));
|
||||
msgBox.exec();
|
||||
|
@ -5,14 +5,13 @@
|
||||
#include <QListWidgetItem>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class NewFileDialog;
|
||||
namespace Ui {
|
||||
class NewFileDialog;
|
||||
}
|
||||
|
||||
class NewFileDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewFileDialog(QWidget *parent = 0);
|
||||
|
@ -43,7 +43,7 @@ OptionsDialog::OptionsDialog(MainWindow *main):
|
||||
ui->bitsComboBox->setToolTip(core->cmd("e? asm.bits").trimmed());
|
||||
|
||||
ui->entry_analbb->setToolTip(core->cmd("e? anal.bb.maxsize").trimmed());
|
||||
|
||||
|
||||
for (auto plugin : core->getRBinPluginDescriptions("bin"))
|
||||
ui->formatComboBox->addItem(plugin.name, QVariant::fromValue(plugin));
|
||||
|
||||
@ -106,8 +106,7 @@ QString OptionsDialog::getSelectedCPU()
|
||||
int OptionsDialog::getSelectedBits()
|
||||
{
|
||||
QString sel_bits = ui->bitsComboBox->currentText();
|
||||
if (sel_bits != "Auto")
|
||||
{
|
||||
if (sel_bits != "Auto") {
|
||||
return sel_bits.toInt();
|
||||
}
|
||||
|
||||
@ -126,8 +125,7 @@ int OptionsDialog::getSelectedBBSize()
|
||||
|
||||
OptionsDialog::Endianness OptionsDialog::getSelectedEndianness()
|
||||
{
|
||||
switch(ui->endiannessComboBox->currentIndex())
|
||||
{
|
||||
switch (ui->endiannessComboBox->currentIndex()) {
|
||||
case 1:
|
||||
return Endianness::Little;
|
||||
case 2:
|
||||
@ -174,18 +172,16 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList<QString> advanced)
|
||||
|
||||
void OptionsDialog::updateProgressTimer()
|
||||
{
|
||||
int secondsElapsed = (analElapsedTimer.elapsed()+500)/1000;
|
||||
int secondsElapsed = (analElapsedTimer.elapsed() + 500) / 1000;
|
||||
int minutesElapsed = secondsElapsed / 60;
|
||||
int hoursElapsed = minutesElapsed / 60;
|
||||
|
||||
QString label = tr("Running for") + " ";
|
||||
if(hoursElapsed)
|
||||
{
|
||||
if (hoursElapsed) {
|
||||
label += tr("%n hour", "%n hours", hoursElapsed);
|
||||
label += " ";
|
||||
}
|
||||
if(minutesElapsed)
|
||||
{
|
||||
if (minutesElapsed) {
|
||||
label += tr("%n minute", "%n minutes", minutesElapsed % 60);
|
||||
label += " ";
|
||||
}
|
||||
@ -201,58 +197,44 @@ void OptionsDialog::updateProgress(const QString &status)
|
||||
void OptionsDialog::on_okButton_clicked()
|
||||
{
|
||||
QList<QString> advanced = QList<QString>();
|
||||
if (ui->analSlider->value() == 3)
|
||||
{
|
||||
if (ui->aa_symbols->isChecked())
|
||||
{
|
||||
if (ui->analSlider->value() == 3) {
|
||||
if (ui->aa_symbols->isChecked()) {
|
||||
advanced << "aa";
|
||||
}
|
||||
if (ui->aar_references->isChecked())
|
||||
{
|
||||
if (ui->aar_references->isChecked()) {
|
||||
advanced << "aar";
|
||||
}
|
||||
if (ui->aac_calls->isChecked())
|
||||
{
|
||||
if (ui->aac_calls->isChecked()) {
|
||||
advanced << "aac";
|
||||
}
|
||||
if (ui->aab_basicblocks->isChecked())
|
||||
{
|
||||
if (ui->aab_basicblocks->isChecked()) {
|
||||
advanced << "aab";
|
||||
}
|
||||
if (ui->aan_rename->isChecked())
|
||||
{
|
||||
if (ui->aan_rename->isChecked()) {
|
||||
advanced << "aan";
|
||||
}
|
||||
if (ui->aae_emulate->isChecked())
|
||||
{
|
||||
if (ui->aae_emulate->isChecked()) {
|
||||
advanced << "aae";
|
||||
}
|
||||
if (ui->aat_consecutive->isChecked())
|
||||
{
|
||||
if (ui->aat_consecutive->isChecked()) {
|
||||
advanced << "aat";
|
||||
}
|
||||
if (ui->afta_typeargument->isChecked())
|
||||
{
|
||||
if (ui->afta_typeargument->isChecked()) {
|
||||
advanced << "afta";
|
||||
}
|
||||
if (ui->aaT_aftertrap->isChecked())
|
||||
{
|
||||
if (ui->aaT_aftertrap->isChecked()) {
|
||||
advanced << "aaT";
|
||||
}
|
||||
if (ui->aap_preludes->isChecked())
|
||||
{
|
||||
if (ui->aap_preludes->isChecked()) {
|
||||
advanced << "aap";
|
||||
}
|
||||
if (ui->jmptbl->isChecked())
|
||||
{
|
||||
if (ui->jmptbl->isChecked()) {
|
||||
advanced << "e! anal.jmptbl";
|
||||
}
|
||||
if (ui->pushret->isChecked())
|
||||
{
|
||||
if (ui->pushret->isChecked()) {
|
||||
advanced << "e! anal.pushret";
|
||||
}
|
||||
if (ui->hasnext->isChecked())
|
||||
{
|
||||
if (ui->hasnext->isChecked()) {
|
||||
advanced << "e! anal.hasnext";
|
||||
}
|
||||
}
|
||||
@ -262,8 +244,7 @@ void OptionsDialog::on_okButton_clicked()
|
||||
|
||||
void OptionsDialog::anal_finished()
|
||||
{
|
||||
if (analThread.isInterrupted())
|
||||
{
|
||||
if (analThread.isInterrupted()) {
|
||||
done(0);
|
||||
return;
|
||||
}
|
||||
@ -277,8 +258,7 @@ void OptionsDialog::anal_finished()
|
||||
|
||||
void OptionsDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (analThread.isRunning())
|
||||
{
|
||||
if (analThread.isRunning()) {
|
||||
analThread.interruptAndWait();
|
||||
}
|
||||
event->accept();
|
||||
@ -287,8 +267,7 @@ void OptionsDialog::closeEvent(QCloseEvent *event)
|
||||
QString OptionsDialog::analysisDescription(int level)
|
||||
{
|
||||
//TODO: replace this with meaningful descriptions
|
||||
switch (level)
|
||||
{
|
||||
switch (level) {
|
||||
case 0:
|
||||
return tr("No analysis");
|
||||
case 1:
|
||||
@ -305,21 +284,15 @@ QString OptionsDialog::analysisDescription(int level)
|
||||
void OptionsDialog::on_analSlider_valueChanged(int value)
|
||||
{
|
||||
ui->analDescription->setText(tr("Level") + QString(": %1").arg(analysisDescription(value)));
|
||||
if (value == 0)
|
||||
{
|
||||
if (value == 0) {
|
||||
ui->analCheckBox->setChecked(false);
|
||||
ui->analCheckBox->setText(tr("Analysis: Disabled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->analCheckBox->setChecked(true);
|
||||
ui->analCheckBox->setText(tr("Analysis: Enabled"));
|
||||
if (value == 3)
|
||||
{
|
||||
if (value == 3) {
|
||||
ui->analoptionsFrame->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->analoptionsFrame->setVisible(false);
|
||||
}
|
||||
}
|
||||
@ -327,13 +300,10 @@ void OptionsDialog::on_analSlider_valueChanged(int value)
|
||||
|
||||
void OptionsDialog::on_AdvOptButton_clicked()
|
||||
{
|
||||
if (ui->AdvOptButton->isChecked())
|
||||
{
|
||||
if (ui->AdvOptButton->isChecked()) {
|
||||
ui->hideFrame->setVisible(true);
|
||||
ui->AdvOptButton->setArrowType(Qt::DownArrow);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->hideFrame->setVisible(false);
|
||||
ui->AdvOptButton->setArrowType(Qt::RightArrow);
|
||||
}
|
||||
@ -362,15 +332,13 @@ void OptionsDialog::on_pdbSelectButton_clicked()
|
||||
dialog.setWindowTitle(tr("Select PDB file"));
|
||||
dialog.setNameFilters({ tr("PDB file (*.pdb)"), tr("All files (*)") });
|
||||
|
||||
if (!dialog.exec())
|
||||
{
|
||||
if (!dialog.exec()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = dialog.selectedFiles().first();
|
||||
|
||||
if (!fileName.isEmpty())
|
||||
{
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->pdbLineEdit->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ private slots:
|
||||
void anal_finished();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
AnalThread analThread;
|
||||
@ -64,7 +64,7 @@ public:
|
||||
QString getSelectedCPU();
|
||||
int getSelectedBits();
|
||||
int getSelectedBBSize();
|
||||
Endianness getSelectedEndianness();
|
||||
Endianness getSelectedEndianness();
|
||||
QString getSelectedOS();
|
||||
QTimer analTimer;
|
||||
QElapsedTimer analElapsedTimer;
|
||||
|
@ -10,9 +10,8 @@ R2PluginsDialog::R2PluginsDialog(QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
for(auto plugin : Core()->getRBinPluginDescriptions())
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
for (auto plugin : Core()->getRBinPluginDescriptions()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, plugin.name);
|
||||
item->setText(1, plugin.description);
|
||||
item->setText(2, plugin.license);
|
||||
@ -21,9 +20,8 @@ R2PluginsDialog::R2PluginsDialog(QWidget *parent) :
|
||||
}
|
||||
qhelpers::adjustColumns(ui->RBinTreeWidget, 0);
|
||||
|
||||
for(auto plugin : Core()->getRIOPluginDescriptions())
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
for (auto plugin : Core()->getRIOPluginDescriptions()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, plugin.name);
|
||||
item->setText(1, plugin.description);
|
||||
item->setText(2, plugin.license);
|
||||
@ -32,18 +30,16 @@ R2PluginsDialog::R2PluginsDialog(QWidget *parent) :
|
||||
}
|
||||
qhelpers::adjustColumns(ui->RIOTreeWidget, 0);
|
||||
|
||||
for(auto plugin : Core()->getRCorePluginDescriptions())
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
for (auto plugin : Core()->getRCorePluginDescriptions()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, plugin.name);
|
||||
item->setText(1, plugin.description);
|
||||
ui->RCoreTreeWidget->addTopLevelItem(item);
|
||||
}
|
||||
qhelpers::adjustColumns(ui->RCoreTreeWidget, 0);
|
||||
|
||||
for(auto plugin : Core()->getRAsmPluginDescriptions())
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
for (auto plugin : Core()->getRAsmPluginDescriptions()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, plugin.name);
|
||||
item->setText(1, plugin.architecture);
|
||||
item->setText(2, plugin.cpus);
|
||||
|
@ -6,9 +6,8 @@
|
||||
|
||||
#include "Cutter.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class R2PluginsDialog;
|
||||
namespace Ui {
|
||||
class R2PluginsDialog;
|
||||
}
|
||||
|
||||
class R2PluginsDialog : public QDialog
|
||||
|
@ -4,9 +4,8 @@
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class RenameDialog;
|
||||
namespace Ui {
|
||||
class RenameDialog;
|
||||
}
|
||||
|
||||
class RenameDialog : public QDialog
|
||||
|
@ -7,21 +7,18 @@
|
||||
#include "utils/TempConfig.h"
|
||||
|
||||
SaveProjectDialog::SaveProjectDialog(bool quit, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SaveProjectDialog)
|
||||
QDialog(parent),
|
||||
ui(new Ui::SaveProjectDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
CutterCore *core = CutterCore::getInstance();
|
||||
|
||||
if (quit)
|
||||
{
|
||||
if (quit) {
|
||||
ui->buttonBox->setStandardButtons(QDialogButtonBox::Save
|
||||
| QDialogButtonBox::Discard
|
||||
| QDialogButtonBox::Cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->buttonBox->setStandardButtons(QDialogButtonBox::Save
|
||||
| QDialogButtonBox::Cancel);
|
||||
}
|
||||
@ -44,40 +41,36 @@ void SaveProjectDialog::on_selectProjectsDirButton_clicked()
|
||||
dialog.setFileMode(QFileDialog::DirectoryOnly);
|
||||
|
||||
QString currentDir = ui->projectsDirEdit->text();
|
||||
if(currentDir.startsWith("~"))
|
||||
{
|
||||
if (currentDir.startsWith("~")) {
|
||||
currentDir = QDir::homePath() + currentDir.mid(1);
|
||||
}
|
||||
dialog.setDirectory(currentDir);
|
||||
|
||||
dialog.setWindowTitle(tr("Select project path (dir.projects)"));
|
||||
|
||||
if(!dialog.exec())
|
||||
{
|
||||
if (!dialog.exec()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString dir = dialog.selectedFiles().first();
|
||||
if (!dir.isEmpty())
|
||||
{
|
||||
if (!dir.isEmpty()) {
|
||||
ui->projectsDirEdit->setText(dir);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveProjectDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
switch(ui->buttonBox->buttonRole(button))
|
||||
{
|
||||
case QDialogButtonBox::DestructiveRole:
|
||||
QDialog::done(Destructive);
|
||||
break;
|
||||
switch (ui->buttonBox->buttonRole(button)) {
|
||||
case QDialogButtonBox::DestructiveRole:
|
||||
QDialog::done(Destructive);
|
||||
break;
|
||||
|
||||
case QDialogButtonBox::RejectRole:
|
||||
QDialog::done(Rejected);
|
||||
break;
|
||||
case QDialogButtonBox::RejectRole:
|
||||
QDialog::done(Rejected);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,14 +78,13 @@ void SaveProjectDialog::accept()
|
||||
{
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("dir.projects", ui->projectsDirEdit->text().toUtf8().constData())
|
||||
.set("prj.simple", ui->simpleCheckBox->isChecked())
|
||||
.set("prj.files", ui->filesCheckBox->isChecked())
|
||||
.set("prj.git", ui->gitCheckBox->isChecked())
|
||||
.set("prj.zip", ui->zipCheckBox->isChecked());
|
||||
.set("prj.simple", ui->simpleCheckBox->isChecked())
|
||||
.set("prj.files", ui->filesCheckBox->isChecked())
|
||||
.set("prj.git", ui->gitCheckBox->isChecked())
|
||||
.set("prj.zip", ui->zipCheckBox->isChecked());
|
||||
|
||||
QString projectName = ui->nameEdit->text().trimmed();
|
||||
if(!CutterCore::isProjectNameValid(projectName))
|
||||
{
|
||||
if (!CutterCore::isProjectNameValid(projectName)) {
|
||||
QMessageBox::critical(this, tr("Save project"), tr("Invalid project name."));
|
||||
return;
|
||||
}
|
||||
|
@ -6,9 +6,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SaveProjectDialog;
|
||||
namespace Ui {
|
||||
class SaveProjectDialog;
|
||||
}
|
||||
|
||||
class SaveProjectDialog : public QDialog
|
||||
|
@ -37,8 +37,7 @@ void XrefsDialog::fillRefs(QList<XrefDescription> refs, QList<XrefDescription> x
|
||||
{
|
||||
/* Fill refs */
|
||||
ui->fromTreeWidget->clear();
|
||||
for (int i = 0; i < refs.size(); ++i)
|
||||
{
|
||||
for (int i = 0; i < refs.size(); ++i) {
|
||||
XrefDescription xref = refs[i];
|
||||
|
||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||
@ -50,15 +49,13 @@ void XrefsDialog::fillRefs(QList<XrefDescription> refs, QList<XrefDescription> x
|
||||
}
|
||||
// Adjust columns to content
|
||||
int count = ui->fromTreeWidget->columnCount();
|
||||
for (int i = 0; i != count; ++i)
|
||||
{
|
||||
for (int i = 0; i != count; ++i) {
|
||||
ui->fromTreeWidget->resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
/* Fill Xrefs */
|
||||
ui->toTreeWidget->clear();
|
||||
for (int i = 0; i < xrefs.size(); ++i)
|
||||
{
|
||||
for (int i = 0; i < xrefs.size(); ++i) {
|
||||
XrefDescription xref = xrefs[i];
|
||||
|
||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||
@ -70,8 +67,7 @@ void XrefsDialog::fillRefs(QList<XrefDescription> refs, QList<XrefDescription> x
|
||||
}
|
||||
// Adjust columns to content
|
||||
int count2 = ui->toTreeWidget->columnCount();
|
||||
for (int i = 0; i != count2; ++i)
|
||||
{
|
||||
for (int i = 0; i != count2; ++i) {
|
||||
ui->toTreeWidget->resizeColumnToContents(i);
|
||||
}
|
||||
}
|
||||
@ -94,13 +90,12 @@ void XrefsDialog::on_toTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int c
|
||||
this->close();
|
||||
}
|
||||
|
||||
QString XrefsDialog::normalizeAddr(const QString& addr) const
|
||||
QString XrefsDialog::normalizeAddr(const QString &addr) const
|
||||
{
|
||||
QString r = addr;
|
||||
QString base = addr.split("0x")[1].trimmed();
|
||||
int len = base.length();
|
||||
if (len < 8)
|
||||
{
|
||||
if (len < 8) {
|
||||
int padding = 8 - len;
|
||||
QString zero = "0";
|
||||
QString zeroes = zero.repeated(padding);
|
||||
@ -118,16 +113,15 @@ void XrefsDialog::setupPreviewFont()
|
||||
void XrefsDialog::setupPreviewColors()
|
||||
{
|
||||
ui->previewTextEdit->setStyleSheet(QString("QPlainTextEdit { background-color: %1; color: %2; }")
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name()));
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name()));
|
||||
}
|
||||
|
||||
void XrefsDialog::highlightCurrentLine()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
if (ui->previewTextEdit->isReadOnly())
|
||||
{
|
||||
if (ui->previewTextEdit->isReadOnly()) {
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
QColor lineColor = QColor(190, 144, 212);
|
||||
|
@ -9,9 +9,8 @@
|
||||
|
||||
class MainWindow;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class XrefsDialog;
|
||||
namespace Ui {
|
||||
class XrefsDialog;
|
||||
}
|
||||
|
||||
class XrefsDialog : public QDialog
|
||||
@ -28,7 +27,7 @@ private slots:
|
||||
void on_fromTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||
void on_toTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||
|
||||
QString normalizeAddr(const QString& addr) const;
|
||||
QString normalizeAddr(const QString &addr) const;
|
||||
|
||||
void setupPreviewFont();
|
||||
void setupPreviewColors();
|
||||
|
@ -10,13 +10,13 @@
|
||||
#include "utils/Configuration.h"
|
||||
|
||||
AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog */*dialog*/, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::AsmOptionsWidget)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::AsmOptionsWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->syntaxComboBox->blockSignals(true);
|
||||
for(const auto &syntax : Core()->cmdList("e asm.syntax=?"))
|
||||
for (const auto &syntax : Core()->cmdList("e asm.syntax=?"))
|
||||
ui->syntaxComboBox->addItem(syntax, syntax);
|
||||
ui->syntaxComboBox->blockSignals(false);
|
||||
|
||||
@ -62,10 +62,8 @@ void AsmOptionsWidget::updateAsmOptionsFromVars()
|
||||
|
||||
|
||||
QString currentSyntax = Core()->getConfig("asm.syntax");
|
||||
for (int i = 0; i < ui->syntaxComboBox->count(); i++)
|
||||
{
|
||||
if (ui->syntaxComboBox->itemData(i) == currentSyntax)
|
||||
{
|
||||
for (int i = 0; i < ui->syntaxComboBox->count(); i++) {
|
||||
if (ui->syntaxComboBox->itemData(i) == currentSyntax) {
|
||||
ui->syntaxComboBox->blockSignals(true);
|
||||
ui->syntaxComboBox->setCurrentIndex(i);
|
||||
ui->syntaxComboBox->blockSignals(false);
|
||||
@ -74,16 +72,11 @@ void AsmOptionsWidget::updateAsmOptionsFromVars()
|
||||
}
|
||||
|
||||
ui->caseComboBox->blockSignals(true);
|
||||
if (Core()->getConfigb("asm.ucase"))
|
||||
{
|
||||
if (Core()->getConfigb("asm.ucase")) {
|
||||
ui->caseComboBox->setCurrentIndex(1);
|
||||
}
|
||||
else if(Core()->getConfigb("asm.capitalize"))
|
||||
{
|
||||
} else if (Core()->getConfigb("asm.capitalize")) {
|
||||
ui->caseComboBox->setCurrentIndex(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->caseComboBox->setCurrentIndex(0);
|
||||
}
|
||||
ui->caseComboBox->blockSignals(false);
|
||||
@ -223,7 +216,8 @@ void AsmOptionsWidget::on_nbytesSpinBox_valueChanged(int value)
|
||||
|
||||
void AsmOptionsWidget::on_syntaxComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
Core()->setConfig("asm.syntax", ui->syntaxComboBox->itemData(index).toString().toUtf8().constData());
|
||||
Core()->setConfig("asm.syntax",
|
||||
ui->syntaxComboBox->itemData(index).toString().toUtf8().constData());
|
||||
triggerAsmOptionsChanged();
|
||||
}
|
||||
|
||||
@ -232,8 +226,7 @@ void AsmOptionsWidget::on_caseComboBox_currentIndexChanged(int index)
|
||||
bool ucase;
|
||||
bool capitalize;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
switch (index) {
|
||||
// lowercase
|
||||
case 0:
|
||||
default:
|
||||
@ -287,15 +280,14 @@ void AsmOptionsWidget::on_varsubOnlyCheckBox_toggled(bool checked)
|
||||
|
||||
void AsmOptionsWidget::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
switch (ui->buttonBox->buttonRole(button))
|
||||
{
|
||||
case QDialogButtonBox::ButtonRole::ApplyRole:
|
||||
saveAsDefault();
|
||||
break;
|
||||
case QDialogButtonBox::ButtonRole::ResetRole:
|
||||
resetToDefault();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (ui->buttonBox->buttonRole(button)) {
|
||||
case QDialogButtonBox::ButtonRole::ApplyRole:
|
||||
saveAsDefault();
|
||||
break;
|
||||
case QDialogButtonBox::ButtonRole::ResetRole:
|
||||
resetToDefault();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
class PreferencesDialog;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AsmOptionsWidget;
|
||||
namespace Ui {
|
||||
class AsmOptionsWidget;
|
||||
}
|
||||
|
||||
class AsmOptionsWidget : public QDialog
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include "utils/Configuration.h"
|
||||
|
||||
GeneralOptionsWidget::GeneralOptionsWidget(PreferencesDialog */*dialog*/, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::GeneralOptionsWidget)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::GeneralOptionsWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -33,7 +33,8 @@ void GeneralOptionsWidget::updateFontFromConfig()
|
||||
void GeneralOptionsWidget::updateThemeFromConfig()
|
||||
{
|
||||
// Disconnect currentIndexChanged because clearing the comboxBox and refiling it causes its index to change.
|
||||
disconnect(ui->colorComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_colorComboBox_currentIndexChanged(int)));
|
||||
disconnect(ui->colorComboBox, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(on_colorComboBox_currentIndexChanged(int)));
|
||||
ui->themeComboBox->setCurrentIndex(Config()->getDarkTheme() ? 1 : 0);
|
||||
|
||||
QList<QString> themes = Core()->getColorThemes();
|
||||
@ -45,7 +46,7 @@ void GeneralOptionsWidget::updateThemeFromConfig()
|
||||
int index = themes.indexOf(curTheme) + 1;
|
||||
ui->colorComboBox->setCurrentIndex(index);
|
||||
int maxThemeLen = 0;
|
||||
for (QString str : themes){
|
||||
for (QString str : themes) {
|
||||
int strLen = str.length();
|
||||
if (strLen > maxThemeLen) {
|
||||
maxThemeLen = strLen;
|
||||
@ -53,7 +54,8 @@ void GeneralOptionsWidget::updateThemeFromConfig()
|
||||
}
|
||||
ui->colorComboBox->setMinimumContentsLength(maxThemeLen);
|
||||
ui->colorComboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
|
||||
connect(ui->colorComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_colorComboBox_currentIndexChanged(int)));
|
||||
connect(ui->colorComboBox, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(on_colorComboBox_currentIndexChanged(int)));
|
||||
}
|
||||
|
||||
void GeneralOptionsWidget::on_fontSelectionButton_clicked()
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
class PreferencesDialog;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class GeneralOptionsWidget;
|
||||
namespace Ui {
|
||||
class GeneralOptionsWidget;
|
||||
}
|
||||
|
||||
class GeneralOptionsWidget : public QDialog
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include "utils/Configuration.h"
|
||||
|
||||
GraphOptionsWidget::GraphOptionsWidget(PreferencesDialog */*dialog*/, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::GraphOptionsWidget)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::GraphOptionsWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
class PreferencesDialog;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class GraphOptionsWidget;
|
||||
namespace Ui {
|
||||
class GraphOptionsWidget;
|
||||
}
|
||||
|
||||
class GraphOptionsWidget : public QDialog
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
|
||||
PreferencesDialog::PreferencesDialog(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::PreferencesDialog)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::PreferencesDialog)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
ui->setupUi(this);
|
||||
@ -32,13 +32,12 @@ PreferencesDialog::~PreferencesDialog()
|
||||
|
||||
void PreferencesDialog::showSection(PreferencesDialog::Section section)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case Section::General:
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
break;
|
||||
case Section::Disassembly:
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
break;
|
||||
switch (section) {
|
||||
case Section::General:
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
break;
|
||||
case Section::Disassembly:
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,13 @@
|
||||
|
||||
#include "Cutter.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PreferencesDialog;
|
||||
namespace Ui {
|
||||
class PreferencesDialog;
|
||||
}
|
||||
|
||||
class PreferencesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Section { General, Disassembly };
|
||||
@ -25,9 +24,9 @@ public:
|
||||
|
||||
void showSection(Section section);
|
||||
|
||||
/*signals:
|
||||
void saveAsDefault();
|
||||
void resetToDefault();*/
|
||||
/*signals:
|
||||
void saveAsDefault();
|
||||
void resetToDefault();*/
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::PreferencesDialog> ui;
|
||||
|
@ -42,15 +42,21 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
|
||||
{
|
||||
createAction(&actionCopy, tr("Copy"), getCopySequence(), SLOT(on_actionCopy_triggered()));
|
||||
copySeparator = addSeparator();
|
||||
createAction(&actionAddComment, tr("Add Comment"), getCommentSequence(), SLOT(on_actionAddComment_triggered()));
|
||||
createAction(&actionAddFlag, tr("Add Flag"), getAddFlagSequence(), SLOT(on_actionAddFlag_triggered()));
|
||||
createAction(&actionCreateFunction, tr("Create Function"), {}, SLOT(on_actionCreateFunction_triggered()));
|
||||
createAction(&actionAddComment, tr("Add Comment"), getCommentSequence(),
|
||||
SLOT(on_actionAddComment_triggered()));
|
||||
createAction(&actionAddFlag, tr("Add Flag"), getAddFlagSequence(),
|
||||
SLOT(on_actionAddFlag_triggered()));
|
||||
createAction(&actionCreateFunction, tr("Create Function"), {}, SLOT(
|
||||
on_actionCreateFunction_triggered()));
|
||||
createAction(&actionRename, tr("Rename"), getRenameSequence(), SLOT(on_actionRename_triggered()));
|
||||
createAction(&actionRenameUsedHere, "Rename Flag/Fcn/Var Used Here", getRenameUsedHereSequence(), SLOT(on_actionRenameUsedHere_triggered()));
|
||||
createAction(&actionRenameUsedHere, "Rename Flag/Fcn/Var Used Here", getRenameUsedHereSequence(),
|
||||
SLOT(on_actionRenameUsedHere_triggered()));
|
||||
|
||||
createAction(&actionDeleteComment, tr("Delete comment"), {}, SLOT(on_actionDeleteComment_triggered()));
|
||||
createAction(&actionDeleteComment, tr("Delete comment"), {}, SLOT(
|
||||
on_actionDeleteComment_triggered()));
|
||||
createAction(&actionDeleteFlag, tr("Delete flag"), {}, SLOT(on_actionDeleteFlag_triggered()));
|
||||
createAction(&actionDeleteFunction, tr("Undefine function"), {}, SLOT(on_actionDeleteFunction_triggered()));
|
||||
createAction(&actionDeleteFunction, tr("Undefine function"), {}, SLOT(
|
||||
on_actionDeleteFunction_triggered()));
|
||||
|
||||
setBaseMenu = new QMenu(tr("Set Immediate Base to..."), this);
|
||||
setBaseMenuAction = addMenu(setBaseMenu);
|
||||
@ -82,7 +88,8 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
|
||||
|
||||
addSeparator();
|
||||
createAction(&actionXRefs, tr("Show X-Refs"), getXRefSequence(), SLOT(on_actionXRefs_triggered()));
|
||||
createAction(&actionDisplayOptions, tr("Show Options"), getDisplayOptionsSequence(), SLOT(on_actionDisplayOptions_triggered()));
|
||||
createAction(&actionDisplayOptions, tr("Show Options"), getDisplayOptionsSequence(),
|
||||
SLOT(on_actionDisplayOptions_triggered()));
|
||||
|
||||
addSeparator();
|
||||
editMenu = new QMenu(tr("Edit"), this);
|
||||
@ -96,19 +103,28 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
|
||||
actionJmpReverse.setText(tr("Reverse Jump"));
|
||||
editMenu->addAction(&actionJmpReverse);
|
||||
|
||||
connect(&actionEditInstruction, SIGNAL(triggered(bool)), this, SLOT(on_actionEditInstruction_triggered()));
|
||||
connect(&actionNopInstruction, SIGNAL(triggered(bool)), this, SLOT(on_actionNopInstruction_triggered()));
|
||||
connect(&actionEditInstruction, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionEditInstruction_triggered()));
|
||||
connect(&actionNopInstruction, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionNopInstruction_triggered()));
|
||||
connect(&actionEditBytes, SIGNAL(triggered(bool)), this, SLOT(on_actionEditBytes_triggered()));
|
||||
connect(&actionJmpReverse, SIGNAL(triggered(bool)), this, SLOT(on_actionJmpReverse_triggered()));
|
||||
|
||||
connect(&actionSetBaseBinary, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseBinary_triggered()));
|
||||
connect(&actionSetBaseOctal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseOctal_triggered()));
|
||||
connect(&actionSetBaseDecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseDecimal_triggered()));
|
||||
connect(&actionSetBaseHexadecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseHexadecimal_triggered()));
|
||||
connect(&actionSetBaseBinary, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseBinary_triggered()));
|
||||
connect(&actionSetBaseOctal, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseOctal_triggered()));
|
||||
connect(&actionSetBaseDecimal, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseDecimal_triggered()));
|
||||
connect(&actionSetBaseHexadecimal, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseHexadecimal_triggered()));
|
||||
connect(&actionSetBasePort, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBasePort_triggered()));
|
||||
connect(&actionSetBaseIPAddr, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseIPAddr_triggered()));
|
||||
connect(&actionSetBaseSyscall, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseSyscall_triggered()));
|
||||
connect(&actionSetBaseString, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseString_triggered()));
|
||||
connect(&actionSetBaseIPAddr, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseIPAddr_triggered()));
|
||||
connect(&actionSetBaseSyscall, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseSyscall_triggered()));
|
||||
connect(&actionSetBaseString, SIGNAL(triggered(bool)), this,
|
||||
SLOT(on_actionSetBaseString_triggered()));
|
||||
|
||||
connect(&actionSetBits16, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBits16_triggered()));
|
||||
connect(&actionSetBits32, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBits32_triggered()));
|
||||
@ -119,8 +135,7 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
|
||||
|
||||
DisassemblyContextMenu::~DisassemblyContextMenu()
|
||||
{
|
||||
for(QAction *action : anonymousActions)
|
||||
{
|
||||
for (QAction *action : anonymousActions) {
|
||||
delete action;
|
||||
}
|
||||
}
|
||||
@ -138,7 +153,8 @@ void DisassemblyContextMenu::setCanCopy(bool enabled)
|
||||
void DisassemblyContextMenu::aboutToShowSlot()
|
||||
{
|
||||
// check if set immediate base menu makes sense
|
||||
QJsonObject instObject = Core()->cmdj("aoj @ " + QString::number(offset)).array().first().toObject();
|
||||
QJsonObject instObject = Core()->cmdj("aoj @ " + QString::number(
|
||||
offset)).array().first().toObject();
|
||||
auto keys = instObject.keys();
|
||||
bool immBase = keys.contains("val") || keys.contains("ptr");
|
||||
setBaseMenuAction->setVisible(immBase);
|
||||
@ -147,13 +163,10 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
||||
actionCreateFunction.setVisible(true);
|
||||
|
||||
QString comment = Core()->cmd("CC." + RAddressString(offset));
|
||||
if (comment.isNull() || comment.isEmpty())
|
||||
{
|
||||
if (comment.isNull() || comment.isEmpty()) {
|
||||
actionDeleteComment.setVisible(false);
|
||||
actionAddComment.setText(tr("Add Comment"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
actionDeleteComment.setVisible(true);
|
||||
actionAddComment.setText(tr("Edit Comment"));
|
||||
}
|
||||
@ -169,41 +182,30 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
||||
actionDeleteFlag.setVisible(f ? true : false);
|
||||
actionDeleteFunction.setVisible(fcn ? true : false);
|
||||
|
||||
if (fcn)
|
||||
{
|
||||
if (fcn) {
|
||||
actionCreateFunction.setVisible(false);
|
||||
actionRename.setVisible(true);
|
||||
actionRename.setText(tr("Rename function \"%1\"").arg(fcn->name));
|
||||
}
|
||||
else if (f)
|
||||
{
|
||||
} else if (f) {
|
||||
actionRename.setVisible(true);
|
||||
actionRename.setText(tr("Rename flag \"%1\"").arg(f->name));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
actionRename.setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
// only show "rename X used here" if there is something to rename
|
||||
QJsonArray thingUsedHereArray = Core()->cmdj("anj @ " + QString::number(offset)).array();
|
||||
if (!thingUsedHereArray.isEmpty())
|
||||
{
|
||||
if (!thingUsedHereArray.isEmpty()) {
|
||||
actionRenameUsedHere.setVisible(true);
|
||||
QJsonObject thingUsedHere = thingUsedHereArray.first().toObject();
|
||||
if (thingUsedHere["type"] == "address")
|
||||
{
|
||||
if (thingUsedHere["type"] == "address") {
|
||||
RVA offset = thingUsedHere["offset"].toVariant().toULongLong();
|
||||
actionRenameUsedHere.setText(tr("Add flag at %1 (used here)").arg(RAddressString(offset)));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
actionRenameUsedHere.setText(tr("Rename \"%1\" (used here)").arg(thingUsedHere["name"].toString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
actionRenameUsedHere.setVisible(false);
|
||||
}
|
||||
|
||||
@ -255,11 +257,10 @@ void DisassemblyContextMenu::on_actionEditInstruction_triggered()
|
||||
QString oldInstruction = Core()->cmdj("aoj").array().first().toObject()["opcode"].toString();
|
||||
e->setInstruction(oldInstruction);
|
||||
|
||||
if (e->exec()){}
|
||||
if (e->exec()) {}
|
||||
{
|
||||
QString instruction = e->getInstruction();
|
||||
if (instruction != oldInstruction)
|
||||
{
|
||||
if (instruction != oldInstruction) {
|
||||
Core()->editInstruction(offset, instruction);
|
||||
}
|
||||
}
|
||||
@ -275,18 +276,14 @@ void DisassemblyContextMenu::showReverseJmpQuery()
|
||||
QString type;
|
||||
|
||||
QJsonArray array = Core()->cmdj("pdj 1 @ " + RAddressString(offset)).array();
|
||||
if (array.isEmpty())
|
||||
{
|
||||
if (array.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
type = array.first().toObject()["type"].toString();
|
||||
if (type == "cjmp")
|
||||
{
|
||||
if (type == "cjmp") {
|
||||
actionJmpReverse.setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
actionJmpReverse.setVisible(false);
|
||||
}
|
||||
}
|
||||
@ -304,11 +301,10 @@ void DisassemblyContextMenu::on_actionEditBytes_triggered()
|
||||
QString oldBytes = Core()->cmdj("aoj").array().first().toObject()["bytes"].toString();
|
||||
e->setInstruction(oldBytes);
|
||||
|
||||
if (e->exec()){}
|
||||
if (e->exec()) {}
|
||||
{
|
||||
QString bytes = e->getInstruction();
|
||||
if (bytes != oldBytes)
|
||||
{
|
||||
if (bytes != oldBytes) {
|
||||
Core()->editBytes(offset, bytes);
|
||||
}
|
||||
}
|
||||
@ -323,28 +319,21 @@ void DisassemblyContextMenu::on_actionAddComment_triggered()
|
||||
{
|
||||
QString oldComment = Core()->cmd("CC." + RAddressString(offset));
|
||||
// Remove newline at the end added by cmd
|
||||
oldComment.remove(oldComment.length()-1, 1);
|
||||
oldComment.remove(oldComment.length() - 1, 1);
|
||||
CommentsDialog *c = new CommentsDialog(this);
|
||||
|
||||
if (oldComment.isNull() || oldComment.isEmpty())
|
||||
{
|
||||
if (oldComment.isNull() || oldComment.isEmpty()) {
|
||||
c->setWindowTitle(tr("Add Comment at %1").arg(RAddressString(offset)));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
c->setWindowTitle(tr("Edit Comment at %1").arg(RAddressString(offset)));
|
||||
}
|
||||
|
||||
c->setComment(oldComment);
|
||||
if (c->exec())
|
||||
{
|
||||
if (c->exec()) {
|
||||
QString comment = c->getComment();
|
||||
if (comment.isEmpty())
|
||||
{
|
||||
if (comment.isEmpty()) {
|
||||
Core()->delComment(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Core()->setComment(offset, comment);
|
||||
}
|
||||
}
|
||||
@ -354,8 +343,7 @@ void DisassemblyContextMenu::on_actionCreateFunction_triggered()
|
||||
{
|
||||
RenameDialog *dialog = new RenameDialog(this);
|
||||
dialog->setWindowTitle(tr("Add function at %1").arg(RAddressString(offset)));
|
||||
if(dialog->exec())
|
||||
{
|
||||
if (dialog->exec()) {
|
||||
QString function_name = dialog->getName();
|
||||
Core()->createFunctionAt(offset, function_name);
|
||||
}
|
||||
@ -375,30 +363,23 @@ void DisassemblyContextMenu::on_actionRename_triggered()
|
||||
|
||||
RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, offset, R_ANAL_FCN_TYPE_NULL);
|
||||
RFlagItem *f = r_flag_get_i (core->flags, offset);
|
||||
if (fcn)
|
||||
{
|
||||
if (fcn) {
|
||||
/* Rename function */
|
||||
dialog->setWindowTitle(tr("Rename function %1").arg(fcn->name));
|
||||
dialog->setName(fcn->name);
|
||||
if (dialog->exec())
|
||||
{
|
||||
if (dialog->exec()) {
|
||||
QString new_name = dialog->getName();
|
||||
Core()->renameFunction(fcn->name, new_name);
|
||||
}
|
||||
}
|
||||
else if (f)
|
||||
{
|
||||
} else if (f) {
|
||||
/* Rename current flag */
|
||||
dialog->setWindowTitle(tr("Rename flag %1").arg(f->name));
|
||||
dialog->setName(f->name);
|
||||
if (dialog->exec())
|
||||
{
|
||||
if (dialog->exec()) {
|
||||
QString new_name = dialog->getName();
|
||||
Core()->renameFlag(f->name, new_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -406,8 +387,7 @@ void DisassemblyContextMenu::on_actionRename_triggered()
|
||||
void DisassemblyContextMenu::on_actionRenameUsedHere_triggered()
|
||||
{
|
||||
QJsonArray array = Core()->cmdj("anj @ " + QString::number(offset)).array();
|
||||
if (array.isEmpty())
|
||||
{
|
||||
if (array.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -418,36 +398,26 @@ void DisassemblyContextMenu::on_actionRenameUsedHere_triggered()
|
||||
|
||||
QString oldName;
|
||||
|
||||
if (type == "address")
|
||||
{
|
||||
if (type == "address") {
|
||||
RVA offset = thingUsedHere["offset"].toVariant().toULongLong();
|
||||
dialog->setWindowTitle(tr("Add flag at %1").arg(RAddressString(offset)));
|
||||
dialog->setName("label." + QString::number(offset, 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
oldName = thingUsedHere.value("name").toString();
|
||||
dialog->setWindowTitle(tr("Rename %1").arg(oldName));
|
||||
dialog->setName(oldName);
|
||||
}
|
||||
|
||||
if (dialog->exec())
|
||||
{
|
||||
if (dialog->exec()) {
|
||||
QString newName = dialog->getName().trimmed();
|
||||
if (!newName.isEmpty())
|
||||
{
|
||||
if (!newName.isEmpty()) {
|
||||
Core()->cmd("an " + newName + " @ " + QString::number(offset));
|
||||
|
||||
if (type == "address" || type == "flag")
|
||||
{
|
||||
if (type == "address" || type == "flag") {
|
||||
Core()->triggerFlagsChanged();
|
||||
}
|
||||
else if (type == "var")
|
||||
{
|
||||
} else if (type == "var") {
|
||||
Core()->triggerVarsChanged();
|
||||
}
|
||||
else if (type == "function")
|
||||
{
|
||||
} else if (type == "function") {
|
||||
Core()->triggerFunctionRenamed(oldName, newName);
|
||||
}
|
||||
}
|
||||
@ -545,7 +515,8 @@ void DisassemblyContextMenu::createAction(QString name, QKeySequence keySequence
|
||||
createAction(action, name, keySequence, slot);
|
||||
}
|
||||
|
||||
void DisassemblyContextMenu::createAction(QAction *action, QString name, QKeySequence keySequence, const char *slot)
|
||||
void DisassemblyContextMenu::createAction(QAction *action, QString name, QKeySequence keySequence,
|
||||
const char *slot)
|
||||
{
|
||||
action->setText(name);
|
||||
addAction(action);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class DisassemblyContextMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisassemblyContextMenu(QWidget *parent = nullptr);
|
||||
@ -68,7 +68,7 @@ private:
|
||||
RVA offset;
|
||||
bool canCopy;
|
||||
|
||||
QList<QAction*> anonymousActions;
|
||||
QList<QAction *> anonymousActions;
|
||||
|
||||
QMenu *editMenu;
|
||||
QAction *editMenuAction;
|
||||
|
@ -9,7 +9,7 @@ class CachedFontMetrics : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CachedFontMetrics(QObject* parent, const QFont & font)
|
||||
explicit CachedFontMetrics(QObject *parent, const QFont &font)
|
||||
: QObject(parent),
|
||||
mFontMetrics(font)
|
||||
{
|
||||
@ -17,31 +17,29 @@ public:
|
||||
mHeight = mFontMetrics.height();
|
||||
}
|
||||
|
||||
int width(const QChar & ch)
|
||||
int width(const QChar &ch)
|
||||
{
|
||||
auto unicode = ch.unicode();
|
||||
if(unicode >= 0xD800)
|
||||
{
|
||||
if(unicode >= 0xE000)
|
||||
if (unicode >= 0xD800) {
|
||||
if (unicode >= 0xE000)
|
||||
unicode -= 0xE000 - 0xD800;
|
||||
else
|
||||
// is lonely surrogate
|
||||
return mFontMetrics.width(ch);
|
||||
}
|
||||
if(!mWidths[unicode])
|
||||
if (!mWidths[unicode])
|
||||
return mWidths[unicode] = mFontMetrics.width(ch);
|
||||
return mWidths[unicode];
|
||||
}
|
||||
|
||||
int width(const QString & text)
|
||||
int width(const QString &text)
|
||||
{
|
||||
int result = 0;
|
||||
QChar temp;
|
||||
for(const QChar & ch : text)
|
||||
{
|
||||
if(ch.isHighSurrogate())
|
||||
for (const QChar &ch : text) {
|
||||
if (ch.isHighSurrogate())
|
||||
temp = ch;
|
||||
else if(ch.isLowSurrogate())
|
||||
else if (ch.isLowSurrogate())
|
||||
result += mFontMetrics.width(QString(temp) + ch);
|
||||
else
|
||||
result += width(ch);
|
||||
|
@ -7,7 +7,7 @@ Colors::Colors()
|
||||
}
|
||||
|
||||
|
||||
void Colors::colorizeAssembly(RichTextPainter::List & list, QString opcode, ut64 type_num)
|
||||
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
|
||||
{
|
||||
RichTextPainter::CustomRichText_t assembly;
|
||||
assembly.highlight = false;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
|
||||
Configuration* Configuration::mPtr = nullptr;
|
||||
Configuration *Configuration::mPtr = nullptr;
|
||||
|
||||
Configuration::Configuration() : QObject()
|
||||
{
|
||||
@ -13,7 +13,7 @@ Configuration::Configuration() : QObject()
|
||||
loadInitial();
|
||||
}
|
||||
|
||||
Configuration* Configuration::instance()
|
||||
Configuration *Configuration::instance()
|
||||
{
|
||||
if (!mPtr)
|
||||
mPtr = new Configuration();
|
||||
@ -73,23 +73,20 @@ void Configuration::loadDarkTheme()
|
||||
{
|
||||
/* Load Qt Theme */
|
||||
QFile f(":qdarkstyle/style.qss");
|
||||
if (!f.exists())
|
||||
{
|
||||
if (!f.exists()) {
|
||||
qWarning() << "Can't find dark theme stylesheet.";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
f.open(QFile::ReadOnly | QFile::Text);
|
||||
QTextStream ts(&f);
|
||||
QString stylesheet = ts.readAll();
|
||||
#ifdef Q_OS_MACX
|
||||
// see https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529
|
||||
stylesheet += "QDockWidget::title"
|
||||
"{"
|
||||
" background-color: #31363b;"
|
||||
" text-align: center;"
|
||||
" height: 12px;"
|
||||
"}";
|
||||
"{"
|
||||
" background-color: #31363b;"
|
||||
" text-align: center;"
|
||||
" height: 12px;"
|
||||
"}";
|
||||
#endif
|
||||
qApp->setStyleSheet(stylesheet);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ private:
|
||||
public:
|
||||
// Functions
|
||||
Configuration();
|
||||
static Configuration* instance();
|
||||
static Configuration *instance();
|
||||
|
||||
void resetAll();
|
||||
|
||||
@ -39,86 +39,236 @@ public:
|
||||
// Colors
|
||||
const QColor getColor(const QString &name) const;
|
||||
void setDarkTheme(bool set);
|
||||
bool getDarkTheme() { return s.value("dark").toBool(); }
|
||||
bool getDarkTheme()
|
||||
{
|
||||
return s.value("dark").toBool();
|
||||
}
|
||||
|
||||
// Images
|
||||
QString getLogoFile();
|
||||
|
||||
// Graph
|
||||
int getGraphBlockMaxChars() const { return s.value("graph.maxcols", 50).toInt(); }
|
||||
void setGraphBlockMaxChars(int ch) { s.setValue("graph.maxcols", ch); }
|
||||
int getGraphBlockMaxChars() const
|
||||
{
|
||||
return s.value("graph.maxcols", 50).toInt();
|
||||
}
|
||||
void setGraphBlockMaxChars(int ch)
|
||||
{
|
||||
s.setValue("graph.maxcols", ch);
|
||||
}
|
||||
|
||||
// TODO Imho it's wrong doing it this way. Should find something else.
|
||||
bool getAsmESIL() const { return s.value("asm.esil", false).toBool(); }
|
||||
void setAsmESIL(bool v) { s.setValue("asm.esil", v); }
|
||||
bool getAsmESIL() const
|
||||
{
|
||||
return s.value("asm.esil", false).toBool();
|
||||
}
|
||||
void setAsmESIL(bool v)
|
||||
{
|
||||
s.setValue("asm.esil", v);
|
||||
}
|
||||
|
||||
bool getAsmPseudo() const { return s.value("asm.pseudo", false).toBool(); }
|
||||
void setAsmPseudo(bool v) { s.setValue("asm.pseudo", v); }
|
||||
bool getAsmPseudo() const
|
||||
{
|
||||
return s.value("asm.pseudo", false).toBool();
|
||||
}
|
||||
void setAsmPseudo(bool v)
|
||||
{
|
||||
s.setValue("asm.pseudo", v);
|
||||
}
|
||||
|
||||
bool getAsmOffset() const { return s.value("asm.offset", true).toBool(); }
|
||||
void setAsmOffset(bool v) { s.setValue("asm.offset", v); }
|
||||
bool getAsmOffset() const
|
||||
{
|
||||
return s.value("asm.offset", true).toBool();
|
||||
}
|
||||
void setAsmOffset(bool v)
|
||||
{
|
||||
s.setValue("asm.offset", v);
|
||||
}
|
||||
|
||||
bool getAsmDescribe() const { return s.value("asm.describe", false).toBool(); }
|
||||
void setAsmDescribe(bool v) { s.setValue("asm.describe", v); }
|
||||
bool getAsmDescribe() const
|
||||
{
|
||||
return s.value("asm.describe", false).toBool();
|
||||
}
|
||||
void setAsmDescribe(bool v)
|
||||
{
|
||||
s.setValue("asm.describe", v);
|
||||
}
|
||||
|
||||
bool getAsmStackPointer() const { return s.value("asm.stackptr", false).toBool(); }
|
||||
void setAsmStackPointer(bool v) { s.setValue("asm.stackptr", v); }
|
||||
bool getAsmStackPointer() const
|
||||
{
|
||||
return s.value("asm.stackptr", false).toBool();
|
||||
}
|
||||
void setAsmStackPointer(bool v)
|
||||
{
|
||||
s.setValue("asm.stackptr", v);
|
||||
}
|
||||
|
||||
bool getAsmSlow() const { return s.value("asm.slow", true).toBool(); }
|
||||
void setAsmSlow(bool v) { s.setValue("asm.slow", v); }
|
||||
bool getAsmSlow() const
|
||||
{
|
||||
return s.value("asm.slow", true).toBool();
|
||||
}
|
||||
void setAsmSlow(bool v)
|
||||
{
|
||||
s.setValue("asm.slow", v);
|
||||
}
|
||||
|
||||
bool getAsmLines() const { return s.value("asm.lines", true).toBool(); }
|
||||
void setAsmLines(bool v) { s.setValue("asm.lines", v); }
|
||||
bool getAsmLines() const
|
||||
{
|
||||
return s.value("asm.lines", true).toBool();
|
||||
}
|
||||
void setAsmLines(bool v)
|
||||
{
|
||||
s.setValue("asm.lines", v);
|
||||
}
|
||||
|
||||
bool getAsmFcnLines() const { return s.value("asm.fcnlines", true).toBool(); }
|
||||
void setAsmFcnLines(bool v) { s.setValue("asm.fcnlines", v); }
|
||||
bool getAsmFcnLines() const
|
||||
{
|
||||
return s.value("asm.fcnlines", true).toBool();
|
||||
}
|
||||
void setAsmFcnLines(bool v)
|
||||
{
|
||||
s.setValue("asm.fcnlines", v);
|
||||
}
|
||||
|
||||
bool getAsmEmu() const { return s.value("asm.emu", false).toBool(); }
|
||||
void setAsmEmu(bool v) { s.setValue("asm.emu", v); }
|
||||
bool getAsmEmu() const
|
||||
{
|
||||
return s.value("asm.emu", false).toBool();
|
||||
}
|
||||
void setAsmEmu(bool v)
|
||||
{
|
||||
s.setValue("asm.emu", v);
|
||||
}
|
||||
|
||||
bool getAsmCmtRight() const { return s.value("asm.cmt.right", true).toBool(); }
|
||||
void setAsmCmtRight(bool v) { s.setValue("asm.cmt.right", v); }
|
||||
bool getAsmCmtRight() const
|
||||
{
|
||||
return s.value("asm.cmt.right", true).toBool();
|
||||
}
|
||||
void setAsmCmtRight(bool v)
|
||||
{
|
||||
s.setValue("asm.cmt.right", v);
|
||||
}
|
||||
|
||||
bool getAsmVarSum() const { return s.value("asm.varsum", false).toBool(); }
|
||||
void setAsmVarSum(bool v) { s.setValue("asm.varsum", v); }
|
||||
bool getAsmVarSum() const
|
||||
{
|
||||
return s.value("asm.varsum", false).toBool();
|
||||
}
|
||||
void setAsmVarSum(bool v)
|
||||
{
|
||||
s.setValue("asm.varsum", v);
|
||||
}
|
||||
|
||||
bool getAsmBytes() const { return s.value("asm.bytes", false).toBool(); }
|
||||
void setAsmBytes(bool v) { s.setValue("asm.bytes", v); }
|
||||
bool getAsmBytes() const
|
||||
{
|
||||
return s.value("asm.bytes", false).toBool();
|
||||
}
|
||||
void setAsmBytes(bool v)
|
||||
{
|
||||
s.setValue("asm.bytes", v);
|
||||
}
|
||||
|
||||
bool getAsmSize() const { return s.value("asm.size", false).toBool(); }
|
||||
void setAsmSize(bool v) { s.setValue("asm.size", v); }
|
||||
bool getAsmSize() const
|
||||
{
|
||||
return s.value("asm.size", false).toBool();
|
||||
}
|
||||
void setAsmSize(bool v)
|
||||
{
|
||||
s.setValue("asm.size", v);
|
||||
}
|
||||
|
||||
bool getAsmBytespace() const { return s.value("asm.bytespace", false).toBool(); }
|
||||
void setAsmBytespace(bool v) { s.setValue("asm.bytespace", v); }
|
||||
bool getAsmBytespace() const
|
||||
{
|
||||
return s.value("asm.bytespace", false).toBool();
|
||||
}
|
||||
void setAsmBytespace(bool v)
|
||||
{
|
||||
s.setValue("asm.bytespace", v);
|
||||
}
|
||||
|
||||
bool getAsmLBytes() const { return s.value("asm.lbytes", true).toBool(); }
|
||||
void setAsmLBytes(bool v) { s.setValue("asm.lbytes", v); }
|
||||
bool getAsmLBytes() const
|
||||
{
|
||||
return s.value("asm.lbytes", true).toBool();
|
||||
}
|
||||
void setAsmLBytes(bool v)
|
||||
{
|
||||
s.setValue("asm.lbytes", v);
|
||||
}
|
||||
|
||||
int getAsmNBytes() const { return s.value("asm.nbytes", 10).toInt(); }
|
||||
void setAsmNBytes(int v) { s.setValue("asm.nbytes", v); }
|
||||
int getAsmNBytes() const
|
||||
{
|
||||
return s.value("asm.nbytes", 10).toInt();
|
||||
}
|
||||
void setAsmNBytes(int v)
|
||||
{
|
||||
s.setValue("asm.nbytes", v);
|
||||
}
|
||||
|
||||
QString getAsmSyntax() const { return s.value("asm.syntax", "intel").toString(); }
|
||||
void setAsmSyntax(const QString &v) { s.setValue("asm.syntax", v); }
|
||||
QString getAsmSyntax() const
|
||||
{
|
||||
return s.value("asm.syntax", "intel").toString();
|
||||
}
|
||||
void setAsmSyntax(const QString &v)
|
||||
{
|
||||
s.setValue("asm.syntax", v);
|
||||
}
|
||||
|
||||
bool getAsmUppercase() const { return s.value("asm.ucase", false).toBool(); }
|
||||
void setAsmUppercase(bool v) { s.setValue("asm.ucase", v); }
|
||||
bool getAsmUppercase() const
|
||||
{
|
||||
return s.value("asm.ucase", false).toBool();
|
||||
}
|
||||
void setAsmUppercase(bool v)
|
||||
{
|
||||
s.setValue("asm.ucase", v);
|
||||
}
|
||||
|
||||
bool getAsmBBLine() const { return s.value("asm.bbline", false).toBool(); }
|
||||
void setAsmBBLine(bool v) { s.setValue("asm.bbline", v); }
|
||||
bool getAsmBBLine() const
|
||||
{
|
||||
return s.value("asm.bbline", false).toBool();
|
||||
}
|
||||
void setAsmBBLine(bool v)
|
||||
{
|
||||
s.setValue("asm.bbline", v);
|
||||
}
|
||||
|
||||
bool getAsmCapitalize() const { return s.value("asm.capitalize", false).toBool(); }
|
||||
void setAsmCapitalize(bool v) { s.setValue("asm.capitalize", v); }
|
||||
bool getAsmCapitalize() const
|
||||
{
|
||||
return s.value("asm.capitalize", false).toBool();
|
||||
}
|
||||
void setAsmCapitalize(bool v)
|
||||
{
|
||||
s.setValue("asm.capitalize", v);
|
||||
}
|
||||
|
||||
bool getAsmVarsub() const { return s.value("asm.varsub", true).toBool(); }
|
||||
void setAsmVarsub(bool v) { s.setValue("asm.varsub", v); }
|
||||
bool getAsmVarsub() const
|
||||
{
|
||||
return s.value("asm.varsub", true).toBool();
|
||||
}
|
||||
void setAsmVarsub(bool v)
|
||||
{
|
||||
s.setValue("asm.varsub", v);
|
||||
}
|
||||
|
||||
bool getAsmVarsubOnly() const { return s.value("asm.varsub_only", true).toBool(); }
|
||||
void setAsmVarsubOnly(bool v) { s.setValue("asm.varsub_only", v); }
|
||||
bool getAsmVarsubOnly() const
|
||||
{
|
||||
return s.value("asm.varsub_only", true).toBool();
|
||||
}
|
||||
void setAsmVarsubOnly(bool v)
|
||||
{
|
||||
s.setValue("asm.varsub_only", v);
|
||||
}
|
||||
|
||||
int getAsmTabs() const { return s.value("asm.tabs", 5).toInt(); }
|
||||
void setAsmTabs(int v) { s.setValue("asm.tabs", v); }
|
||||
int getAsmTabs() const
|
||||
{
|
||||
return s.value("asm.tabs", 5).toInt();
|
||||
}
|
||||
void setAsmTabs(int v)
|
||||
{
|
||||
s.setValue("asm.tabs", v);
|
||||
}
|
||||
|
||||
QString getCurrentTheme() const { return s.value("theme", "solarized").toString(); }
|
||||
QString getCurrentTheme() const
|
||||
{
|
||||
return s.value("theme", "solarized").toString();
|
||||
}
|
||||
void setColorTheme(QString theme);
|
||||
|
||||
signals:
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include <QAbstractButton>
|
||||
#include <QDockWidget>
|
||||
|
||||
|
||||
|
||||
static QAbstractItemView::ScrollMode scrollMode()
|
||||
{
|
||||
const bool use_scrollperpixel = true;
|
||||
@ -21,174 +19,168 @@ static QAbstractItemView::ScrollMode scrollMode()
|
||||
}
|
||||
|
||||
|
||||
namespace qhelpers
|
||||
namespace qhelpers {
|
||||
|
||||
QString formatBytecount(const long bytecount)
|
||||
{
|
||||
if (bytecount == 0)
|
||||
return "0";
|
||||
const int exp = log(bytecount) / log(1000);
|
||||
constexpr char suffixes[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E'};
|
||||
|
||||
QString formatBytecount(const long bytecount)
|
||||
{
|
||||
if (bytecount == 0)
|
||||
return "0";
|
||||
const int exp = log(bytecount) / log(1000);
|
||||
constexpr char suffixes[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E'};
|
||||
QString str;
|
||||
QTextStream stream(&str);
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1000, exp)
|
||||
<< ' ' << suffixes[exp] << 'B';
|
||||
return stream.readAll();
|
||||
}
|
||||
|
||||
QString str;
|
||||
QTextStream stream(&str);
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1000, exp)
|
||||
<< ' ' << suffixes[exp] << 'B';
|
||||
return stream.readAll();
|
||||
}
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding)
|
||||
{
|
||||
for (int i = 0; i != columnCount; ++i)
|
||||
{
|
||||
tv->resizeColumnToContents(i);
|
||||
if (padding > 0)
|
||||
{
|
||||
int width = tv->columnWidth(i);
|
||||
tv->setColumnWidth(i, width + padding);
|
||||
}
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding)
|
||||
{
|
||||
for (int i = 0; i != columnCount; ++i) {
|
||||
tv->resizeColumnToContents(i);
|
||||
if (padding > 0) {
|
||||
int width = tv->columnWidth(i);
|
||||
tv->setColumnWidth(i, width + padding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjustColumns(QTreeWidget *tw, int padding)
|
||||
{
|
||||
adjustColumns(tw, tw->columnCount(), padding);
|
||||
}
|
||||
void adjustColumns(QTreeWidget *tw, int padding)
|
||||
{
|
||||
adjustColumns(tw, tw->columnCount(), padding);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
|
||||
const QString &str3, const QString &str4, const QString &str5)
|
||||
{
|
||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||
// Fill dummy hidden column
|
||||
tempItem->setText(0, "0");
|
||||
tempItem->setText(1, str);
|
||||
if (!str2.isNull())
|
||||
tempItem->setText(2, str2);
|
||||
if (!str3.isNull())
|
||||
tempItem->setText(3, str3);
|
||||
if (!str4.isNull())
|
||||
tempItem->setText(4, str4);
|
||||
if (!str5.isNull())
|
||||
tempItem->setText(5, str5);
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
|
||||
const QString &str3, const QString &str4, const QString &str5)
|
||||
{
|
||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||
// Fill dummy hidden column
|
||||
tempItem->setText(0, "0");
|
||||
tempItem->setText(1, str);
|
||||
if (!str2.isNull())
|
||||
tempItem->setText(2, str2);
|
||||
if (!str3.isNull())
|
||||
tempItem->setText(3, str3);
|
||||
if (!str4.isNull())
|
||||
tempItem->setText(4, str4);
|
||||
if (!str5.isNull())
|
||||
tempItem->setText(5, str5);
|
||||
|
||||
tw->insertTopLevelItem(0, tempItem);
|
||||
tw->insertTopLevelItem(0, tempItem);
|
||||
|
||||
return tempItem;
|
||||
}
|
||||
return tempItem;
|
||||
}
|
||||
|
||||
void setVerticalScrollMode(QAbstractItemView *tw)
|
||||
{
|
||||
tw->setVerticalScrollMode(scrollMode());
|
||||
}
|
||||
void setVerticalScrollMode(QAbstractItemView *tw)
|
||||
{
|
||||
tw->setVerticalScrollMode(scrollMode());
|
||||
}
|
||||
|
||||
void setCheckedWithoutSignals(QAbstractButton *button, bool checked)
|
||||
{
|
||||
bool blocked = button->signalsBlocked();
|
||||
button->blockSignals(true);
|
||||
button->setChecked(checked);
|
||||
button->blockSignals(blocked);
|
||||
}
|
||||
void setCheckedWithoutSignals(QAbstractButton *button, bool checked)
|
||||
{
|
||||
bool blocked = button->signalsBlocked();
|
||||
button->blockSignals(true);
|
||||
button->setChecked(checked);
|
||||
button->blockSignals(blocked);
|
||||
}
|
||||
|
||||
SizePolicyMinMax forceWidth(QWidget *widget, int width)
|
||||
{
|
||||
SizePolicyMinMax r;
|
||||
r.sizePolicy = widget->sizePolicy();
|
||||
r.min = widget->minimumWidth();
|
||||
r.max = widget->maximumWidth();
|
||||
|
||||
SizePolicyMinMax forceWidth(QWidget *widget, int width)
|
||||
{
|
||||
SizePolicyMinMax r;
|
||||
r.sizePolicy = widget->sizePolicy();
|
||||
r.min = widget->minimumWidth();
|
||||
r.max = widget->maximumWidth();
|
||||
QSizePolicy sizePolicy = r.sizePolicy;
|
||||
sizePolicy.setHorizontalPolicy(QSizePolicy::Fixed);
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumWidth(width);
|
||||
widget->setMaximumWidth(width);
|
||||
|
||||
QSizePolicy sizePolicy = r.sizePolicy;
|
||||
sizePolicy.setHorizontalPolicy(QSizePolicy::Fixed);
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumWidth(width);
|
||||
widget->setMaximumWidth(width);
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
SizePolicyMinMax forceHeight(QWidget *widget, int height)
|
||||
{
|
||||
SizePolicyMinMax r;
|
||||
r.sizePolicy = widget->sizePolicy();
|
||||
r.min = widget->minimumHeight();
|
||||
r.max = widget->maximumHeight();
|
||||
|
||||
QSizePolicy sizePolicy = r.sizePolicy;
|
||||
sizePolicy.setVerticalPolicy(QSizePolicy::Fixed);
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumHeight(height);
|
||||
widget->setMaximumHeight(height);
|
||||
|
||||
SizePolicyMinMax forceHeight(QWidget *widget, int height)
|
||||
{
|
||||
SizePolicyMinMax r;
|
||||
r.sizePolicy = widget->sizePolicy();
|
||||
r.min = widget->minimumHeight();
|
||||
r.max = widget->maximumHeight();
|
||||
return r;
|
||||
}
|
||||
|
||||
QSizePolicy sizePolicy = r.sizePolicy;
|
||||
sizePolicy.setVerticalPolicy(QSizePolicy::Fixed);
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumHeight(height);
|
||||
widget->setMaximumHeight(height);
|
||||
void SizePolicyMinMax::restoreWidth(QWidget *widget)
|
||||
{
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumWidth(min);
|
||||
widget->setMaximumWidth(max);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
void SizePolicyMinMax::restoreHeight(QWidget *widget)
|
||||
{
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumHeight(min);
|
||||
widget->setMaximumHeight(max);
|
||||
}
|
||||
|
||||
void SizePolicyMinMax::restoreWidth(QWidget *widget)
|
||||
{
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumWidth(min);
|
||||
widget->setMaximumWidth(max);
|
||||
}
|
||||
int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||
return (textEdit->height()
|
||||
- (textEdit->contentsMargins().top()
|
||||
+ textEdit->contentsMargins().bottom()
|
||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
void SizePolicyMinMax::restoreHeight(QWidget *widget)
|
||||
{
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
widget->setMinimumHeight(min);
|
||||
widget->setMaximumHeight(max);
|
||||
}
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||
return (plainTextEdit->height()
|
||||
- (plainTextEdit->contentsMargins().top()
|
||||
+ plainTextEdit->contentsMargins().bottom()
|
||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||
return (textEdit->height()
|
||||
- (textEdit->contentsMargins().top()
|
||||
+ textEdit->contentsMargins().bottom()
|
||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||
{
|
||||
static const QRegularExpression styleRegExp("(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
||||
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||
return (plainTextEdit->height()
|
||||
- (plainTextEdit->contentsMargins().top()
|
||||
+ plainTextEdit->contentsMargins().bottom()
|
||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
||||
int replaceStrLen = replaceStr.length();
|
||||
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||
{
|
||||
static const QRegularExpression styleRegExp("(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
||||
QString xml = QString::fromUtf8(data);
|
||||
|
||||
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
||||
int replaceStrLen = replaceStr.length();
|
||||
|
||||
QString xml = QString::fromUtf8(data);
|
||||
|
||||
int offset = 0;
|
||||
while(true)
|
||||
{
|
||||
QRegularExpressionMatch match = styleRegExp.match(xml, offset);
|
||||
if (!match.hasMatch())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
int captureIndex = match.captured(1).isNull() ? 2 : 1;
|
||||
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex), replaceStr);
|
||||
offset = match.capturedStart(captureIndex) + replaceStrLen;
|
||||
int offset = 0;
|
||||
while (true) {
|
||||
QRegularExpressionMatch match = styleRegExp.match(xml, offset);
|
||||
if (!match.hasMatch()) {
|
||||
break;
|
||||
}
|
||||
|
||||
return xml.toUtf8();
|
||||
int captureIndex = match.captured(1).isNull() ? 2 : 1;
|
||||
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex), replaceStr);
|
||||
offset = match.capturedStart(captureIndex) + replaceStrLen;
|
||||
}
|
||||
|
||||
QByteArray applyColorToSvg(const QString &filename, QColor color)
|
||||
{
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
return xml.toUtf8();
|
||||
}
|
||||
|
||||
return applyColorToSvg(file.readAll(), color);
|
||||
}
|
||||
QByteArray applyColorToSvg(const QString &filename, QColor color)
|
||||
{
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
return applyColorToSvg(file.readAll(), color);
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -15,38 +15,36 @@ class QAbstractButton;
|
||||
class QWidget;
|
||||
class QTreeView;
|
||||
|
||||
namespace qhelpers
|
||||
{
|
||||
QString formatBytecount(const long bytecount);
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
||||
void adjustColumns(QTreeWidget *tw, int padding);
|
||||
namespace qhelpers {
|
||||
QString formatBytecount(const long bytecount);
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
||||
void adjustColumns(QTreeWidget *tw, int padding);
|
||||
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
||||
|
||||
void setVerticalScrollMode(QAbstractItemView *tw);
|
||||
void setVerticalScrollMode(QAbstractItemView *tw);
|
||||
|
||||
void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
||||
void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
||||
|
||||
|
||||
struct SizePolicyMinMax
|
||||
{
|
||||
QSizePolicy sizePolicy;
|
||||
int min;
|
||||
int max;
|
||||
struct SizePolicyMinMax {
|
||||
QSizePolicy sizePolicy;
|
||||
int min;
|
||||
int max;
|
||||
|
||||
void restoreWidth(QWidget *widget);
|
||||
void restoreHeight(QWidget *widget);
|
||||
};
|
||||
void restoreWidth(QWidget *widget);
|
||||
void restoreHeight(QWidget *widget);
|
||||
};
|
||||
|
||||
SizePolicyMinMax forceWidth(QWidget *widget, int width);
|
||||
SizePolicyMinMax forceHeight(QWidget *widget, int height);
|
||||
SizePolicyMinMax forceWidth(QWidget *widget, int width);
|
||||
SizePolicyMinMax forceHeight(QWidget *widget, int height);
|
||||
|
||||
int getMaxFullyDisplayedLines(QTextEdit *textEdit);
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
|
||||
int getMaxFullyDisplayedLines(QTextEdit *textEdit);
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
|
||||
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color);
|
||||
QByteArray applyColorToSvg(const QString &filename, QColor color);
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color);
|
||||
QByteArray applyColorToSvg(const QString &filename, QColor color);
|
||||
}
|
||||
|
||||
#endif // HELPERS_H
|
||||
|
@ -18,12 +18,10 @@ AsciiHighlighter::AsciiHighlighter(QTextDocument *parent)
|
||||
|
||||
void AsciiHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0)
|
||||
{
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
@ -35,17 +33,13 @@ void AsciiHighlighter::highlightBlock(const QString &text)
|
||||
if (previousBlockState() != 1)
|
||||
startIndex = commentStartExpression.indexIn(text);
|
||||
|
||||
while (startIndex >= 0)
|
||||
{
|
||||
while (startIndex >= 0) {
|
||||
int endIndex = commentEndExpression.indexIn(text, startIndex);
|
||||
int commentLength;
|
||||
if (endIndex == -1)
|
||||
{
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ commentEndExpression.matchedLength();
|
||||
}
|
||||
|
@ -19,8 +19,7 @@ protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
struct HighlightingRule
|
||||
{
|
||||
struct HighlightingRule {
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -11,7 +11,8 @@ HexHighlighter::HexHighlighter(QTextDocument *parent)
|
||||
keywordFormat.setFontWeight(QFont::Bold);
|
||||
QStringList keywordPatterns;
|
||||
// I know, your eyes are bleeding, mine too
|
||||
keywordPatterns << "\\b20\\b" << "\\b21\\b" << "\\b22\\b" << "\\b23\\b" << "\\b24\\b" << "\\b25\\b" << "\\b26\\b"
|
||||
keywordPatterns << "\\b20\\b" << "\\b21\\b" << "\\b22\\b" << "\\b23\\b" << "\\b24\\b" << "\\b25\\b"
|
||||
<< "\\b26\\b"
|
||||
<< "\\b27\\b" << "\\b28\\b" << "\\b29\\b" << "\\b2a\\b" << "\\b2b\\b" << "\\b2c\\b" << "\\b2d\\b"
|
||||
<< "\\b2e\\b" << "\\b2f\\b" << "\\b30\\b" << "\\b31\\b" << "\\b32\\b" << "\\b33\\b" << "\\b34\\b"
|
||||
<< "\\b35\\b" << "\\b36\\b" << "\\b37\\b" << "\\b38\\b" << "\\b39\\b" << "\\b3a\\b" << "\\b3b\\b"
|
||||
@ -25,8 +26,7 @@ HexHighlighter::HexHighlighter(QTextDocument *parent)
|
||||
<< "\\b6e\\b" << "\\b6f\\b" << "\\b70\\b" << "\\b71\\b" << "\\b72\\b" << "\\b73\\b" << "\\b74\\b"
|
||||
<< "\\b75\\b" << "\\b76\\b" << "\\b77\\b" << "\\b78\\b" << "\\b79\\b" << "\\b7a\\b" << "\\b7b\\b"
|
||||
<< "\\b7c\\b" << "\\b7d\\b" << "\\b7e\\b" << "\\b7f\\b";
|
||||
foreach (const QString &pattern, keywordPatterns)
|
||||
{
|
||||
foreach (const QString &pattern, keywordPatterns) {
|
||||
rule.pattern = QRegExp(pattern);
|
||||
rule.pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
rule.format = keywordFormat;
|
||||
@ -45,12 +45,10 @@ HexHighlighter::HexHighlighter(QTextDocument *parent)
|
||||
|
||||
void HexHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0)
|
||||
{
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
@ -62,17 +60,13 @@ void HexHighlighter::highlightBlock(const QString &text)
|
||||
if (previousBlockState() != 1)
|
||||
startIndex = commentStartExpression.indexIn(text);
|
||||
|
||||
while (startIndex >= 0)
|
||||
{
|
||||
while (startIndex >= 0) {
|
||||
int endIndex = commentEndExpression.indexIn(text, startIndex);
|
||||
int commentLength;
|
||||
if (endIndex == -1)
|
||||
{
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ commentEndExpression.matchedLength();
|
||||
}
|
||||
|
@ -19,8 +19,7 @@ protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
struct HighlightingRule
|
||||
{
|
||||
struct HighlightingRule {
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -13,8 +13,7 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
||||
keywordFormat.setForeground(QColor(65, 131, 215));
|
||||
keywordFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
foreach (const QString &pattern, this->core->opcodes)
|
||||
{
|
||||
foreach (const QString &pattern, this->core->opcodes) {
|
||||
rule.pattern = QRegExp("\\b" + pattern + "\\b");
|
||||
rule.pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
rule.format = keywordFormat;
|
||||
@ -24,8 +23,7 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
||||
regFormat.setForeground(QColor(236, 100, 75));
|
||||
regFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
foreach (const QString &pattern, this->core->regs)
|
||||
{
|
||||
foreach (const QString &pattern, this->core->regs) {
|
||||
rule.pattern = QRegExp("\\b" + pattern + "\\b");
|
||||
rule.pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
rule.format = regFormat;
|
||||
@ -45,12 +43,10 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
||||
|
||||
void Highlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0)
|
||||
{
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
@ -62,17 +58,13 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
if (previousBlockState() != 1)
|
||||
startIndex = commentStartExpression.indexIn(text);
|
||||
|
||||
while (startIndex >= 0)
|
||||
{
|
||||
while (startIndex >= 0) {
|
||||
int endIndex = commentEndExpression.indexIn(text, startIndex);
|
||||
int commentLength;
|
||||
if (endIndex == -1)
|
||||
{
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ commentEndExpression.matchedLength();
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ protected:
|
||||
private:
|
||||
CutterCore *core;
|
||||
|
||||
struct HighlightingRule
|
||||
{
|
||||
struct HighlightingRule {
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -22,8 +22,7 @@ bool JsonModel::loadJson(const QByteArray &json)
|
||||
{
|
||||
mDocument = QJsonDocument::fromJson(json);
|
||||
|
||||
if (!mDocument.isNull())
|
||||
{
|
||||
if (!mDocument.isNull()) {
|
||||
beginResetModel();
|
||||
delete mRootItem;
|
||||
if (mDocument.isArray()) {
|
||||
@ -44,7 +43,7 @@ QVariant JsonModel::data(const QModelIndex &index, int role) const
|
||||
return QVariant();
|
||||
|
||||
|
||||
JsonTreeItem *item = static_cast<JsonTreeItem*>(index.internalPointer());
|
||||
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
|
||||
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
@ -67,8 +66,7 @@ QVariant JsonModel::headerData(int section, Qt::Orientation orientation, int rol
|
||||
if (orientation == Qt::Horizontal) {
|
||||
|
||||
return mHeaders.value(section);
|
||||
}
|
||||
else
|
||||
} else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@ -82,7 +80,7 @@ QModelIndex JsonModel::index(int row, int column, const QModelIndex &parent) con
|
||||
if (!parent.isValid())
|
||||
parentItem = mRootItem;
|
||||
else
|
||||
parentItem = static_cast<JsonTreeItem*>(parent.internalPointer());
|
||||
parentItem = static_cast<JsonTreeItem *>(parent.internalPointer());
|
||||
|
||||
JsonTreeItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
@ -96,7 +94,7 @@ QModelIndex JsonModel::parent(const QModelIndex &index) const
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
JsonTreeItem *childItem = static_cast<JsonTreeItem*>(index.internalPointer());
|
||||
JsonTreeItem *childItem = static_cast<JsonTreeItem *>(index.internalPointer());
|
||||
JsonTreeItem *parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == mRootItem)
|
||||
@ -114,7 +112,7 @@ int JsonModel::rowCount(const QModelIndex &parent) const
|
||||
if (!parent.isValid())
|
||||
parentItem = mRootItem;
|
||||
else
|
||||
parentItem = static_cast<JsonTreeItem*>(parent.internalPointer());
|
||||
parentItem = static_cast<JsonTreeItem *>(parent.internalPointer());
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
@ -15,20 +15,21 @@ class JsonTreeItem;
|
||||
|
||||
class JsonModel : public QAbstractItemModel
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
explicit JsonModel(QObject *parent = 0);
|
||||
bool load(QIODevice * device);
|
||||
bool loadJson(const QByteArray& json);
|
||||
bool load(QIODevice *device);
|
||||
bool loadJson(const QByteArray &json);
|
||||
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
|
||||
QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
~JsonModel();
|
||||
private:
|
||||
JsonTreeItem * mRootItem;
|
||||
JsonTreeItem *mRootItem;
|
||||
QJsonDocument mDocument;
|
||||
QStringList mHeaders;
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ int JsonTreeItem::childCount() const
|
||||
int JsonTreeItem::row() const
|
||||
{
|
||||
if (mParent)
|
||||
return mParent->mChilds.indexOf(const_cast<JsonTreeItem*>(this));
|
||||
return mParent->mChilds.indexOf(const_cast<JsonTreeItem *>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -68,39 +68,34 @@ QJsonValue::Type JsonTreeItem::type() const
|
||||
return mType;
|
||||
}
|
||||
|
||||
JsonTreeItem* JsonTreeItem::load(const QJsonValue& value, JsonTreeItem* parent)
|
||||
JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
||||
{
|
||||
JsonTreeItem * rootItem = new JsonTreeItem(parent);
|
||||
JsonTreeItem *rootItem = new JsonTreeItem(parent);
|
||||
rootItem->setKey("root");
|
||||
|
||||
if ( value.isObject())
|
||||
{
|
||||
if ( value.isObject()) {
|
||||
|
||||
//Get all QJsonValue childs
|
||||
for (QString key : value.toObject().keys()){
|
||||
for (QString key : value.toObject().keys()) {
|
||||
QJsonValue v = value.toObject().value(key);
|
||||
JsonTreeItem * child = load(v,rootItem);
|
||||
JsonTreeItem *child = load(v, rootItem);
|
||||
child->setKey(key);
|
||||
child->setType(v.type());
|
||||
rootItem->appendChild(child);
|
||||
}
|
||||
|
||||
}
|
||||
else if ( value.isArray())
|
||||
{
|
||||
} else if ( value.isArray()) {
|
||||
//Get all QJsonValue childs
|
||||
int index = 0;
|
||||
for (QJsonValue v : value.toArray()){
|
||||
for (QJsonValue v : value.toArray()) {
|
||||
|
||||
JsonTreeItem * child = load(v,rootItem);
|
||||
JsonTreeItem *child = load(v, rootItem);
|
||||
child->setKey(QString::number(index));
|
||||
child->setType(v.type());
|
||||
rootItem->appendChild(child);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
rootItem->setValue(value.toVariant().toString());
|
||||
rootItem->setType(value.type());
|
||||
}
|
||||
|
@ -13,26 +13,26 @@
|
||||
class JsonTreeItem
|
||||
{
|
||||
public:
|
||||
JsonTreeItem(JsonTreeItem * parent = 0);
|
||||
JsonTreeItem(JsonTreeItem *parent = 0);
|
||||
~JsonTreeItem();
|
||||
void appendChild(JsonTreeItem * item);
|
||||
void appendChild(JsonTreeItem *item);
|
||||
JsonTreeItem *child(int row);
|
||||
JsonTreeItem *parent();
|
||||
int childCount() const;
|
||||
int row() const;
|
||||
void setKey(const QString& key);
|
||||
void setValue(const QString& value);
|
||||
void setType(const QJsonValue::Type& type);
|
||||
void setKey(const QString &key);
|
||||
void setValue(const QString &value);
|
||||
void setType(const QJsonValue::Type &type);
|
||||
QString key() const;
|
||||
QString value() const;
|
||||
QJsonValue::Type type() const;
|
||||
static JsonTreeItem *load(const QJsonValue& value, JsonTreeItem * parent = 0);
|
||||
static JsonTreeItem *load(const QJsonValue &value, JsonTreeItem *parent = 0);
|
||||
|
||||
private:
|
||||
QString mKey;
|
||||
QString mValue;
|
||||
QJsonValue::Type mType;
|
||||
QList<JsonTreeItem*> mChilds;
|
||||
QList<JsonTreeItem *> mChilds;
|
||||
JsonTreeItem *mParent;
|
||||
};
|
||||
|
||||
|
@ -28,12 +28,10 @@ JupyterConnection::JupyterConnection(QObject *parent) : QObject(parent)
|
||||
|
||||
JupyterConnection::~JupyterConnection()
|
||||
{
|
||||
if (pyThreadState)
|
||||
{
|
||||
if (pyThreadState) {
|
||||
PyEval_RestoreThread(pyThreadState);
|
||||
|
||||
if (cutterNotebookAppInstance)
|
||||
{
|
||||
if (cutterNotebookAppInstance) {
|
||||
auto stopFunc = PyObject_GetAttrString(cutterNotebookAppInstance, "stop");
|
||||
PyObject_CallObject(stopFunc, nullptr);
|
||||
Py_DECREF(cutterNotebookAppInstance);
|
||||
@ -42,8 +40,7 @@ JupyterConnection::~JupyterConnection()
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
if (pythonHome)
|
||||
{
|
||||
if (pythonHome) {
|
||||
PyMem_RawFree(pythonHome);
|
||||
}
|
||||
}
|
||||
@ -52,24 +49,23 @@ JupyterConnection::~JupyterConnection()
|
||||
void JupyterConnection::initPython()
|
||||
{
|
||||
#if defined(APPIMAGE) || defined(MACOS_PYTHON_FRAMEWORK_BUNDLED)
|
||||
if(customPythonHome.isNull())
|
||||
{
|
||||
if (customPythonHome.isNull()) {
|
||||
auto pythonHomeDir = QDir(QCoreApplication::applicationDirPath());
|
||||
# ifdef APPIMAGE
|
||||
// Executable is in appdir/bin
|
||||
pythonHomeDir.cdUp();
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() << " for AppImage.";
|
||||
// Executable is in appdir/bin
|
||||
pythonHomeDir.cdUp();
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() << " for AppImage.";
|
||||
# else // MACOS_PYTHON_FRAMEWORK_BUNDLED
|
||||
// @executable_path/../Frameworks/Python.framework/Versions/Current
|
||||
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() << " for macOS Application Bundle.";
|
||||
// @executable_path/../Frameworks/Python.framework/Versions/Current
|
||||
pythonHomeDir.cd("../Frameworks/Python.framework/Versions/Current");
|
||||
qInfo() << "Setting PYTHONHOME =" << pythonHomeDir.absolutePath() <<
|
||||
" for macOS Application Bundle.";
|
||||
# endif
|
||||
customPythonHome = pythonHomeDir.absolutePath();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!customPythonHome.isNull())
|
||||
{
|
||||
if (!customPythonHome.isNull()) {
|
||||
qInfo() << "PYTHONHOME =" << customPythonHome;
|
||||
pythonHome = Py_DecodeLocale(customPythonHome.toLocal8Bit().constData(), nullptr);
|
||||
Py_SetPythonHome(pythonHome);
|
||||
@ -92,9 +88,9 @@ void JupyterConnection::createCutterJupyterModule()
|
||||
QByteArray moduleCode = moduleFile.readAll();
|
||||
moduleFile.close();
|
||||
|
||||
auto moduleCodeObject = Py_CompileString(moduleCode.constData(), "cutter_jupyter.py", Py_file_input);
|
||||
if (!moduleCodeObject)
|
||||
{
|
||||
auto moduleCodeObject = Py_CompileString(moduleCode.constData(), "cutter_jupyter.py",
|
||||
Py_file_input);
|
||||
if (!moduleCodeObject) {
|
||||
PyErr_Print();
|
||||
qWarning() << "Could not compile cutter_jupyter.";
|
||||
emit creationFailed();
|
||||
@ -102,8 +98,7 @@ void JupyterConnection::createCutterJupyterModule()
|
||||
return;
|
||||
}
|
||||
cutterJupyterModule = PyImport_ExecCodeModule("cutter_jupyter", moduleCodeObject);
|
||||
if (!cutterJupyterModule)
|
||||
{
|
||||
if (!cutterJupyterModule) {
|
||||
PyErr_Print();
|
||||
qWarning() << "Could not import cutter_jupyter.";
|
||||
emit creationFailed();
|
||||
@ -117,22 +112,18 @@ void JupyterConnection::createCutterJupyterModule()
|
||||
|
||||
void JupyterConnection::start()
|
||||
{
|
||||
if (cutterNotebookAppInstance)
|
||||
{
|
||||
if (cutterNotebookAppInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Py_IsInitialized())
|
||||
{
|
||||
if (!Py_IsInitialized()) {
|
||||
initPython();
|
||||
}
|
||||
|
||||
if (!cutterJupyterModule)
|
||||
{
|
||||
if (!cutterJupyterModule) {
|
||||
createCutterJupyterModule();
|
||||
|
||||
if(!cutterJupyterModule)
|
||||
{
|
||||
if (!cutterJupyterModule) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -147,8 +138,7 @@ void JupyterConnection::start()
|
||||
|
||||
QString JupyterConnection::getUrl()
|
||||
{
|
||||
if (!cutterNotebookAppInstance)
|
||||
{
|
||||
if (!cutterNotebookAppInstance) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -169,8 +159,7 @@ long JupyterConnection::startNestedIPyKernel(const QStringList &argv)
|
||||
{
|
||||
NestedIPyKernel *kernel = NestedIPyKernel::start(argv);
|
||||
|
||||
if (!kernel)
|
||||
{
|
||||
if (!kernel) {
|
||||
qWarning() << "Could not start nested IPyKernel.";
|
||||
return 0;
|
||||
}
|
||||
@ -184,8 +173,7 @@ long JupyterConnection::startNestedIPyKernel(const QStringList &argv)
|
||||
NestedIPyKernel *JupyterConnection::getNestedIPyKernel(long id)
|
||||
{
|
||||
auto it = kernels.find(id);
|
||||
if(it == kernels.end())
|
||||
{
|
||||
if (it == kernels.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return *it;
|
||||
@ -194,16 +182,14 @@ NestedIPyKernel *JupyterConnection::getNestedIPyKernel(long id)
|
||||
QVariant JupyterConnection::pollNestedIPyKernel(long id)
|
||||
{
|
||||
auto it = kernels.find(id);
|
||||
if(it == kernels.end())
|
||||
{
|
||||
if (it == kernels.end()) {
|
||||
return QVariant(0);
|
||||
}
|
||||
|
||||
NestedIPyKernel *kernel = *it;
|
||||
QVariant v = kernel->poll();
|
||||
|
||||
if(!v.isNull())
|
||||
{
|
||||
if (!v.isNull()) {
|
||||
// if poll of kernel returns anything but None, it has already quit and should be cleaned up
|
||||
PyThreadState *subinterpreterState = kernel->getThreadState();
|
||||
delete kernel;
|
||||
|
@ -20,12 +20,15 @@ class JupyterConnection : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static JupyterConnection* getInstance();
|
||||
static JupyterConnection *getInstance();
|
||||
|
||||
JupyterConnection(QObject *parent = nullptr);
|
||||
~JupyterConnection();
|
||||
|
||||
void setPythonHome(const QString pythonHome) { customPythonHome = pythonHome; }
|
||||
void setPythonHome(const QString pythonHome)
|
||||
{
|
||||
customPythonHome = pythonHome;
|
||||
}
|
||||
|
||||
void start();
|
||||
QString getUrl();
|
||||
|
@ -15,8 +15,7 @@ MdHighlighter::MdHighlighter(QTextDocument *parent)
|
||||
<< "\\*([^\\\\]+)\\*" << "\\_([^\\\\]+)\\_"
|
||||
<< "\\_\\_([^\\\\]+)\\_\\_";
|
||||
|
||||
foreach (const QString &pattern, keywordPatterns)
|
||||
{
|
||||
foreach (const QString &pattern, keywordPatterns) {
|
||||
rule.pattern = QRegExp(pattern);
|
||||
rule.format = keywordFormat;
|
||||
highlightingRules.append(rule);
|
||||
@ -31,12 +30,10 @@ MdHighlighter::MdHighlighter(QTextDocument *parent)
|
||||
|
||||
void MdHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0)
|
||||
{
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
|
@ -19,8 +19,7 @@ protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
struct HighlightingRule
|
||||
{
|
||||
struct HighlightingRule {
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -14,8 +14,7 @@ NestedIPyKernel *NestedIPyKernel::start(const QStringList &argv)
|
||||
PyThreadState *parentThreadState = PyThreadState_Get();
|
||||
|
||||
PyThreadState *threadState = Py_NewInterpreter();
|
||||
if (!threadState)
|
||||
{
|
||||
if (!threadState) {
|
||||
qWarning() << "Could not create subinterpreter.";
|
||||
return nullptr;
|
||||
}
|
||||
@ -25,16 +24,15 @@ NestedIPyKernel *NestedIPyKernel::start(const QStringList &argv)
|
||||
QByteArray moduleCode = moduleFile.readAll();
|
||||
moduleFile.close();
|
||||
|
||||
auto moduleCodeObject = Py_CompileString(moduleCode.constData(), "cutter_ipykernel.py", Py_file_input);
|
||||
if (!moduleCodeObject)
|
||||
{
|
||||
auto moduleCodeObject = Py_CompileString(moduleCode.constData(), "cutter_ipykernel.py",
|
||||
Py_file_input);
|
||||
if (!moduleCodeObject) {
|
||||
qWarning() << "Could not compile cutter_ipykernel.";
|
||||
return nullptr;
|
||||
}
|
||||
auto cutterIPykernelModule = PyImport_ExecCodeModule("cutter_ipykernel", moduleCodeObject);
|
||||
Py_DECREF(moduleCodeObject);
|
||||
if (!cutterIPykernelModule)
|
||||
{
|
||||
if (!cutterIPykernelModule) {
|
||||
qWarning() << "Could not import cutter_ipykernel.";
|
||||
return nullptr;
|
||||
}
|
||||
@ -53,10 +51,10 @@ NestedIPyKernel::NestedIPyKernel(PyObject *cutterIPykernelModule, const QStringL
|
||||
auto launchFunc = PyObject_GetAttrString(cutterIPykernelModule, "launch_ipykernel");
|
||||
|
||||
PyObject *argvListObject = PyList_New(argv.size());
|
||||
for (int i = 0; i < argv.size(); i++)
|
||||
{
|
||||
for (int i = 0; i < argv.size(); i++) {
|
||||
QString s = argv[i];
|
||||
PyList_SetItem(argvListObject, i, PyUnicode_DecodeUTF8(s.toUtf8().constData(), s.length(), nullptr));
|
||||
PyList_SetItem(argvListObject, i, PyUnicode_DecodeUTF8(s.toUtf8().constData(), s.length(),
|
||||
nullptr));
|
||||
}
|
||||
|
||||
kernel = PyObject_CallFunction(launchFunc, "O", argvListObject);
|
||||
@ -66,8 +64,7 @@ NestedIPyKernel::~NestedIPyKernel()
|
||||
{
|
||||
auto parentThreadState = PyThreadState_Swap(threadState);
|
||||
auto ret = PyObject_CallMethod(kernel, "cleanup", nullptr);
|
||||
if (!ret)
|
||||
{
|
||||
if (!ret) {
|
||||
PyErr_Print();
|
||||
}
|
||||
PyThreadState_Swap(parentThreadState);
|
||||
@ -77,8 +74,7 @@ void NestedIPyKernel::sendSignal(long signum)
|
||||
{
|
||||
auto parentThreadState = PyThreadState_Swap(threadState);
|
||||
auto ret = PyObject_CallMethod(kernel, "send_signal", "l", signum);
|
||||
if (!ret)
|
||||
{
|
||||
if (!ret) {
|
||||
PyErr_Print();
|
||||
}
|
||||
PyThreadState_Swap(parentThreadState);
|
||||
@ -89,15 +85,11 @@ QVariant NestedIPyKernel::poll()
|
||||
QVariant ret;
|
||||
auto parentThreadState = PyThreadState_Swap(threadState);
|
||||
PyObject *pyRet = PyObject_CallMethod(kernel, "poll", nullptr);
|
||||
if(pyRet)
|
||||
{
|
||||
if(PyLong_Check(pyRet))
|
||||
{
|
||||
if (pyRet) {
|
||||
if (PyLong_Check(pyRet)) {
|
||||
ret = (qlonglong)PyLong_AsLong(pyRet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PyErr_Print();
|
||||
}
|
||||
PyThreadState_Swap(parentThreadState);
|
||||
|
@ -21,7 +21,10 @@ public:
|
||||
void sendSignal(long signum);
|
||||
QVariant poll();
|
||||
|
||||
PyThreadState *getThreadState() { return threadState; }
|
||||
PyThreadState *getThreadState()
|
||||
{
|
||||
return threadState;
|
||||
}
|
||||
|
||||
private:
|
||||
NestedIPyKernel(PyObject *cutterIPykernelModule, const QStringList &argv);
|
||||
|
@ -19,11 +19,10 @@ PyObject *api_cmd(PyObject *self, PyObject *args)
|
||||
{
|
||||
Q_UNUSED(self);
|
||||
char *command;
|
||||
char *result = (char*) "";
|
||||
char *result = (char *) "";
|
||||
QString cmdRes;
|
||||
QByteArray cmdBytes;
|
||||
if (PyArg_ParseTuple(args, "s:command", &command))
|
||||
{
|
||||
if (PyArg_ParseTuple(args, "s:command", &command)) {
|
||||
cmdRes = Core()->cmd(command);
|
||||
cmdBytes = cmdRes.toLocal8Bit();
|
||||
result = cmdBytes.data();
|
||||
@ -35,11 +34,10 @@ PyObject *api_cmdj(PyObject *self, PyObject *args)
|
||||
{
|
||||
Q_UNUSED(self);
|
||||
char *command;
|
||||
char *result = (char*) "";
|
||||
char *result = (char *) "";
|
||||
QString cmdRes;
|
||||
QByteArray cmdBytes;
|
||||
if (PyArg_ParseTuple(args, "s:command", &command))
|
||||
{
|
||||
if (PyArg_ParseTuple(args, "s:command", &command)) {
|
||||
cmdRes = Core()->cmd(command);
|
||||
cmdBytes = cmdRes.toLocal8Bit();
|
||||
result = cmdBytes.data();
|
||||
@ -55,12 +53,18 @@ PyObject *api_cmdj(PyObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
PyMethodDef CutterMethods[] = {
|
||||
{"version", api_version, METH_NOARGS,
|
||||
"Returns Cutter current version"},
|
||||
{"cmd", api_cmd, METH_VARARGS,
|
||||
"Execute a command inside Cutter"},
|
||||
{"cmdj", api_cmdj, METH_VARARGS,
|
||||
"Execute a JSON command and return the result as a dictionnary"},
|
||||
{
|
||||
"version", api_version, METH_NOARGS,
|
||||
"Returns Cutter current version"
|
||||
},
|
||||
{
|
||||
"cmd", api_cmd, METH_VARARGS,
|
||||
"Execute a command inside Cutter"
|
||||
},
|
||||
{
|
||||
"cmdj", api_cmdj, METH_VARARGS,
|
||||
"Execute a JSON command and return the result as a dictionnary"
|
||||
},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@ -87,16 +91,14 @@ PyObject *api_internal_launch_ipykernel(PyObject *self, PyObject *args, PyObject
|
||||
PyObject *argvListObject;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &argvListObject)
|
||||
|| !PyList_Check(argvListObject))
|
||||
{
|
||||
|| !PyList_Check(argvListObject)) {
|
||||
const char *msg = "Invalid args passed to api_internal_launch_ipykernel().";
|
||||
qWarning() << msg;
|
||||
PyErr_SetString(PyExc_RuntimeError, msg);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < PyList_Size(argvListObject); i++)
|
||||
{
|
||||
for (int i = 0; i < PyList_Size(argvListObject); i++) {
|
||||
PyObject *o = PyList_GetItem(argvListObject, i);
|
||||
QString s = QString::fromUtf8(PyUnicode_AsUTF8(o));
|
||||
argv.append(s);
|
||||
@ -112,8 +114,7 @@ PyObject *api_internal_kernel_interface_send_signal(PyObject *, PyObject *args)
|
||||
long id;
|
||||
long signum;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ll", &id, &signum))
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "ll", &id, &signum)) {
|
||||
const char *msg = "Invalid args passed to api_internal_kernel_interface_send_signal().";
|
||||
qWarning() << msg;
|
||||
PyErr_SetString(PyExc_RuntimeError, msg);
|
||||
@ -121,8 +122,7 @@ PyObject *api_internal_kernel_interface_send_signal(PyObject *, PyObject *args)
|
||||
}
|
||||
|
||||
NestedIPyKernel *kernel = Jupyter()->getNestedIPyKernel(id);
|
||||
if(kernel)
|
||||
{
|
||||
if (kernel) {
|
||||
kernel->sendSignal(signum);
|
||||
}
|
||||
|
||||
@ -133,8 +133,7 @@ PyObject *api_internal_kernel_interface_poll(PyObject *, PyObject *args)
|
||||
{
|
||||
long id;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l", &id))
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "l", &id)) {
|
||||
const char *msg = "Invalid args passed to api_internal_kernel_interface_poll().";
|
||||
qWarning() << msg;
|
||||
PyErr_SetString(PyExc_RuntimeError, msg);
|
||||
@ -144,12 +143,9 @@ PyObject *api_internal_kernel_interface_poll(PyObject *, PyObject *args)
|
||||
QVariant v = Jupyter()->pollNestedIPyKernel(id);
|
||||
bool ok;
|
||||
auto ret = static_cast<long>(v.toLongLong(&ok));
|
||||
if(ok)
|
||||
{
|
||||
if (ok) {
|
||||
return PyLong_FromLong(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
@ -159,8 +155,7 @@ PyObject *api_internal_thread_set_async_exc(PyObject *, PyObject *args)
|
||||
long id;
|
||||
PyObject *exc;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "lO", &id, &exc))
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "lO", &id, &exc)) {
|
||||
const char *msg = "Invalid args passed to api_internal_thread_set_async_exc().";
|
||||
qWarning() << msg;
|
||||
PyErr_SetString(PyExc_RuntimeError, msg);
|
||||
@ -172,8 +167,10 @@ PyObject *api_internal_thread_set_async_exc(PyObject *, PyObject *args)
|
||||
}
|
||||
|
||||
PyMethodDef CutterInternalMethods[] = {
|
||||
{"launch_ipykernel", (PyCFunction)api_internal_launch_ipykernel, METH_VARARGS | METH_KEYWORDS,
|
||||
"Launch an IPython Kernel in a subinterpreter"},
|
||||
{
|
||||
"launch_ipykernel", (PyCFunction)api_internal_launch_ipykernel, METH_VARARGS | METH_KEYWORDS,
|
||||
"Launch an IPython Kernel in a subinterpreter"
|
||||
},
|
||||
{"kernel_interface_send_signal", (PyCFunction)api_internal_kernel_interface_send_signal, METH_VARARGS, ""},
|
||||
{"kernel_interface_poll", (PyCFunction)api_internal_kernel_interface_poll, METH_VARARGS, ""},
|
||||
{"thread_set_async_exc", (PyCFunction)api_internal_thread_set_async_exc, METH_VARARGS, ""},
|
||||
|
@ -6,21 +6,20 @@
|
||||
#include <QTextFragment>
|
||||
|
||||
//TODO: fix performance (possibly use QTextLayout?)
|
||||
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics)
|
||||
void RichTextPainter::paintRichText(QPainter *painter, int x, int y, int w, int h, int xinc,
|
||||
const List &richText, CachedFontMetrics *fontMetrics)
|
||||
{
|
||||
QPen pen;
|
||||
QPen highlightPen;
|
||||
QBrush brush(Qt::cyan);
|
||||
for(const CustomRichText_t & curRichText : richText)
|
||||
{
|
||||
for (const CustomRichText_t &curRichText : richText) {
|
||||
int textWidth = fontMetrics->width(curRichText.text);
|
||||
int 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)
|
||||
{
|
||||
switch (curRichText.flags) {
|
||||
case FlagNone: //defaults
|
||||
break;
|
||||
case FlagColor: //color only
|
||||
@ -28,15 +27,13 @@ void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int
|
||||
painter->setPen(pen);
|
||||
break;
|
||||
case FlagBackground: //background only
|
||||
if(backgroundWidth > 0 && curRichText.textBackground.alpha())
|
||||
{
|
||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||
brush.setColor(curRichText.textBackground);
|
||||
painter->fillRect(QRect(x + xinc, y, backgroundWidth, h), brush);
|
||||
}
|
||||
break;
|
||||
case FlagAll: //color+background
|
||||
if(backgroundWidth > 0 && curRichText.textBackground.alpha())
|
||||
{
|
||||
if (backgroundWidth > 0 && curRichText.textBackground.alpha()) {
|
||||
brush.setColor(curRichText.textBackground);
|
||||
painter->fillRect(QRect(x + xinc, y, backgroundWidth, h), brush);
|
||||
}
|
||||
@ -45,13 +42,13 @@ void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int
|
||||
break;
|
||||
}
|
||||
painter->drawText(QRect(x + xinc, y, w - xinc, h), Qt::TextBypassShaping, curRichText.text);
|
||||
if(curRichText.highlight && curRichText.highlightColor.alpha())
|
||||
{
|
||||
if (curRichText.highlight && curRichText.highlightColor.alpha()) {
|
||||
highlightPen.setColor(curRichText.highlightColor);
|
||||
highlightPen.setWidth(curRichText.highlightWidth);
|
||||
painter->setPen(highlightPen);
|
||||
int highlightOffsetX = curRichText.highlightConnectPrev ? -1 : 1;
|
||||
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1, x + xinc + backgroundWidth - 1, y + h - 1);
|
||||
painter->drawLine(x + xinc + highlightOffsetX, y + h - 1, x + xinc + backgroundWidth - 1,
|
||||
y + h - 1);
|
||||
}
|
||||
xinc += textWidth;
|
||||
}
|
||||
@ -63,18 +60,15 @@ void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int
|
||||
* @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)
|
||||
void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain)
|
||||
{
|
||||
for(const CustomRichText_t & curRichText : richText)
|
||||
{
|
||||
if(curRichText.text == " ") //blank
|
||||
{
|
||||
for (const CustomRichText_t &curRichText : richText) {
|
||||
if (curRichText.text == " ") { //blank
|
||||
textHtml += " ";
|
||||
textPlain += " ";
|
||||
continue;
|
||||
}
|
||||
switch(curRichText.flags)
|
||||
{
|
||||
switch (curRichText.flags) {
|
||||
case FlagNone: //defaults
|
||||
textHtml += "<span>";
|
||||
break;
|
||||
@ -82,22 +76,25 @@ void RichTextPainter::htmlRichText(const List & richText, QString & textHtml, QS
|
||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||
break;
|
||||
case FlagBackground: //background only
|
||||
if(curRichText.textBackground != Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
if (curRichText.textBackground !=
|
||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"background-color:%1\">").arg(curRichText.textBackground.name());
|
||||
else
|
||||
textHtml += QString("<span>");
|
||||
break;
|
||||
case FlagAll: //color+background
|
||||
if(curRichText.textBackground != Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"color:%1; background-color:%2\">").arg(curRichText.textColor.name(), curRichText.textBackground.name());
|
||||
if (curRichText.textBackground !=
|
||||
Qt::transparent) // QColor::name() returns "#000000" for transparent color. That's not desired. Leave it blank.
|
||||
textHtml += QString("<span style=\"color:%1; background-color:%2\">").arg(
|
||||
curRichText.textColor.name(), curRichText.textBackground.name());
|
||||
else
|
||||
textHtml += QString("<span style=\"color:%1\">").arg(curRichText.textColor.name());
|
||||
break;
|
||||
}
|
||||
if(curRichText.highlight) //Underline highlighted token
|
||||
if (curRichText.highlight) //Underline highlighted token
|
||||
textHtml += "<u>";
|
||||
textHtml += curRichText.text.toHtmlEscaped();
|
||||
if(curRichText.highlight)
|
||||
if (curRichText.highlight)
|
||||
textHtml += "</u>";
|
||||
textHtml += "</span>"; //Close the tag
|
||||
textPlain += curRichText.text;
|
||||
@ -108,10 +105,8 @@ RichTextPainter::List RichTextPainter::fromTextDocument(const QTextDocument &doc
|
||||
{
|
||||
List r;
|
||||
|
||||
for (QTextBlock block = doc.begin(); block != doc.end(); block = block.next())
|
||||
{
|
||||
for (QTextBlock::iterator it = block.begin(); it != block.end(); it++)
|
||||
{
|
||||
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();
|
||||
|
||||
@ -123,20 +118,13 @@ RichTextPainter::List RichTextPainter::fromTextDocument(const QTextDocument &doc
|
||||
bool hasForeground = format.hasProperty(QTextFormat::ForegroundBrush);
|
||||
bool hasBackground = format.hasProperty(QTextFormat::BackgroundBrush);
|
||||
|
||||
if (hasForeground && !hasBackground)
|
||||
{
|
||||
if (hasForeground && !hasBackground) {
|
||||
text.flags = FlagColor;
|
||||
}
|
||||
else if (!hasForeground && hasBackground)
|
||||
{
|
||||
} else if (!hasForeground && hasBackground) {
|
||||
text.flags = FlagBackground;
|
||||
}
|
||||
else if (hasForeground && hasBackground)
|
||||
{
|
||||
} else if (hasForeground && hasBackground) {
|
||||
text.flags = FlagAll;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
text.flags = FlagNone;
|
||||
}
|
||||
|
||||
@ -147,27 +135,22 @@ RichTextPainter::List RichTextPainter::fromTextDocument(const QTextDocument &doc
|
||||
return r;
|
||||
}
|
||||
|
||||
RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &richText, int maxCols, const QString &indicator, bool *croppedOut)
|
||||
RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &richText, int maxCols,
|
||||
const QString &indicator, bool *croppedOut)
|
||||
{
|
||||
List r;
|
||||
r.reserve(richText.size());
|
||||
|
||||
int cols = 0;
|
||||
bool cropped = false;
|
||||
for(const auto &text : richText)
|
||||
{
|
||||
for (const auto &text : richText) {
|
||||
int textLength = text.text.size();
|
||||
if(cols + textLength <= maxCols)
|
||||
{
|
||||
if (cols + textLength <= maxCols) {
|
||||
r.push_back(text);
|
||||
cols += textLength;
|
||||
}
|
||||
else if(cols == maxCols)
|
||||
{
|
||||
} else if (cols == maxCols) {
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
CustomRichText_t croppedText = text;
|
||||
croppedText.text.truncate(maxCols - cols);
|
||||
r.push_back(croppedText);
|
||||
@ -176,20 +159,16 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
|
||||
}
|
||||
}
|
||||
|
||||
if(cropped && !indicator.isEmpty())
|
||||
{
|
||||
if (cropped && !indicator.isEmpty()) {
|
||||
int indicatorCropLength = indicator.length();
|
||||
if(indicatorCropLength > maxCols)
|
||||
{
|
||||
if (indicatorCropLength > maxCols) {
|
||||
indicatorCropLength = maxCols;
|
||||
}
|
||||
|
||||
while(!r.empty())
|
||||
{
|
||||
while (!r.empty()) {
|
||||
auto &text = r.back();
|
||||
|
||||
if(text.text.length() >= indicatorCropLength)
|
||||
{
|
||||
if (text.text.length() >= indicatorCropLength) {
|
||||
text.text.replace(text.text.length() - indicatorCropLength, indicatorCropLength, indicator);
|
||||
break;
|
||||
}
|
||||
@ -199,8 +178,7 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
|
||||
}
|
||||
}
|
||||
|
||||
if(croppedOut)
|
||||
{
|
||||
if (croppedOut) {
|
||||
*croppedOut = cropped;
|
||||
}
|
||||
return r;
|
||||
|
@ -14,16 +14,14 @@ class RichTextPainter
|
||||
{
|
||||
public:
|
||||
//structures
|
||||
enum CustomRichTextFlags
|
||||
{
|
||||
enum CustomRichTextFlags {
|
||||
FlagNone,
|
||||
FlagColor,
|
||||
FlagBackground,
|
||||
FlagAll
|
||||
};
|
||||
|
||||
struct CustomRichText_t
|
||||
{
|
||||
struct CustomRichText_t {
|
||||
QString text;
|
||||
QColor textColor;
|
||||
QColor textBackground;
|
||||
@ -37,12 +35,14 @@ public:
|
||||
typedef std::vector<CustomRichText_t> List;
|
||||
|
||||
//functions
|
||||
static void paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics);
|
||||
static void htmlRichText(const List & richText, QString & textHtml, QString & textPlain);
|
||||
static void paintRichText(QPainter *painter, int x, int y, int w, int h, int xinc,
|
||||
const List &richText, CachedFontMetrics *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);
|
||||
static List cropped(const List &richText, int maxCols, const QString &indicator = nullptr,
|
||||
bool *croppedOut = nullptr);
|
||||
};
|
||||
|
||||
#endif // RICHTEXTPAINTER_H
|
||||
|
@ -29,7 +29,8 @@ SvgIconEngine::SvgIconEngine(const QByteArray &svgData, QColor tintColor)
|
||||
this->svgData = qhelpers::applyColorToSvg(svgData, tintColor);
|
||||
}
|
||||
|
||||
void SvgIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode /*mode*/, QIcon::State /*state*/)
|
||||
void SvgIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode /*mode*/,
|
||||
QIcon::State /*state*/)
|
||||
{
|
||||
QSvgRenderer renderer(svgData);
|
||||
renderer.render(painter, rect);
|
||||
|
@ -10,16 +10,16 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
|
||||
|
||||
//C language keywords
|
||||
keywordPatterns << "\\bauto\\b" << "\\bdouble\\b" << "\\bint\\b"
|
||||
<< "\\bstruct\\b" << "\\bbreak\\b" << "\\belse\\b"
|
||||
<< "\\blong\\b" << "\\switch\\b" << "\\bcase\\b"
|
||||
<< "\\benum\\b" << "\\bregister\\b" << "\\btypedef\\b"
|
||||
<< "\\bchar\\b" << "\\bextern\\b" << "\\breturn\\b"
|
||||
<< "\\bunion\\b" << "\\bconst\\b" << "\\bfloat\\b"
|
||||
<< "\\bshort\\b" << "\\bunsigned\\b" << "\\bcontinue\\b"
|
||||
<< "\\bfor\\b" << "\\bsigned\\b" << "\\bvoid\\b"
|
||||
<< "\\bdefault\\b" << "\\bgoto\\b" << "\\bsizeof\\b"
|
||||
<< "\\bvolatile\\b" << "\\bdo\\b" << "\\bif\\b"
|
||||
<< "\\static\\b" << "\\while\\b";
|
||||
<< "\\bstruct\\b" << "\\bbreak\\b" << "\\belse\\b"
|
||||
<< "\\blong\\b" << "\\switch\\b" << "\\bcase\\b"
|
||||
<< "\\benum\\b" << "\\bregister\\b" << "\\btypedef\\b"
|
||||
<< "\\bchar\\b" << "\\bextern\\b" << "\\breturn\\b"
|
||||
<< "\\bunion\\b" << "\\bconst\\b" << "\\bfloat\\b"
|
||||
<< "\\bshort\\b" << "\\bunsigned\\b" << "\\bcontinue\\b"
|
||||
<< "\\bfor\\b" << "\\bsigned\\b" << "\\bvoid\\b"
|
||||
<< "\\bdefault\\b" << "\\bgoto\\b" << "\\bsizeof\\b"
|
||||
<< "\\bvolatile\\b" << "\\bdo\\b" << "\\bif\\b"
|
||||
<< "\\static\\b" << "\\while\\b";
|
||||
//Special words
|
||||
keywordPatterns << "\\bloc_*\\b" << "\\bsym.*\\b";
|
||||
|
||||
@ -27,11 +27,10 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
|
||||
keywordFormat.setForeground(Qt::red);
|
||||
keywordFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
for( const auto& pattern : keywordPatterns )
|
||||
{
|
||||
rule.pattern.setPattern(pattern);
|
||||
rule.format = keywordFormat;
|
||||
highlightingRules.append(rule);
|
||||
for ( const auto &pattern : keywordPatterns ) {
|
||||
rule.pattern.setPattern(pattern);
|
||||
rule.format = keywordFormat;
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
//Functions
|
||||
@ -59,13 +58,11 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
|
||||
multiLineCommentFormat.setForeground(Qt::gray);
|
||||
}
|
||||
|
||||
void SyntaxHighlighter::highlightBlock(const QString&text)
|
||||
void SyntaxHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
for( const auto& it : highlightingRules )
|
||||
{
|
||||
for ( const auto &it : highlightingRules ) {
|
||||
auto matchIterator = it.pattern.globalMatch(text);
|
||||
while (matchIterator.hasNext())
|
||||
{
|
||||
while (matchIterator.hasNext()) {
|
||||
const auto match = matchIterator.next();
|
||||
setFormat(match.capturedStart(), match.capturedLength(), it.format);
|
||||
}
|
||||
@ -74,24 +71,19 @@ void SyntaxHighlighter::highlightBlock(const QString&text)
|
||||
setCurrentBlockState(0);
|
||||
|
||||
int startIndex = 0;
|
||||
if (previousBlockState() != 1)
|
||||
{
|
||||
if (previousBlockState() != 1) {
|
||||
startIndex = text.indexOf(commentStartExpression);
|
||||
}
|
||||
|
||||
while (startIndex >= 0)
|
||||
{
|
||||
while (startIndex >= 0) {
|
||||
const auto match = commentEndExpression.match(text, startIndex);
|
||||
const int endIndex = match.capturedStart();
|
||||
int commentLength = 0;
|
||||
|
||||
if (endIndex == -1)
|
||||
{
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ match.capturedLength();
|
||||
}
|
||||
|
@ -19,8 +19,7 @@ protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
private:
|
||||
struct HighlightingRule
|
||||
{
|
||||
struct HighlightingRule {
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
@ -6,30 +6,27 @@
|
||||
|
||||
TempConfig::~TempConfig()
|
||||
{
|
||||
for (auto i = resetValues.begin(); i != resetValues.end(); i++)
|
||||
{
|
||||
switch(i.value().type())
|
||||
{
|
||||
case QVariant::String:
|
||||
Core()->setConfig(i.key(), i.value().toString());
|
||||
break;
|
||||
case QVariant::Int:
|
||||
Core()->setConfig(i.key(), i.value().toInt());
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
Core()->setConfig(i.key(), i.value().toBool());
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
for (auto i = resetValues.begin(); i != resetValues.end(); i++) {
|
||||
switch (i.value().type()) {
|
||||
case QVariant::String:
|
||||
Core()->setConfig(i.key(), i.value().toString());
|
||||
break;
|
||||
case QVariant::Int:
|
||||
Core()->setConfig(i.key(), i.value().toInt());
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
Core()->setConfig(i.key(), i.value().toBool());
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TempConfig &TempConfig::set(const QString &key, const QString &value)
|
||||
{
|
||||
if (!resetValues.contains(key))
|
||||
{
|
||||
if (!resetValues.contains(key)) {
|
||||
resetValues[key] = Core()->getConfig(key);
|
||||
}
|
||||
|
||||
@ -39,8 +36,7 @@ TempConfig &TempConfig::set(const QString &key, const QString &value)
|
||||
|
||||
TempConfig &TempConfig::set(const QString &key, int value)
|
||||
{
|
||||
if (!resetValues.contains(key))
|
||||
{
|
||||
if (!resetValues.contains(key)) {
|
||||
resetValues[key] = Core()->getConfigi(key);
|
||||
}
|
||||
|
||||
@ -50,8 +46,7 @@ TempConfig &TempConfig::set(const QString &key, int value)
|
||||
|
||||
TempConfig &TempConfig::set(const QString &key, bool value)
|
||||
{
|
||||
if (!resetValues.contains(key))
|
||||
{
|
||||
if (!resetValues.contains(key)) {
|
||||
resetValues[key] = Core()->getConfigb(key);
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,11 @@ QModelIndex ClassesModel::parent(const QModelIndex &index) const
|
||||
|
||||
int ClassesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid()) // root
|
||||
{
|
||||
if (!parent.isValid()) { // root
|
||||
return classes->count();
|
||||
}
|
||||
|
||||
if (parent.internalId() == 0) // methods/fields
|
||||
{
|
||||
if (parent.internalId() == 0) { // methods/fields
|
||||
const ClassDescription *cls = &classes->at(parent.row());
|
||||
return cls->methods.length() + cls->fields.length();
|
||||
}
|
||||
@ -58,121 +56,100 @@ QVariant ClassesModel::data(const QModelIndex &index, int role) const
|
||||
const ClassDescription *cls;
|
||||
const ClassMethodDescription *meth = nullptr;
|
||||
const ClassFieldDescription *field = nullptr;
|
||||
if (index.internalId() == 0) // class row
|
||||
{
|
||||
if (index.row() >= classes->count())
|
||||
{
|
||||
if (index.internalId() == 0) { // class row
|
||||
if (index.row() >= classes->count()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
cls = &classes->at(index.row());
|
||||
}
|
||||
else // method/field row
|
||||
{
|
||||
} else { // method/field row
|
||||
cls = &classes->at(static_cast<int>(index.internalId() - 1));
|
||||
|
||||
if (index.row() >= cls->methods.length() + cls->fields.length())
|
||||
{
|
||||
if (index.row() >= cls->methods.length() + cls->fields.length()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (index.row() < cls->methods.length())
|
||||
{
|
||||
if (index.row() < cls->methods.length()) {
|
||||
meth = &cls->methods[index.row()];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
field = &cls->fields[index.row() - cls->methods.length()];
|
||||
}
|
||||
}
|
||||
|
||||
if (meth)
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return meth->name;
|
||||
case TYPE:
|
||||
return tr("method");
|
||||
case OFFSET:
|
||||
return RAddressString(meth->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(meth->addr);
|
||||
case NameRole:
|
||||
if (meth) {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case NAME:
|
||||
return meth->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(METHOD);
|
||||
case TYPE:
|
||||
return tr("method");
|
||||
case OFFSET:
|
||||
return RAddressString(meth->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(meth->addr);
|
||||
case NameRole:
|
||||
return meth->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(METHOD);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else if (field)
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return field->name;
|
||||
case TYPE:
|
||||
return tr("field");
|
||||
case OFFSET:
|
||||
return RAddressString(field->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(field->addr);
|
||||
case NameRole:
|
||||
} else if (field) {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case NAME:
|
||||
return field->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(FIELD);
|
||||
case TYPE:
|
||||
return tr("field");
|
||||
case OFFSET:
|
||||
return RAddressString(field->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(field->addr);
|
||||
case NameRole:
|
||||
return field->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(FIELD);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return cls->name;
|
||||
case TYPE:
|
||||
return tr("class");
|
||||
case OFFSET:
|
||||
return RAddressString(cls->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(cls->addr);
|
||||
case NameRole:
|
||||
} else {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case NAME:
|
||||
return cls->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(CLASS);
|
||||
case TYPE:
|
||||
return tr("class");
|
||||
case OFFSET:
|
||||
return RAddressString(cls->addr);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case OffsetRole:
|
||||
return QVariant::fromValue(cls->addr);
|
||||
case NameRole:
|
||||
return cls->name;
|
||||
case TypeRole:
|
||||
return QVariant::fromValue(CLASS);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ClassesModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (section)
|
||||
{
|
||||
switch (section) {
|
||||
case NAME:
|
||||
return tr("Name");
|
||||
case TYPE:
|
||||
@ -201,7 +178,8 @@ void ClassesModel::endReload()
|
||||
|
||||
|
||||
|
||||
ClassesSortFilterProxyModel::ClassesSortFilterProxyModel(ClassesModel *source_model, QObject *parent)
|
||||
ClassesSortFilterProxyModel::ClassesSortFilterProxyModel(ClassesModel *source_model,
|
||||
QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(source_model);
|
||||
@ -215,18 +193,15 @@ bool ClassesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &p
|
||||
|
||||
bool ClassesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
switch (left.column())
|
||||
{
|
||||
case ClassesModel::OFFSET:
|
||||
{
|
||||
switch (left.column()) {
|
||||
case ClassesModel::OFFSET: {
|
||||
RVA left_offset = left.data(ClassesModel::OffsetRole).toULongLong();
|
||||
RVA right_offset = right.data(ClassesModel::OffsetRole).toULongLong();
|
||||
if (left_offset != right_offset)
|
||||
return left_offset < right_offset;
|
||||
}
|
||||
// fallthrough
|
||||
case ClassesModel::TYPE:
|
||||
{
|
||||
case ClassesModel::TYPE: {
|
||||
auto left_type = left.data(ClassesModel::TypeRole).value<ClassesModel::RowType>();
|
||||
auto right_type = right.data(ClassesModel::TypeRole).value<ClassesModel::RowType>();
|
||||
if (left_type != right_type)
|
||||
@ -263,20 +238,16 @@ ClassesWidget::~ClassesWidget() {}
|
||||
|
||||
ClassesWidget::Source ClassesWidget::getSource()
|
||||
{
|
||||
if (ui->classSourceCombo->currentIndex() == 1)
|
||||
{
|
||||
if (ui->classSourceCombo->currentIndex() == 1) {
|
||||
return Source::FLAGS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return Source::BIN;
|
||||
}
|
||||
}
|
||||
|
||||
void ClassesWidget::flagsChanged()
|
||||
{
|
||||
if (getSource() == Source::FLAGS)
|
||||
{
|
||||
if (getSource() == Source::FLAGS) {
|
||||
refreshClasses();
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,8 @@
|
||||
#include <QAbstractListModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ClassesWidget;
|
||||
namespace Ui {
|
||||
class ClassesWidget;
|
||||
}
|
||||
|
||||
class QTreeWidget;
|
||||
@ -43,7 +42,8 @@ public:
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
void beginReload();
|
||||
void endReload();
|
||||
|
@ -45,8 +45,7 @@ void CommentsWidget::on_commentsTreeWidget_itemDoubleClicked(QTreeWidgetItem *it
|
||||
void CommentsWidget::on_nestedCmtsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int)
|
||||
{
|
||||
// don't react on top-level items
|
||||
if (item->parent() == nullptr)
|
||||
{
|
||||
if (item->parent() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -74,13 +73,10 @@ void CommentsWidget::showTitleContextMenu(const QPoint &pt)
|
||||
menu->addAction(ui->actionHorizontal);
|
||||
menu->addAction(ui->actionVertical);
|
||||
|
||||
if (ui->tabWidget->currentIndex() == 0)
|
||||
{
|
||||
if (ui->tabWidget->currentIndex() == 0) {
|
||||
ui->actionHorizontal->setChecked(true);
|
||||
ui->actionVertical->setChecked(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->actionVertical->setChecked(true);
|
||||
ui->actionHorizontal->setChecked(false);
|
||||
}
|
||||
@ -105,15 +101,11 @@ void CommentsWidget::on_actionVertical_triggered()
|
||||
|
||||
void CommentsWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
if (main->responsive && isVisible())
|
||||
{
|
||||
if (event->size().width() >= event->size().height())
|
||||
{
|
||||
if (main->responsive && isVisible()) {
|
||||
if (event->size().width() >= event->size().height()) {
|
||||
// Set horizontal view (list)
|
||||
on_actionHorizontal_triggered();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Set vertical view (Tree)
|
||||
on_actionVertical_triggered();
|
||||
}
|
||||
@ -150,8 +142,7 @@ void CommentsWidget::refreshTree()
|
||||
QList<CommentDescription> comments = CutterCore::getInstance()->getAllComments("CCu");
|
||||
QMap<QString, QList<CommentDescription>> nestedComments;
|
||||
|
||||
for (CommentDescription comment : comments)
|
||||
{
|
||||
for (CommentDescription comment : comments) {
|
||||
QString fcn_name = CutterCore::getInstance()->cmdFunctionAt(comment.offset);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, RAddressString(comment.offset));
|
||||
@ -166,12 +157,10 @@ void CommentsWidget::refreshTree()
|
||||
|
||||
// Add nested comments
|
||||
ui->nestedCmtsTreeWidget->clear();
|
||||
for (auto functionName : nestedComments.keys())
|
||||
{
|
||||
for (auto functionName : nestedComments.keys()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(ui->nestedCmtsTreeWidget);
|
||||
item->setText(0, functionName);
|
||||
for (CommentDescription comment : nestedComments.value(functionName))
|
||||
{
|
||||
for (CommentDescription comment : nestedComments.value(functionName)) {
|
||||
QTreeWidgetItem *it = new QTreeWidgetItem();
|
||||
it->setText(0, RAddressString(comment.offset));
|
||||
it->setText(1, comment.name);
|
||||
|
@ -8,9 +8,8 @@
|
||||
class MainWindow;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CommentsWidget;
|
||||
namespace Ui {
|
||||
class CommentsWidget;
|
||||
}
|
||||
|
||||
class CommentsWidget : public CutterDockWidget
|
||||
|
@ -14,8 +14,7 @@
|
||||
// TODO: Find a way to get to this without copying it here
|
||||
// source: libr/core/core.c:585..
|
||||
// remark: u.* is missing
|
||||
static const QStringList radareArgs(
|
||||
{
|
||||
static const QStringList radareArgs( {
|
||||
"?", "?v", "whereis", "which", "ls", "rm", "mkdir", "pwd", "cat", "less",
|
||||
"dH", "ds", "dso", "dsl", "dc", "dd", "dm", "db ", "db-",
|
||||
"dp", "dr", "dcu", "dmd", "dmp", "dml",
|
||||
@ -75,14 +74,12 @@ static bool isForbidden(const QString &input)
|
||||
|
||||
const QStringList &commands = input.split(delimiters, QString::SkipEmptyParts);
|
||||
|
||||
for (const QString &command : commands)
|
||||
{
|
||||
for (const QString &command : commands) {
|
||||
const QString &trimmedCommand = command.trimmed();
|
||||
|
||||
if (forbiddenArgs.contains(trimmedCommand)) return true;
|
||||
|
||||
for (const QString &arg : forbiddenArgs)
|
||||
{
|
||||
for (const QString &arg : forbiddenArgs) {
|
||||
if (trimmedCommand.startsWith(arg + " ")) return true;
|
||||
}
|
||||
}
|
||||
@ -102,7 +99,8 @@ ConsoleWidget::ConsoleWidget(MainWindow *main, QAction *action) :
|
||||
// Adjust console lineedit
|
||||
ui->inputLineEdit->setTextMargins(10, 0, 0, 0);
|
||||
|
||||
ui->execButton->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/arrow_right.svg"), palette().buttonText().color())));
|
||||
ui->execButton->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/arrow_right.svg"),
|
||||
palette().buttonText().color())));
|
||||
|
||||
setupFont();
|
||||
|
||||
@ -159,8 +157,7 @@ void ConsoleWidget::addOutput(const QString &msg)
|
||||
|
||||
void ConsoleWidget::addDebugOutput(const QString &msg)
|
||||
{
|
||||
if (debugOutputEnabled)
|
||||
{
|
||||
if (debugOutputEnabled) {
|
||||
ui->outputTextEdit->appendHtml("<font color=\"red\"> [DEBUG]:\t" + msg + "</font>");
|
||||
scrollOutputToEnd();
|
||||
}
|
||||
@ -174,18 +171,14 @@ void ConsoleWidget::focusInputLineEdit()
|
||||
void ConsoleWidget::on_inputLineEdit_returnPressed()
|
||||
{
|
||||
QString input = ui->inputLineEdit->text();
|
||||
if (!input.isEmpty())
|
||||
{
|
||||
if (!isForbidden(input))
|
||||
{
|
||||
if (!input.isEmpty()) {
|
||||
if (!isForbidden(input)) {
|
||||
QString res = CutterCore::getInstance()->cmd(input);
|
||||
QString cmd_line = "[" + RAddressString(Core()->getOffset()) + "]> " + input + "\n";
|
||||
ui->outputTextEdit->appendPlainText(cmd_line + res);
|
||||
scrollOutputToEnd();
|
||||
historyAdd(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
addDebugOutput(tr("command forbidden: ") + input);
|
||||
}
|
||||
|
||||
@ -208,23 +201,17 @@ void ConsoleWidget::showCustomContextMenu(const QPoint &pt)
|
||||
|
||||
void ConsoleWidget::historyNext()
|
||||
{
|
||||
if (!history.isEmpty())
|
||||
{
|
||||
if (lastHistoryPosition > invalidHistoryPos)
|
||||
{
|
||||
if (lastHistoryPosition >= history.size())
|
||||
{
|
||||
if (!history.isEmpty()) {
|
||||
if (lastHistoryPosition > invalidHistoryPos) {
|
||||
if (lastHistoryPosition >= history.size()) {
|
||||
lastHistoryPosition = history.size() - 1 ;
|
||||
}
|
||||
|
||||
--lastHistoryPosition;
|
||||
|
||||
if (lastHistoryPosition >= 0)
|
||||
{
|
||||
if (lastHistoryPosition >= 0) {
|
||||
ui->inputLineEdit->setText(history.at(lastHistoryPosition));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->inputLineEdit->clear();
|
||||
}
|
||||
|
||||
@ -235,10 +222,8 @@ void ConsoleWidget::historyNext()
|
||||
|
||||
void ConsoleWidget::historyPrev()
|
||||
{
|
||||
if (!history.isEmpty())
|
||||
{
|
||||
if (lastHistoryPosition >= history.size() - 1)
|
||||
{
|
||||
if (!history.isEmpty()) {
|
||||
if (lastHistoryPosition >= history.size() - 1) {
|
||||
lastHistoryPosition = history.size() - 2;
|
||||
}
|
||||
|
||||
@ -265,8 +250,7 @@ void ConsoleWidget::scrollOutputToEnd()
|
||||
|
||||
void ConsoleWidget::historyAdd(const QString &input)
|
||||
{
|
||||
if (history.size() + 1 > maxHistoryEntries)
|
||||
{
|
||||
if (history.size() + 1 > maxHistoryEntries) {
|
||||
history.removeLast();
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,8 @@
|
||||
#include "MainWindow.h"
|
||||
#include "CutterDockWidget.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ConsoleWidget;
|
||||
namespace Ui {
|
||||
class ConsoleWidget;
|
||||
}
|
||||
|
||||
|
||||
@ -23,9 +22,15 @@ public:
|
||||
void addOutput(const QString &msg);
|
||||
void addDebugOutput(const QString &msg);
|
||||
|
||||
void setDebugOutputEnabled(bool enabled) { debugOutputEnabled = enabled; }
|
||||
void setDebugOutputEnabled(bool enabled)
|
||||
{
|
||||
debugOutputEnabled = enabled;
|
||||
}
|
||||
|
||||
void setMaxHistoryEntries(int max) { maxHistoryEntries = max; }
|
||||
void setMaxHistoryEntries(int max)
|
||||
{
|
||||
maxHistoryEntries = max;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void focusInputLineEdit();
|
||||
|
@ -16,18 +16,16 @@ CutterDockWidget::CutterDockWidget(MainWindow *main, QAction *action) :
|
||||
|
||||
void CutterDockWidget::toggleDockWidget(bool show)
|
||||
{
|
||||
if (!show)
|
||||
{
|
||||
if (!show) {
|
||||
this->close();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->show();
|
||||
this->raise();
|
||||
}
|
||||
}
|
||||
|
||||
void CutterDockWidget::closeEvent(QCloseEvent * event) {
|
||||
void CutterDockWidget::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (action) {
|
||||
this->action->setChecked(false);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ private:
|
||||
QAction *action;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent * event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // CUTTERWIDGET_H
|
||||
|
@ -53,8 +53,7 @@ void Dashboard::updateContents()
|
||||
this->ui->compiledEdit->setText(item2["compiled"].toString());
|
||||
this->ui->bitsEdit->setText(QString::number(item2["bits"].toDouble()));
|
||||
|
||||
if (!item2["relro"].isUndefined())
|
||||
{
|
||||
if (!item2["relro"].isUndefined()) {
|
||||
QString relro = item2["relro"].toString().split(" ").at(0);
|
||||
relro[0] = relro[0].toUpper();
|
||||
this->ui->relroEdit->setText(relro);
|
||||
@ -62,68 +61,44 @@ void Dashboard::updateContents()
|
||||
|
||||
this->ui->baddrEdit->setText(QString::number(item2["baddr"].toDouble()));
|
||||
|
||||
if (item2["va"].toBool() == true)
|
||||
{
|
||||
if (item2["va"].toBool() == true) {
|
||||
this->ui->vaEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->vaEdit->setText("False");
|
||||
}
|
||||
if (item2["canary"].toBool() == true)
|
||||
{
|
||||
if (item2["canary"].toBool() == true) {
|
||||
this->ui->canaryEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->canaryEdit->setText("False");
|
||||
}
|
||||
if (item2["crypto"].toBool() == true)
|
||||
{
|
||||
if (item2["crypto"].toBool() == true) {
|
||||
this->ui->cryptoEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->cryptoEdit->setText("False");
|
||||
}
|
||||
if (item2["nx"].toBool() == true)
|
||||
{
|
||||
if (item2["nx"].toBool() == true) {
|
||||
this->ui->nxEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->nxEdit->setText("False");
|
||||
}
|
||||
if (item2["pic"].toBool() == true)
|
||||
{
|
||||
if (item2["pic"].toBool() == true) {
|
||||
this->ui->picEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->picEdit->setText("False");
|
||||
}
|
||||
if (item2["static"].toBool() == true)
|
||||
{
|
||||
if (item2["static"].toBool() == true) {
|
||||
this->ui->staticEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->staticEdit->setText("False");
|
||||
}
|
||||
if (item2["stripped"].toBool() == true)
|
||||
{
|
||||
if (item2["stripped"].toBool() == true) {
|
||||
this->ui->strippedEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->strippedEdit->setText("False");
|
||||
}
|
||||
if (item2["relocs"].toBool() == true)
|
||||
{
|
||||
if (item2["relocs"].toBool() == true) {
|
||||
this->ui->relocsEdit->setText("True");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ui->relocsEdit->setText("False");
|
||||
}
|
||||
|
||||
@ -135,21 +110,17 @@ void Dashboard::updateContents()
|
||||
|
||||
QString libs = CutterCore::getInstance()->cmd("il");
|
||||
QStringList lines = libs.split("\n", QString::SkipEmptyParts);
|
||||
if (!lines.isEmpty())
|
||||
{
|
||||
if (!lines.isEmpty()) {
|
||||
lines.removeFirst();
|
||||
lines.removeLast();
|
||||
}
|
||||
|
||||
// dunno: why not label->setText(lines.join("\n")?
|
||||
while (ui->verticalLayout_2->count() > 0)
|
||||
{
|
||||
while (ui->verticalLayout_2->count() > 0) {
|
||||
QLayoutItem *item = ui->verticalLayout_2->takeAt(0);
|
||||
if (item != nullptr)
|
||||
{
|
||||
if (item != nullptr) {
|
||||
QWidget *w = item->widget();
|
||||
if (w != nullptr)
|
||||
{
|
||||
if (w != nullptr) {
|
||||
w->deleteLater();
|
||||
}
|
||||
|
||||
@ -157,8 +128,7 @@ void Dashboard::updateContents()
|
||||
}
|
||||
}
|
||||
|
||||
for (QString lib : lines)
|
||||
{
|
||||
for (QString lib : lines) {
|
||||
QLabel *label = new QLabel(this);
|
||||
label->setText(lib);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
@ -179,29 +149,26 @@ void Dashboard::updateContents()
|
||||
QStringList stats = CutterCore::getInstance()->getStats();
|
||||
}
|
||||
|
||||
void Dashboard::on_certificateButton_clicked()
|
||||
{
|
||||
void Dashboard::on_certificateButton_clicked()
|
||||
{
|
||||
static QDialog *viewDialog = nullptr;
|
||||
static QTreeView *view = nullptr;
|
||||
static JsonModel *model = nullptr;
|
||||
static QString qstrCertificates;
|
||||
if(!viewDialog)
|
||||
{
|
||||
if (!viewDialog) {
|
||||
viewDialog = new QDialog(this);
|
||||
view = new QTreeView(viewDialog);
|
||||
model = new JsonModel();
|
||||
QJsonDocument qjsonCertificatesDoc = Core()->cmdj("iCj");
|
||||
qstrCertificates = qjsonCertificatesDoc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
if (QString::compare("{}",qstrCertificates))
|
||||
{
|
||||
if(!viewDialog->isVisible())
|
||||
{
|
||||
if (QString::compare("{}", qstrCertificates)) {
|
||||
if (!viewDialog->isVisible()) {
|
||||
std::string strCertificates = qstrCertificates.toUtf8().constData();
|
||||
model->loadJson(QByteArray::fromStdString(strCertificates));
|
||||
view->setModel(model);
|
||||
view->expandAll();
|
||||
view->resize(900,600);
|
||||
view->resize(900, 600);
|
||||
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
@ -209,16 +176,14 @@ void Dashboard::on_certificateButton_clicked()
|
||||
viewDialog->setSizePolicy(sizePolicy);
|
||||
viewDialog->setMinimumSize(QSize(900, 600));
|
||||
viewDialog->setMaximumSize(QSize(900, 600));
|
||||
viewDialog->setSizeGripEnabled(false);
|
||||
viewDialog->setSizeGripEnabled(false);
|
||||
viewDialog->setWindowTitle("Certificates");
|
||||
viewDialog->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QMessageBox msgBoxCertificateInf(QMessageBox::Information, "Certificate Information ",
|
||||
"There is no certificate information",
|
||||
QMessageBox::NoButton, this);
|
||||
msgBoxCertificateInf.exec();
|
||||
}
|
||||
msgBoxCertificateInf.exec();
|
||||
}
|
||||
}
|
@ -6,9 +6,8 @@
|
||||
|
||||
class MainWindow;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class Dashboard;
|
||||
namespace Ui {
|
||||
class Dashboard;
|
||||
}
|
||||
|
||||
class Dashboard : public CutterDockWidget
|
||||
|
@ -26,7 +26,8 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
// Signals that require a refresh all
|
||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this,
|
||||
SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(instructionChanged(RVA)), this, SLOT(refreshView()));
|
||||
@ -41,7 +42,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
// Space to switch to disassembly
|
||||
QShortcut *shortcut_disassembly = new QShortcut(QKeySequence(Qt::Key_Space), this);
|
||||
shortcut_disassembly->setContext(Qt::WidgetShortcut);
|
||||
connect(shortcut_disassembly, &QShortcut::activated, this, []{
|
||||
connect(shortcut_disassembly, &QShortcut::activated, this, [] {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
|
||||
Core()->triggerRaisePrioritizedMemoryWidget();
|
||||
});
|
||||
@ -104,8 +105,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
|
||||
DisassemblerGraphView::~DisassemblerGraphView()
|
||||
{
|
||||
for(QShortcut *shortcut : shortcuts)
|
||||
{
|
||||
for (QShortcut *shortcut : shortcuts) {
|
||||
delete shortcut;
|
||||
}
|
||||
}
|
||||
@ -121,10 +121,10 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
{
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("scr.html", true)
|
||||
.set("scr.color", COLOR_MODE_16M)
|
||||
.set("asm.bbline", false)
|
||||
.set("asm.lines", false)
|
||||
.set("asm.fcnlines", false);
|
||||
.set("scr.color", COLOR_MODE_16M)
|
||||
.set("asm.bbline", false)
|
||||
.set("asm.lines", false)
|
||||
.set("asm.fcnlines", false);
|
||||
QJsonDocument functionsDoc = Core()->cmdj("agJ");
|
||||
QJsonArray functions = functionsDoc.array();
|
||||
|
||||
@ -142,8 +142,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
|
||||
QString windowTitle = tr("Graph");
|
||||
QString funcName = func["name"].toString().trimmed();
|
||||
if (!funcName.isEmpty())
|
||||
{
|
||||
if (!funcName.isEmpty()) {
|
||||
windowTitle += " (" + funcName + ")";
|
||||
}
|
||||
parentWidget()->setWindowTitle(windowTitle);
|
||||
@ -164,34 +163,27 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
db.entry = block_entry;
|
||||
db.true_path = RVA_INVALID;
|
||||
db.false_path = RVA_INVALID;
|
||||
if(block_fail)
|
||||
{
|
||||
if (block_fail) {
|
||||
db.false_path = block_fail;
|
||||
gb.exits.push_back(block_fail);
|
||||
}
|
||||
if(block_jump)
|
||||
{
|
||||
if(block_fail)
|
||||
{
|
||||
if (block_jump) {
|
||||
if (block_fail) {
|
||||
db.true_path = block_jump;
|
||||
}
|
||||
gb.exits.push_back(block_jump);
|
||||
}
|
||||
QJsonArray opArray = block["ops"].toArray();
|
||||
for (int opIndex=0; opIndex<opArray.size(); opIndex++)
|
||||
{
|
||||
for (int opIndex = 0; opIndex < opArray.size(); opIndex++) {
|
||||
QJsonObject op = opArray[opIndex].toObject();
|
||||
Instr i;
|
||||
i.addr = op["offset"].toVariant().toULongLong();
|
||||
|
||||
if (opIndex < opArray.size() - 1)
|
||||
{
|
||||
if (opIndex < opArray.size() - 1) {
|
||||
// get instruction size from distance to next instruction ...
|
||||
RVA nextOffset = opArray[opIndex+1].toObject()["offset"].toVariant().toULongLong();
|
||||
RVA nextOffset = opArray[opIndex + 1].toObject()["offset"].toVariant().toULongLong();
|
||||
i.size = nextOffset - i.addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// or to the end of the block.
|
||||
i.size = (block_entry + block_size) - i.addr;
|
||||
}
|
||||
@ -202,16 +194,17 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
QString disas;
|
||||
disas = op["text"].toString();
|
||||
|
||||
QTextDocument textDoc;
|
||||
textDoc.setHtml(disas);
|
||||
QTextDocument textDoc;
|
||||
textDoc.setHtml(disas);
|
||||
|
||||
RichTextPainter::List richText = RichTextPainter::fromTextDocument(textDoc);
|
||||
//Colors::colorizeAssembly(richText, textDoc.toPlainText(), 0);
|
||||
|
||||
bool cropped;
|
||||
int blockLength = Config()->getGraphBlockMaxChars() + Core()->getConfigb("asm.bytes") * 24 + Core()->getConfigb("asm.emu") * 10;
|
||||
int blockLength = Config()->getGraphBlockMaxChars() + Core()->getConfigb("asm.bytes") * 24 +
|
||||
Core()->getConfigb("asm.emu") * 10;
|
||||
i.text = Text(RichTextPainter::cropped(richText, blockLength, "...", &cropped));
|
||||
if(cropped)
|
||||
if (cropped)
|
||||
i.fullText = richText;
|
||||
else
|
||||
i.fullText = Text();
|
||||
@ -228,13 +221,11 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
anal.status = "Ready.";
|
||||
anal.entry = f.entry;
|
||||
|
||||
if(func["blocks"].toArray().size() > 0)
|
||||
{
|
||||
if (func["blocks"].toArray().size() > 0) {
|
||||
computeGraph(entry);
|
||||
viewport()->update();
|
||||
|
||||
if(first_draw)
|
||||
{
|
||||
if (first_draw) {
|
||||
showBlock(blocks[entry]);
|
||||
first_draw = false;
|
||||
}
|
||||
@ -246,23 +237,20 @@ void DisassemblerGraphView::prepareGraphNode(GraphBlock &block)
|
||||
DisassemblyBlock &db = disassembly_blocks[block.entry];
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
for(auto & line : db.header_text.lines)
|
||||
{
|
||||
for (auto &line : db.header_text.lines) {
|
||||
int lw = 0;
|
||||
for(auto & part : line)
|
||||
for (auto &part : line)
|
||||
lw += mFontMetrics->width(part.text);
|
||||
if(lw > width)
|
||||
if (lw > width)
|
||||
width = lw;
|
||||
height += 1;
|
||||
}
|
||||
for(Instr & instr : db.instrs)
|
||||
{
|
||||
for(auto & line : instr.text.lines)
|
||||
{
|
||||
for (Instr &instr : db.instrs) {
|
||||
for (auto &line : instr.text.lines) {
|
||||
int lw = 0;
|
||||
for(auto & part : line)
|
||||
for (auto &part : line)
|
||||
lw += mFontMetrics->width(part.text);
|
||||
if(lw > width)
|
||||
if (lw > width)
|
||||
width = lw;
|
||||
height += 1;
|
||||
}
|
||||
@ -281,12 +269,12 @@ void DisassemblerGraphView::initFont()
|
||||
charWidth = metrics.width('X');
|
||||
charHeight = metrics.height();
|
||||
charOffset = 0;
|
||||
if(mFontMetrics)
|
||||
if (mFontMetrics)
|
||||
delete mFontMetrics;
|
||||
mFontMetrics = new CachedFontMetrics(this, font());
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block)
|
||||
void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
{
|
||||
p.setPen(Qt::black);
|
||||
p.setBrush(Qt::gray);
|
||||
@ -299,11 +287,9 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
RVA selected_instruction = RVA_INVALID;
|
||||
|
||||
// Figure out if the current block is selected
|
||||
for(const Instr & instr : db.instrs)
|
||||
{
|
||||
for (const Instr &instr : db.instrs) {
|
||||
RVA addr = Core()->getOffset();
|
||||
if((instr.addr <= addr) && (addr <= instr.addr+instr.size))
|
||||
{
|
||||
if ((instr.addr <= addr) && (addr <= instr.addr + instr.size)) {
|
||||
block_selected = true;
|
||||
selected_instruction = instr.addr;
|
||||
}
|
||||
@ -311,10 +297,9 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
}
|
||||
|
||||
p.setPen(QColor(0, 0, 0, 0));
|
||||
if(db.terminal)
|
||||
{
|
||||
if (db.terminal) {
|
||||
p.setBrush(retShadowColor);
|
||||
} else if(db.indirectcall) {
|
||||
} else if (db.indirectcall) {
|
||||
p.setBrush(indirectcallShadowColor);
|
||||
} else {
|
||||
p.setBrush(QColor(0, 0, 0, 128));
|
||||
@ -324,8 +309,7 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
block.width + 4, block.height + 4);
|
||||
p.setPen(graphNodeColor);
|
||||
|
||||
if(block_selected)
|
||||
{
|
||||
if (block_selected) {
|
||||
p.setBrush(disassemblySelectedBackgroundColor);
|
||||
} else {
|
||||
p.setBrush(disassemblyBackgroundColor);
|
||||
@ -335,37 +319,31 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
block.width, block.height);
|
||||
|
||||
// Draw different background for selected instruction
|
||||
if(selected_instruction != RVA_INVALID)
|
||||
{
|
||||
if (selected_instruction != RVA_INVALID) {
|
||||
int y = block.y + (2 * charWidth) + (db.header_text.lines.size() * charHeight);
|
||||
for(Instr & instr : db.instrs)
|
||||
{
|
||||
for (Instr &instr : db.instrs) {
|
||||
auto selected = instr.addr == selected_instruction;
|
||||
//auto traceCount = dbgfunctions->GetTraceRecordHitCount(instr.addr);
|
||||
auto traceCount = 0;
|
||||
if(selected && traceCount)
|
||||
{
|
||||
if (selected && traceCount) {
|
||||
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
|
||||
int(instr.text.lines.size()) * charHeight), disassemblyTracedSelectionColor);
|
||||
}
|
||||
else if(selected)
|
||||
{
|
||||
} else if (selected) {
|
||||
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
|
||||
int(instr.text.lines.size()) * charHeight), disassemblySelectionColor);
|
||||
}
|
||||
else if(traceCount)
|
||||
{
|
||||
} else if (traceCount) {
|
||||
// Color depending on how often a sequence of code is executed
|
||||
int exponent = 1;
|
||||
while(traceCount >>= 1) //log2(traceCount)
|
||||
while (traceCount >>= 1) //log2(traceCount)
|
||||
exponent++;
|
||||
int colorDiff = (exponent * exponent) / 2;
|
||||
|
||||
// If the user has a light trace background color, substract
|
||||
if(disassemblyTracedColor.blue() > 160)
|
||||
if (disassemblyTracedColor.blue() > 160)
|
||||
colorDiff *= -1;
|
||||
|
||||
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth), int(instr.text.lines.size()) * charHeight),
|
||||
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
|
||||
int(instr.text.lines.size()) * charHeight),
|
||||
QColor(disassemblyTracedColor.red(),
|
||||
disassemblyTracedColor.green(),
|
||||
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
|
||||
@ -378,18 +356,14 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
// Render node text
|
||||
auto x = block.x + (2 * charWidth);
|
||||
int y = block.y + (2 * charWidth);
|
||||
for(auto & line : db.header_text.lines)
|
||||
{
|
||||
for (auto &line : db.header_text.lines) {
|
||||
RichTextPainter::paintRichText(&p, x, y, block.width, charHeight, 0, line, mFontMetrics);
|
||||
y += charHeight;
|
||||
}
|
||||
for(Instr & instr : db.instrs)
|
||||
{
|
||||
for(auto & line : instr.text.lines)
|
||||
{
|
||||
for (Instr &instr : db.instrs) {
|
||||
for (auto &line : instr.text.lines) {
|
||||
int rectSize = qRound(charWidth);
|
||||
if(rectSize % 2)
|
||||
{
|
||||
if (rectSize % 2) {
|
||||
rectSize++;
|
||||
}
|
||||
// Assume charWidth <= charHeight
|
||||
@ -397,27 +371,24 @@ void DisassemblerGraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block
|
||||
|
||||
// TODO: Breakpoint/Cip stuff
|
||||
|
||||
RichTextPainter::paintRichText(&p, x + charWidth, y, block.width - charWidth, charHeight, 0, line, mFontMetrics);
|
||||
RichTextPainter::paintRichText(&p, x + charWidth, y, block.width - charWidth, charHeight, 0, line,
|
||||
mFontMetrics);
|
||||
y += charHeight;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphView::EdgeConfiguration DisassemblerGraphView::edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to)
|
||||
GraphView::EdgeConfiguration DisassemblerGraphView::edgeConfiguration(GraphView::GraphBlock &from,
|
||||
GraphView::GraphBlock *to)
|
||||
{
|
||||
EdgeConfiguration ec;
|
||||
DisassemblyBlock &db = disassembly_blocks[from.entry];
|
||||
if(to->entry == db.true_path)
|
||||
{
|
||||
if (to->entry == db.true_path) {
|
||||
ec.color = brtrueColor;
|
||||
}
|
||||
else if(to->entry == db.false_path)
|
||||
{
|
||||
} else if (to->entry == db.false_path) {
|
||||
ec.color = brfalseColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ec.color = jmpColor;
|
||||
}
|
||||
ec.start_arrow = false;
|
||||
@ -436,14 +407,12 @@ RVA DisassemblerGraphView::getAddrForMouseEvent(GraphBlock &block, QPoint *point
|
||||
int mouse_row = text_point_y / charHeight;
|
||||
|
||||
int cur_row = db.header_text.lines.size();
|
||||
if (mouse_row < cur_row)
|
||||
{
|
||||
if (mouse_row < cur_row) {
|
||||
return db.entry;
|
||||
}
|
||||
|
||||
Instr *instr = getInstrForMouseEvent(block, point);
|
||||
if(instr)
|
||||
{
|
||||
if (instr) {
|
||||
return instr->addr;
|
||||
}
|
||||
|
||||
@ -451,7 +420,8 @@ RVA DisassemblerGraphView::getAddrForMouseEvent(GraphBlock &block, QPoint *point
|
||||
}
|
||||
|
||||
|
||||
DisassemblerGraphView::Instr *DisassemblerGraphView::getInstrForMouseEvent(GraphView::GraphBlock &block, QPoint *point)
|
||||
DisassemblerGraphView::Instr *DisassemblerGraphView::getInstrForMouseEvent(
|
||||
GraphView::GraphBlock &block, QPoint *point)
|
||||
{
|
||||
DisassemblyBlock &db = disassembly_blocks[block.entry];
|
||||
|
||||
@ -463,10 +433,8 @@ DisassemblerGraphView::Instr *DisassemblerGraphView::getInstrForMouseEvent(Graph
|
||||
|
||||
int cur_row = db.header_text.lines.size();
|
||||
|
||||
for(Instr & instr : db.instrs)
|
||||
{
|
||||
if(mouse_row < cur_row + (int)instr.text.lines.size())
|
||||
{
|
||||
for (Instr &instr : db.instrs) {
|
||||
if (mouse_row < cur_row + (int)instr.text.lines.size()) {
|
||||
return &instr;
|
||||
}
|
||||
cur_row += instr.text.lines.size();
|
||||
@ -503,13 +471,10 @@ void DisassemblerGraphView::fontsUpdatedSlot()
|
||||
|
||||
DisassemblerGraphView::DisassemblyBlock *DisassemblerGraphView::blockForAddress(RVA addr)
|
||||
{
|
||||
for(auto & blockIt : disassembly_blocks)
|
||||
{
|
||||
for (auto &blockIt : disassembly_blocks) {
|
||||
DisassemblyBlock &db = blockIt.second;
|
||||
for(Instr i : db.instrs)
|
||||
{
|
||||
if((i.addr <= addr) && (addr <= i.addr + i.size))
|
||||
{
|
||||
for (Instr i : db.instrs) {
|
||||
if ((i.addr <= addr) && (addr <= i.addr + i.size)) {
|
||||
return &db;
|
||||
}
|
||||
}
|
||||
@ -521,11 +486,9 @@ void DisassemblerGraphView::onSeekChanged(RVA addr)
|
||||
{
|
||||
mMenu->setOffset(addr);
|
||||
// If this seek was NOT done by us...
|
||||
if(!sent_seek)
|
||||
{
|
||||
if (!sent_seek) {
|
||||
DisassemblyBlock *db = blockForAddress(addr);
|
||||
if(db)
|
||||
{
|
||||
if (db) {
|
||||
// This is a local address! We animated to it.
|
||||
transition_dont_seek = true;
|
||||
showBlock(&blocks[db->entry], true);
|
||||
@ -533,8 +496,7 @@ void DisassemblerGraphView::onSeekChanged(RVA addr)
|
||||
} else {
|
||||
refreshView();
|
||||
DisassemblyBlock *db = blockForAddress(addr);
|
||||
if(db)
|
||||
{
|
||||
if (db) {
|
||||
// This is a local address! We animated to it.
|
||||
transition_dont_seek = true;
|
||||
showBlock(&blocks[db->entry], false);
|
||||
@ -573,12 +535,9 @@ void DisassemblerGraphView::zoomReset()
|
||||
void DisassemblerGraphView::takeTrue()
|
||||
{
|
||||
DisassemblyBlock *db = blockForAddress(Core()->getOffset());
|
||||
if(db->true_path != RVA_INVALID)
|
||||
{
|
||||
if (db->true_path != RVA_INVALID) {
|
||||
Core()->seek(db->true_path);
|
||||
}
|
||||
else if(blocks[db->entry].exits.size())
|
||||
{
|
||||
} else if (blocks[db->entry].exits.size()) {
|
||||
Core()->seek(blocks[db->entry].exits[0]);
|
||||
}
|
||||
}
|
||||
@ -586,12 +545,9 @@ void DisassemblerGraphView::takeTrue()
|
||||
void DisassemblerGraphView::takeFalse()
|
||||
{
|
||||
DisassemblyBlock *db = blockForAddress(Core()->getOffset());
|
||||
if(db->false_path != RVA_INVALID)
|
||||
{
|
||||
if (db->false_path != RVA_INVALID) {
|
||||
Core()->seek(db->false_path);
|
||||
}
|
||||
else if(blocks[db->entry].exits.size())
|
||||
{
|
||||
} else if (blocks[db->entry].exits.size()) {
|
||||
Core()->seek(blocks[db->entry].exits[0]);
|
||||
}
|
||||
}
|
||||
@ -600,27 +556,21 @@ void DisassemblerGraphView::seekInstruction(bool previous_instr)
|
||||
{
|
||||
RVA addr = Core()->getOffset();
|
||||
DisassemblyBlock *db = blockForAddress(addr);
|
||||
if(!db)
|
||||
{
|
||||
if (!db) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(size_t i=0; i < db->instrs.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < db->instrs.size(); i++) {
|
||||
Instr &instr = db->instrs[i];
|
||||
if(!((instr.addr <= addr) && (addr <= instr.addr + instr.size)))
|
||||
{
|
||||
if (!((instr.addr <= addr) && (addr <= instr.addr + instr.size))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found the instructon. Check if a next one exists
|
||||
if(!previous_instr && (i < db->instrs.size()-1))
|
||||
{
|
||||
seek(db->instrs[i+1].addr, true);
|
||||
}
|
||||
else if(previous_instr && (i > 0))
|
||||
{
|
||||
seek(db->instrs[i-1].addr);
|
||||
if (!previous_instr && (i < db->instrs.size() - 1)) {
|
||||
seek(db->instrs[i + 1].addr, true);
|
||||
} else if (previous_instr && (i > 0)) {
|
||||
seek(db->instrs[i - 1].addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -639,8 +589,7 @@ void DisassemblerGraphView::seek(RVA addr, bool update_viewport)
|
||||
{
|
||||
sent_seek = true;
|
||||
Core()->seek(addr);
|
||||
if(update_viewport)
|
||||
{
|
||||
if (update_viewport) {
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
@ -650,29 +599,28 @@ void DisassemblerGraphView::seekPrev()
|
||||
Core()->seekPrev();
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos)
|
||||
void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEvent *event,
|
||||
QPoint pos)
|
||||
{
|
||||
RVA instr = getAddrForMouseEvent(block, &pos);
|
||||
if(instr == RVA_INVALID)
|
||||
{
|
||||
if (instr == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
seek(instr, true);
|
||||
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
mMenu->setOffset(instr);
|
||||
mMenu->exec(event->globalPos());
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos)
|
||||
void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event,
|
||||
QPoint pos)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
RVA instr = getAddrForMouseEvent(block, &pos);
|
||||
if(instr == RVA_INVALID)
|
||||
{
|
||||
if (instr == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
QList<XrefDescription> refs = Core()->getXRefs(instr, false, false);
|
||||
@ -685,11 +633,11 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos)
|
||||
void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event,
|
||||
QPoint pos)
|
||||
{
|
||||
Instr *instr = getInstrForMouseEvent(block, &pos);
|
||||
if(!instr || instr->fullText.lines.empty())
|
||||
{
|
||||
if (!instr || instr->fullText.lines.empty()) {
|
||||
QToolTip::hideText();
|
||||
event->ignore();
|
||||
return;
|
||||
@ -700,8 +648,7 @@ void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEv
|
||||
|
||||
bool DisassemblerGraphView::helpEvent(QHelpEvent *event)
|
||||
{
|
||||
if(!GraphView::helpEvent(event))
|
||||
{
|
||||
if (!GraphView::helpEvent(event)) {
|
||||
QToolTip::hideText();
|
||||
event->ignore();
|
||||
}
|
||||
@ -711,8 +658,7 @@ bool DisassemblerGraphView::helpEvent(QHelpEvent *event)
|
||||
|
||||
void DisassemblerGraphView::blockTransitionedTo(GraphView::GraphBlock *to)
|
||||
{
|
||||
if(transition_dont_seek)
|
||||
{
|
||||
if (transition_dont_seek) {
|
||||
transition_dont_seek = false;
|
||||
return;
|
||||
}
|
||||
@ -722,9 +668,9 @@ void DisassemblerGraphView::blockTransitionedTo(GraphView::GraphBlock *to)
|
||||
void DisassemblerGraphView::on_actionExportGraph_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Export Graph"), "", tr("Dot file (*.dot)"));
|
||||
tr("Export Graph"), "", tr("Dot file (*.dot)"));
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qWarning() << "Can't open file";
|
||||
return;
|
||||
}
|
||||
|
@ -16,8 +16,7 @@ class DisassemblerGraphView : public GraphView
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
struct Token
|
||||
{
|
||||
struct Token {
|
||||
int start; //token[0]
|
||||
int length; //token[1]
|
||||
QString type; //token[2]
|
||||
@ -25,20 +24,19 @@ class DisassemblerGraphView : public GraphView
|
||||
QString name; //token[4]
|
||||
};
|
||||
|
||||
struct HighlightToken
|
||||
{
|
||||
struct HighlightToken {
|
||||
QString type; //highlight_token[0]
|
||||
ut64 addr; //highlight_token[1]
|
||||
QString name; //highlight_token[2]
|
||||
|
||||
bool equalsToken(const Token & token)
|
||||
bool equalsToken(const Token &token)
|
||||
{
|
||||
return this->type == token.type &&
|
||||
this->addr == token.addr &&
|
||||
this->name == token.name;
|
||||
}
|
||||
|
||||
static HighlightToken* fromToken(const Token & token)
|
||||
static HighlightToken *fromToken(const Token &token)
|
||||
{
|
||||
//TODO: memory leaks
|
||||
auto result = new HighlightToken();
|
||||
@ -49,13 +47,12 @@ class DisassemblerGraphView : public GraphView
|
||||
}
|
||||
};
|
||||
|
||||
struct Text
|
||||
{
|
||||
struct Text {
|
||||
std::vector<RichTextPainter::List> lines;
|
||||
|
||||
Text() {}
|
||||
|
||||
Text(const QString & text, QColor color, QColor background)
|
||||
Text(const QString &text, QColor color, QColor background)
|
||||
{
|
||||
RichTextPainter::List richText;
|
||||
RichTextPainter::CustomRichText_t rt;
|
||||
@ -68,7 +65,7 @@ class DisassemblerGraphView : public GraphView
|
||||
lines.push_back(richText);
|
||||
}
|
||||
|
||||
Text(const RichTextPainter::List & richText)
|
||||
Text(const RichTextPainter::List &richText)
|
||||
{
|
||||
lines.push_back(richText);
|
||||
}
|
||||
@ -76,10 +73,8 @@ class DisassemblerGraphView : public GraphView
|
||||
QString ToQString() const
|
||||
{
|
||||
QString result;
|
||||
for(auto & line : lines)
|
||||
{
|
||||
for(auto & t : line)
|
||||
{
|
||||
for (auto &line : lines) {
|
||||
for (auto &t : line) {
|
||||
result += t.text;
|
||||
}
|
||||
}
|
||||
@ -87,8 +82,7 @@ class DisassemblerGraphView : public GraphView
|
||||
}
|
||||
};
|
||||
|
||||
struct Instr
|
||||
{
|
||||
struct Instr {
|
||||
ut64 addr = 0;
|
||||
ut64 size = 0;
|
||||
Text text;
|
||||
@ -97,8 +91,7 @@ class DisassemblerGraphView : public GraphView
|
||||
};
|
||||
|
||||
|
||||
struct DisassemblyBlock
|
||||
{
|
||||
struct DisassemblyBlock {
|
||||
Text header_text;
|
||||
std::vector<Instr> instrs;
|
||||
ut64 entry = 0;
|
||||
@ -108,23 +101,21 @@ class DisassemblerGraphView : public GraphView
|
||||
bool indirectcall = false;
|
||||
};
|
||||
|
||||
struct Function
|
||||
{
|
||||
struct Function {
|
||||
bool ready;
|
||||
ut64 entry;
|
||||
ut64 update_id;
|
||||
std::vector<DisassemblyBlock> blocks;
|
||||
};
|
||||
|
||||
struct Analysis
|
||||
{
|
||||
struct Analysis {
|
||||
ut64 entry = 0;
|
||||
std::unordered_map<ut64, Function> functions;
|
||||
bool ready = false;
|
||||
ut64 update_id = 0;
|
||||
QString status = "Analyzing...";
|
||||
|
||||
bool find_instr(ut64 addr, ut64 & func, ut64 & instr)
|
||||
bool find_instr(ut64 addr, ut64 &func, ut64 &instr)
|
||||
{
|
||||
//TODO implement
|
||||
Q_UNUSED(addr);
|
||||
@ -140,12 +131,14 @@ public:
|
||||
DisassemblerGraphView(QWidget *parent);
|
||||
~DisassemblerGraphView();
|
||||
std::unordered_map<ut64, DisassemblyBlock> disassembly_blocks;
|
||||
virtual void drawBlock(QPainter & p, GraphView::GraphBlock &block) override;
|
||||
virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block) override;
|
||||
virtual void blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos) override;
|
||||
virtual void blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos) override;
|
||||
virtual void blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event,
|
||||
QPoint pos) override;
|
||||
virtual bool helpEvent(QHelpEvent *event) override;
|
||||
virtual void blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos) override;
|
||||
virtual GraphView::EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to) override;
|
||||
virtual GraphView::EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from,
|
||||
GraphView::GraphBlock *to) override;
|
||||
virtual void blockTransitionedTo(GraphView::GraphBlock *to) override;
|
||||
|
||||
void loadCurrentGraph();
|
||||
@ -176,25 +169,25 @@ private:
|
||||
bool transition_dont_seek = false;
|
||||
bool sent_seek = false;
|
||||
|
||||
HighlightToken* highlight_token;
|
||||
HighlightToken *highlight_token;
|
||||
// Font data
|
||||
CachedFontMetrics* mFontMetrics;
|
||||
CachedFontMetrics *mFontMetrics;
|
||||
qreal charWidth;
|
||||
int charHeight;
|
||||
int charOffset;
|
||||
int baseline;
|
||||
|
||||
DisassemblyContextMenu* mMenu;
|
||||
DisassemblyContextMenu *mMenu;
|
||||
|
||||
void initFont();
|
||||
void prepareGraphNode(GraphBlock &block);
|
||||
RVA getAddrForMouseEvent(GraphBlock &block, QPoint *point);
|
||||
Instr *getInstrForMouseEvent(GraphBlock &block, QPoint *point);
|
||||
DisassemblyBlock *blockForAddress(RVA addr);
|
||||
void seek(RVA addr, bool update_viewport=true);
|
||||
void seek(RVA addr, bool update_viewport = true);
|
||||
void seekInstruction(bool previous_instr);
|
||||
|
||||
QList<QShortcut*> shortcuts;
|
||||
QList<QShortcut *> shortcuts;
|
||||
|
||||
QColor disassemblyBackgroundColor;
|
||||
QColor disassemblySelectedBackgroundColor;
|
||||
|
@ -28,8 +28,7 @@ public:
|
||||
static DisassemblyTextBlockUserData *getUserData(const QTextBlock &block)
|
||||
{
|
||||
QTextBlockUserData *userData = block.userData();
|
||||
if (!userData)
|
||||
{
|
||||
if (!userData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -89,7 +88,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
// Space to switch to graph
|
||||
QShortcut *graphShortcut = new QShortcut(QKeySequence(Qt::Key_Space), this);
|
||||
graphShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
||||
connect(graphShortcut, &QShortcut::activated, this, []{
|
||||
connect(graphShortcut, &QShortcut::activated, this, [] {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
|
||||
Core()->triggerRaisePrioritizedMemoryWidget();
|
||||
});
|
||||
@ -99,24 +98,24 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
connect(mDisasScrollArea, SIGNAL(disassemblyResized()), this, SLOT(updateMaxLines()));
|
||||
|
||||
connectCursorPositionChanged(false);
|
||||
connect(mDisasTextEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, [=](int value) {
|
||||
if (value != 0)
|
||||
{
|
||||
connect(mDisasTextEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, [ = ](int value) {
|
||||
if (value != 0) {
|
||||
mDisasTextEdit->verticalScrollBar()->setValue(0);
|
||||
}
|
||||
});
|
||||
|
||||
connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
||||
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
||||
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this,
|
||||
SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
||||
connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(functionsChanged()), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this,
|
||||
SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm()));
|
||||
connect(Core(), &CutterCore::instructionChanged, this, [this](RVA offset) {
|
||||
if (offset >= topOffset && offset <= bottomOffset)
|
||||
{
|
||||
if (offset >= topOffset && offset <= bottomOffset) {
|
||||
refreshDisasm();
|
||||
}
|
||||
});
|
||||
@ -125,8 +124,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
||||
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
|
||||
if (visibility)
|
||||
{
|
||||
if (visibility) {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
|
||||
}
|
||||
});
|
||||
@ -148,34 +146,43 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
s->setContext(Qt::WidgetShortcut); \
|
||||
connect(s, &QShortcut::activated, this, (slot)); \
|
||||
}
|
||||
ADD_SHORTCUT(QKeySequence(Qt::Key_J), [this]() { moveCursorRelative(false, false); })
|
||||
ADD_SHORTCUT(QKeySequence::MoveToNextLine, [this]() { moveCursorRelative(false, false); })
|
||||
ADD_SHORTCUT(QKeySequence(Qt::Key_K), [this]() { moveCursorRelative(true, false); })
|
||||
ADD_SHORTCUT(QKeySequence::MoveToPreviousLine, [this]() { moveCursorRelative(true, false); })
|
||||
ADD_SHORTCUT(QKeySequence::MoveToNextPage, [this]() { moveCursorRelative(false, true); })
|
||||
ADD_SHORTCUT(QKeySequence::MoveToPreviousPage, [this]() { moveCursorRelative(true, true); })
|
||||
ADD_SHORTCUT(QKeySequence(Qt::Key_J), [this]() {
|
||||
moveCursorRelative(false, false);
|
||||
})
|
||||
ADD_SHORTCUT(QKeySequence::MoveToNextLine, [this]() {
|
||||
moveCursorRelative(false, false);
|
||||
})
|
||||
ADD_SHORTCUT(QKeySequence(Qt::Key_K), [this]() {
|
||||
moveCursorRelative(true, false);
|
||||
})
|
||||
ADD_SHORTCUT(QKeySequence::MoveToPreviousLine, [this]() {
|
||||
moveCursorRelative(true, false);
|
||||
})
|
||||
ADD_SHORTCUT(QKeySequence::MoveToNextPage, [this]() {
|
||||
moveCursorRelative(false, true);
|
||||
})
|
||||
ADD_SHORTCUT(QKeySequence::MoveToPreviousPage, [this]() {
|
||||
moveCursorRelative(true, true);
|
||||
})
|
||||
#undef ADD_SHORTCUT
|
||||
}
|
||||
|
||||
QWidget* DisassemblyWidget::getTextWidget()
|
||||
QWidget *DisassemblyWidget::getTextWidget()
|
||||
{
|
||||
return mDisasTextEdit;
|
||||
}
|
||||
|
||||
void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
{
|
||||
if (offset != RVA_INVALID)
|
||||
{
|
||||
if (offset != RVA_INVALID) {
|
||||
topOffset = offset;
|
||||
}
|
||||
|
||||
if (topOffset == RVA_INVALID)
|
||||
{
|
||||
if (topOffset == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxLines <= 0)
|
||||
{
|
||||
if (maxLines <= 0) {
|
||||
connectCursorPositionChanged(true);
|
||||
mDisasTextEdit->clear();
|
||||
connectCursorPositionChanged(false);
|
||||
@ -184,12 +191,12 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
|
||||
int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value();
|
||||
mDisasTextEdit->setLockScroll(true); // avoid flicker
|
||||
|
||||
|
||||
QList<DisassemblyLine> disassemblyLines;
|
||||
{
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("scr.html", true)
|
||||
.set("scr.color", COLOR_MODE_16M);
|
||||
.set("scr.color", COLOR_MODE_16M);
|
||||
disassemblyLines = Core()->disassembleLines(topOffset, maxLines);
|
||||
}
|
||||
|
||||
@ -197,8 +204,7 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
|
||||
mDisasTextEdit->document()->clear();
|
||||
QTextCursor cursor(mDisasTextEdit->document());
|
||||
for (DisassemblyLine line : disassemblyLines)
|
||||
{
|
||||
for (DisassemblyLine line : disassemblyLines) {
|
||||
cursor.insertHtml(line.text);
|
||||
auto a = new DisassemblyTextBlockUserData(line);
|
||||
cursor.block().setUserData(a);
|
||||
@ -215,8 +221,7 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
connectCursorPositionChanged(false);
|
||||
|
||||
bottomOffset = readCurrentDisassemblyOffset();
|
||||
if (bottomOffset == RVA_INVALID)
|
||||
{
|
||||
if (bottomOffset == RVA_INVALID) {
|
||||
bottomOffset = topOffset;
|
||||
}
|
||||
|
||||
@ -234,18 +239,14 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
|
||||
void DisassemblyWidget::scrollInstructions(int count)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
RVA offset;
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > 0) {
|
||||
offset = Core()->nextOpAddr(topOffset, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
offset = Core()->prevOpAddr(topOffset, -count);
|
||||
}
|
||||
|
||||
@ -257,8 +258,7 @@ bool DisassemblyWidget::updateMaxLines()
|
||||
{
|
||||
int currentMaxLines = qhelpers::getMaxFullyDisplayedLines(mDisasTextEdit);
|
||||
|
||||
if (currentMaxLines != maxLines)
|
||||
{
|
||||
if (currentMaxLines != maxLines) {
|
||||
maxLines = currentMaxLines;
|
||||
refreshDisasm();
|
||||
return true;
|
||||
@ -302,18 +302,15 @@ void DisassemblyWidget::highlightCurrentLine()
|
||||
highlightSelection.cursor = cursor;
|
||||
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||
|
||||
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd())
|
||||
{
|
||||
highlightSelection.cursor = document->find(searchString, highlightSelection.cursor, QTextDocument::FindWholeWords);
|
||||
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) {
|
||||
highlightSelection.cursor = document->find(searchString, highlightSelection.cursor,
|
||||
QTextDocument::FindWholeWords);
|
||||
|
||||
if (!highlightSelection.cursor.isNull())
|
||||
{
|
||||
if (highlightSelection.cursor.position() >= listStartPos && highlightSelection.cursor.position() <= lineEndPos)
|
||||
{
|
||||
if (!highlightSelection.cursor.isNull()) {
|
||||
if (highlightSelection.cursor.position() >= listStartPos
|
||||
&& highlightSelection.cursor.position() <= lineEndPos) {
|
||||
highlightSelection.format.setBackground(highlightWordCurrentLineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
highlightSelection.format.setBackground(highlightWordColor);
|
||||
}
|
||||
|
||||
@ -339,8 +336,7 @@ RVA DisassemblyWidget::readCurrentDisassemblyOffset()
|
||||
RVA DisassemblyWidget::readDisassemblyOffset(QTextCursor tc)
|
||||
{
|
||||
auto userData = getUserData(tc.block());
|
||||
if (!userData)
|
||||
{
|
||||
if (!userData) {
|
||||
return RVA_INVALID;
|
||||
}
|
||||
|
||||
@ -353,50 +349,40 @@ void DisassemblyWidget::updateCursorPosition()
|
||||
|
||||
// already fine where it is?
|
||||
RVA currentLineOffset = readCurrentDisassemblyOffset();
|
||||
if (currentLineOffset == offset)
|
||||
{
|
||||
if (currentLineOffset == offset) {
|
||||
return;
|
||||
}
|
||||
|
||||
connectCursorPositionChanged(true);
|
||||
|
||||
if (offset < topOffset || (offset > bottomOffset && bottomOffset != RVA_INVALID))
|
||||
{
|
||||
if (offset < topOffset || (offset > bottomOffset && bottomOffset != RVA_INVALID)) {
|
||||
mDisasTextEdit->moveCursor(QTextCursor::Start);
|
||||
mDisasTextEdit->setExtraSelections({});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
RVA currentCursorOffset = readCurrentDisassemblyOffset();
|
||||
QTextCursor originalCursor = mDisasTextEdit->textCursor();
|
||||
|
||||
QTextCursor cursor = originalCursor;
|
||||
cursor.movePosition(QTextCursor::Start);
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
RVA lineOffset = readDisassemblyOffset(cursor);
|
||||
if (lineOffset == offset)
|
||||
{
|
||||
if (cursorLineOffset > 0)
|
||||
{
|
||||
if (lineOffset == offset) {
|
||||
if (cursorLineOffset > 0) {
|
||||
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, cursorLineOffset);
|
||||
}
|
||||
|
||||
mDisasTextEdit->setTextCursor(cursor);
|
||||
highlightCurrentLine();
|
||||
break;
|
||||
}
|
||||
else if (lineOffset != RVA_INVALID && lineOffset > offset)
|
||||
{
|
||||
} else if (lineOffset != RVA_INVALID && lineOffset > offset) {
|
||||
mDisasTextEdit->moveCursor(QTextCursor::Start);
|
||||
mDisasTextEdit->setExtraSelections({});
|
||||
break;
|
||||
}
|
||||
|
||||
cursor.movePosition(QTextCursor::EndOfLine);
|
||||
if (cursor.atEnd())
|
||||
{
|
||||
if (cursor.atEnd()) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -405,8 +391,7 @@ void DisassemblyWidget::updateCursorPosition()
|
||||
|
||||
// this is true if a seek came from the user clicking on a line.
|
||||
// then the cursor should be restored 1:1 to retain selection and cursor position.
|
||||
if (currentCursorOffset == offset)
|
||||
{
|
||||
if (currentCursorOffset == offset) {
|
||||
mDisasTextEdit->setTextCursor(originalCursor);
|
||||
}
|
||||
}
|
||||
@ -415,12 +400,10 @@ void DisassemblyWidget::updateCursorPosition()
|
||||
|
||||
void DisassemblyWidget::connectCursorPositionChanged(bool disconnect)
|
||||
{
|
||||
if (disconnect)
|
||||
{
|
||||
QObject::disconnect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disconnect) {
|
||||
QObject::disconnect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this,
|
||||
SLOT(cursorPositionChanged()));
|
||||
} else {
|
||||
connect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));
|
||||
}
|
||||
}
|
||||
@ -431,11 +414,9 @@ void DisassemblyWidget::cursorPositionChanged()
|
||||
|
||||
cursorLineOffset = 0;
|
||||
QTextCursor c = mDisasTextEdit->textCursor();
|
||||
while (c.blockNumber() > 0)
|
||||
{
|
||||
while (c.blockNumber() > 0) {
|
||||
c.movePosition(QTextCursor::PreviousBlock);
|
||||
if (readDisassemblyOffset(c) != offset)
|
||||
{
|
||||
if (readDisassemblyOffset(c) != offset) {
|
||||
break;
|
||||
}
|
||||
cursorLineOffset++;
|
||||
@ -450,15 +431,11 @@ void DisassemblyWidget::cursorPositionChanged()
|
||||
|
||||
void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
{
|
||||
if (page)
|
||||
{
|
||||
if (page) {
|
||||
RVA offset;
|
||||
if (!up)
|
||||
{
|
||||
if (!up) {
|
||||
offset = Core()->nextOpAddr(bottomOffset, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
offset = Core()->prevOpAddr(topOffset, maxLines);
|
||||
|
||||
// disassembly from calculated offset may have more than maxLines lines
|
||||
@ -466,43 +443,33 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
|
||||
auto lines = Core()->disassembleLines(offset, maxLines).toVector();
|
||||
int oldTopLine;
|
||||
for (oldTopLine=lines.length(); oldTopLine>0; oldTopLine--)
|
||||
{
|
||||
if (lines[oldTopLine - 1].offset < topOffset)
|
||||
{
|
||||
for (oldTopLine = lines.length(); oldTopLine > 0; oldTopLine--) {
|
||||
if (lines[oldTopLine - 1].offset < topOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int overflowLines = oldTopLine - maxLines;
|
||||
if(overflowLines > 0)
|
||||
{
|
||||
while (lines[overflowLines-1].offset == lines[overflowLines].offset
|
||||
&& overflowLines < lines.length()-1)
|
||||
{
|
||||
if (overflowLines > 0) {
|
||||
while (lines[overflowLines - 1].offset == lines[overflowLines].offset
|
||||
&& overflowLines < lines.length() - 1) {
|
||||
overflowLines++;
|
||||
}
|
||||
offset = lines[overflowLines].offset;
|
||||
}
|
||||
}
|
||||
refreshDisasm(offset);
|
||||
}
|
||||
else // normal arrow keys
|
||||
{
|
||||
} else { // normal arrow keys
|
||||
int blockCount = mDisasTextEdit->blockCount();
|
||||
if (blockCount < 1)
|
||||
{
|
||||
if (blockCount < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int blockNumber = mDisasTextEdit->textCursor().blockNumber();
|
||||
|
||||
if (blockNumber == blockCount - 1 && !up)
|
||||
{
|
||||
if (blockNumber == blockCount - 1 && !up) {
|
||||
scrollInstructions(1);
|
||||
}
|
||||
else if (blockNumber == 0 && up)
|
||||
{
|
||||
} else if (blockNumber == 0 && up) {
|
||||
scrollInstructions(-1);
|
||||
}
|
||||
|
||||
@ -510,8 +477,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
|
||||
// handle cases where top instruction offsets change
|
||||
RVA offset = readCurrentDisassemblyOffset();
|
||||
if (offset != Core()->getOffset())
|
||||
{
|
||||
if (offset != Core()->getOffset()) {
|
||||
Core()->seek(offset);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
@ -520,8 +486,8 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
|
||||
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport()) && event->type() == QEvent::MouseButtonDblClick)
|
||||
{
|
||||
if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport())
|
||||
&& event->type() == QEvent::MouseButtonDblClick) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
|
||||
QTextCursor cursor = mDisasTextEdit->cursorForPosition(QPoint(mouseEvent->x(), mouseEvent->y()));
|
||||
@ -529,18 +495,16 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
RVA jump = Core()->getOffsetJump(offset);
|
||||
|
||||
if (jump == RVA_INVALID)
|
||||
{
|
||||
if (jump == RVA_INVALID) {
|
||||
bool ok;
|
||||
RVA xref = Core()->cmdj("axfj@" + QString::number(offset)).array().first().toObject().value("to").toVariant().toULongLong(&ok);
|
||||
if (ok)
|
||||
{
|
||||
RVA xref = Core()->cmdj("axfj@" + QString::number(
|
||||
offset)).array().first().toObject().value("to").toVariant().toULongLong(&ok);
|
||||
if (ok) {
|
||||
jump = xref;
|
||||
}
|
||||
}
|
||||
|
||||
if (jump != RVA_INVALID)
|
||||
{
|
||||
if (jump != RVA_INVALID) {
|
||||
CutterCore::getInstance()->seek(jump);
|
||||
}
|
||||
|
||||
@ -551,19 +515,15 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
void DisassemblyWidget::on_seekChanged(RVA offset)
|
||||
{
|
||||
if (!seekFromCursor)
|
||||
{
|
||||
if (!seekFromCursor) {
|
||||
cursorLineOffset = 0;
|
||||
}
|
||||
|
||||
if (topOffset != RVA_INVALID && bottomOffset != RVA_INVALID
|
||||
&& offset >= topOffset && offset <= bottomOffset)
|
||||
{
|
||||
&& offset >= topOffset && offset <= bottomOffset) {
|
||||
// if the line with the seek offset is currently visible, just move the cursor there
|
||||
updateCursorPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// otherwise scroll there
|
||||
refreshDisasm(offset);
|
||||
}
|
||||
@ -572,8 +532,7 @@ void DisassemblyWidget::on_seekChanged(RVA offset)
|
||||
|
||||
void DisassemblyWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
||||
{
|
||||
if (type == CutterCore::MemoryWidgetType::Disassembly)
|
||||
{
|
||||
if (type == CutterCore::MemoryWidgetType::Disassembly) {
|
||||
raise();
|
||||
setFocus();
|
||||
}
|
||||
@ -583,8 +542,7 @@ void DisassemblyWidget::fontsUpdatedSlot()
|
||||
{
|
||||
setupFonts();
|
||||
|
||||
if (!updateMaxLines()) // updateMaxLines() returns true if it already refreshed.
|
||||
{
|
||||
if (!updateMaxLines()) { // updateMaxLines() returns true if it already refreshed.
|
||||
refreshDisasm();
|
||||
}
|
||||
}
|
||||
@ -604,8 +562,8 @@ void DisassemblyWidget::setupFonts()
|
||||
void DisassemblyWidget::setupColors()
|
||||
{
|
||||
mDisasTextEdit->setStyleSheet(QString("QPlainTextEdit { background-color: %1; color: %2; }")
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name()));
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name()));
|
||||
}
|
||||
|
||||
DisassemblyScrollArea::DisassemblyScrollArea(QWidget *parent) : QAbstractScrollArea(parent)
|
||||
@ -615,13 +573,11 @@ DisassemblyScrollArea::DisassemblyScrollArea(QWidget *parent) : QAbstractScrollA
|
||||
bool DisassemblyScrollArea::viewportEvent(QEvent *event)
|
||||
{
|
||||
int dy = verticalScrollBar()->value() - 5;
|
||||
if (dy != 0)
|
||||
{
|
||||
if (dy != 0) {
|
||||
emit scrollLines(dy);
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::Resize)
|
||||
{
|
||||
if (event->type() == QEvent::Resize) {
|
||||
emit disassemblyResized();
|
||||
}
|
||||
|
||||
@ -639,19 +595,17 @@ void DisassemblyScrollArea::resetScrollBars()
|
||||
|
||||
bool DisassemblyTextEdit::viewportEvent(QEvent *event)
|
||||
{
|
||||
switch(event->type())
|
||||
{
|
||||
case QEvent::Type::Wheel:
|
||||
return false;
|
||||
default:
|
||||
return QAbstractScrollArea::viewportEvent(event);
|
||||
switch (event->type()) {
|
||||
case QEvent::Type::Wheel:
|
||||
return false;
|
||||
default:
|
||||
return QAbstractScrollArea::viewportEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblyTextEdit::scrollContentsBy(int dx, int dy)
|
||||
{
|
||||
if (!lockScroll)
|
||||
{
|
||||
if (!lockScroll) {
|
||||
QPlainTextEdit::scrollContentsBy(dx, dy);
|
||||
}
|
||||
}
|
||||
@ -665,8 +619,7 @@ void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QPlainTextEdit::mousePressEvent(event);
|
||||
|
||||
if (event->button() == Qt::RightButton && !textCursor().hasSelection())
|
||||
{
|
||||
if (event->button() == Qt::RightButton && !textCursor().hasSelection()) {
|
||||
setTextCursor(cursorForPosition(event->pos()));
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class DisassemblyWidget : public CutterDockWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisassemblyWidget(MainWindow *main, QAction *action = nullptr);
|
||||
QWidget* getTextWidget();
|
||||
QWidget *getTextWidget();
|
||||
|
||||
public slots:
|
||||
void highlightCurrentLine();
|
||||
@ -90,10 +90,13 @@ class DisassemblyTextEdit: public QPlainTextEdit
|
||||
|
||||
public:
|
||||
explicit DisassemblyTextEdit(QWidget *parent = nullptr)
|
||||
: QPlainTextEdit(parent),
|
||||
lockScroll(false) {}
|
||||
: QPlainTextEdit(parent),
|
||||
lockScroll(false) {}
|
||||
|
||||
void setLockScroll(bool lock) { this->lockScroll = lock; }
|
||||
void setLockScroll(bool lock)
|
||||
{
|
||||
this->lockScroll = lock;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool viewportEvent(QEvent *event) override;
|
||||
|
@ -28,8 +28,7 @@ EntrypointWidget::~EntrypointWidget() {}
|
||||
void EntrypointWidget::fillEntrypoint()
|
||||
{
|
||||
ui->entrypointTreeWidget->clear();
|
||||
for (auto i : CutterCore::getInstance()->getAllEntrypoint())
|
||||
{
|
||||
for (auto i : CutterCore::getInstance()->getAllEntrypoint()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, RAddressString(i.vaddr));
|
||||
item->setText(1, i.type);
|
||||
@ -45,7 +44,8 @@ void EntrypointWidget::setScrollMode()
|
||||
qhelpers::setVerticalScrollMode(ui->entrypointTreeWidget);
|
||||
}
|
||||
|
||||
void EntrypointWidget::on_entrypointTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int /* column */)
|
||||
void EntrypointWidget::on_entrypointTreeWidget_itemDoubleClicked(QTreeWidgetItem *item,
|
||||
int /* column */)
|
||||
{
|
||||
EntrypointDescription ep = item->data(0, Qt::UserRole).value<EntrypointDescription>();
|
||||
CutterCore::getInstance()->seek(ep.vaddr);
|
||||
|
@ -10,9 +10,8 @@
|
||||
class MainWindow;
|
||||
class QTreeWidget;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EntrypointWidget;
|
||||
namespace Ui {
|
||||
class EntrypointWidget;
|
||||
}
|
||||
|
||||
class EntrypointWidget : public CutterDockWidget
|
||||
|
@ -26,11 +26,9 @@ QVariant ExportsModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
const ExportDescription &exp = exports->at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
switch (index.column()) {
|
||||
case OFFSET:
|
||||
return RAddressString(exp.vaddr);
|
||||
case SIZE:
|
||||
@ -51,11 +49,9 @@ QVariant ExportsModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QVariant ExportsModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (section)
|
||||
{
|
||||
switch (section) {
|
||||
case OFFSET:
|
||||
return tr("Address");
|
||||
case SIZE:
|
||||
@ -86,7 +82,8 @@ void ExportsModel::endReloadExports()
|
||||
|
||||
|
||||
|
||||
ExportsSortFilterProxyModel::ExportsSortFilterProxyModel(ExportsModel *source_model, QObject *parent)
|
||||
ExportsSortFilterProxyModel::ExportsSortFilterProxyModel(ExportsModel *source_model,
|
||||
QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(source_model);
|
||||
@ -101,11 +98,12 @@ bool ExportsSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &p
|
||||
|
||||
bool ExportsSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
ExportDescription left_exp = left.data(ExportsModel::ExportDescriptionRole).value<ExportDescription>();
|
||||
ExportDescription right_exp = right.data(ExportsModel::ExportDescriptionRole).value<ExportDescription>();
|
||||
ExportDescription left_exp = left.data(
|
||||
ExportsModel::ExportDescriptionRole).value<ExportDescription>();
|
||||
ExportDescription right_exp = right.data(
|
||||
ExportsModel::ExportDescriptionRole).value<ExportDescription>();
|
||||
|
||||
switch (left.column())
|
||||
{
|
||||
switch (left.column()) {
|
||||
case ExportsModel::SIZE:
|
||||
if (left_exp.size != right_exp.size)
|
||||
return left_exp.size < right_exp.size;
|
||||
|
@ -12,9 +12,8 @@
|
||||
class MainWindow;
|
||||
class QTreeWidget;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExportsWidget;
|
||||
namespace Ui {
|
||||
class ExportsWidget;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,11 +31,9 @@ QVariant FlagsModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
const FlagDescription &flag = flags->at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
switch (index.column()) {
|
||||
case SIZE:
|
||||
return RSizeString(flag.size);
|
||||
case OFFSET:
|
||||
@ -54,11 +52,9 @@ QVariant FlagsModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QVariant FlagsModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (section)
|
||||
{
|
||||
switch (section) {
|
||||
case SIZE:
|
||||
return tr("Size");
|
||||
case OFFSET:
|
||||
@ -105,8 +101,7 @@ bool FlagsSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIn
|
||||
FlagDescription left_flag = left.data(FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
FlagDescription right_flag = right.data(FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
|
||||
switch (left.column())
|
||||
{
|
||||
switch (left.column()) {
|
||||
case FlagsModel::SIZE:
|
||||
if (left_flag.size != right_flag.size)
|
||||
return left_flag.size < right_flag.size;
|
||||
@ -135,14 +130,16 @@ FlagsWidget::FlagsWidget(MainWindow *main, QAction *action) :
|
||||
|
||||
flags_model = new FlagsModel(&flags, this);
|
||||
flags_proxy_model = new FlagsSortFilterProxyModel(flags_model, this);
|
||||
connect(ui->filterLineEdit, SIGNAL(textChanged(const QString &)), flags_proxy_model, SLOT(setFilterWildcard(const QString &)));
|
||||
connect(ui->filterLineEdit, SIGNAL(textChanged(const QString &)), flags_proxy_model,
|
||||
SLOT(setFilterWildcard(const QString &)));
|
||||
ui->flagsTreeView->setModel(flags_proxy_model);
|
||||
ui->flagsTreeView->sortByColumn(FlagsModel::OFFSET, Qt::AscendingOrder);
|
||||
|
||||
setScrollMode();
|
||||
|
||||
ui->flagsTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->flagsTreeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showContextMenu(const QPoint &)));
|
||||
connect(ui->flagsTreeView, SIGNAL(customContextMenuRequested(const QPoint &)), this,
|
||||
SLOT(showContextMenu(const QPoint &)));
|
||||
|
||||
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(flagsChanged()));
|
||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshFlagspaces()));
|
||||
@ -165,12 +162,12 @@ void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1)
|
||||
|
||||
void FlagsWidget::on_actionRename_triggered()
|
||||
{
|
||||
FlagDescription flag = ui->flagsTreeView->selectionModel()->currentIndex().data(FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
FlagDescription flag = ui->flagsTreeView->selectionModel()->currentIndex().data(
|
||||
FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
|
||||
RenameDialog *r = new RenameDialog(this);
|
||||
r->setName(flag.name);
|
||||
if (r->exec())
|
||||
{
|
||||
if (r->exec()) {
|
||||
QString new_name = r->getName();
|
||||
CutterCore::getInstance()->renameFlag(flag.name, new_name);
|
||||
}
|
||||
@ -178,7 +175,8 @@ void FlagsWidget::on_actionRename_triggered()
|
||||
|
||||
void FlagsWidget::on_actionDelete_triggered()
|
||||
{
|
||||
FlagDescription flag = ui->flagsTreeView->selectionModel()->currentIndex().data(FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
FlagDescription flag = ui->flagsTreeView->selectionModel()->currentIndex().data(
|
||||
FlagsModel::FlagDescriptionRole).value<FlagDescription>();
|
||||
Core()->delFlag(flag.name);
|
||||
}
|
||||
|
||||
@ -206,8 +204,7 @@ void FlagsWidget::refreshFlagspaces()
|
||||
ui->flagspaceCombo->clear();
|
||||
ui->flagspaceCombo->addItem(tr("(all)"));
|
||||
|
||||
for (auto i : CutterCore::getInstance()->getAllFlagspaces())
|
||||
{
|
||||
for (auto i : CutterCore::getInstance()->getAllFlagspaces()) {
|
||||
ui->flagspaceCombo->addItem(i.name, QVariant::fromValue(i));
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,8 @@ protected:
|
||||
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FlagsWidget;
|
||||
namespace Ui {
|
||||
class FlagsWidget;
|
||||
}
|
||||
|
||||
class FlagsWidget : public CutterDockWidget
|
||||
|
@ -15,7 +15,8 @@
|
||||
#include <QShortcut>
|
||||
#include <QJsonObject>
|
||||
|
||||
FunctionModel::FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *importAddresses, ut64 *mainAdress, bool nested, QFont default_font, QFont highlight_font, QObject *parent)
|
||||
FunctionModel::FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *importAddresses,
|
||||
ut64 *mainAdress, bool nested, QFont default_font, QFont highlight_font, QObject *parent)
|
||||
: QAbstractItemModel(parent),
|
||||
functions(functions),
|
||||
importAddresses(importAddresses),
|
||||
@ -27,7 +28,8 @@ FunctionModel::FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *i
|
||||
|
||||
{
|
||||
connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(seekChanged(RVA)));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this, SLOT(functionRenamed(QString, QString)));
|
||||
connect(Core(), SIGNAL(functionRenamed(const QString &, const QString &)), this,
|
||||
SLOT(functionRenamed(QString, QString)));
|
||||
}
|
||||
|
||||
QModelIndex FunctionModel::index(int row, int column, const QModelIndex &parent) const
|
||||
@ -35,7 +37,8 @@ QModelIndex FunctionModel::index(int row, int column, const QModelIndex &parent)
|
||||
if (!parent.isValid())
|
||||
return createIndex(row, column, (quintptr)0); // root function nodes have id = 0
|
||||
|
||||
return createIndex(row, column, (quintptr)(parent.row() + 1)); // sub-nodes have id = function index + 1
|
||||
return createIndex(row, column,
|
||||
(quintptr)(parent.row() + 1)); // sub-nodes have id = function index + 1
|
||||
}
|
||||
|
||||
QModelIndex FunctionModel::parent(const QModelIndex &index) const
|
||||
@ -54,13 +57,11 @@ int FunctionModel::rowCount(const QModelIndex &parent) const
|
||||
if (!parent.isValid())
|
||||
return functions->count();
|
||||
|
||||
if (nested)
|
||||
{
|
||||
if (nested) {
|
||||
if (parent.internalId() == 0)
|
||||
return 3; // sub-nodes for nested functions
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -89,13 +90,10 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
int function_index;
|
||||
bool subnode;
|
||||
if (index.internalId() != 0) // sub-node
|
||||
{
|
||||
if (index.internalId() != 0) { // sub-node
|
||||
function_index = index.parent().row();
|
||||
subnode = true;
|
||||
}
|
||||
else // root function node
|
||||
{
|
||||
} else { // root function node
|
||||
function_index = index.row();
|
||||
subnode = false;
|
||||
}
|
||||
@ -105,15 +103,11 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
if (function_index >= functions->count())
|
||||
return QVariant();
|
||||
|
||||
switch (role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
if (nested)
|
||||
{
|
||||
if (subnode)
|
||||
{
|
||||
switch (index.row())
|
||||
{
|
||||
if (nested) {
|
||||
if (subnode) {
|
||||
switch (index.row()) {
|
||||
case 0:
|
||||
return tr("Offset: %1").arg(RAddressString(function.offset));
|
||||
case 1:
|
||||
@ -123,14 +117,10 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return function.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
} else {
|
||||
switch (index.column()) {
|
||||
case NameColumn:
|
||||
return function.name;
|
||||
case SizeColumn:
|
||||
@ -158,11 +148,9 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
return static_cast<int>(Qt::AlignRight | Qt::AlignVCenter);
|
||||
return static_cast<int>(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
{
|
||||
case Qt::ToolTipRole: {
|
||||
QList<QString> info = CutterCore::getInstance()->cmd("afi @ " + function.name).split("\n");
|
||||
if (info.length() > 2)
|
||||
{
|
||||
if (info.length() > 2) {
|
||||
QString size = info[4].split(" ")[1];
|
||||
QString complex = info[8].split(" ")[1];
|
||||
QString bb = info[11].split(" ")[1];
|
||||
@ -195,16 +183,11 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QVariant FunctionModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||
{
|
||||
if (nested)
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
if (nested) {
|
||||
return tr("Name");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
} else {
|
||||
switch (section) {
|
||||
case NameColumn:
|
||||
return tr("Name");
|
||||
case SizeColumn:
|
||||
@ -243,8 +226,7 @@ void FunctionModel::setNested(bool nested)
|
||||
|
||||
void FunctionModel::seekChanged(RVA)
|
||||
{
|
||||
if (updateCurrentIndex())
|
||||
{
|
||||
if (updateCurrentIndex()) {
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
}
|
||||
}
|
||||
@ -256,13 +238,11 @@ bool FunctionModel::updateCurrentIndex()
|
||||
|
||||
RVA seek = Core()->getOffset();
|
||||
|
||||
for (int i = 0; i < functions->count(); i++)
|
||||
{
|
||||
for (int i = 0; i < functions->count(); i++) {
|
||||
const FunctionDescription &function = functions->at(i);
|
||||
|
||||
if (function.contains(seek)
|
||||
&& function.offset >= offset)
|
||||
{
|
||||
&& function.offset >= offset) {
|
||||
offset = function.offset;
|
||||
index = i;
|
||||
}
|
||||
@ -277,18 +257,17 @@ bool FunctionModel::updateCurrentIndex()
|
||||
|
||||
void FunctionModel::functionRenamed(const QString &prev_name, const QString &new_name)
|
||||
{
|
||||
for (int i = 0; i < functions->count(); i++)
|
||||
{
|
||||
for (int i = 0; i < functions->count(); i++) {
|
||||
FunctionDescription &function = (*functions)[i];
|
||||
if (function.name == prev_name)
|
||||
{
|
||||
if (function.name == prev_name) {
|
||||
function.name = new_name;
|
||||
emit dataChanged(index(i, 0), index(i, columnCount() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FunctionSortFilterProxyModel::FunctionSortFilterProxyModel(FunctionModel *source_model, QObject *parent)
|
||||
FunctionSortFilterProxyModel::FunctionSortFilterProxyModel(FunctionModel *source_model,
|
||||
QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(source_model);
|
||||
@ -299,7 +278,8 @@ FunctionSortFilterProxyModel::FunctionSortFilterProxyModel(FunctionModel *source
|
||||
bool FunctionSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||
FunctionDescription function = index.data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = index.data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
return function.name.contains(filterRegExp());
|
||||
}
|
||||
|
||||
@ -311,26 +291,23 @@ bool FunctionSortFilterProxyModel::lessThan(const QModelIndex &left, const QMode
|
||||
if (left.parent().isValid() || right.parent().isValid())
|
||||
return false;
|
||||
|
||||
FunctionDescription left_function = left.data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription right_function = right.data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription left_function = left.data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription right_function = right.data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
|
||||
|
||||
if (static_cast<FunctionModel *>(sourceModel())->isNested())
|
||||
{
|
||||
if (static_cast<FunctionModel *>(sourceModel())->isNested()) {
|
||||
return left_function.name < right_function.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (left.column())
|
||||
{
|
||||
} else {
|
||||
switch (left.column()) {
|
||||
case FunctionModel::OffsetColumn:
|
||||
return left_function.offset < right_function.offset;
|
||||
case FunctionModel::SizeColumn:
|
||||
if (left_function.size != right_function.size)
|
||||
return left_function.size < right_function.size;
|
||||
break;
|
||||
case FunctionModel::ImportColumn:
|
||||
{
|
||||
case FunctionModel::ImportColumn: {
|
||||
bool left_is_import = left.data(FunctionModel::IsImportRole).toBool();
|
||||
bool right_is_import = right.data(FunctionModel::IsImportRole).toBool();
|
||||
if (!left_is_import && right_is_import)
|
||||
@ -373,12 +350,14 @@ FunctionsWidget::FunctionsWidget(MainWindow *main, QAction *action) :
|
||||
QFont default_font = QFont(font_info.family(), font_info.pointSize());
|
||||
QFont highlight_font = QFont(font_info.family(), font_info.pointSize(), QFont::Bold);
|
||||
|
||||
functionModel = new FunctionModel(&functions, &importAddresses, &mainAdress, false, default_font, highlight_font, this);
|
||||
functionModel = new FunctionModel(&functions, &importAddresses, &mainAdress, false, default_font,
|
||||
highlight_font, this);
|
||||
functionProxyModel = new FunctionSortFilterProxyModel(functionModel, this);
|
||||
ui->functionsTreeView->setModel(functionProxyModel);
|
||||
ui->functionsTreeView->sortByColumn(FunctionModel::NameColumn, Qt::AscendingOrder);
|
||||
|
||||
connect(ui->quickFilterView, SIGNAL(filterTextChanged(const QString &)), functionProxyModel, SLOT(setFilterWildcard(const QString &)));
|
||||
connect(ui->quickFilterView, SIGNAL(filterTextChanged(const QString &)), functionProxyModel,
|
||||
SLOT(setFilterWildcard(const QString &)));
|
||||
connect(ui->quickFilterView, SIGNAL(filterClosed()), ui->functionsTreeView, SLOT(setFocus()));
|
||||
|
||||
setScrollMode();
|
||||
@ -387,7 +366,8 @@ FunctionsWidget::FunctionsWidget(MainWindow *main, QAction *action) :
|
||||
connect(ui->functionsTreeView, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||
this, SLOT(showFunctionsContextMenu(const QPoint &)));
|
||||
|
||||
connect(ui->functionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(onFunctionsDoubleClicked(const QModelIndex &)));
|
||||
connect(ui->functionsTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this,
|
||||
SLOT(onFunctionsDoubleClicked(const QModelIndex &)));
|
||||
|
||||
// Use a custom context menu on the dock title bar
|
||||
//this->title_bar = this->titleBarWidget();
|
||||
@ -424,7 +404,8 @@ void FunctionsWidget::refreshTree()
|
||||
|
||||
void FunctionsWidget::onFunctionsDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
FunctionDescription function = index.data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = index.data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
Core()->seek(function.offset);
|
||||
}
|
||||
|
||||
@ -447,13 +428,13 @@ void FunctionsWidget::showFunctionsContextMenu(const QPoint &pt)
|
||||
void FunctionsWidget::on_actionDisasAdd_comment_triggered()
|
||||
{
|
||||
// Get selected item in functions tree view
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
|
||||
// Create dialog
|
||||
CommentsDialog *c = new CommentsDialog(this);
|
||||
|
||||
if (c->exec())
|
||||
{
|
||||
if (c->exec()) {
|
||||
// Get new function name
|
||||
QString comment = c->getComment();
|
||||
// Rename function in r2 core
|
||||
@ -467,7 +448,8 @@ void FunctionsWidget::on_actionDisasAdd_comment_triggered()
|
||||
void FunctionsWidget::on_actionFunctionsRename_triggered()
|
||||
{
|
||||
// Get selected item in functions tree view
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
|
||||
// Create dialog
|
||||
RenameDialog *r = new RenameDialog(this);
|
||||
@ -475,8 +457,7 @@ void FunctionsWidget::on_actionFunctionsRename_triggered()
|
||||
// Set function name in dialog
|
||||
r->setName(function.name);
|
||||
// If user accepted
|
||||
if (r->exec())
|
||||
{
|
||||
if (r->exec()) {
|
||||
// Get new function name
|
||||
QString new_name = r->getName();
|
||||
|
||||
@ -490,14 +471,16 @@ void FunctionsWidget::on_actionFunctionsRename_triggered()
|
||||
|
||||
void FunctionsWidget::on_actionFunctionsUndefine_triggered()
|
||||
{
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
Core()->delFunction(function.offset);
|
||||
}
|
||||
|
||||
void FunctionsWidget::on_action_References_triggered()
|
||||
{
|
||||
// Get selected item in functions tree view
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
FunctionDescription function = ui->functionsTreeView->selectionModel()->currentIndex().data(
|
||||
FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
|
||||
XrefsDialog *x = new XrefsDialog(this);
|
||||
x->fillRefsForAddress(function.offset, function.name, true);
|
||||
x->exec();
|
||||
@ -511,13 +494,10 @@ void FunctionsWidget::showTitleContextMenu(const QPoint &pt)
|
||||
menu->addAction(ui->actionHorizontal);
|
||||
menu->addAction(ui->actionVertical);
|
||||
|
||||
if (!functionModel->isNested())
|
||||
{
|
||||
if (!functionModel->isNested()) {
|
||||
ui->actionHorizontal->setChecked(true);
|
||||
ui->actionVertical->setChecked(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->actionVertical->setChecked(true);
|
||||
ui->actionHorizontal->setChecked(false);
|
||||
}
|
||||
@ -542,15 +522,11 @@ void FunctionsWidget::on_actionVertical_triggered()
|
||||
|
||||
void FunctionsWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
if (main->responsive && isVisible())
|
||||
{
|
||||
if (event->size().width() >= event->size().height())
|
||||
{
|
||||
if (main->responsive && isVisible()) {
|
||||
if (event->size().width() >= event->size().height()) {
|
||||
// Set horizontal view (list)
|
||||
on_actionHorizontal_triggered();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Set vertical view (Tree)
|
||||
on_actionVertical_triggered();
|
||||
}
|
||||
|
@ -12,9 +12,8 @@
|
||||
class MainWindow;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FunctionsWidget;
|
||||
namespace Ui {
|
||||
class FunctionsWidget;
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +43,8 @@ public:
|
||||
|
||||
enum Column { NameColumn = 0, SizeColumn, ImportColumn, OffsetColumn, ColumnCount };
|
||||
|
||||
FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *importAddresses, ut64 *mainAdress, bool nested, QFont defaultFont, QFont highlightFont, QObject *parent = 0);
|
||||
FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *importAddresses, ut64 *mainAdress,
|
||||
bool nested, QFont defaultFont, QFont highlightFont, QObject *parent = 0);
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
@ -64,7 +64,10 @@ public:
|
||||
bool updateCurrentIndex();
|
||||
|
||||
void setNested(bool nested);
|
||||
bool isNested() { return nested; }
|
||||
bool isNested()
|
||||
{
|
||||
return nested;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void seekChanged(RVA addr);
|
||||
|
@ -24,21 +24,21 @@ GraphView::~GraphView()
|
||||
|
||||
// Vector functions
|
||||
template<class T>
|
||||
static void removeFromVec(std::vector<T> & vec, T elem)
|
||||
static void removeFromVec(std::vector<T> &vec, T elem)
|
||||
{
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), elem), vec.end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void initVec(std::vector<T> & vec, size_t size, T value)
|
||||
static void initVec(std::vector<T> &vec, size_t size, T value)
|
||||
{
|
||||
vec.resize(size);
|
||||
for(size_t i = 0; i < size; i++)
|
||||
for (size_t i = 0; i < size; i++)
|
||||
vec[i] = value;
|
||||
}
|
||||
|
||||
// Callbacks
|
||||
void GraphView::drawBlock(QPainter & p, GraphView::GraphBlock &block)
|
||||
void GraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
Q_UNUSED(block);
|
||||
@ -70,16 +70,16 @@ void GraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event,
|
||||
|
||||
bool GraphView::helpEvent(QHelpEvent *event)
|
||||
{
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) + horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) + verticalScrollBar()->value();
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) +
|
||||
horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) +
|
||||
verticalScrollBar()->value();
|
||||
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
if((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height))
|
||||
{
|
||||
if ((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height)) {
|
||||
QPoint pos = QPoint(x - block.x, y - block.y);
|
||||
blockHelpEvent(block, event, pos);
|
||||
return true;
|
||||
@ -95,7 +95,8 @@ void GraphView::blockTransitionedTo(GraphView::GraphBlock *to)
|
||||
qWarning() << "blockTransitionedTo not overridden!";
|
||||
}
|
||||
|
||||
GraphView::EdgeConfiguration GraphView::edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to)
|
||||
GraphView::EdgeConfiguration GraphView::edgeConfiguration(GraphView::GraphBlock &from,
|
||||
GraphView::GraphBlock *to)
|
||||
{
|
||||
Q_UNUSED(from);
|
||||
Q_UNUSED(to);
|
||||
@ -108,30 +109,26 @@ void GraphView::adjustSize(int new_width, int new_height)
|
||||
{
|
||||
double hfactor = 0.0;
|
||||
double vfactor = 0.0;
|
||||
if(horizontalScrollBar()->maximum())
|
||||
{
|
||||
if (horizontalScrollBar()->maximum()) {
|
||||
hfactor = (double)horizontalScrollBar()->value() / (double)horizontalScrollBar()->maximum();
|
||||
}
|
||||
if(verticalScrollBar()->maximum())
|
||||
{
|
||||
if (verticalScrollBar()->maximum()) {
|
||||
vfactor = (double)verticalScrollBar()->value() / (double)verticalScrollBar()->maximum();
|
||||
}
|
||||
|
||||
//Update scroll bar information
|
||||
horizontalScrollBar()->setPageStep(new_width);
|
||||
horizontalScrollBar()->setRange(0, width - (new_width/current_scale));
|
||||
horizontalScrollBar()->setRange(0, width - (new_width / current_scale));
|
||||
verticalScrollBar()->setPageStep(new_height);
|
||||
verticalScrollBar()->setRange(0, height - (new_height/current_scale));
|
||||
verticalScrollBar()->setRange(0, height - (new_height / current_scale));
|
||||
horizontalScrollBar()->setValue((int)((double)horizontalScrollBar()->maximum() * hfactor));
|
||||
verticalScrollBar()->setValue((int)((double)verticalScrollBar()->maximum() * vfactor));
|
||||
}
|
||||
|
||||
bool GraphView::event(QEvent *event)
|
||||
{
|
||||
if(event->type() == QEvent::ToolTip)
|
||||
{
|
||||
if(helpEvent(static_cast<QHelpEvent *>(event)))
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
if (helpEvent(static_cast<QHelpEvent *>(event))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -145,11 +142,9 @@ void GraphView::computeGraph(ut64 entry)
|
||||
QSize areaSize = viewport()->size();
|
||||
|
||||
// Populate incoming lists
|
||||
for(auto &blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
for(auto & edge : block.exits)
|
||||
{
|
||||
for (auto &edge : block.exits) {
|
||||
blocks[edge].incoming.push_back(block.entry);
|
||||
}
|
||||
}
|
||||
@ -161,33 +156,27 @@ void GraphView::computeGraph(ut64 entry)
|
||||
queue.push(entry);
|
||||
|
||||
bool changed = true;
|
||||
while(changed)
|
||||
{
|
||||
while (changed) {
|
||||
changed = false;
|
||||
|
||||
// Pick nodes with single entrypoints
|
||||
while(!queue.empty())
|
||||
{
|
||||
while (!queue.empty()) {
|
||||
GraphBlock &block = blocks[queue.front()];
|
||||
queue.pop();
|
||||
block_order.push_back(block.entry);
|
||||
for(ut64 edge : block.exits)
|
||||
{
|
||||
for (ut64 edge : block.exits) {
|
||||
// Skip edge if we already visited it
|
||||
if(visited.count(edge))
|
||||
{
|
||||
if (visited.count(edge)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some edges might not be available
|
||||
if(!blocks.count(edge))
|
||||
{
|
||||
if (!blocks.count(edge)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this node has no other incoming edges, add it to the graph layout
|
||||
if(blocks[edge].incoming.size() == 1)
|
||||
{
|
||||
if (blocks[edge].incoming.size() == 1) {
|
||||
removeFromVec(blocks[edge].incoming, block.entry);
|
||||
block.new_exits.push_back(edge);
|
||||
queue.push(blocks[edge].entry);
|
||||
@ -204,37 +193,30 @@ void GraphView::computeGraph(ut64 entry)
|
||||
ut64 best = 0;
|
||||
int best_edges;
|
||||
ut64 best_parent;
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
// Skip blocks we haven't visited yet
|
||||
if(!visited.count(block.entry))
|
||||
{
|
||||
if (!visited.count(block.entry)) {
|
||||
continue;
|
||||
}
|
||||
for(ut64 edge : block.exits)
|
||||
{
|
||||
for (ut64 edge : block.exits) {
|
||||
// If we already visited the exit, skip it
|
||||
if(visited.count(edge))
|
||||
{
|
||||
if (visited.count(edge)) {
|
||||
continue;
|
||||
}
|
||||
if(!blocks.count(edge))
|
||||
{
|
||||
if (!blocks.count(edge)) {
|
||||
continue;
|
||||
}
|
||||
// find best edge
|
||||
if((best == 0) || ((int)blocks[edge].incoming.size() < best_edges) || (
|
||||
((int)blocks[edge].incoming.size() == best_edges) && (edge < best)))
|
||||
{
|
||||
if ((best == 0) || ((int)blocks[edge].incoming.size() < best_edges) || (
|
||||
((int)blocks[edge].incoming.size() == best_edges) && (edge < best))) {
|
||||
best = edge;
|
||||
best_edges = blocks[edge].incoming.size();
|
||||
best_parent = block.entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(best != 0)
|
||||
{
|
||||
if (best != 0) {
|
||||
GraphBlock &best_parentb = blocks[best_parent];
|
||||
removeFromVec(blocks[best].incoming, best_parentb.entry);
|
||||
best_parentb.new_exits.push_back(best);
|
||||
@ -253,33 +235,29 @@ void GraphView::computeGraph(ut64 entry)
|
||||
vert_edges.resize(entryb.row_count + 1);
|
||||
Matrix<bool> edge_valid;
|
||||
edge_valid.resize(entryb.row_count + 1);
|
||||
for(int row = 0; row < entryb.row_count + 1; row++)
|
||||
{
|
||||
horiz_edges[row].resize(entryb.col_count +1);
|
||||
for (int row = 0; row < entryb.row_count + 1; row++) {
|
||||
horiz_edges[row].resize(entryb.col_count + 1);
|
||||
vert_edges[row].resize(entryb.col_count + 1);
|
||||
initVec(edge_valid[row], entryb.col_count + 1, true);
|
||||
for(int col = 0; col < entryb.col_count + 1; col++)
|
||||
{
|
||||
for (int col = 0; col < entryb.col_count + 1; col++) {
|
||||
horiz_edges[row][col].clear();
|
||||
vert_edges[row][col].clear();
|
||||
}
|
||||
}
|
||||
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
edge_valid[block.row][block.col + 1] = false;
|
||||
}
|
||||
|
||||
// Perform edge routing
|
||||
for(ut64 block_id : block_order)
|
||||
{
|
||||
for (ut64 block_id : block_order) {
|
||||
GraphBlock &block = blocks[block_id];
|
||||
GraphBlock &start = block;
|
||||
for(ut64 edge : block.exits)
|
||||
{
|
||||
for (ut64 edge : block.exits) {
|
||||
GraphBlock &end = blocks[edge];
|
||||
start.edges.push_back(routeEdge(horiz_edges, vert_edges, edge_valid, start, end, QColor(255, 0, 0)));
|
||||
start.edges.push_back(routeEdge(horiz_edges, vert_edges, edge_valid, start, end, QColor(255, 0,
|
||||
0)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,13 +265,11 @@ void GraphView::computeGraph(ut64 entry)
|
||||
std::vector<int> col_edge_count, row_edge_count;
|
||||
initVec(col_edge_count, entryb.col_count + 1, 0);
|
||||
initVec(row_edge_count, entryb.row_count + 1, 0);
|
||||
for(int row = 0; row < entryb.row_count + 1; row++)
|
||||
{
|
||||
for(int col = 0; col < entryb.col_count + 1; col++)
|
||||
{
|
||||
if(int(horiz_edges[row][col].size()) > row_edge_count[row])
|
||||
for (int row = 0; row < entryb.row_count + 1; row++) {
|
||||
for (int col = 0; col < entryb.col_count + 1; col++) {
|
||||
if (int(horiz_edges[row][col].size()) > row_edge_count[row])
|
||||
row_edge_count[row] = int(horiz_edges[row][col].size());
|
||||
if(int(vert_edges[row][col].size()) > col_edge_count[col])
|
||||
if (int(vert_edges[row][col].size()) > col_edge_count[col])
|
||||
col_edge_count[col] = int(vert_edges[row][col].size());
|
||||
}
|
||||
}
|
||||
@ -303,14 +279,13 @@ void GraphView::computeGraph(ut64 entry)
|
||||
std::vector<int> col_width, row_height;
|
||||
initVec(col_width, entryb.col_count + 1, 0);
|
||||
initVec(row_height, entryb.row_count + 1, 0);
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
if((int(block.width / 2)) > col_width[block.col])
|
||||
if ((int(block.width / 2)) > col_width[block.col])
|
||||
col_width[block.col] = int(block.width / 2);
|
||||
if((int(block.width / 2)) > col_width[block.col + 1])
|
||||
if ((int(block.width / 2)) > col_width[block.col + 1])
|
||||
col_width[block.col + 1] = int(block.width / 2);
|
||||
if(int(block.height) > row_height[block.row])
|
||||
if (int(block.height) > row_height[block.row])
|
||||
row_height[block.row] = int(block.height);
|
||||
}
|
||||
|
||||
@ -321,20 +296,17 @@ void GraphView::computeGraph(ut64 entry)
|
||||
initVec(col_edge_x, entryb.col_count + 1, 0);
|
||||
initVec(row_edge_y, entryb.row_count + 1, 0);
|
||||
int x = block_horizontal_margin * 2;
|
||||
for(int i = 0; i < entryb.col_count; i++)
|
||||
{
|
||||
for (int i = 0; i < entryb.col_count; i++) {
|
||||
col_edge_x[i] = x;
|
||||
x += block_horizontal_margin * col_edge_count[i];
|
||||
col_x[i] = x;
|
||||
x += col_width[i];
|
||||
}
|
||||
int y = block_vertical_margin * 2;
|
||||
for(int i = 0; i < entryb.row_count; i++)
|
||||
{
|
||||
for (int i = 0; i < entryb.row_count; i++) {
|
||||
row_edge_y[i] = y;
|
||||
// TODO: The 1 when row_edge_count is 0 is not needed on the original.. not sure why it's required for us
|
||||
if(!row_edge_count[i])
|
||||
{
|
||||
if (!row_edge_count[i]) {
|
||||
row_edge_count[i] = 1;
|
||||
}
|
||||
y += block_vertical_margin * row_edge_count[i];
|
||||
@ -343,54 +315,57 @@ void GraphView::computeGraph(ut64 entry)
|
||||
}
|
||||
col_edge_x[entryb.col_count] = x;
|
||||
row_edge_y[entryb.row_count] = y;
|
||||
width = x + (block_horizontal_margin * 2) + (block_horizontal_margin * col_edge_count[entryb.col_count]);
|
||||
height = y + (block_vertical_margin * 2) + (block_vertical_margin * row_edge_count[entryb.row_count]);
|
||||
width = x + (block_horizontal_margin * 2) + (block_horizontal_margin *
|
||||
col_edge_count[entryb.col_count]);
|
||||
height = y + (block_vertical_margin * 2) + (block_vertical_margin *
|
||||
row_edge_count[entryb.row_count]);
|
||||
|
||||
//Compute node positions
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
block.x = int(
|
||||
(col_x[block.col] + col_width[block.col] + ((block_horizontal_margin / 2) * col_edge_count[block.col + 1])) - (block.width / 2));
|
||||
if((block.x + block.width) > (
|
||||
col_x[block.col] + col_width[block.col] + col_width[block.col + 1] + block_horizontal_margin * col_edge_count[
|
||||
block.col + 1]))
|
||||
{
|
||||
block.x = int((col_x[block.col] + col_width[block.col] + col_width[block.col + 1] + block_horizontal_margin * col_edge_count[
|
||||
block.col + 1]) - block.width);
|
||||
(col_x[block.col] + col_width[block.col] + ((block_horizontal_margin / 2) * col_edge_count[block.col
|
||||
+ 1])) - (block.width / 2));
|
||||
if ((block.x + block.width) > (
|
||||
col_x[block.col] + col_width[block.col] + col_width[block.col + 1] + block_horizontal_margin *
|
||||
col_edge_count[
|
||||
block.col + 1])) {
|
||||
block.x = int((col_x[block.col] + col_width[block.col] + col_width[block.col + 1] +
|
||||
block_horizontal_margin * col_edge_count[
|
||||
block.col + 1]) - block.width);
|
||||
}
|
||||
block.y = row_y[block.row];
|
||||
}
|
||||
|
||||
// Precompute coordinates for edges
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
for(GraphEdge & edge : block.edges)
|
||||
{
|
||||
for (GraphEdge &edge : block.edges) {
|
||||
auto start = edge.points[0];
|
||||
auto start_col = start.col;
|
||||
auto last_index = edge.start_index;
|
||||
// This is the start point of the edge.
|
||||
auto first_pt = QPoint(col_edge_x[start_col] + (block_horizontal_margin * last_index) + (block_horizontal_margin / 2),
|
||||
auto first_pt = QPoint(col_edge_x[start_col] + (block_horizontal_margin * last_index) +
|
||||
(block_horizontal_margin / 2),
|
||||
block.y + block.height);
|
||||
auto last_pt = first_pt;
|
||||
QPolygonF pts;
|
||||
pts.append(last_pt);
|
||||
|
||||
for(int i = 0; i < int(edge.points.size()); i++)
|
||||
{
|
||||
for (int i = 0; i < int(edge.points.size()); i++) {
|
||||
auto end = edge.points[i];
|
||||
auto end_row = end.row;
|
||||
auto end_col = end.col;
|
||||
auto last_index = end.index;
|
||||
QPoint new_pt;
|
||||
// block_vertical_margin/2 gives the margin from block to the horizontal lines
|
||||
if(start_col == end_col)
|
||||
new_pt = QPoint(last_pt.x(), row_edge_y[end_row] + (block_vertical_margin * last_index) + (block_vertical_margin/2));
|
||||
if (start_col == end_col)
|
||||
new_pt = QPoint(last_pt.x(), row_edge_y[end_row] + (block_vertical_margin * last_index) +
|
||||
(block_vertical_margin / 2));
|
||||
else
|
||||
new_pt = QPoint(col_edge_x[end_col] + (block_horizontal_margin * last_index) + (block_horizontal_margin/2), last_pt.y());
|
||||
new_pt = QPoint(col_edge_x[end_col] + (block_horizontal_margin * last_index) +
|
||||
(block_horizontal_margin / 2), last_pt.y());
|
||||
pts.push_back(new_pt);
|
||||
last_pt = new_pt;
|
||||
start_col = end_col;
|
||||
@ -402,16 +377,14 @@ void GraphView::computeGraph(ut64 entry)
|
||||
pts.push_back(new_pt);
|
||||
edge.polyline = pts;
|
||||
edge.color = ec.color;
|
||||
if(ec.start_arrow)
|
||||
{
|
||||
if (ec.start_arrow) {
|
||||
pts.clear();
|
||||
pts.append(QPoint(first_pt.x() - 3, first_pt.y() + 6));
|
||||
pts.append(QPoint(first_pt.x() + 3, first_pt.y() + 6));
|
||||
pts.append(first_pt);
|
||||
edge.arrow_start = pts;
|
||||
}
|
||||
if(ec.end_arrow)
|
||||
{
|
||||
if (ec.end_arrow) {
|
||||
pts.clear();
|
||||
pts.append(QPoint(new_pt.x() - 3, new_pt.y() - 6));
|
||||
pts.append(QPoint(new_pt.x() + 3, new_pt.y() - 6));
|
||||
@ -428,7 +401,7 @@ void GraphView::computeGraph(ut64 entry)
|
||||
adjustSize(areaSize.width(), areaSize.height());
|
||||
}
|
||||
|
||||
void GraphView::paintEvent(QPaintEvent* event)
|
||||
void GraphView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainter p(viewport());
|
||||
@ -451,13 +424,11 @@ void GraphView::paintEvent(QPaintEvent* event)
|
||||
unscrolled_render_offset_y = 0;
|
||||
|
||||
// We do not have a scrollbar on this axis, so we center the view
|
||||
if(!hscrollbar)
|
||||
{
|
||||
if (!hscrollbar) {
|
||||
unscrolled_render_offset_x = (viewport()->size().width() - (width * current_scale)) / 2;
|
||||
render_offset_x += unscrolled_render_offset_x;
|
||||
}
|
||||
if(!vscrollbar)
|
||||
{
|
||||
if (!vscrollbar) {
|
||||
unscrolled_render_offset_y = (viewport()->size().height() - (height * current_scale)) / 2;
|
||||
render_offset_y += unscrolled_render_offset_y;
|
||||
}
|
||||
@ -467,16 +438,14 @@ void GraphView::paintEvent(QPaintEvent* event)
|
||||
|
||||
|
||||
// Draw blocks
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
// Check if block is visible
|
||||
if((block.x + block.width > -render_offset_x) ||
|
||||
if ((block.x + block.width > -render_offset_x) ||
|
||||
(block.y + block.height > -render_offset_y) ||
|
||||
(-render_offset_x + render_width > block.x) ||
|
||||
(-render_offset_y + render_height > block.y))
|
||||
{
|
||||
(-render_offset_y + render_height > block.y)) {
|
||||
// Only draw block if it is visible
|
||||
drawBlock(p, block);
|
||||
}
|
||||
@ -486,8 +455,7 @@ void GraphView::paintEvent(QPaintEvent* event)
|
||||
// Always draw edges
|
||||
// TODO: Only draw edges if they are actually visible ...
|
||||
// Draw edges
|
||||
for(GraphEdge & edge : block.edges)
|
||||
{
|
||||
for (GraphEdge &edge : block.edges) {
|
||||
EdgeConfiguration ec = edgeConfiguration(block, edge.dest);
|
||||
QPen pen(edge.color);
|
||||
// if(blockSelected)
|
||||
@ -497,12 +465,10 @@ void GraphView::paintEvent(QPaintEvent* event)
|
||||
p.drawPolyline(edge.polyline);
|
||||
pen.setStyle(Qt::SolidLine);
|
||||
p.setPen(pen);
|
||||
if(ec.start_arrow)
|
||||
{
|
||||
if (ec.start_arrow) {
|
||||
p.drawConvexPolygon(edge.arrow_start);
|
||||
}
|
||||
if(ec.end_arrow)
|
||||
{
|
||||
if (ec.end_arrow) {
|
||||
p.drawConvexPolygon(edge.arrow_end);
|
||||
}
|
||||
}
|
||||
@ -519,8 +485,7 @@ void GraphView::computeGraphLayout(GraphBlock &block)
|
||||
int childColumn = 0;
|
||||
bool singleChild = block.new_exits.size() == 1;
|
||||
// Compute all children nodes
|
||||
for(size_t i = 0; i < block.new_exits.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < block.new_exits.size(); i++) {
|
||||
ut64 edge = block.new_exits[i];
|
||||
GraphBlock &edgeb = blocks[edge];
|
||||
computeGraphLayout(edgeb);
|
||||
@ -528,55 +493,40 @@ void GraphView::computeGraphLayout(GraphBlock &block)
|
||||
childColumn = edgeb.col;
|
||||
}
|
||||
|
||||
if(layoutType != LayoutType::Wide && block.new_exits.size() == 2)
|
||||
{
|
||||
if (layoutType != LayoutType::Wide && block.new_exits.size() == 2) {
|
||||
GraphBlock &left = blocks[block.new_exits[0]];
|
||||
GraphBlock &right= blocks[block.new_exits[1]];
|
||||
if(left.new_exits.size() == 0)
|
||||
{
|
||||
GraphBlock &right = blocks[block.new_exits[1]];
|
||||
if (left.new_exits.size() == 0) {
|
||||
left.col = right.col - 2;
|
||||
int add = left.col < 0 ? - left.col : 0;
|
||||
adjustGraphLayout(right, add, 1);
|
||||
adjustGraphLayout(left, add, 1);
|
||||
col = right.col_count + add;
|
||||
}
|
||||
else if(right.new_exits.size() == 0)
|
||||
{
|
||||
} else if (right.new_exits.size() == 0) {
|
||||
adjustGraphLayout(left, 0, 1);
|
||||
adjustGraphLayout(right, left.col + 2, 1);
|
||||
col = std::max(left.col_count, right.col + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
adjustGraphLayout(left, 0, 1);
|
||||
adjustGraphLayout(right, left.col_count, 1);
|
||||
col = left.col_count + right.col_count;
|
||||
}
|
||||
block.col_count = std::max(2, col);
|
||||
if(layoutType == LayoutType::Medium)
|
||||
{
|
||||
if (layoutType == LayoutType::Medium) {
|
||||
block.col = (left.col + right.col) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
block.col = singleChild ? childColumn : (col - 2) / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(ut64 edge : block.new_exits)
|
||||
{
|
||||
} else {
|
||||
for (ut64 edge : block.new_exits) {
|
||||
adjustGraphLayout(blocks[edge], col, 1);
|
||||
col += blocks[edge].col_count;
|
||||
}
|
||||
if(col >= 2)
|
||||
{
|
||||
if (col >= 2) {
|
||||
// Place this node centered over the child nodes
|
||||
block.col = singleChild ? childColumn : (col - 2) / 2;
|
||||
block.col_count = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
//No child nodes, set single node's width (nodes are 2 columns wide to allow
|
||||
//centering over a branch)
|
||||
block.col = 0;
|
||||
@ -588,21 +538,22 @@ void GraphView::computeGraphLayout(GraphBlock &block)
|
||||
}
|
||||
|
||||
// Edge computing stuff
|
||||
bool GraphView::isEdgeMarked(EdgesVector & edges, int row, int col, int index)
|
||||
bool GraphView::isEdgeMarked(EdgesVector &edges, int row, int col, int index)
|
||||
{
|
||||
if(index >= int(edges[row][col].size()))
|
||||
if (index >= int(edges[row][col].size()))
|
||||
return false;
|
||||
return edges[row][col][index];
|
||||
}
|
||||
|
||||
void GraphView::markEdge(EdgesVector & edges, int row, int col, int index, bool used)
|
||||
void GraphView::markEdge(EdgesVector &edges, int row, int col, int index, bool used)
|
||||
{
|
||||
while(int(edges[row][col].size()) <= index)
|
||||
while (int(edges[row][col].size()) <= index)
|
||||
edges[row][col].push_back(false);
|
||||
edges[row][col][index] = used;
|
||||
}
|
||||
|
||||
GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector & vert_edges, Matrix<bool> & edge_valid, GraphBlock &start, GraphBlock &end, QColor color)
|
||||
GraphView::GraphEdge GraphView::routeEdge(EdgesVector &horiz_edges, EdgesVector &vert_edges,
|
||||
Matrix<bool> &edge_valid, GraphBlock &start, GraphBlock &end, QColor color)
|
||||
{
|
||||
GraphEdge edge;
|
||||
edge.color = color;
|
||||
@ -610,9 +561,8 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
|
||||
//Find edge index for initial outgoing line
|
||||
int i = 0;
|
||||
while(true)
|
||||
{
|
||||
if(!isEdgeMarked(vert_edges, start.row + 1, start.col + 1, i))
|
||||
while (true) {
|
||||
if (!isEdgeMarked(vert_edges, start.row + 1, start.col + 1, i))
|
||||
break;
|
||||
i += 1;
|
||||
}
|
||||
@ -623,53 +573,39 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
|
||||
//Find valid column for moving vertically to the target node
|
||||
int min_row, max_row;
|
||||
if(end.row < (start.row + 1))
|
||||
{
|
||||
if (end.row < (start.row + 1)) {
|
||||
min_row = end.row;
|
||||
max_row = start.row + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
min_row = start.row + 1;
|
||||
max_row = end.row;
|
||||
}
|
||||
int col = start.col + 1;
|
||||
if(min_row != max_row)
|
||||
{
|
||||
auto checkColumn = [min_row, max_row, &edge_valid](int column)
|
||||
{
|
||||
if(column < 0 || column >= int(edge_valid[min_row].size()))
|
||||
if (min_row != max_row) {
|
||||
auto checkColumn = [min_row, max_row, &edge_valid](int column) {
|
||||
if (column < 0 || column >= int(edge_valid[min_row].size()))
|
||||
return false;
|
||||
for(int row = min_row; row < max_row; row++)
|
||||
{
|
||||
if(!edge_valid[row][column])
|
||||
{
|
||||
for (int row = min_row; row < max_row; row++) {
|
||||
if (!edge_valid[row][column]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if(!checkColumn(col))
|
||||
{
|
||||
if(checkColumn(end.col + 1))
|
||||
{
|
||||
if (!checkColumn(col)) {
|
||||
if (checkColumn(end.col + 1)) {
|
||||
col = end.col + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int ofs = 0;
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
col = start.col + 1 - ofs;
|
||||
if(checkColumn(col))
|
||||
{
|
||||
if (checkColumn(col)) {
|
||||
break;
|
||||
}
|
||||
|
||||
col = start.col + 1 + ofs;
|
||||
if(checkColumn(col))
|
||||
{
|
||||
if (checkColumn(col)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -679,17 +615,13 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
}
|
||||
}
|
||||
|
||||
if(col != (start.col + 1))
|
||||
{
|
||||
if (col != (start.col + 1)) {
|
||||
//Not in same column, need to generate a line for moving to the correct column
|
||||
int min_col, max_col;
|
||||
if(col < (start.col + 1))
|
||||
{
|
||||
if (col < (start.col + 1)) {
|
||||
min_col = col;
|
||||
max_col = start.col + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
min_col = start.col + 1;
|
||||
max_col = col;
|
||||
}
|
||||
@ -698,29 +630,24 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
horiz = true;
|
||||
}
|
||||
|
||||
if(end.row != (start.row + 1))
|
||||
{
|
||||
if (end.row != (start.row + 1)) {
|
||||
//Not in same row, need to generate a line for moving to the correct row
|
||||
if(col == (start.col + 1))
|
||||
if (col == (start.col + 1))
|
||||
markEdge(vert_edges, start.row + 1, start.col + 1, i, false);
|
||||
int index = findVertEdgeIndex(vert_edges, col, min_row, max_row);
|
||||
if(col == (start.col + 1))
|
||||
if (col == (start.col + 1))
|
||||
edge.start_index = index;
|
||||
edge.addPoint(end.row, col, index);
|
||||
horiz = false;
|
||||
}
|
||||
|
||||
if(col != (end.col + 1))
|
||||
{
|
||||
if (col != (end.col + 1)) {
|
||||
//Not in ending column, need to generate a line for moving to the correct column
|
||||
int min_col, max_col;
|
||||
if(col < (end.col + 1))
|
||||
{
|
||||
if (col < (end.col + 1)) {
|
||||
min_col = col;
|
||||
max_col = end.col + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
min_col = end.col + 1;
|
||||
max_col = col;
|
||||
}
|
||||
@ -730,8 +657,7 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
}
|
||||
|
||||
//If last line was horizontal, choose the ending edge index for the incoming edge
|
||||
if(horiz)
|
||||
{
|
||||
if (horiz) {
|
||||
int index = findVertEdgeIndex(vert_edges, end.col + 1, end.row, end.row);
|
||||
edge.points[int(edge.points.size()) - 1].index = index;
|
||||
}
|
||||
@ -740,50 +666,46 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
}
|
||||
|
||||
|
||||
int GraphView::findHorizEdgeIndex(EdgesVector & edges, int row, int min_col, int max_col)
|
||||
int GraphView::findHorizEdgeIndex(EdgesVector &edges, int row, int min_col, int max_col)
|
||||
{
|
||||
//Find a valid index
|
||||
int i = 0;
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
bool valid = true;
|
||||
for(int col = min_col; col < max_col + 1; col++)
|
||||
if(isEdgeMarked(edges, row, col, i))
|
||||
{
|
||||
for (int col = min_col; col < max_col + 1; col++)
|
||||
if (isEdgeMarked(edges, row, col, i)) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
if(valid)
|
||||
if (valid)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
//Mark chosen index as used
|
||||
for(int col = min_col; col < max_col + 1; col++)
|
||||
for (int col = min_col; col < max_col + 1; col++)
|
||||
markEdge(edges, row, col, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
int GraphView::findVertEdgeIndex(EdgesVector & edges, int col, int min_row, int max_row)
|
||||
int GraphView::findVertEdgeIndex(EdgesVector &edges, int col, int min_row, int max_row)
|
||||
{
|
||||
//Find a valid index
|
||||
int i = 0;
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
bool valid = true;
|
||||
for(int row = min_row; row < max_row + 1; row++)
|
||||
if(isEdgeMarked(edges, row, col, i))
|
||||
{
|
||||
for (int row = min_row; row < max_row + 1; row++)
|
||||
if (isEdgeMarked(edges, row, col, i)) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
if(valid)
|
||||
if (valid)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
//Mark chosen index as used
|
||||
for(int row = min_row; row < max_row + 1; row++)
|
||||
for (int row = min_row; row < max_row + 1; row++)
|
||||
markEdge(edges, row, col, i);
|
||||
return i;
|
||||
}
|
||||
@ -799,7 +721,7 @@ void GraphView::showBlock(GraphBlock *block, bool animated)
|
||||
|
||||
|
||||
// Show block middle of X
|
||||
int target_x = (block->x + (block->width / 2)) - (render_width/2);
|
||||
int target_x = (block->x + (block->width / 2)) - (render_width / 2);
|
||||
int show_block_offset_y = 30;
|
||||
// But beginning of Y (so we show the top of the block)
|
||||
int target_y = block->y - show_block_offset_y;
|
||||
@ -808,8 +730,7 @@ void GraphView::showBlock(GraphBlock *block, bool animated)
|
||||
target_y = std::max(0, target_y);
|
||||
target_x = std::min(horizontalScrollBar()->maximum(), target_x);
|
||||
target_y = std::min(verticalScrollBar()->maximum(), target_y);
|
||||
if(animated)
|
||||
{
|
||||
if (animated) {
|
||||
QPropertyAnimation *animation_x = new QPropertyAnimation(horizontalScrollBar(), "value");
|
||||
animation_x->setDuration(500);
|
||||
animation_x->setStartValue(horizontalScrollBar()->value());
|
||||
@ -836,8 +757,7 @@ void GraphView::adjustGraphLayout(GraphBlock &block, int col, int row)
|
||||
{
|
||||
block.col += col;
|
||||
block.row += row;
|
||||
for(ut64 edge : block.new_exits)
|
||||
{
|
||||
for (ut64 edge : block.new_exits) {
|
||||
adjustGraphLayout(blocks[edge], col, row);
|
||||
}
|
||||
}
|
||||
@ -856,17 +776,16 @@ void GraphView::setEntry(ut64 e)
|
||||
bool GraphView::checkPointClicked(QPointF &point, int x, int y, bool above_y)
|
||||
{
|
||||
int half_target_size = 5;
|
||||
if((point.x() - half_target_size < x) &&
|
||||
if ((point.x() - half_target_size < x) &&
|
||||
(point.y() - (above_y ? (2 * half_target_size) : 0) < y) &&
|
||||
(x < point.x() + half_target_size) &&
|
||||
(y < point.y() + (above_y ? 0 : (3 * half_target_size))))
|
||||
{
|
||||
(y < point.y() + (above_y ? 0 : (3 * half_target_size)))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GraphView::resizeEvent(QResizeEvent* event)
|
||||
void GraphView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
adjustSize(event->size().width(), event->size().height());
|
||||
}
|
||||
@ -874,17 +793,17 @@ void GraphView::resizeEvent(QResizeEvent* event)
|
||||
// Mouse events
|
||||
void GraphView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) + horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) + verticalScrollBar()->value();
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) +
|
||||
horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) +
|
||||
verticalScrollBar()->value();
|
||||
|
||||
// Check if a block was clicked
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
if((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height))
|
||||
{
|
||||
if ((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height)) {
|
||||
QPoint pos = QPoint(x - block.x, y - block.y);
|
||||
blockClicked(block, event, pos);
|
||||
// Don't do anything else here! blockClicked might seek and
|
||||
@ -894,26 +813,21 @@ void GraphView::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
// Check if a line beginning/end was clicked
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
for(GraphEdge & edge : block.edges)
|
||||
{
|
||||
if(edge.polyline.length() < 2)
|
||||
{
|
||||
for (GraphEdge &edge : block.edges) {
|
||||
if (edge.polyline.length() < 2) {
|
||||
continue;
|
||||
}
|
||||
QPointF start = edge.polyline.first();
|
||||
QPointF end = edge.polyline.last();
|
||||
if(checkPointClicked(start, x, y))
|
||||
{
|
||||
if (checkPointClicked(start, x, y)) {
|
||||
showBlock(edge.dest, true);
|
||||
// TODO: Callback to child
|
||||
return;
|
||||
break;
|
||||
}
|
||||
if(checkPointClicked(end, x, y, true))
|
||||
{
|
||||
if (checkPointClicked(end, x, y, true)) {
|
||||
showBlock(block, true);
|
||||
// TODO: Callback to child
|
||||
return;
|
||||
@ -923,8 +837,7 @@ void GraphView::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
// No block was clicked
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
//Left click outside any block, enter scrolling mode
|
||||
scroll_base_x = event->x();
|
||||
scroll_base_y = event->y();
|
||||
@ -935,10 +848,9 @@ void GraphView::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
}
|
||||
|
||||
void GraphView::mouseMoveEvent(QMouseEvent* event)
|
||||
void GraphView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if(scroll_mode)
|
||||
{
|
||||
if (scroll_mode) {
|
||||
int x_delta = scroll_base_x - event->x();
|
||||
int y_delta = scroll_base_y - event->y();
|
||||
scroll_base_x = event->x();
|
||||
@ -950,17 +862,17 @@ void GraphView::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
void GraphView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) + horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) + verticalScrollBar()->value();
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) +
|
||||
horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) +
|
||||
verticalScrollBar()->value();
|
||||
|
||||
// Check if a block was clicked
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
for (auto &blockIt : blocks) {
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
if((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height))
|
||||
{
|
||||
if ((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height)) {
|
||||
QPoint pos = QPoint(x - block.x, y - block.y);
|
||||
blockDoubleClicked(block, event, pos);
|
||||
return;
|
||||
@ -968,7 +880,7 @@ void GraphView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void GraphView::mouseReleaseEvent(QMouseEvent* event)
|
||||
void GraphView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
// TODO
|
||||
// if(event->button() == Qt::ForwardButton)
|
||||
@ -976,11 +888,10 @@ void GraphView::mouseReleaseEvent(QMouseEvent* event)
|
||||
// else if(event->button() == Qt::BackButton)
|
||||
// gotoPreviousSlot();
|
||||
|
||||
if(event->button() != Qt::LeftButton)
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
if(scroll_mode)
|
||||
{
|
||||
if (scroll_mode) {
|
||||
scroll_mode = false;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
viewport()->releaseMouse();
|
||||
|
@ -19,8 +19,7 @@ class GraphView : public QAbstractScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum class LayoutType
|
||||
{
|
||||
enum class LayoutType {
|
||||
Medium,
|
||||
Wide,
|
||||
Narrow,
|
||||
@ -28,15 +27,13 @@ class GraphView : public QAbstractScrollArea
|
||||
public:
|
||||
struct GraphBlock;
|
||||
|
||||
struct Point
|
||||
{
|
||||
struct Point {
|
||||
int row; //point[0]
|
||||
int col; //point[1]
|
||||
int index; //point[2]
|
||||
};
|
||||
|
||||
struct GraphEdge
|
||||
{
|
||||
struct GraphEdge {
|
||||
QColor color;
|
||||
GraphBlock *dest;
|
||||
std::vector<Point> points;
|
||||
@ -50,7 +47,7 @@ public:
|
||||
{
|
||||
Point point = {row, col, 0};
|
||||
this->points.push_back(point);
|
||||
if(int(this->points.size()) > 1)
|
||||
if (int(this->points.size()) > 1)
|
||||
this->points[this->points.size() - 2].index = index;
|
||||
}
|
||||
};
|
||||
@ -83,8 +80,7 @@ public:
|
||||
std::vector<GraphEdge> edges;
|
||||
};
|
||||
|
||||
struct EdgeConfiguration
|
||||
{
|
||||
struct EdgeConfiguration {
|
||||
QColor color = QColor(128, 128, 128);
|
||||
bool start_arrow = false;
|
||||
bool end_arrow = true;
|
||||
@ -92,11 +88,11 @@ public:
|
||||
|
||||
GraphView(QWidget *parent);
|
||||
~GraphView();
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
// Show a block centered. Animates to it if animated=true
|
||||
void showBlock(GraphBlock &block, bool animated=false);
|
||||
void showBlock(GraphBlock *block, bool animated=false);
|
||||
void showBlock(GraphBlock &block, bool animated = false);
|
||||
void showBlock(GraphBlock *block, bool animated = false);
|
||||
|
||||
protected:
|
||||
std::unordered_map<ut64, GraphBlock> blocks;
|
||||
@ -119,7 +115,7 @@ protected:
|
||||
void computeGraph(ut64 entry);
|
||||
|
||||
// Callbacks that should be overridden
|
||||
virtual void drawBlock(QPainter & p, GraphView::GraphBlock &block);
|
||||
virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block);
|
||||
virtual void blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos);
|
||||
virtual void blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos);
|
||||
virtual void blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos);
|
||||
@ -131,7 +127,7 @@ protected:
|
||||
|
||||
bool event(QEvent *event) override;
|
||||
private:
|
||||
bool checkPointClicked(QPointF &point, int x, int y, bool above_y=false);
|
||||
bool checkPointClicked(QPointF &point, int x, int y, bool above_y = false);
|
||||
|
||||
ut64 entry;
|
||||
|
||||
@ -160,14 +156,15 @@ private:
|
||||
using EdgesVector = Matrix<std::vector<bool>>;
|
||||
std::vector<int> col_edge_x;
|
||||
std::vector<int> row_edge_y;
|
||||
bool isEdgeMarked(EdgesVector & edges, int row, int col, int index);
|
||||
void markEdge(EdgesVector & edges, int row, int col, int index, bool used = true);
|
||||
int findHorizEdgeIndex(EdgesVector & edges, int row, int min_col, int max_col);
|
||||
int findVertEdgeIndex(EdgesVector & edges, int col, int min_row, int max_row);
|
||||
GraphEdge routeEdge(EdgesVector & horiz_edges, EdgesVector & vert_edges, Matrix<bool> & edge_valid, GraphBlock &start, GraphBlock &end, QColor color);
|
||||
bool isEdgeMarked(EdgesVector &edges, int row, int col, int index);
|
||||
void markEdge(EdgesVector &edges, int row, int col, int index, bool used = true);
|
||||
int findHorizEdgeIndex(EdgesVector &edges, int row, int min_col, int max_col);
|
||||
int findVertEdgeIndex(EdgesVector &edges, int col, int min_row, int max_row);
|
||||
GraphEdge routeEdge(EdgesVector &horiz_edges, EdgesVector &vert_edges, Matrix<bool> &edge_valid,
|
||||
GraphBlock &start, GraphBlock &end, QColor color);
|
||||
|
||||
private slots:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
// Mouse events
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
@ -10,18 +10,15 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
this->graphView = new DisassemblerGraphView(this);
|
||||
this->setWidget(graphView);
|
||||
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility)
|
||||
{
|
||||
if (visibility)
|
||||
{
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
|
||||
if (visibility) {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
|
||||
}
|
||||
});
|
||||
|
||||
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget, this, [ = ](CutterCore::MemoryWidgetType type)
|
||||
{
|
||||
if (type == CutterCore::MemoryWidgetType::Graph)
|
||||
{
|
||||
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget,
|
||||
this, [ = ](CutterCore::MemoryWidgetType type) {
|
||||
if (type == CutterCore::MemoryWidgetType::Graph) {
|
||||
this->raise();
|
||||
this->graphView->setFocus();
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include <QScrollBar>
|
||||
|
||||
HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action),
|
||||
ui(new Ui::HexdumpWidget)
|
||||
CutterDockWidget(main, action),
|
||||
ui(new Ui::HexdumpWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -25,8 +25,10 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine()));
|
||||
//highlightHexCurrentLine();
|
||||
|
||||
ui->copyMD5->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/transfer.svg"), palette().buttonText().color())));
|
||||
ui->copySHA1->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/transfer.svg"), palette().buttonText().color())));
|
||||
ui->copyMD5->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/transfer.svg"),
|
||||
palette().buttonText().color())));
|
||||
ui->copySHA1->setIcon(QIcon(new SvgIconEngine(QString(":/img/icons/transfer.svg"),
|
||||
palette().buttonText().color())));
|
||||
|
||||
int margin = static_cast<int>(ui->hexOffsetText->document()->documentMargin());
|
||||
ui->offsetHeaderLabel->setContentsMargins(margin, 0, margin, 0);
|
||||
@ -62,11 +64,11 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
||||
|
||||
connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
||||
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
||||
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this,
|
||||
SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
||||
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
|
||||
if (visibility)
|
||||
{
|
||||
if (visibility) {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Hexdump);
|
||||
}
|
||||
});
|
||||
@ -78,7 +80,8 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
connect(ui->hexHexText, &QTextEdit::selectionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexASCIIText, &QTextEdit::selectionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, this,
|
||||
&HexdumpWidget::selectionChanged);
|
||||
|
||||
format = Format::Hex;
|
||||
initParsing();
|
||||
@ -94,8 +97,7 @@ void HexdumpWidget::setupScrollSync()
|
||||
*/
|
||||
|
||||
auto offsetHexFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexHexText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
@ -103,22 +105,24 @@ void HexdumpWidget::setupScrollSync()
|
||||
};
|
||||
|
||||
auto offsetASCIIFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexHexText->verticalScrollBar(), offsetHexFunc);
|
||||
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(), offsetHexFunc);
|
||||
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexASCIIText->verticalScrollBar(), offsetASCIIFunc);
|
||||
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(), offsetASCIIFunc);
|
||||
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexHexText->verticalScrollBar(), offsetHexFunc);
|
||||
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(),
|
||||
offsetHexFunc);
|
||||
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexASCIIText->verticalScrollBar(), offsetASCIIFunc);
|
||||
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(),
|
||||
offsetASCIIFunc);
|
||||
|
||||
auto hexOffsetFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
@ -126,22 +130,24 @@ void HexdumpWidget::setupScrollSync()
|
||||
};
|
||||
|
||||
auto hexASCIIFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexOffsetText->verticalScrollBar(), hexOffsetFunc);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(), hexOffsetFunc);
|
||||
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexASCIIText->verticalScrollBar(), hexASCIIFunc);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(), hexASCIIFunc);
|
||||
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexOffsetText->verticalScrollBar(), hexOffsetFunc);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(),
|
||||
hexOffsetFunc);
|
||||
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexASCIIText->verticalScrollBar(), hexASCIIFunc);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(),
|
||||
hexASCIIFunc);
|
||||
|
||||
auto asciiOffsetFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
@ -149,24 +155,26 @@ void HexdumpWidget::setupScrollSync()
|
||||
};
|
||||
|
||||
auto asciiHexFunc = [this]() {
|
||||
if(!scroll_disabled)
|
||||
{
|
||||
if (!scroll_disabled) {
|
||||
scroll_disabled = true;
|
||||
ui->hexHexText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
||||
scroll_disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexOffsetText->verticalScrollBar(), asciiOffsetFunc);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(), asciiOffsetFunc);
|
||||
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged, ui->hexHexText->verticalScrollBar(), asciiHexFunc);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(), asciiHexFunc);
|
||||
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexOffsetText->verticalScrollBar(), asciiOffsetFunc);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(),
|
||||
asciiOffsetFunc);
|
||||
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
ui->hexHexText->verticalScrollBar(), asciiHexFunc);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(),
|
||||
asciiHexFunc);
|
||||
}
|
||||
|
||||
void HexdumpWidget::on_seekChanged(RVA addr)
|
||||
{
|
||||
if(sent_seek)
|
||||
{
|
||||
if (sent_seek) {
|
||||
sent_seek = false;
|
||||
return;
|
||||
}
|
||||
@ -175,8 +183,7 @@ void HexdumpWidget::on_seekChanged(RVA addr)
|
||||
|
||||
void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
||||
{
|
||||
if (type == CutterCore::MemoryWidgetType::Hexdump)
|
||||
{
|
||||
if (type == CutterCore::MemoryWidgetType::Hexdump) {
|
||||
raise();
|
||||
}
|
||||
}
|
||||
@ -184,14 +191,11 @@ void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType ty
|
||||
void HexdumpWidget::connectScroll(bool disconnect_)
|
||||
{
|
||||
scroll_disabled = disconnect_;
|
||||
if (disconnect_)
|
||||
{
|
||||
if (disconnect_) {
|
||||
disconnect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||
&HexdumpWidget::scrollChanged);
|
||||
&HexdumpWidget::scrollChanged);
|
||||
disconnect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::scrollChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||
&HexdumpWidget::scrollChanged);
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::scrollChanged);
|
||||
@ -278,8 +282,7 @@ void HexdumpWidget::refresh(RVA addr)
|
||||
|
||||
updateHeaders();
|
||||
|
||||
if(addr == RVA_INVALID)
|
||||
{
|
||||
if (addr == RVA_INVALID) {
|
||||
addr = Core()->getOffset();
|
||||
}
|
||||
|
||||
@ -306,7 +309,8 @@ void HexdumpWidget::refresh(RVA addr)
|
||||
ui->hexHexText->setText(hexdump[1]);
|
||||
ui->hexASCIIText->setText(hexdump[2]);
|
||||
|
||||
QTextCursor cursor(ui->hexHexText->document()->findBlockByLineNumber(bufferLines)); // ln-1 because line number starts from 0
|
||||
QTextCursor cursor(ui->hexHexText->document()->findBlockByLineNumber(
|
||||
bufferLines)); // ln-1 because line number starts from 0
|
||||
ui->hexHexText->moveCursor(QTextCursor::End);
|
||||
ui->hexHexText->setTextCursor(cursor);
|
||||
|
||||
@ -338,8 +342,7 @@ void HexdumpWidget::updateHeaders()
|
||||
|
||||
// Custom spacing for the header
|
||||
QString space = " ";
|
||||
switch(format)
|
||||
{
|
||||
switch (format) {
|
||||
case Hex:
|
||||
space = space.repeated(1);
|
||||
break;
|
||||
@ -351,18 +354,15 @@ void HexdumpWidget::updateHeaders()
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i=0; i<cols; i++)
|
||||
{
|
||||
if (i > 0 && ((pairs && !(i&1)) || !pairs))
|
||||
{
|
||||
for (int i = 0; i < cols; i++) {
|
||||
if (i > 0 && ((pairs && !(i & 1)) || !pairs)) {
|
||||
hexHeader << " ";
|
||||
}
|
||||
|
||||
hexHeader << space << (i & 0xF);
|
||||
}
|
||||
|
||||
for (int i=0; i < ascii_cols; i++)
|
||||
{
|
||||
for (int i = 0; i < ascii_cols; i++) {
|
||||
asciiHeader << (i & 0xF);
|
||||
}
|
||||
|
||||
@ -387,30 +387,28 @@ std::array<QString, 3> HexdumpWidget::fetchHexdump(RVA addr, int lines)
|
||||
int bytes = cols * lines;
|
||||
|
||||
QString command = QString("pxj %1 @%2").arg(
|
||||
QString::number(bytes),
|
||||
RAddressString(addr));
|
||||
QString::number(bytes),
|
||||
RAddressString(addr));
|
||||
QJsonArray byte_array = Core()->cmdj(command).array();
|
||||
|
||||
QString hexText = "";
|
||||
QString offsetText = "";
|
||||
QString asciiText = "";
|
||||
RVA cur_addr = addr;
|
||||
for(int i=0; i < lines; i++)
|
||||
{
|
||||
for(int j=0; j < cols; j++) {
|
||||
for (int i = 0; i < lines; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
int b = byte_array[(i * cols) + j].toInt();
|
||||
if((j > 0) && (j < cols)) {
|
||||
if ((j > 0) && (j < cols)) {
|
||||
hexText += " ";
|
||||
}
|
||||
// Non printable
|
||||
if((b < 0x20) || (b > 0x7E))
|
||||
{
|
||||
if ((b < 0x20) || (b > 0x7E)) {
|
||||
asciiText += ".";
|
||||
} else {
|
||||
asciiText += (char)b;
|
||||
}
|
||||
|
||||
switch(format) {
|
||||
switch (format) {
|
||||
case Octal:
|
||||
hexText += QString::number(b, 8).rightJustified(3, '0');
|
||||
break;
|
||||
@ -431,17 +429,14 @@ std::array<QString, 3> HexdumpWidget::fetchHexdump(RVA addr, int lines)
|
||||
|
||||
void HexdumpWidget::selectionChanged()
|
||||
{
|
||||
if(scroll_disabled)
|
||||
{
|
||||
if (scroll_disabled) {
|
||||
return;
|
||||
}
|
||||
connectScroll(true);
|
||||
|
||||
if(sender() == ui->hexHexText)
|
||||
{
|
||||
if (sender() == ui->hexHexText) {
|
||||
QTextCursor textCursor = ui->hexHexText->textCursor();
|
||||
if(!textCursor.hasSelection())
|
||||
{
|
||||
if (!textCursor.hasSelection()) {
|
||||
clearParseWindow();
|
||||
RVA adr = hexPositionToAddress(textCursor.position());
|
||||
int pos = asciiAddressToPosition(adr);
|
||||
@ -460,33 +455,26 @@ void HexdumpWidget::selectionChanged()
|
||||
QChar end = ui->hexHexText->document()->characterAt(selectionEnd);
|
||||
|
||||
// This adjusts the selection to make sense with the chosen format
|
||||
switch(format)
|
||||
{
|
||||
switch (format) {
|
||||
case Hex:
|
||||
// Handle the spaces/newlines (if it's at the start, move forward,
|
||||
// if it's at the end, move back)
|
||||
|
||||
if (!start.isLetterOrNumber())
|
||||
{
|
||||
if (!start.isLetterOrNumber()) {
|
||||
selectionStart += 1;
|
||||
}
|
||||
else if(ui->hexHexText->document()->characterAt(selectionStart-1).isLetterOrNumber())
|
||||
{
|
||||
} else if (ui->hexHexText->document()->characterAt(selectionStart - 1).isLetterOrNumber()) {
|
||||
selectionStart += 2;
|
||||
}
|
||||
|
||||
if (!end.isLetterOrNumber())
|
||||
{
|
||||
if (!end.isLetterOrNumber()) {
|
||||
selectionEnd += 1;
|
||||
}
|
||||
break;
|
||||
case Octal:
|
||||
if (!start.isLetterOrNumber())
|
||||
{
|
||||
if (!start.isLetterOrNumber()) {
|
||||
selectionStart += 1;
|
||||
}
|
||||
if (!end.isLetterOrNumber())
|
||||
{
|
||||
if (!end.isLetterOrNumber()) {
|
||||
selectionEnd += 1;
|
||||
}
|
||||
break;
|
||||
@ -507,12 +495,9 @@ void HexdumpWidget::selectionChanged()
|
||||
sent_seek = true;
|
||||
Core()->seek(startAddress);
|
||||
sent_seek = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QTextCursor textCursor = ui->hexASCIIText->textCursor();
|
||||
if(!textCursor.hasSelection())
|
||||
{
|
||||
if (!textCursor.hasSelection()) {
|
||||
clearParseWindow();
|
||||
RVA adr = asciiPositionToAddress(textCursor.position());
|
||||
int pos = hexAddressToPosition(adr);
|
||||
@ -650,8 +635,8 @@ void HexdumpWidget::fontsUpdated()
|
||||
void HexdumpWidget::colorsUpdatedSlot()
|
||||
{
|
||||
QString styleSheet = QString("QTextEdit { background-color: %1; color: %2; }")
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name());
|
||||
.arg(ConfigColor("gui.background").name())
|
||||
.arg(ConfigColor("btext").name());
|
||||
|
||||
ui->hexOffsetText->setStyleSheet(styleSheet);
|
||||
ui->hexHexText->setStyleSheet(styleSheet);
|
||||
@ -677,47 +662,47 @@ void HexdumpWidget::updateParseWindow(RVA start_address, int size)
|
||||
QString bits = ui->parseBitsComboBox->currentText();
|
||||
bool bigEndian = ui->parseEndianComboBox->currentIndex() == 1;
|
||||
|
||||
{ // scope for TempConfig
|
||||
{
|
||||
// scope for TempConfig
|
||||
TempConfig tempConfig;
|
||||
tempConfig
|
||||
.set("asm.arch", arch)
|
||||
.set("asm.bits", bits)
|
||||
.set("cfg.bigendian", bigEndian);
|
||||
.set("asm.arch", arch)
|
||||
.set("asm.bits", bits)
|
||||
.set("cfg.bigendian", bigEndian);
|
||||
|
||||
switch(ui->parseTypeComboBox->currentIndex())
|
||||
{
|
||||
case 0: // Disassembly
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pda " + argument));
|
||||
break;
|
||||
case 1: // String
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcs " + argument));
|
||||
break;
|
||||
case 2: // Assembler
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pca " + argument));
|
||||
break;
|
||||
case 3: // C byte array
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pc " + argument));
|
||||
break;
|
||||
case 4: // C half-word
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pch " + argument));
|
||||
break;
|
||||
case 5: // C word
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcw " + argument));
|
||||
break;
|
||||
case 6: // C dword
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcd " + argument));
|
||||
break;
|
||||
case 7: // Python
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcp " + argument));
|
||||
break;
|
||||
case 8: // JSON
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcj " + argument));
|
||||
break;
|
||||
case 9: // JavaScript
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcJ " + argument));
|
||||
break;
|
||||
default:
|
||||
ui->hexDisasTextEdit->setPlainText("");
|
||||
switch (ui->parseTypeComboBox->currentIndex()) {
|
||||
case 0: // Disassembly
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pda " + argument));
|
||||
break;
|
||||
case 1: // String
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcs " + argument));
|
||||
break;
|
||||
case 2: // Assembler
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pca " + argument));
|
||||
break;
|
||||
case 3: // C byte array
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pc " + argument));
|
||||
break;
|
||||
case 4: // C half-word
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pch " + argument));
|
||||
break;
|
||||
case 5: // C word
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcw " + argument));
|
||||
break;
|
||||
case 6: // C dword
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcd " + argument));
|
||||
break;
|
||||
case 7: // Python
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcp " + argument));
|
||||
break;
|
||||
case 8: // JSON
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcj " + argument));
|
||||
break;
|
||||
case 9: // JavaScript
|
||||
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcJ " + argument));
|
||||
break;
|
||||
default:
|
||||
ui->hexDisasTextEdit->setPlainText("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,8 +716,7 @@ void HexdumpWidget::updateParseWindow(RVA start_address, int size)
|
||||
|
||||
RVA HexdumpWidget::hexPositionToAddress(int position)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
switch (format) {
|
||||
|
||||
case Octal:
|
||||
return first_loaded_address + (position / 4);
|
||||
@ -754,8 +738,7 @@ RVA HexdumpWidget::asciiPositionToAddress(int position)
|
||||
int HexdumpWidget::hexAddressToPosition(RVA address)
|
||||
{
|
||||
// This strictly assumes that the address is actually loaded.
|
||||
switch(format)
|
||||
{
|
||||
switch (format) {
|
||||
|
||||
case Octal:
|
||||
return (address - first_loaded_address) * 4;
|
||||
@ -785,8 +768,7 @@ int HexdumpWidget::getDisplayedLined(QTextEdit *textEdit, bool bottom)
|
||||
QPoint top_right(textEdit->viewport()->x(), textEdit->viewport()->y());
|
||||
QPoint bottom_right(textEdit->viewport()->width(), textEdit->viewport()->height() - 1);
|
||||
QPoint point = top_right;
|
||||
if(bottom)
|
||||
{
|
||||
if (bottom) {
|
||||
point = bottom_right;
|
||||
}
|
||||
|
||||
@ -805,8 +787,7 @@ void HexdumpWidget::removeTopLinesWithoutScroll(QTextEdit *textEdit, int lines)
|
||||
|
||||
QTextBlock block = textEdit->document()->firstBlock();
|
||||
QTextCursor textCursor = textEdit->textCursor();
|
||||
for(int i=0; i < lines; i++)
|
||||
{
|
||||
for (int i = 0; i < lines; i++) {
|
||||
QTextCursor cursor(block);
|
||||
cursor.select(QTextCursor::BlockUnderCursor);
|
||||
cursor.removeSelectedText();
|
||||
@ -821,8 +802,7 @@ void HexdumpWidget::removeBottomLinesWithoutScroll(QTextEdit *textEdit, int line
|
||||
{
|
||||
QTextBlock block = textEdit->document()->lastBlock();
|
||||
QTextCursor textCursor = textEdit->textCursor();
|
||||
for(int i=0; i < lines; i++)
|
||||
{
|
||||
for (int i = 0; i < lines; i++) {
|
||||
QTextCursor cursor(block);
|
||||
cursor.select(QTextCursor::BlockUnderCursor);
|
||||
cursor.removeSelectedText();
|
||||
@ -864,8 +844,7 @@ void HexdumpWidget::scrollChanged()
|
||||
connectScroll(true);
|
||||
|
||||
int firstLine = getDisplayedLined(ui->hexHexText);
|
||||
if(firstLine < (bufferLines/2))
|
||||
{
|
||||
if (firstLine < (bufferLines / 2)) {
|
||||
auto hexdump = fetchHexdump(first_loaded_address, bufferLines);
|
||||
first_loaded_address -= bufferLines * cols;
|
||||
prependWithoutScroll(ui->hexOffsetText, hexdump[0]);
|
||||
@ -883,8 +862,7 @@ void HexdumpWidget::scrollChanged()
|
||||
|
||||
int blocks = ui->hexHexText->document()->blockCount();
|
||||
int lastLine = getDisplayedLined(ui->hexHexText, true);
|
||||
if(blocks - lastLine < (bufferLines/2))
|
||||
{
|
||||
if (blocks - lastLine < (bufferLines / 2)) {
|
||||
auto hexdump = fetchHexdump(last_loaded_address, bufferLines);
|
||||
last_loaded_address += bufferLines * cols;
|
||||
removeTopLinesWithoutScroll(ui->hexOffsetText, bufferLines);
|
||||
@ -903,12 +881,9 @@ void HexdumpWidget::scrollChanged()
|
||||
|
||||
void HexdumpWidget::on_actionHideHexdump_side_panel_triggered()
|
||||
{
|
||||
if (ui->hexSideTab_2->isVisible())
|
||||
{
|
||||
if (ui->hexSideTab_2->isVisible()) {
|
||||
ui->hexSideTab_2->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->hexSideTab_2->show();
|
||||
}
|
||||
}
|
||||
@ -969,12 +944,9 @@ void HexdumpWidget::on_actionFormatOctal_triggered()
|
||||
|
||||
void HexdumpWidget::on_parseTypeComboBox_currentTextChanged(const QString &)
|
||||
{
|
||||
if (ui->parseTypeComboBox->currentIndex() == 0)
|
||||
{
|
||||
if (ui->parseTypeComboBox->currentIndex() == 0) {
|
||||
ui->hexSideFrame_2->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->hexSideFrame_2->hide();
|
||||
}
|
||||
selectionChanged();
|
||||
@ -1011,22 +983,16 @@ void HexdumpWidget::resizeEvent(QResizeEvent *event)
|
||||
refresh();
|
||||
}
|
||||
|
||||
void HexdumpWidget::wheelEvent(QWheelEvent* event)
|
||||
void HexdumpWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if( Qt::ControlModifier == event->modifiers() )
|
||||
{
|
||||
if ( Qt::ControlModifier == event->modifiers() ) {
|
||||
const QPoint numDegrees = event->angleDelta() / 8;
|
||||
if(!numDegrees.isNull())
|
||||
{
|
||||
if (!numDegrees.isNull()) {
|
||||
const QPoint numSteps = numDegrees / 15;
|
||||
if( 0 != numSteps.y() )
|
||||
{
|
||||
if(numSteps.y() > 0)
|
||||
{
|
||||
if ( 0 != numSteps.y() ) {
|
||||
if (numSteps.y() > 0) {
|
||||
zoomIn(1);
|
||||
}
|
||||
else if( numSteps.y() < 0 )
|
||||
{
|
||||
} else if ( numSteps.y() < 0 ) {
|
||||
zoomOut(1);
|
||||
}
|
||||
}
|
||||
@ -1064,27 +1030,22 @@ void HexdumpWidget::selectHexPreview()
|
||||
QString bits = Core()->cmd("e asm.bits").trimmed();
|
||||
|
||||
//int arch_index = ui->hexArchComboBox_2->findText(arch);
|
||||
if (ui->parseArchComboBox->findText(arch) != -1)
|
||||
{
|
||||
if (ui->parseArchComboBox->findText(arch) != -1) {
|
||||
ui->parseArchComboBox->setCurrentIndex(ui->parseArchComboBox->findText(arch));
|
||||
}
|
||||
|
||||
//int bits_index = ui->hexBitsComboBox_2->findText(bits);
|
||||
if (ui->parseBitsComboBox->findText(bits) != -1)
|
||||
{
|
||||
if (ui->parseBitsComboBox->findText(bits) != -1) {
|
||||
ui->parseBitsComboBox->setCurrentIndex(ui->parseBitsComboBox->findText(bits));
|
||||
}
|
||||
}
|
||||
|
||||
void HexdumpWidget::showOffsets(bool show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
if (show) {
|
||||
ui->hexOffsetText->show();
|
||||
Core()->setConfig("asm.offset", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->hexOffsetText->hide();
|
||||
Core()->setConfig("asm.offset", 0);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public slots:
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
virtual void wheelEvent(QWheelEvent* event) override;
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
|
||||
private:
|
||||
static const int linesMarginMin = 32;
|
||||
|
@ -9,12 +9,14 @@
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
void CMyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
void CMyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItem itemOption(option);
|
||||
initStyleOption(&itemOption, index);
|
||||
|
||||
itemOption.rect.adjust(10, 0, 0, 0); // Make the item rectangle 10 pixels smaller from the left side.
|
||||
itemOption.rect.adjust(10, 0, 0,
|
||||
0); // Make the item rectangle 10 pixels smaller from the left side.
|
||||
|
||||
// Draw your item content.
|
||||
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &itemOption, painter, nullptr);
|
||||
@ -50,8 +52,7 @@ ImportsWidget::~ImportsWidget() {}
|
||||
void ImportsWidget::fillImports()
|
||||
{
|
||||
ui->importsTreeWidget->clear();
|
||||
for (auto i : CutterCore::getInstance()->getAllImports())
|
||||
{
|
||||
for (auto i : CutterCore::getInstance()->getAllImports()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, RAddressString(i.plt));
|
||||
item->setText(1, i.type);
|
||||
@ -67,23 +68,35 @@ void ImportsWidget::fillImports()
|
||||
|
||||
void ImportsWidget::highlightUnsafe()
|
||||
{
|
||||
static const QString banned("[a-zA-Z_.]*(system|strcpy|strcpyA|strcpyW|wcscpy|_tcscpy|_mbscpy|StrCpy|StrCpyA|StrCpyW|lstrcpy|lstrcpyA|lstrcpyW" \
|
||||
"|_tccpy|_mbccpy|_ftcscpy|strcat|strcatA|strcatW|wcscat|_tcscat|_mbscat|StrCat|StrCatA|StrCatW|lstrcat|lstrcatA|" \
|
||||
"lstrcatW|StrCatBuff|StrCatBuffA|StrCatBuffW|StrCatChainW|_tccat|_mbccat|_ftcscat|sprintfW|sprintfA|wsprintf|wsprintfW|" \
|
||||
"wsprintfA|sprintf|swprintf|_stprintf|wvsprintf|wvsprintfA|wvsprintfW|vsprintf|_vstprintf|vswprintf|strncpy|wcsncpy|" \
|
||||
"_tcsncpy|_mbsncpy|_mbsnbcpy|StrCpyN|StrCpyNA|StrCpyNW|StrNCpy|strcpynA|StrNCpyA|StrNCpyW|lstrcpyn|lstrcpynA|lstrcpynW|" \
|
||||
"strncat|wcsncat|_tcsncat|_mbsncat|_mbsnbcat|StrCatN|StrCatNA|StrCatNW|StrNCat|StrNCatA|StrNCatW|lstrncat|lstrcatnA|" \
|
||||
"lstrcatnW|lstrcatn|gets|_getts|_gettws|IsBadWritePtr|IsBadHugeWritePtr|IsBadReadPtr|IsBadHugeReadPtr|IsBadCodePtr|" \
|
||||
"IsBadStringPtr|memcpy|RtlCopyMemory|CopyMemory|wmemcpy|wnsprintf|wnsprintfA|wnsprintfW|_snwprintf|_snprintf|_sntprintf|" \
|
||||
"_vsnprintf|vsnprintf|_vsnwprintf|_vsntprintf|wvnsprintf|wvnsprintfA|wvnsprintfW|strtok|_tcstok|wcstok|_mbstok|makepath|" \
|
||||
"_tmakepath| _makepath|_wmakepath|_splitpath|_tsplitpath|_wsplitpath|scanf|wscanf|_tscanf|sscanf|swscanf|_stscanf|snscanf|" \
|
||||
"snwscanf|_sntscanf|_itoa|_itow|_i64toa|_i64tow|_ui64toa|_ui64tot|_ui64tow|_ultoa|_ultot|_ultow|CharToOem|CharToOemA|CharToOemW|" \
|
||||
"OemToChar|OemToCharA|OemToCharW|CharToOemBuffA|CharToOemBuffW|alloca|_alloca|strlen|wcslen|_mbslen|_mbstrlen|StrLen|lstrlen|" \
|
||||
"ChangeWindowMessageFilter)");
|
||||
static const QString
|
||||
banned("[a-zA-Z_.]*(system|strcpy|strcpyA|strcpyW|wcscpy|_tcscpy|_mbscpy|StrCpy|StrCpyA|StrCpyW|lstrcpy|lstrcpyA|lstrcpyW"
|
||||
\
|
||||
"|_tccpy|_mbccpy|_ftcscpy|strcat|strcatA|strcatW|wcscat|_tcscat|_mbscat|StrCat|StrCatA|StrCatW|lstrcat|lstrcatA|"
|
||||
\
|
||||
"lstrcatW|StrCatBuff|StrCatBuffA|StrCatBuffW|StrCatChainW|_tccat|_mbccat|_ftcscat|sprintfW|sprintfA|wsprintf|wsprintfW|"
|
||||
\
|
||||
"wsprintfA|sprintf|swprintf|_stprintf|wvsprintf|wvsprintfA|wvsprintfW|vsprintf|_vstprintf|vswprintf|strncpy|wcsncpy|"
|
||||
\
|
||||
"_tcsncpy|_mbsncpy|_mbsnbcpy|StrCpyN|StrCpyNA|StrCpyNW|StrNCpy|strcpynA|StrNCpyA|StrNCpyW|lstrcpyn|lstrcpynA|lstrcpynW|"
|
||||
\
|
||||
"strncat|wcsncat|_tcsncat|_mbsncat|_mbsnbcat|StrCatN|StrCatNA|StrCatNW|StrNCat|StrNCatA|StrNCatW|lstrncat|lstrcatnA|"
|
||||
\
|
||||
"lstrcatnW|lstrcatn|gets|_getts|_gettws|IsBadWritePtr|IsBadHugeWritePtr|IsBadReadPtr|IsBadHugeReadPtr|IsBadCodePtr|"
|
||||
\
|
||||
"IsBadStringPtr|memcpy|RtlCopyMemory|CopyMemory|wmemcpy|wnsprintf|wnsprintfA|wnsprintfW|_snwprintf|_snprintf|_sntprintf|"
|
||||
\
|
||||
"_vsnprintf|vsnprintf|_vsnwprintf|_vsntprintf|wvnsprintf|wvnsprintfA|wvnsprintfW|strtok|_tcstok|wcstok|_mbstok|makepath|"
|
||||
\
|
||||
"_tmakepath| _makepath|_wmakepath|_splitpath|_tsplitpath|_wsplitpath|scanf|wscanf|_tscanf|sscanf|swscanf|_stscanf|snscanf|"
|
||||
\
|
||||
"snwscanf|_sntscanf|_itoa|_itow|_i64toa|_i64tow|_ui64toa|_ui64tot|_ui64tow|_ultoa|_ultot|_ultow|CharToOem|CharToOemA|CharToOemW|"
|
||||
\
|
||||
"OemToChar|OemToCharA|OemToCharW|CharToOemBuffA|CharToOemBuffW|alloca|_alloca|strlen|wcslen|_mbslen|_mbstrlen|StrLen|lstrlen|"
|
||||
\
|
||||
"ChangeWindowMessageFilter)");
|
||||
|
||||
QList<QTreeWidgetItem *> clist = ui->importsTreeWidget->findItems(banned, Qt::MatchRegExp, 4);
|
||||
foreach (QTreeWidgetItem *item, clist)
|
||||
{
|
||||
foreach (QTreeWidgetItem *item, clist) {
|
||||
item->setText(2, "Unsafe");
|
||||
//item->setBackgroundColor(4, QColor(255, 129, 123));
|
||||
//item->setForeground(4, Qt::white);
|
||||
|
@ -11,9 +11,8 @@
|
||||
class MainWindow;
|
||||
class QTreeWidget;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ImportsWidget;
|
||||
namespace Ui {
|
||||
class ImportsWidget;
|
||||
}
|
||||
|
||||
class ImportsWidget : public CutterDockWidget
|
||||
@ -41,7 +40,8 @@ class CMyDelegate : public QStyledItemDelegate
|
||||
public:
|
||||
explicit CMyDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
};
|
||||
|
||||
#endif // IMPORTSWIDGET_H
|
||||
|
@ -68,7 +68,9 @@ void JupyterWidget::urlReceived(const QString &url)
|
||||
clearTabs();
|
||||
QWidget *failPage = new QWidget(this);
|
||||
QLabel *label = new QLabel(failPage);
|
||||
label->setText(tr("Cutter has been built without QtWebEngine.<br />Open the following URL in your Browser to use Jupyter:<br /><a href=\"%1\">%1</a>").arg(url));
|
||||
label->setText(
|
||||
tr("Cutter has been built without QtWebEngine.<br />Open the following URL in your Browser to use Jupyter:<br /><a href=\"%1\">%1</a>").arg(
|
||||
url));
|
||||
label->setTextFormat(Qt::RichText);
|
||||
label->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
label->setOpenExternalLinks(true);
|
||||
@ -87,7 +89,8 @@ void JupyterWidget::creationFailed()
|
||||
clearTabs();
|
||||
QWidget *failPage = new QWidget(this);
|
||||
QLabel *label = new QLabel(failPage);
|
||||
label->setText(tr("An error occurred while opening jupyter. Make sure Jupyter is installed system-wide."));
|
||||
label->setText(
|
||||
tr("An error occurred while opening jupyter. Make sure Jupyter is installed system-wide."));
|
||||
QHBoxLayout *layout = new QHBoxLayout();
|
||||
layout->addWidget(label);
|
||||
layout->setAlignment(label, Qt::AlignCenter);
|
||||
@ -101,8 +104,7 @@ void JupyterWidget::openHomeTab()
|
||||
{
|
||||
#ifdef CUTTER_ENABLE_QTWEBENGINE
|
||||
QString url = Jupyter()->getUrl();
|
||||
if (!url.isNull())
|
||||
{
|
||||
if (!url.isNull()) {
|
||||
createNewTab()->load(QUrl(url));
|
||||
}
|
||||
#endif
|
||||
@ -111,8 +113,7 @@ void JupyterWidget::openHomeTab()
|
||||
void JupyterWidget::tabCloseRequested(int index)
|
||||
{
|
||||
removeTab(index);
|
||||
if (ui->tabWidget->count() == 0)
|
||||
{
|
||||
if (ui->tabWidget->count() == 0) {
|
||||
openHomeTab();
|
||||
}
|
||||
}
|
||||
@ -126,8 +127,7 @@ void JupyterWidget::removeTab(int index)
|
||||
|
||||
void JupyterWidget::clearTabs()
|
||||
{
|
||||
while (ui->tabWidget->count() > 0)
|
||||
{
|
||||
while (ui->tabWidget->count() > 0) {
|
||||
removeTab(0);
|
||||
}
|
||||
}
|
||||
@ -149,12 +149,11 @@ void JupyterWebView::setTabWidget(QTabWidget *tabWidget)
|
||||
|
||||
QWebEngineView *JupyterWebView::createWindow(QWebEnginePage::WebWindowType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case QWebEnginePage::WebBrowserTab:
|
||||
return mainWidget->createNewTab();
|
||||
default:
|
||||
return nullptr;
|
||||
switch (type) {
|
||||
case QWebEnginePage::WebBrowserTab:
|
||||
return mainWidget->createNewTab();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,14 +164,12 @@ void JupyterWebView::onTitleChanged(const QString &)
|
||||
|
||||
void JupyterWebView::updateTitle()
|
||||
{
|
||||
if (!tabWidget)
|
||||
{
|
||||
if (!tabWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString title = this->title();
|
||||
if (title.isEmpty())
|
||||
{
|
||||
if (title.isEmpty()) {
|
||||
title = tr("Jupyter");
|
||||
}
|
||||
tabWidget->setTabText(tabWidget->indexOf(this), title);
|
||||
|
@ -11,9 +11,8 @@
|
||||
#include "CutterDockWidget.h"
|
||||
#include "utils/JupyterConnection.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class JupyterWidget;
|
||||
namespace Ui {
|
||||
class JupyterWidget;
|
||||
}
|
||||
|
||||
class JupyterWebView;
|
||||
@ -22,7 +21,7 @@ class MainWindow;
|
||||
|
||||
class JupyterWidget : public CutterDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JupyterWidget(MainWindow *main, QAction *action = nullptr);
|
||||
@ -54,7 +53,7 @@ private:
|
||||
|
||||
class JupyterWebView : public QWebEngineView
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JupyterWebView(JupyterWidget *mainWidget, QWidget *parent = nullptr);
|
||||
|
@ -65,8 +65,7 @@ void Omnibar::clear()
|
||||
void Omnibar::on_gotoEntry_returnPressed()
|
||||
{
|
||||
QString str = this->text();
|
||||
if (!str.isEmpty())
|
||||
{
|
||||
if (!str.isEmpty()) {
|
||||
Core()->seek(str);
|
||||
}
|
||||
|
||||
|
@ -82,14 +82,12 @@ void PieView::dataChanged(const QModelIndex &topLeft,
|
||||
validItems = 0;
|
||||
totalValue = 0.0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row)
|
||||
{
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
totalValue += value;
|
||||
validItems++;
|
||||
}
|
||||
@ -118,8 +116,7 @@ QModelIndex PieView::indexAt(const QPoint &point) const
|
||||
int wx = point.x() + horizontalScrollBar()->value();
|
||||
int wy = point.y() + verticalScrollBar()->value();
|
||||
|
||||
if (wx < totalSize)
|
||||
{
|
||||
if (wx < totalSize) {
|
||||
double cx = wx - totalSize / 2;
|
||||
double cy = totalSize / 2 - wy; // positive cy for items above the center
|
||||
|
||||
@ -137,14 +134,12 @@ QModelIndex PieView::indexAt(const QPoint &point) const
|
||||
// Find the relevant slice of the pie.
|
||||
double startAngle = 0.0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row)
|
||||
{
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
double sliceAngle = 360 * value / totalValue;
|
||||
|
||||
if (angle >= startAngle && angle < (startAngle + sliceAngle))
|
||||
@ -153,19 +148,15 @@ QModelIndex PieView::indexAt(const QPoint &point) const
|
||||
startAngle += sliceAngle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
double itemHeight = QFontMetrics(viewOptions().font).height();
|
||||
int listItem = int((wy - margin) / itemHeight);
|
||||
int validRow = 0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row)
|
||||
{
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
if (model()->data(index).toDouble() > 0.0)
|
||||
{
|
||||
if (model()->data(index).toDouble() > 0.0) {
|
||||
|
||||
if (listItem == validRow)
|
||||
return model()->index(row, 0, rootIndex());
|
||||
@ -208,16 +199,14 @@ QRect PieView::itemRect(const QModelIndex &index) const
|
||||
return QRect();
|
||||
|
||||
int listItem = 0;
|
||||
for (int row = index.row() - 1; row >= 0; --row)
|
||||
{
|
||||
for (int row = index.row() - 1; row >= 0; --row) {
|
||||
if (model()->data(model()->index(row, 1, rootIndex())).toDouble() > 0.0)
|
||||
listItem++;
|
||||
}
|
||||
|
||||
double itemHeight;
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
itemHeight = QFontMetrics(viewOptions().font).height();
|
||||
|
||||
@ -242,18 +231,15 @@ QRegion PieView::itemRegion(const QModelIndex &index) const
|
||||
return QRegion();
|
||||
|
||||
double startAngle = 0.0;
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row)
|
||||
{
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex sliceIndex = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(sliceIndex).toDouble();
|
||||
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
double angle = 360 * value / totalValue;
|
||||
|
||||
if (sliceIndex == index)
|
||||
{
|
||||
if (sliceIndex == index) {
|
||||
QPainterPath slicePath;
|
||||
slicePath.moveTo(totalSize / 2, totalSize / 2);
|
||||
slicePath.arcTo(margin, margin, margin + pieSize, margin + pieSize,
|
||||
@ -305,8 +291,7 @@ QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
|
||||
{
|
||||
QModelIndex current = currentIndex();
|
||||
|
||||
switch (cursorAction)
|
||||
{
|
||||
switch (cursorAction) {
|
||||
case MoveLeft:
|
||||
case MoveUp:
|
||||
if (current.row() > 0)
|
||||
@ -364,13 +349,11 @@ void PieView::paintEvent(QPaintEvent *event)
|
||||
double startAngle = 0.0;
|
||||
int row;
|
||||
|
||||
for (row = 0; row < model()->rowCount(rootIndex()); ++row)
|
||||
{
|
||||
for (row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
double angle = 360 * value / totalValue;
|
||||
|
||||
QModelIndex colorIndex = model()->index(row, 0, rootIndex());
|
||||
@ -413,13 +396,11 @@ int PieView::rows(const QModelIndex &index) const
|
||||
|
||||
void PieView::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
for (int row = start; row <= end; ++row)
|
||||
{
|
||||
for (int row = start; row <= end; ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
totalValue += value;
|
||||
++validItems;
|
||||
}
|
||||
@ -430,12 +411,10 @@ void PieView::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||
|
||||
void PieView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
for (int row = start; row <= end; ++row)
|
||||
{
|
||||
for (int row = start; row <= end; ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
if (value > 0.0)
|
||||
{
|
||||
if (value > 0.0) {
|
||||
totalValue -= value;
|
||||
--validItems;
|
||||
}
|
||||
@ -454,25 +433,19 @@ void PieView::scrollTo(const QModelIndex &index, ScrollHint)
|
||||
QRect area = viewport()->rect();
|
||||
QRect rect = visualRect(index);
|
||||
|
||||
if (rect.left() < area.left())
|
||||
{
|
||||
if (rect.left() < area.left()) {
|
||||
horizontalScrollBar()->setValue(
|
||||
horizontalScrollBar()->value() + rect.left() - area.left());
|
||||
}
|
||||
else if (rect.right() > area.right())
|
||||
{
|
||||
} else if (rect.right() > area.right()) {
|
||||
horizontalScrollBar()->setValue(
|
||||
horizontalScrollBar()->value() + qMin(
|
||||
rect.right() - area.right(), rect.left() - area.left()));
|
||||
}
|
||||
|
||||
if (rect.top() < area.top())
|
||||
{
|
||||
if (rect.top() < area.top()) {
|
||||
verticalScrollBar()->setValue(
|
||||
verticalScrollBar()->value() + rect.top() - area.top());
|
||||
}
|
||||
else if (rect.bottom() > area.bottom())
|
||||
{
|
||||
} else if (rect.bottom() > area.bottom()) {
|
||||
verticalScrollBar()->setValue(
|
||||
verticalScrollBar()->value() + qMin(
|
||||
rect.bottom() - area.bottom(), rect.top() - area.top()));
|
||||
@ -500,10 +473,8 @@ void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlag
|
||||
int columns = model()->columnCount(rootIndex());
|
||||
QModelIndexList indexes;
|
||||
|
||||
for (int row = 0; row < rows; ++row)
|
||||
{
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int column = 0; column < columns; ++column) {
|
||||
QModelIndex index = model()->index(row, column, rootIndex());
|
||||
QRegion region = itemRegion(index);
|
||||
if (region.intersects(contentsRect))
|
||||
@ -511,15 +482,13 @@ void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlag
|
||||
}
|
||||
}
|
||||
|
||||
if (indexes.size() > 0)
|
||||
{
|
||||
if (indexes.size() > 0) {
|
||||
int firstRow = indexes[0].row();
|
||||
int lastRow = indexes[0].row();
|
||||
int firstColumn = indexes[0].column();
|
||||
int lastColumn = indexes[0].column();
|
||||
|
||||
for (int i = 1; i < indexes.size(); ++i)
|
||||
{
|
||||
for (int i = 1; i < indexes.size(); ++i) {
|
||||
firstRow = qMin(firstRow, indexes[i].row());
|
||||
lastRow = qMax(lastRow, indexes[i].row());
|
||||
firstColumn = qMin(firstColumn, indexes[i].column());
|
||||
@ -529,13 +498,13 @@ void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlag
|
||||
QItemSelection selection(
|
||||
model()->index(firstRow, firstColumn, rootIndex()),
|
||||
model()->index(lastRow, lastColumn, rootIndex()));
|
||||
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectionModel()->select(selection,
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
} else {
|
||||
QModelIndex noIndex;
|
||||
QItemSelection selection(noIndex, noIndex);
|
||||
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
selectionModel()->select(selection,
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
update();
|
||||
@ -585,13 +554,10 @@ QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const
|
||||
return QRect();
|
||||
|
||||
QRegion region;
|
||||
for (int i = 0; i < ranges; ++i)
|
||||
{
|
||||
for (int i = 0; i < ranges; ++i) {
|
||||
QItemSelectionRange range = selection.at(i);
|
||||
for (int row = range.top(); row <= range.bottom(); ++row)
|
||||
{
|
||||
for (int col = range.left(); col <= range.right(); ++col)
|
||||
{
|
||||
for (int row = range.top(); row <= range.bottom(); ++row) {
|
||||
for (int col = range.left(); col <= range.right(); ++col) {
|
||||
QModelIndex index = model()->index(row, col, rootIndex());
|
||||
region += visualRect(index);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user