Convert Rizin commands to the API calls

This commit is contained in:
billow 2022-05-22 16:51:54 +08:00 committed by Anton Kochkov
parent df8c2749a6
commit cf30b400f3
10 changed files with 158 additions and 182 deletions

View File

@ -37,9 +37,7 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
QDir().mkpath(customRzThemesLocationPath); QDir().mkpath(customRzThemesLocationPath);
} }
QDir currDir { QDir currDir { QStringLiteral("%1%2%3").arg(rz_path_prefix(nullptr), RZ_SYS_DIR, RZ_THEMES) };
QStringLiteral("%1%2%3").arg(rz_path_prefix(nullptr)).arg(RZ_SYS_DIR).arg(RZ_THEMES)
};
if (currDir.exists()) { if (currDir.exists()) {
standardRzThemesLocationPath = currDir.absolutePath(); standardRzThemesLocationPath = currDir.absolutePath();
} else { } else {
@ -78,27 +76,15 @@ QString ColorThemeWorker::copy(const QString &srcThemeName, const QString &copyT
return save(getTheme(srcThemeName), copyThemeName); return save(getTheme(srcThemeName), copyThemeName);
} }
QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeName) const QString ColorThemeWorker::save(const Theme &theme, const QString &themeName) const
{ {
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName)); QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) { if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath()); return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
} }
QJsonObject obj = theme.object(); for (auto it = theme.constBegin(); it != theme.constEnd(); it++) {
for (auto it = obj.constBegin(); it != obj.constEnd(); it++) { const QColor &color = it.value();
QJsonArray arr = it.value().toArray();
QColor color;
if (arr.isEmpty()) {
color = it.value().toVariant().value<QColor>();
} else if (arr.size() == 4) {
color = QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt(), arr[3].toInt());
} else if (arr.size() == 3) {
color = QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt());
} else {
continue;
}
if (cutterSpecificOptions.contains(it.key())) { if (cutterSpecificOptions.contains(it.key())) {
fOut.write(QString("#~%1 rgb:%2\n") fOut.write(QString("#~%1 rgb:%2\n")
.arg(it.key(), color.name(QColor::HexArgb).remove('#')) .arg(it.key(), color.name(QColor::HexArgb).remove('#'))
@ -125,37 +111,18 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
return themes.contains(name); return themes.contains(name);
} }
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const ColorThemeWorker::Theme ColorThemeWorker::getTheme(const QString &themeName) const
{ {
int r, g, b, a; Theme theme;
CutterJson rzTheme;
QVariantMap theme;
QString curr = Config()->getColorTheme(); QString curr = Config()->getColorTheme();
if (themeName != curr) { if (themeName != curr) {
RzCoreLocked core(Core()); RzCoreLocked core(Core());
rz_core_theme_load(core, themeName.toUtf8().constData()); rz_core_theme_load(core, themeName.toUtf8().constData());
rzTheme = Core()->cmdj("ecj"); theme = Core()->getTheme();
rz_core_theme_load(core, curr.toUtf8().constData()); rz_core_theme_load(core, curr.toUtf8().constData());
} else { } else {
rzTheme = Core()->cmdj("ecj"); theme = Core()->getTheme();
}
for (CutterJson value : rzTheme) {
QJsonArray arr;
int count = 0;
for (CutterJson element : value) {
arr.append(element.toSt64());
count++;
if (count >= 3) {
break;
}
}
while (count < 3) {
arr.append(0);
}
arr.append(255);
theme[value.key()] = arr;
} }
ColorFlags colorFlags = ColorFlags::DarkFlag; ColorFlags colorFlags = ColorFlags::DarkFlag;
@ -164,14 +131,13 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
} }
for (auto &it : cutterSpecificOptions) { for (auto &it : cutterSpecificOptions) {
Configuration::cutterOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a); theme.insert(it, QColor(Configuration::cutterOptionColors[it][colorFlags]));
theme.insert(it, QJsonArray { r, g, b, a });
} }
if (isCustomTheme(themeName)) { if (isCustomTheme(themeName)) {
QFile src(QDir(customRzThemesLocationPath).filePath(themeName)); QFile src(QDir(customRzThemesLocationPath).filePath(themeName));
if (!src.open(QFile::ReadOnly)) { if (!src.open(QFile::ReadOnly)) {
return QJsonDocument(); return {};
} }
QStringList sl; QStringList sl;
for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) { for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
@ -181,8 +147,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
if (sl.size() != 3 || sl[0][0] == '#') { if (sl.size() != 3 || sl[0][0] == '#') {
continue; continue;
} }
QColor(sl[2]).getRgb(&r, &g, &b, &a); theme.insert(sl[1], QColor(sl[2]));
theme.insert(sl[1], QJsonArray({ r, g, b, a }));
} }
} }
@ -190,21 +155,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
theme.remove(key); theme.remove(key);
} }
// manualy converting instead of using QJsonObject::fromVariantMap because return theme;
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
// QJson values like QJsonArray.
// https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
QJsonObject obj;
for (auto it = theme.begin(); it != theme.end(); it++) {
auto &value = it.value();
if (value.canConvert<QJsonArray>()) {
obj[it.key()] = it.value().value<QJsonArray>();
} else {
obj[it.key()] = QJsonValue::fromVariant(value);
}
}
return QJsonDocument(obj);
} }
QString ColorThemeWorker::deleteTheme(const QString &themeName) const QString ColorThemeWorker::deleteTheme(const QString &themeName) const
@ -291,11 +242,10 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none"; const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
QString options = QString options =
(Core()->cmdj("ecj").keys() << cutterSpecificOptions).join('|').replace(".", "\\."); (Core()->getThemeKeys() << cutterSpecificOptions).join('|').replace(".", "\\.");
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*") QString pattern =
.arg(options) QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options, colors);
.arg(colors);
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before // The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
QRegularExpression regexp("\\A(?:" + pattern + ")\\z"); QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
@ -326,7 +276,7 @@ QStringList ColorThemeWorker::customThemes() const
const QStringList &ColorThemeWorker::getRizinSpecificOptions() const QStringList &ColorThemeWorker::getRizinSpecificOptions()
{ {
if (rizinSpecificOptions.isEmpty()) { if (rizinSpecificOptions.isEmpty()) {
rizinSpecificOptions = Core()->cmdj("ecj").keys(); rizinSpecificOptions << Core()->getThemeKeys();
} }
return rizinSpecificOptions; return rizinSpecificOptions;
} }

