2017-10-14 09:35:49 +00:00
|
|
|
#include "Configuration.h"
|
2017-10-15 07:14:05 +00:00
|
|
|
#include <QJsonObject>
|
|
|
|
#include <QJsonArray>
|
2017-11-20 20:20:31 +00:00
|
|
|
#include <QFontDatabase>
|
2018-01-09 11:03:07 +00:00
|
|
|
#include <QFile>
|
|
|
|
#include <QApplication>
|
2017-10-14 09:35:49 +00:00
|
|
|
|
2018-03-21 20:32:32 +00:00
|
|
|
Configuration *Configuration::mPtr = nullptr;
|
2017-10-14 09:35:49 +00:00
|
|
|
|
2018-03-22 08:42:54 +00:00
|
|
|
/*!
|
|
|
|
* \brief All asm.* options saved as settings. Values are the default values.
|
|
|
|
*/
|
|
|
|
static const QHash<QString, QVariant> asmOptions = {
|
|
|
|
{ "asm.esil", false },
|
|
|
|
{ "asm.pseudo", false },
|
|
|
|
{ "asm.offset", true },
|
|
|
|
{ "asm.describe", false },
|
|
|
|
{ "asm.stackptr", false },
|
|
|
|
{ "asm.slow", true },
|
|
|
|
{ "asm.lines", true },
|
|
|
|
{ "asm.fcnlines", true },
|
|
|
|
{ "asm.flgoff", false },
|
|
|
|
{ "asm.emu", false },
|
|
|
|
{ "asm.cmt.right", true },
|
|
|
|
{ "asm.varsum", false },
|
|
|
|
{ "asm.bytes", false },
|
|
|
|
{ "asm.size", false },
|
|
|
|
{ "asm.bytespace", false },
|
|
|
|
{ "asm.lbytes", true },
|
|
|
|
{ "asm.nbytes", 10 },
|
|
|
|
{ "asm.syntax", "intel" },
|
|
|
|
{ "asm.ucase", false },
|
|
|
|
{ "asm.bbline", false },
|
|
|
|
{ "asm.capitalize", false },
|
|
|
|
{ "asm.varsub", true },
|
|
|
|
{ "asm.varsub_only", true },
|
|
|
|
{ "asm.tabs", 5 }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2017-10-14 09:35:49 +00:00
|
|
|
Configuration::Configuration() : QObject()
|
|
|
|
{
|
|
|
|
mPtr = this;
|
2017-12-03 12:10:09 +00:00
|
|
|
loadInitial();
|
2017-10-14 09:35:49 +00:00
|
|
|
}
|
|
|
|
|
2018-03-21 20:32:32 +00:00
|
|
|
Configuration *Configuration::instance()
|
2017-10-14 09:35:49 +00:00
|
|
|
{
|
2018-02-26 22:25:23 +00:00
|
|
|
if (!mPtr)
|
|
|
|
mPtr = new Configuration();
|
2017-10-14 09:35:49 +00:00
|
|
|
return mPtr;
|
|
|
|
}
|
|
|
|
|
2017-12-03 12:10:09 +00:00
|
|
|
void Configuration::loadInitial()
|
|
|
|
{
|
2017-12-14 15:14:33 +00:00
|
|
|
setDarkTheme(getDarkTheme());
|
2018-03-09 11:44:19 +00:00
|
|
|
setColorTheme(getCurrentTheme());
|
2018-03-22 08:42:54 +00:00
|
|
|
applySavedAsmOptions();
|
2017-12-03 12:10:09 +00:00
|
|
|
}
|
|
|
|
|
2018-03-25 16:58:34 +00:00
|
|
|
QString Configuration::getDirProjects()
|
|
|
|
{
|
|
|
|
auto projectsDir = s.value("dir.projects").toString();
|
|
|
|
if (projectsDir == "") {
|
|
|
|
projectsDir = Core()->getConfig("dir.projects");
|
|
|
|
setDirProjects(projectsDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
return projectsDir;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Configuration::setDirProjects(const QString &dir)
|
|
|
|
{
|
|
|
|
s.setValue("dir.projects", dir);
|
|
|
|
}
|
|
|
|
|
2017-12-03 12:10:09 +00:00
|
|
|
void Configuration::resetAll()
|
|
|
|
{
|
2017-12-03 12:48:51 +00:00
|
|
|
Core()->cmd("e-");
|
|
|
|
Core()->setSettings();
|
2018-03-22 08:42:54 +00:00
|
|
|
resetToDefaultAsmOptions();
|
2018-03-09 11:44:19 +00:00
|
|
|
// Delete the file so no extra configuration is in it.
|
|
|
|
QFile settingsFile(s.fileName());
|
|
|
|
settingsFile.remove();
|
|
|
|
s.clear();
|
2017-12-03 12:48:51 +00:00
|
|
|
|
2017-12-03 12:10:09 +00:00
|
|
|
loadInitial();
|
|
|
|
emit fontsUpdated();
|
2017-12-03 12:48:51 +00:00
|
|
|
Core()->triggerAsmOptionsChanged();
|
2017-12-03 12:10:09 +00:00
|
|
|
}
|
|
|
|
|
2017-11-20 11:23:37 +00:00
|
|
|
void Configuration::loadDefaultTheme()
|
2017-10-15 07:14:05 +00:00
|
|
|
{
|
2018-02-26 22:25:23 +00:00
|
|
|
/* Load Qt Theme */
|
|
|
|
qApp->setStyleSheet("");
|
2017-11-20 11:23:37 +00:00
|
|
|
|
2018-02-26 22:25:23 +00:00
|
|
|
/* Images */
|
|
|
|
logoFile = QString(":/img/cutter_plain.svg");
|
2017-11-20 11:23:37 +00:00
|
|
|
|
2018-02-26 22:25:23 +00:00
|
|
|
/* Colors */
|
2017-11-20 11:23:37 +00:00
|
|
|
// GUI
|
2018-02-26 22:25:23 +00:00
|
|
|
setColor("gui.cflow", QColor(0, 0, 0));
|
|
|
|
setColor("gui.dataoffset", QColor(0, 0, 0));
|
|
|
|
setColor("gui.border", QColor(0, 0, 0));
|
|
|
|
setColor("highlight", QColor(210, 210, 255));
|
2017-11-20 11:23:37 +00:00
|
|
|
// Windows background
|
|
|
|
setColor("gui.background", QColor(255, 255, 255));
|
2018-05-02 06:02:24 +00:00
|
|
|
setColor("gui.disass_selected", QColor(255, 255, 255));
|
2017-11-20 11:23:37 +00:00
|
|
|
// Disassembly nodes background
|
|
|
|
setColor("gui.alt_background", QColor(245, 250, 255));
|
2017-12-20 15:40:46 +00:00
|
|
|
// Custom
|
2018-02-26 22:25:23 +00:00
|
|
|
setColor("gui.imports", QColor(50, 140, 255));
|
|
|
|
setColor("gui.main", QColor(0, 128, 0));
|
2018-02-01 16:06:30 +00:00
|
|
|
setColor("gui.navbar.err", QColor(255, 0, 0));
|
|
|
|
setColor("gui.navbar.code", QColor(104, 229, 69));
|
|
|
|
setColor("gui.navbar.str", QColor(69, 104, 229));
|
|
|
|
setColor("gui.navbar.sym", QColor(229, 150, 69));
|
|
|
|
setColor("gui.navbar.empty", QColor(100, 100, 100));
|
2017-11-20 11:23:37 +00:00
|
|
|
}
|
|
|
|
|
2018-05-02 06:02:24 +00:00
|
|
|
void Configuration::loadBaseDark()
|
2017-11-20 11:23:37 +00:00
|
|
|
{
|
2018-01-09 11:03:07 +00:00
|
|
|
/* Load Qt Theme */
|
|
|
|
QFile f(":qdarkstyle/style.qss");
|
2018-03-21 20:32:32 +00:00
|
|
|
if (!f.exists()) {
|
2018-01-09 11:03:07 +00:00
|
|
|
qWarning() << "Can't find dark theme stylesheet.";
|
2018-03-21 20:32:32 +00:00
|
|
|
} else {
|
2018-01-09 11:03:07 +00:00
|
|
|
f.open(QFile::ReadOnly | QFile::Text);
|
|
|
|
QTextStream ts(&f);
|
2018-02-03 20:00:31 +00:00
|
|
|
QString stylesheet = ts.readAll();
|
|
|
|
#ifdef Q_OS_MACX
|
|
|
|
// see https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529
|
|
|
|
stylesheet += "QDockWidget::title"
|
2018-03-21 20:32:32 +00:00
|
|
|
"{"
|
|
|
|
" background-color: #31363b;"
|
|
|
|
" text-align: center;"
|
|
|
|
" height: 12px;"
|
|
|
|
"}";
|
2018-02-03 20:00:31 +00:00
|
|
|
#endif
|
|
|
|
qApp->setStyleSheet(stylesheet);
|
2018-01-09 11:03:07 +00:00
|
|
|
}
|
2018-02-12 12:22:53 +00:00
|
|
|
|
|
|
|
/* Images */
|
|
|
|
logoFile = QString(":/img/cutter_white_plain.svg");
|
2018-02-26 22:25:23 +00:00
|
|
|
|
|
|
|
/* Colors */
|
|
|
|
// GUI
|
|
|
|
setColor("gui.cflow", QColor(255, 255, 255));
|
|
|
|
setColor("gui.dataoffset", QColor(255, 255, 255));
|
|
|
|
// Custom
|
|
|
|
setColor("gui.imports", QColor(50, 140, 255));
|
|
|
|
setColor("gui.main", QColor(0, 128, 0));
|
|
|
|
setColor("gui.navbar.err", QColor(255, 0, 0));
|
|
|
|
setColor("gui.navbar.code", QColor(104, 229, 69));
|
|
|
|
setColor("gui.navbar.str", QColor(69, 104, 229));
|
|
|
|
setColor("gui.navbar.sym", QColor(229, 150, 69));
|
|
|
|
setColor("gui.navbar.empty", QColor(100, 100, 100));
|
2017-10-15 07:14:05 +00:00
|
|
|
}
|
|
|
|
|
2018-05-02 06:02:24 +00:00
|
|
|
void Configuration::loadDarkTheme()
|
|
|
|
{
|
|
|
|
loadBaseDark();
|
2018-05-03 07:53:01 +00:00
|
|
|
setColor("gui.border", QColor(255, 255, 255));
|
2018-05-02 06:02:24 +00:00
|
|
|
// Windows background
|
|
|
|
setColor("gui.background", QColor(36, 66, 79));
|
|
|
|
// Disassembly nodes background
|
|
|
|
setColor("gui.alt_background", QColor(58, 100, 128));
|
|
|
|
// Disassembly nodes background when selected
|
|
|
|
setColor("gui.disass_selected", QColor(36, 66, 79));
|
|
|
|
// Disassembly line selected
|
|
|
|
setColor("highlight", QColor(64, 115, 115));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Configuration::loadDarkGreyTheme()
|
|
|
|
{
|
|
|
|
loadBaseDark();
|
2018-05-03 07:53:01 +00:00
|
|
|
setColor("gui.border", QColor(100,100,100));
|
2018-05-02 06:02:24 +00:00
|
|
|
// Windows background
|
|
|
|
setColor("gui.background", QColor(37, 40, 43));
|
|
|
|
// Disassembly nodes background
|
|
|
|
setColor("gui.alt_background", QColor(28, 31, 36));
|
|
|
|
// Disassembly nodes background when selected
|
|
|
|
setColor("gui.disass_selected", QColor(44, 53, 54));
|
|
|
|
// Disassembly line selected
|
|
|
|
setColor("highlight", QColor(21, 29, 29));
|
|
|
|
}
|
|
|
|
|
2017-10-14 09:35:49 +00:00
|
|
|
const QFont Configuration::getFont() const
|
|
|
|
{
|
2018-01-31 15:36:09 +00:00
|
|
|
QFont font = s.value("font", QFont("Inconsolata", 12)).value<QFont>();
|
2017-10-14 09:35:49 +00:00
|
|
|
return font;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Configuration::setFont(const QFont &font)
|
|
|
|
{
|
|
|
|
s.setValue("font", font);
|
|
|
|
emit fontsUpdated();
|
|
|
|
}
|
2017-10-15 07:14:05 +00:00
|
|
|
|
2018-05-02 06:02:24 +00:00
|
|
|
void Configuration::setDarkTheme(int theme)
|
2017-11-20 11:23:37 +00:00
|
|
|
{
|
2018-05-02 06:02:24 +00:00
|
|
|
s.setValue("dark", theme);
|
|
|
|
switch(theme){
|
|
|
|
case 1:
|
2017-11-20 11:23:37 +00:00
|
|
|
loadDarkTheme();
|
2018-05-02 06:02:24 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
loadDarkGreyTheme();
|
|
|
|
break;
|
|
|
|
default:
|
2017-11-20 11:23:37 +00:00
|
|
|
loadDefaultTheme();
|
|
|
|
}
|
|
|
|
emit colorsUpdated();
|
|
|
|
}
|
|
|
|
|
2018-02-12 12:22:53 +00:00
|
|
|
QString Configuration::getLogoFile()
|
|
|
|
{
|
|
|
|
return logoFile;
|
|
|
|
}
|
|
|
|
|
2018-03-09 11:24:26 +00:00
|
|
|
/*!
|
|
|
|
* \brief Configuration::setColor sets the local Cutter configuration color
|
|
|
|
* \param name Color Name
|
|
|
|
* \param color The color you want to set
|
2017-11-20 11:23:37 +00:00
|
|
|
*/
|
|
|
|
void Configuration::setColor(const QString &name, const QColor &color)
|
|
|
|
{
|
|
|
|
s.setValue("colors." + name, color);
|
2018-02-26 22:25:23 +00:00
|
|
|
}
|
|
|
|
|
2018-03-09 11:24:26 +00:00
|
|
|
const QColor Configuration::getColor(const QString &name) const
|
|
|
|
{
|
|
|
|
if (s.contains("colors." + name)) {
|
|
|
|
return s.value("colors." + name).value<QColor>();
|
|
|
|
} else {
|
|
|
|
return s.value("colors.other").value<QColor>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-26 22:25:23 +00:00
|
|
|
void Configuration::setColorTheme(QString theme)
|
|
|
|
{
|
2018-03-09 11:24:26 +00:00
|
|
|
if (theme == "default") {
|
2018-02-26 22:25:23 +00:00
|
|
|
Core()->cmd("ecd");
|
|
|
|
s.setValue("theme", "default");
|
2018-03-09 11:24:26 +00:00
|
|
|
} else {
|
2018-02-26 22:25:23 +00:00
|
|
|
Core()->cmd(QString("eco %1").arg(theme));
|
|
|
|
s.setValue("theme", theme);
|
|
|
|
}
|
2018-03-09 11:24:26 +00:00
|
|
|
// Duplicate interesting colors into our Cutter Settings
|
|
|
|
// Dirty fix for arrow colors, TODO refactor getColor, setColor, etc.
|
|
|
|
QJsonDocument colors = Core()->cmdj("ecj");
|
|
|
|
QJsonObject colorsObject = colors.object();
|
|
|
|
QJsonObject::iterator it;
|
|
|
|
for (it = colorsObject.begin(); it != colorsObject.end(); it++) {
|
|
|
|
if (!it.key().contains("graph"))
|
|
|
|
continue;
|
|
|
|
QJsonArray rgb = it.value().toArray();
|
|
|
|
s.setValue("colors." + it.key(), QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt()));
|
|
|
|
}
|
2018-02-26 22:25:23 +00:00
|
|
|
emit colorsUpdated();
|
2017-11-20 11:23:37 +00:00
|
|
|
}
|
2018-03-22 08:42:54 +00:00
|
|
|
|
|
|
|
void Configuration::resetToDefaultAsmOptions()
|
|
|
|
{
|
|
|
|
for (auto it = asmOptions.begin(); it != asmOptions.end(); it++) {
|
|
|
|
setConfig(it.key(), it.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Configuration::applySavedAsmOptions()
|
|
|
|
{
|
|
|
|
for (auto it = asmOptions.begin(); it != asmOptions.end(); it++) {
|
|
|
|
Core()->setConfig(it.key(), s.value(it.key(), it.value()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant Configuration::getConfigVar(const QString &key)
|
|
|
|
{
|
|
|
|
QHash<QString, QVariant>::const_iterator it = asmOptions.find(key);
|
|
|
|
if (it != asmOptions.end()) {
|
|
|
|
switch(it.value().type()) {
|
|
|
|
case QVariant::Type::Bool:
|
|
|
|
return Core()->getConfigb(key);
|
|
|
|
case QVariant::Type::Int:
|
|
|
|
return Core()->getConfigi(key);
|
|
|
|
default:
|
|
|
|
return Core()->getConfig(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Configuration::getConfigBool(const QString &key)
|
|
|
|
{
|
|
|
|
return getConfigVar(key).toBool();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Configuration::getConfigInt(const QString &key)
|
|
|
|
{
|
|
|
|
return getConfigVar(key).toInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Configuration::getConfigString(const QString &key)
|
|
|
|
{
|
|
|
|
return getConfigVar(key).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Configuration::setConfig(const QString &key, const QVariant &value)
|
|
|
|
{
|
|
|
|
if (asmOptions.contains(key)) {
|
|
|
|
s.setValue(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
Core()->setConfig(key, value);
|
2018-03-28 09:25:40 +00:00
|
|
|
}
|