2018-10-17 07:55:53 +00:00
|
|
|
#include "common/ColorSchemeFileSaver.h"
|
2018-10-10 09:37:24 +00:00
|
|
|
|
|
|
|
#include <QDir>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QColor>
|
|
|
|
#include <QJsonArray>
|
|
|
|
#include <QJsonObject>
|
|
|
|
#include <QStandardPaths>
|
2018-10-17 07:55:53 +00:00
|
|
|
#include "common/Configuration.h"
|
2018-10-10 09:37:24 +00:00
|
|
|
|
|
|
|
static const QStringList cutterSpecificOptions = {
|
|
|
|
"gui.main",
|
|
|
|
"highlight",
|
|
|
|
"gui.imports",
|
|
|
|
"highlightPC",
|
|
|
|
"highlightWord",
|
|
|
|
"gui.navbar.err",
|
|
|
|
"gui.navbar.sym",
|
|
|
|
"gui.dataoffset",
|
|
|
|
"gui.navbar.code",
|
|
|
|
"gui.navbar.empty",
|
|
|
|
"angui.navbar.str",
|
|
|
|
"gui.disass_selected",
|
|
|
|
"gui.breakpoint_background"
|
|
|
|
};
|
|
|
|
|
|
|
|
ColorSchemeFileSaver::ColorSchemeFileSaver(QObject *parent) : QObject (parent)
|
|
|
|
{
|
2018-11-29 07:39:58 +00:00
|
|
|
char* szThemes = r_str_home(R2_HOME_THEMES);
|
|
|
|
customR2ThemesLocationPath = szThemes;
|
|
|
|
R_FREE(szThemes);
|
2018-10-10 09:37:24 +00:00
|
|
|
if (!QDir(customR2ThemesLocationPath).exists()) {
|
|
|
|
QDir().mkpath(customR2ThemesLocationPath);
|
|
|
|
}
|
2018-10-11 11:35:59 +00:00
|
|
|
|
2018-11-29 07:39:58 +00:00
|
|
|
QDir currDir { QStringLiteral("%1%2%3")
|
|
|
|
.arg(r_sys_prefix(nullptr))
|
|
|
|
.arg(R_SYS_DIR)
|
|
|
|
.arg(R2_THEMES)
|
|
|
|
};
|
2018-10-12 09:47:35 +00:00
|
|
|
if (currDir.exists()) {
|
|
|
|
standardR2ThemesLocationPath = currDir.absolutePath();
|
|
|
|
} else {
|
2018-11-29 07:39:58 +00:00
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Standard themes not found!"),
|
|
|
|
tr("The radare2 standard themes could not be found! This probably means radare2 is not properly installed. If you think it is open an issue please.")
|
|
|
|
);
|
2018-10-11 11:35:59 +00:00
|
|
|
}
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QFile::FileError ColorSchemeFileSaver::copy(const QString &srcThemeName,
|
|
|
|
const QString ©ThemeName) const
|
|
|
|
{
|
|
|
|
QFile fIn(standardR2ThemesLocationPath + QDir::separator() + srcThemeName);
|
|
|
|
QFile fOut(customR2ThemesLocationPath + QDir::separator() + copyThemeName);
|
|
|
|
|
2018-11-29 07:39:58 +00:00
|
|
|
if (srcThemeName != QStringLiteral("default") && !fIn.open(QFile::ReadOnly)) {
|
2018-10-10 09:37:24 +00:00
|
|
|
fIn.setFileName(customR2ThemesLocationPath + QDir::separator() + srcThemeName);
|
|
|
|
if (!fIn.open(QFile::ReadOnly)) {
|
|
|
|
return fIn.error();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-29 07:39:58 +00:00
|
|
|
const QString &srcTheme = fIn.readAll();
|
|
|
|
fIn.close();
|
|
|
|
|
2018-10-10 09:37:24 +00:00
|
|
|
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
|
|
|
|
return fOut.error();
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList options = Core()->cmdj("ecj").object().keys();
|
|
|
|
options << cutterSpecificOptions;
|
|
|
|
QStringList src;
|
|
|
|
|
|
|
|
if (srcThemeName == "default") {
|
2018-11-29 07:39:58 +00:00
|
|
|
const QString &theme = Config()->getColorTheme();
|
2018-10-10 09:37:24 +00:00
|
|
|
Core()->cmd("ecd");
|
2018-11-29 07:39:58 +00:00
|
|
|
QJsonObject obj = Core()->cmdj("ecj").object();
|
|
|
|
Core()->cmd(QStringLiteral("eco %1").arg(theme));
|
2018-10-10 09:37:24 +00:00
|
|
|
QColor back = Config()->getColor(standardBackgroundOptionName);
|
2018-11-29 07:39:58 +00:00
|
|
|
obj[standardBackgroundOptionName] = QJsonArray({back.red(), back.green(), back.blue()});
|
|
|
|
for (const QString &it : obj.keys()) {
|
|
|
|
QJsonArray rgb = obj[it].toArray();
|
2018-10-11 11:35:59 +00:00
|
|
|
if (rgb.size() != 3) {
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-29 07:39:58 +00:00
|
|
|
src.push_back(QStringLiteral("ec %1 rgb:%2")
|
|
|
|
.arg(it)
|
|
|
|
.arg(QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt()).name().remove('#')));
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
} else {
|
2018-11-29 07:39:58 +00:00
|
|
|
src = srcTheme.split('\n');
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 11:35:59 +00:00
|
|
|
QStringList tmp;
|
2018-11-26 22:34:34 +00:00
|
|
|
for (const QString &it : src) {
|
2018-10-10 09:37:24 +00:00
|
|
|
if (it.isEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
fOut.write(it.toUtf8() + '\n');
|
|
|
|
|
2018-10-11 11:35:59 +00:00
|
|
|
tmp = it.split(' ');
|
2018-10-10 09:37:24 +00:00
|
|
|
if (it.length() > 2 && it.left(2) == "#~") {
|
2018-10-11 11:35:59 +00:00
|
|
|
options.removeOne(tmp[0].remove("#~").toUtf8());
|
|
|
|
} else if (tmp.size() > 1) {
|
|
|
|
options.removeOne(tmp.at(1));
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-26 22:34:34 +00:00
|
|
|
for (const QString &it : options) {
|
2018-10-10 09:37:24 +00:00
|
|
|
if (cutterSpecificOptions.contains(it)) {
|
|
|
|
fOut.write("#~");
|
|
|
|
} else {
|
|
|
|
fOut.write("ec ");
|
|
|
|
}
|
2018-11-29 07:39:58 +00:00
|
|
|
fOut.write(QStringLiteral("%1 rgb:%2\n")
|
|
|
|
.arg(it)
|
|
|
|
.arg(Config()->getColor(it).name().remove('#')).toUtf8());
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fOut.close();
|
|
|
|
|
|
|
|
return QFile::FileError::NoError;
|
|
|
|
}
|
|
|
|
|
|
|
|
QFile::FileError ColorSchemeFileSaver::save(const QString &scheme, const QString &schemeName) const
|
|
|
|
{
|
|
|
|
QFile fOut(customR2ThemesLocationPath + QDir::separator() + schemeName);
|
|
|
|
if (!fOut.open(QFile::WriteOnly | QFile::Truncate))
|
|
|
|
return fOut.error();
|
|
|
|
|
|
|
|
fOut.write(scheme.toUtf8());
|
|
|
|
fOut.close();
|
|
|
|
return QFile::FileError::NoError;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ColorSchemeFileSaver::isCustomScheme(const QString &schemeName) const
|
|
|
|
{
|
2018-11-29 07:39:58 +00:00
|
|
|
return QFile::exists(QDir(customR2ThemesLocationPath).filePath(schemeName));
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ColorSchemeFileSaver::isNameEngaged(const QString &name) const
|
|
|
|
{
|
2018-11-29 07:39:58 +00:00
|
|
|
return (!standardR2ThemesLocationPath.isEmpty() && QFile::exists(standardR2ThemesLocationPath + QDir::separator() + name)) ||
|
2018-10-10 09:37:24 +00:00
|
|
|
QFile::exists(customR2ThemesLocationPath + QDir::separator() + name);
|
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QColor> ColorSchemeFileSaver::getCutterSpecific() const
|
|
|
|
{
|
2018-11-29 07:39:58 +00:00
|
|
|
QFile f(customR2ThemesLocationPath + QDir::separator() + Config()->getColorTheme());
|
2018-10-10 09:37:24 +00:00
|
|
|
if (!f.open(QFile::ReadOnly))
|
|
|
|
return QMap<QString, QColor>();
|
|
|
|
|
2018-11-29 07:39:58 +00:00
|
|
|
const QStringList &data = QString(f.readAll()).split('\n');
|
|
|
|
f.close();
|
|
|
|
|
2018-10-10 09:37:24 +00:00
|
|
|
QMap<QString, QColor> ret;
|
2018-11-26 22:34:34 +00:00
|
|
|
for (const QString &it : data) {
|
2018-10-10 09:37:24 +00:00
|
|
|
if (it.length() > 2 && it.left(2) == "#~") {
|
|
|
|
QStringList currLine = it.split(' ');
|
2018-10-11 11:35:59 +00:00
|
|
|
if (currLine.size() > 1) {
|
|
|
|
ret.insert(currLine[0].remove("#~"), currLine[1].replace("rgb:", "#"));
|
|
|
|
}
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList ColorSchemeFileSaver::getCustomSchemes() const
|
|
|
|
{
|
2018-11-29 07:39:58 +00:00
|
|
|
return QDir(customR2ThemesLocationPath).entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
|
2018-10-10 09:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorSchemeFileSaver::deleteScheme(const QString &schemeName) const
|
|
|
|
{
|
|
|
|
if (!isCustomScheme(schemeName))
|
|
|
|
return;
|
|
|
|
QFile::remove(customR2ThemesLocationPath + QDir::separator() + schemeName);
|
|
|
|
}
|