View File

@ -18,6 +18,8 @@ class ColorThemeWorker : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef QHash<QString, QColor> Theme;
/** /**
* @brief cutterSpecificOptions is list of all available Cutter-only color options. * @brief cutterSpecificOptions is list of all available Cutter-only color options.
*/ */
@ -54,7 +56,7 @@ public:
* Name of theme to save. * Name of theme to save.
* @return "" on success or error message. * @return "" on success or error message.
*/ */
QString save(const QJsonDocument &theme, const QString &themeName) const; QString save(const Theme &theme, const QString &themeName) const;
/** /**
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or * @brief Returns whether or not @a themeName theme is custom (created by user or imported) or
@ -71,12 +73,11 @@ public:
bool isThemeExist(const QString &name) const; bool isThemeExist(const QString &name) const;
/** /**
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red, * @brief Returns theme as QHash where key is option name and value is QColor.
* Green, Blue).
* @param themeName * @param themeName
* Theme to get. * Theme to get.
*/ */
QJsonDocument getTheme(const QString &themeName) const; Theme getTheme(const QString &themeName) const;
/** /**
* @brief Deletes theme named @a themeName. * @brief Deletes theme named @a themeName.

View File

@ -534,13 +534,9 @@ void Configuration::setColorTheme(const QString &theme)
s.setValue("theme", theme); s.setValue("theme", theme);
} }
QJsonObject colorTheme = ThemeWorker().getTheme(theme).object(); ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme);
for (auto it = colorTheme.constBegin(); it != colorTheme.constEnd(); it++) { for (auto it = colorTheme.constBegin(); it != colorTheme.constEnd(); it++) {
QJsonArray rgb = it.value().toArray(); setColor(it.key(), it.value());
if (rgb.size() != 4) {
continue;
}
setColor(it.key(), QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt(), rgb[3].toInt()));
} }
emit colorsUpdated(); emit colorsUpdated();

View File

@ -181,26 +181,21 @@ void Cutter::initializeSettings()
static void removeObsoleteOptionsFromCustomThemes() static void removeObsoleteOptionsFromCustomThemes()
{ {
const QStringList options = Core()->cmdj("ecj").keys() const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
<< ColorThemeWorker::cutterSpecificOptions; QStringList themes = Core()->getColorThemes();
RzList *themes_list = rz_core_theme_list(Core()->core()); for (const auto &themeName : themes) {
RzListIter *th_iter; if (!ThemeWorker().isCustomTheme(themeName)) {
const char *th;
CutterRzListForeach (themes_list, th_iter, const char, th) {
auto theme = QString(th).trimmed();
if (!ThemeWorker().isCustomTheme(theme)) {
continue; continue;
} }
QJsonObject updatedTheme; ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName);
auto sch = ThemeWorker().getTheme(theme).object(); ColorThemeWorker::Theme updatedTheme;
for (const auto &key : sch.keys()) { for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) {
if (options.contains(key)) { if (options.contains(it.key())) {
updatedTheme.insert(key, sch[key]); updatedTheme.insert(it.key(), it.value());
} }
} }
ThemeWorker().save(QJsonDocument(updatedTheme), theme); ThemeWorker().save(updatedTheme, themeName);
} }
rz_list_free(themes_list);
} }
void Cutter::migrateThemes() void Cutter::migrateThemes()

View File

@ -2157,26 +2157,9 @@ void CutterCore::stopDebug()
if (currentlyEmulating) { if (currentlyEmulating) {
cmdEsil("aeim-; aei-; wcr; .ar-; aets-"); cmdEsil("aeim-; aei-; wcr; .ar-; aets-");
currentlyEmulating = false; currentlyEmulating = false;
} else if (currentlyAttachedToPID != -1) {
// Use cmd because cmdRaw would not work with command concatenation
cmd(QString("dp- %1; o %2; .ar-")
.arg(QString::number(currentlyAttachedToPID), currentlyOpenFile));
currentlyAttachedToPID = -1;
} else { } else {
QString ptraceFiles = ""; rz_core_debug_process_close(core());
// close ptrace file descriptors left open currentlyAttachedToPID = -1;
RzCoreLocked core(Core());
RzList *descs = rz_id_storage_list(core->io->files);
RzListIter *it;
RzIODesc *desc;
CutterRzListForeach (descs, it, RzIODesc, desc) {
QString URI = QString(desc->uri);
if (URI.contains("ptrace")) {
ptraceFiles += "o-" + QString::number(desc->fd) + ";";
}
}
// Use cmd because cmdRaw would not work with command concatenation
cmd("doc" + ptraceFiles);
} }
syncAndSeekProgramCounter(); syncAndSeekProgramCounter();
@ -2331,7 +2314,16 @@ void CutterCore::continueUntilSyscall()
return; return;
} }
} else { } else {
if (!asyncCmd("dcs", debugTask)) { if (!asyncTask(
[](RzCore *core) {
rz_cons_break_push(reinterpret_cast<RzConsBreak>(rz_debug_stop), core->dbg);
rz_reg_arena_swap(core->dbg->reg, true);
rz_debug_continue_syscalls(core->dbg, NULL, 0);
rz_cons_break_pop();
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask)) {
return; return;
} }
} }
@ -2390,7 +2382,15 @@ void CutterCore::stepOverDebug()
return; return;
} }
} else { } else {
if (!asyncCmd("dso", debugTask)) { bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_over(core, 1);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return; return;
} }
} }
@ -2413,7 +2413,15 @@ void CutterCore::stepOutDebug()
} }
emit debugTaskStateChanged(); emit debugTaskStateChanged();
if (!asyncCmd("dsf", debugTask)) { bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_until_frame(core);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return; return;
} }
@ -2438,7 +2446,15 @@ void CutterCore::stepBackDebug()
return; return;
} }
} else { } else {
if (!asyncCmd("dsb", debugTask)) { bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_back(core, 1);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return; return;
} }
} }
@ -2457,11 +2473,11 @@ void CutterCore::stepBackDebug()
QStringList CutterCore::getDebugPlugins() QStringList CutterCore::getDebugPlugins()
{ {
QStringList plugins; QStringList plugins;
RzListIter *iter;
for (CutterJson pluginObject : cmdj("dLj")) { RzDebugPlugin *plugin;
QString plugin = pluginObject[RJsonKey::name].toString(); CORE_LOCK();
CutterRzListForeach (core->dbg->plugins, iter, RzDebugPlugin, plugin) {
plugins << plugin; plugins << plugin->name;
} }
return plugins; return plugins;
} }
@ -2661,11 +2677,9 @@ void CutterCore::disableBreakpoint(RVA addr)
void CutterCore::setBreakpointTrace(int index, bool enabled) void CutterCore::setBreakpointTrace(int index, bool enabled)
{ {
if (enabled) { CORE_LOCK();
cmdRaw(QString("dbite %1").arg(index)); RzBreakpointItem *bpi = rz_bp_get_index(core->dbg->bp, index);
} else { bpi->trace = enabled;
cmdRaw(QString("dbitd %1").arg(index));
}
} }
static BreakpointDescription breakpointDescriptionFromRizin(int index, rz_bp_item_t *bpi) static BreakpointDescription breakpointDescriptionFromRizin(int index, rz_bp_item_t *bpi)
@ -2746,11 +2760,6 @@ bool CutterCore::isBreakpoint(const QList<RVA> &breakpoints, RVA addr)
return breakpoints.contains(addr); return breakpoints.contains(addr);
} }
CutterJson CutterCore::getBacktrace()
{
return cmdj("dbtj");
}
QList<ProcessDescription> CutterCore::getProcessThreads(int pid = -1) QList<ProcessDescription> CutterCore::getProcessThreads(int pid = -1)
{ {
CORE_LOCK(); CORE_LOCK();
@ -4120,15 +4129,56 @@ QString CutterCore::getVersionInformation()
return versionInfo; return versionInfo;
} }
QList<QString> CutterCore::getColorThemes() QStringList CutterCore::getColorThemes()
{ {
QList<QString> r; QStringList r;
for (CutterJson s : cmdj("ecoj")) { CORE_LOCK();
r << s.toString(); RzList *themes_list = rz_core_theme_list(core);
RzListIter *it;
const char *th;
CutterRzListForeach (themes_list, it, const char, th) {
r << fromOwnedCharPtr(rz_str_trim_dup(th));
} }
rz_list_free(themes_list);
return r; return r;
} }
QHash<QString, QColor> CutterCore::getTheme()
{
QHash<QString, QColor> theme;
for (int i = 0;; ++i) {
const char *k = rz_cons_pal_get_name(i);
if (!k) {
break;
}
RzColor color = rz_cons_pal_get_i(i);
theme.insert(k, QColor(color.r, color.g, color.b));
}
return theme;
}
QStringList CutterCore::getThemeKeys()
{
QStringList stringList;
for (int i = 0;; ++i) {
const char *k = rz_cons_pal_get_name(i);
if (!k) {
break;
}
stringList << k;
}
return stringList;
}
bool CutterCore::setColor(const QString &key, const QString &color)
{
if (!rz_cons_pal_set(key.toUtf8().constData(), color.toUtf8().constData())) {
return false;
}
rz_cons_pal_update_event();
return true;
}
QString CutterCore::ansiEscapeToHtml(const QString &text) QString CutterCore::ansiEscapeToHtml(const QString &text)
{ {
int len; int len;

View File

@ -393,7 +393,10 @@ public:
QString getConfig(const char *k); QString getConfig(const char *k);
QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); } QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); }
QString getConfigDescription(const char *k); QString getConfigDescription(const char *k);
QList<QString> getColorThemes(); QStringList getColorThemes();
QHash<QString, QColor> getTheme();
QStringList getThemeKeys();
bool setColor(const QString &key, const QString &color);
/* Assembly\Hexdump related methods */ /* Assembly\Hexdump related methods */
QByteArray assemble(const QString &code); QByteArray assemble(const QString &code);
@ -449,7 +452,6 @@ public:
* @return List of ProcessDescription * @return List of ProcessDescription
*/ */
QList<ProcessDescription> getProcessThreads(int pid); QList<ProcessDescription> getProcessThreads(int pid);
CutterJson getBacktrace();
/** /**
* @brief Get a list of heap chunks * @brief Get a list of heap chunks
* Uses RZ_API rz_heap_chunks_list to get vector of chunks * Uses RZ_API rz_heap_chunks_list to get vector of chunks

View File

@ -72,7 +72,7 @@ ColorThemeEditDialog::~ColorThemeEditDialog()
void ColorThemeEditDialog::accept() void ColorThemeEditDialog::accept()
{ {
colorTheme = Config()->getColorTheme(); colorTheme = Config()->getColorTheme();
QJsonDocument sch = ui->colorThemeListView->colorSettingsModel()->getTheme(); ColorThemeWorker::Theme sch = ui->colorThemeListView->colorSettingsModel()->getTheme();
if (ThemeWorker().isCustomTheme(colorTheme)) { if (ThemeWorker().isCustomTheme(colorTheme)) {
QString err = ThemeWorker().save(sch, colorTheme); QString err = ThemeWorker().save(sch, colorTheme);
if (!err.isEmpty()) { if (!err.isEmpty()) {
@ -133,7 +133,7 @@ void ColorThemeEditDialog::colorOptionChanged(const QColor &newColor)
Config()->setColor(currOption.optionName, currOption.color); Config()->setColor(currOption.optionName, currOption.color);
if (!ColorThemeWorker::cutterSpecificOptions.contains(currOption.optionName)) { if (!ColorThemeWorker::cutterSpecificOptions.contains(currOption.optionName)) {
Core()->cmdRaw(QString("ec %1 %2").arg(currOption.optionName).arg(currOption.color.name())); Core()->setColor(currOption.optionName, currOption.color.name());
} }
previewDisasmWidget->colorsUpdatedSlot(); previewDisasmWidget->colorsUpdatedSlot();
} }

View File

@ -44,27 +44,25 @@ void BacktraceWidget::updateContents()
void BacktraceWidget::setBacktraceGrid() void BacktraceWidget::setBacktraceGrid()
{ {
RzList *list = rz_core_debug_backtraces(Core()->core());
int i = 0; int i = 0;
for (CutterJson backtraceItem : Core()->getBacktrace()) { RzListIter *iter;
QString progCounter = RzAddressString(backtraceItem["pc"].toRVA()); RzBacktrace *bt;
QString stackPointer = RzAddressString(backtraceItem["sp"].toRVA()); CutterRzListForeach (list, iter, RzBacktrace, bt) {
st64 frameSize = backtraceItem["frame_size"].toSt64(); QString funcName = bt->fcn ? bt->fcn->name : "";
QString funcName = backtraceItem["fname"].toString(); QString pc = RzAddressString(bt->frame ? bt->frame->addr : 0);
QString desc = backtraceItem["desc"].toString(); QString sp = RzAddressString(bt->frame ? bt->frame->sp : 0);
QString frameSize = QString::number(bt->frame ? bt->frame->size : 0);
QString desc = bt->desc;
QStandardItem *rowPC = new QStandardItem(progCounter); modelBacktrace->setItem(i, 0, new QStandardItem(funcName));
QStandardItem *rowSP = new QStandardItem(stackPointer); modelBacktrace->setItem(i, 1, new QStandardItem(sp));
QStandardItem *rowFrameSize = new QStandardItem(QString::number(frameSize)); modelBacktrace->setItem(i, 2, new QStandardItem(pc));
QStandardItem *rowFuncName = new QStandardItem(funcName); modelBacktrace->setItem(i, 3, new QStandardItem(desc));
QStandardItem *rowDesc = new QStandardItem(desc); modelBacktrace->setItem(i, 4, new QStandardItem(frameSize));
++i;
modelBacktrace->setItem(i, 0, rowFuncName);
modelBacktrace->setItem(i, 1, rowSP);
modelBacktrace->setItem(i, 2, rowPC);
modelBacktrace->setItem(i, 3, rowDesc);
modelBacktrace->setItem(i, 4, rowFrameSize);
i++;
} }
rz_list_free(list);
// Remove irrelevant old rows // Remove irrelevant old rows
if (modelBacktrace->rowCount() > i) { if (modelBacktrace->rowCount() > i) {

View File

@ -220,13 +220,7 @@ ColorThemeListView::ColorThemeListView(QWidget *parent) : QListView(parent)
setItemDelegate(new ColorOptionDelegate(this)); setItemDelegate(new ColorOptionDelegate(this));
setResizeMode(ResizeMode::Adjust); setResizeMode(ResizeMode::Adjust);
QJsonArray rgb = backgroundColor = colorSettingsModel()->getTheme().find("gui.background").value();
colorSettingsModel()->getTheme().object().find("gui.background").value().toArray();
if (rgb.size() == 3) {
backgroundColor = QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt());
} else {
backgroundColor = palette().base().color();
}
connect(&blinkTimer, &QTimer::timeout, this, &ColorThemeListView::blinkTimeout); connect(&blinkTimer, &QTimer::timeout, this, &ColorThemeListView::blinkTimeout);
@ -241,7 +235,7 @@ void ColorThemeListView::currentChanged(const QModelIndex &current, const QModel
ColorOption prev = previous.data(Qt::UserRole).value<ColorOption>(); ColorOption prev = previous.data(Qt::UserRole).value<ColorOption>();
Config()->setColor(prev.optionName, prev.color); Config()->setColor(prev.optionName, prev.color);
if (ThemeWorker().getRizinSpecificOptions().contains(prev.optionName)) { if (ThemeWorker().getRizinSpecificOptions().contains(prev.optionName)) {
Core()->cmdRaw(QString("ec %1 %2").arg(prev.optionName).arg(prev.color.name())); Core()->setColor(prev.optionName, prev.color.name());
} }
QListView::currentChanged(current, previous); QListView::currentChanged(current, previous);
@ -267,9 +261,7 @@ void ColorThemeListView::mouseReleaseEvent(QMouseEvent *e)
.contains(e->pos())) { .contains(e->pos())) {
ColorOption co = currentIndex().data(Qt::UserRole).value<ColorOption>(); ColorOption co = currentIndex().data(Qt::UserRole).value<ColorOption>();
co.changed = false; co.changed = false;
QJsonArray rgb = co.color = ThemeWorker().getTheme(Config()->getColorTheme())[co.optionName];
ThemeWorker().getTheme(Config()->getColorTheme()).object()[co.optionName].toArray();
co.color = QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt());
model()->setData(currentIndex(), QVariant::fromValue(co)); model()->setData(currentIndex(), QVariant::fromValue(co));
QCursor c; QCursor c;
c.setShape(Qt::CursorShape::ArrowCursor); c.setShape(Qt::CursorShape::ArrowCursor);
@ -307,7 +299,7 @@ void ColorThemeListView::blinkTimeout()
auto updateColor = [](const QString &name, const QColor &color) { auto updateColor = [](const QString &name, const QColor &color) {
Config()->setColor(name, color); Config()->setColor(name, color);
if (ThemeWorker().getRizinSpecificOptions().contains(name)) { if (ThemeWorker().getRizinSpecificOptions().contains(name)) {
Core()->cmdRaw(QString("ec %1 %2").arg(name).arg(color.name())); Core()->setColor(name, color.name());
} }
}; };
@ -374,16 +366,10 @@ void ColorSettingsModel::updateTheme()
{ {
beginResetModel(); beginResetModel();
theme.clear(); theme.clear();
QJsonObject obj = ThemeWorker().getTheme(Config()->getColorTheme()).object(); ColorThemeWorker::Theme obj = ThemeWorker().getTheme(Config()->getColorTheme());
for (auto it = obj.constBegin(); it != obj.constEnd(); it++) { for (auto it = obj.constBegin(); it != obj.constEnd(); it++) {
QJsonArray rgb = it.value().toArray(); theme.push_back({ it.key(), it.value(), false });
if (rgb.size() != 4) {
continue;
}
theme.push_back({ it.key(),
QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt(), rgb[3].toInt()),
false });
} }
std::sort(theme.begin(), theme.end(), [](const ColorOption &f, const ColorOption &s) { std::sort(theme.begin(), theme.end(), [](const ColorOption &f, const ColorOption &s) {
@ -395,15 +381,13 @@ void ColorSettingsModel::updateTheme()
endResetModel(); endResetModel();
} }
QJsonDocument ColorSettingsModel::getTheme() const ColorThemeWorker::Theme ColorSettingsModel::getTheme() const
{ {
QJsonObject obj; ColorThemeWorker::Theme th;
int r, g, b, a;
for (auto &it : theme) { for (auto &it : theme) {
it.color.getRgb(&r, &g, &b, &a); th.insert(it.optionName, it.color);
obj.insert(it.optionName, QJsonArray({ r, g, b, a }));
} }
return QJsonDocument(obj); return th;
} }
const QMap<QString, OptionInfo> optionInfoMap__ = { const QMap<QString, OptionInfo> optionInfoMap__ = {

View File

@ -73,7 +73,7 @@ public:
void updateTheme(); void updateTheme();
QJsonDocument getTheme() const; QHash<QString, QColor> getTheme() const;
private: private:
QList<ColorOption> theme; QList<ColorOption> theme;