2017-12-14 13:42:24 +00:00
|
|
|
#include <QLabel>
|
|
|
|
#include <QFontDialog>
|
|
|
|
|
|
|
|
#include "AsmOptionsWidget.h"
|
|
|
|
#include "ui_AsmOptionsWidget.h"
|
|
|
|
|
|
|
|
#include "PreferencesDialog.h"
|
|
|
|
|
2018-10-17 07:55:53 +00:00
|
|
|
#include "common/Helpers.h"
|
|
|
|
#include "common/Configuration.h"
|
2017-12-14 13:42:24 +00:00
|
|
|
|
2019-03-16 12:41:45 +00:00
|
|
|
AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog)
|
|
|
|
: QDialog(dialog),
|
2018-03-21 20:32:32 +00:00
|
|
|
ui(new Ui::AsmOptionsWidget)
|
2017-12-14 13:42:24 +00:00
|
|
|
{
|
2018-11-26 22:34:34 +00:00
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
|
|
ui->syntaxComboBox->blockSignals(true);
|
2018-03-21 20:32:32 +00:00
|
|
|
for (const auto &syntax : Core()->cmdList("e asm.syntax=?"))
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->syntaxComboBox->addItem(syntax, syntax);
|
|
|
|
ui->syntaxComboBox->blockSignals(false);
|
|
|
|
|
2019-06-29 05:09:51 +00:00
|
|
|
checkboxes = {
|
2019-06-29 16:38:43 +00:00
|
|
|
{ ui->describeCheckBox, "asm.describe" },
|
2019-06-29 05:09:51 +00:00
|
|
|
{ ui->refptrCheckBox, "asm.refptr" },
|
|
|
|
{ ui->xrefCheckBox, "asm.xrefs" },
|
|
|
|
{ ui->bblineCheckBox, "asm.bb.line" },
|
|
|
|
{ ui->varsubCheckBox, "asm.var.sub" },
|
|
|
|
{ ui->varsubOnlyCheckBox, "asm.var.subonly" },
|
|
|
|
{ ui->lbytesCheckBox, "asm.lbytes" },
|
|
|
|
{ ui->bytespaceCheckBox, "asm.bytespace" },
|
|
|
|
{ ui->bytesCheckBox, "asm.bytes" },
|
|
|
|
{ ui->xrefCheckBox, "asm.xrefs" },
|
|
|
|
{ ui->indentCheckBox, "asm.indent" },
|
|
|
|
{ ui->offsetCheckBox, "asm.offset" },
|
2020-06-11 16:43:32 +00:00
|
|
|
{ ui->relOffsetCheckBox, "asm.reloff" },
|
2020-06-16 10:54:36 +00:00
|
|
|
{ ui->relOffFlagsCheckBox, "asm.reloff.flags" },
|
2019-06-29 05:09:51 +00:00
|
|
|
{ ui->slowCheckBox, "asm.slow" },
|
|
|
|
{ ui->linesCheckBox, "asm.lines" },
|
|
|
|
{ ui->fcnlinesCheckBox, "asm.lines.fcn" },
|
|
|
|
{ ui->flgoffCheckBox, "asm.flags.offset" },
|
|
|
|
{ ui->emuCheckBox, "asm.emu" },
|
|
|
|
{ ui->emuStrCheckBox, "emu.str" },
|
|
|
|
{ ui->varsumCheckBox, "asm.var.summary" },
|
|
|
|
{ ui->sizeCheckBox, "asm.size" },
|
2020-01-21 10:00:38 +00:00
|
|
|
{ ui->realnameCheckBox, "asm.flags.real" }
|
2019-06-29 05:09:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
QList<ConfigCheckbox>::iterator confCheckbox;
|
|
|
|
|
|
|
|
// Connect each checkbox from "checkboxes" to the generic signal "checkboxEnabler"
|
|
|
|
for (confCheckbox = checkboxes.begin(); confCheckbox != checkboxes.end(); ++confCheckbox) {
|
|
|
|
QString val = confCheckbox->config;
|
|
|
|
QCheckBox &cb = *confCheckbox->checkBox;
|
|
|
|
connect(confCheckbox->checkBox, &QCheckBox::stateChanged, [this, val, &cb]() { checkboxEnabler(&cb, val) ;});
|
|
|
|
}
|
2017-12-14 13:42:24 +00:00
|
|
|
|
2019-10-06 17:35:44 +00:00
|
|
|
using indexSignalType = void (QComboBox::*)(int);
|
|
|
|
connect(ui->commentsComboBox, static_cast<indexSignalType>(&QComboBox::currentIndexChanged), this,
|
2019-06-29 05:09:51 +00:00
|
|
|
&AsmOptionsWidget::commentsComboBoxChanged);
|
2019-10-06 17:35:44 +00:00
|
|
|
connect(ui->asmComboBox, static_cast<indexSignalType>(&QComboBox::currentIndexChanged), this,
|
2019-06-29 05:09:51 +00:00
|
|
|
&AsmOptionsWidget::asmComboBoxChanged);
|
2020-06-11 16:43:32 +00:00
|
|
|
connect(ui->offsetCheckBox, &QCheckBox::toggled, this, &AsmOptionsWidget::offsetCheckBoxToggled);
|
2020-06-16 10:54:36 +00:00
|
|
|
connect(ui->relOffsetCheckBox, &QCheckBox::toggled, this, &AsmOptionsWidget::relOffCheckBoxToggled);
|
2017-12-14 13:42:24 +00:00
|
|
|
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(updateAsmOptionsFromVars()));
|
2019-06-29 05:09:51 +00:00
|
|
|
updateAsmOptionsFromVars();
|
2017-12-14 13:42:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AsmOptionsWidget::~AsmOptionsWidget() {}
|
|
|
|
|
|
|
|
|
|
|
|
void AsmOptionsWidget::updateAsmOptionsFromVars()
|
|
|
|
{
|
2018-07-17 07:25:17 +00:00
|
|
|
bool cmtRightEnabled = Config()->getConfigBool("asm.cmt.right");
|
|
|
|
ui->cmtcolSpinBox->blockSignals(true);
|
|
|
|
ui->cmtcolSpinBox->setValue(Config()->getConfigInt("asm.cmt.col"));
|
|
|
|
ui->cmtcolSpinBox->blockSignals(false);
|
|
|
|
ui->cmtcolSpinBox->setEnabled(cmtRightEnabled);
|
|
|
|
|
2020-06-11 16:43:32 +00:00
|
|
|
bool offsetsEnabled = Config()->getConfigBool("asm.offset") || Config()->getConfigBool("graph.offset");
|
2020-06-16 10:54:36 +00:00
|
|
|
ui->relOffsetLabel->setEnabled(offsetsEnabled);
|
2020-06-11 16:43:32 +00:00
|
|
|
ui->relOffsetCheckBox->setEnabled(offsetsEnabled);
|
2020-06-16 10:54:36 +00:00
|
|
|
ui->relOffFlagsCheckBox->setEnabled(Config()->getConfigBool("asm.offset") && Config()->getConfigBool("asm.reloff"));
|
2020-06-11 16:43:32 +00:00
|
|
|
|
2018-03-22 08:42:54 +00:00
|
|
|
bool bytesEnabled = Config()->getConfigBool("asm.bytes");
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->bytespaceCheckBox->setEnabled(bytesEnabled);
|
|
|
|
ui->lbytesCheckBox->setEnabled(bytesEnabled);
|
2018-02-01 09:01:09 +00:00
|
|
|
ui->nbytesSpinBox->blockSignals(true);
|
2018-03-22 08:42:54 +00:00
|
|
|
ui->nbytesSpinBox->setValue(Config()->getConfigInt("asm.nbytes"));
|
2018-02-01 09:01:09 +00:00
|
|
|
ui->nbytesSpinBox->blockSignals(false);
|
|
|
|
ui->nbytesLabel->setEnabled(bytesEnabled);
|
|
|
|
ui->nbytesSpinBox->setEnabled(bytesEnabled);
|
2019-06-29 05:09:51 +00:00
|
|
|
bool varsubEnabled = Config()->getConfigBool("asm.var.sub");
|
|
|
|
ui->varsubOnlyCheckBox->setEnabled(varsubEnabled);
|
2017-12-14 13:42:24 +00:00
|
|
|
|
2018-03-22 08:42:54 +00:00
|
|
|
QString currentSyntax = Config()->getConfigString("asm.syntax");
|
2018-03-21 20:32:32 +00:00
|
|
|
for (int i = 0; i < ui->syntaxComboBox->count(); i++) {
|
|
|
|
if (ui->syntaxComboBox->itemData(i) == currentSyntax) {
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->syntaxComboBox->blockSignals(true);
|
|
|
|
ui->syntaxComboBox->setCurrentIndex(i);
|
|
|
|
ui->syntaxComboBox->blockSignals(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->caseComboBox->blockSignals(true);
|
2018-03-22 08:42:54 +00:00
|
|
|
if (Config()->getConfigBool("asm.ucase")) {
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->caseComboBox->setCurrentIndex(1);
|
2018-03-22 08:42:54 +00:00
|
|
|
} else if (Config()->getConfigBool("asm.capitalize")) {
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->caseComboBox->setCurrentIndex(2);
|
2018-03-21 20:32:32 +00:00
|
|
|
} else {
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->caseComboBox->setCurrentIndex(0);
|
|
|
|
}
|
|
|
|
ui->caseComboBox->blockSignals(false);
|
|
|
|
|
2018-01-31 08:01:16 +00:00
|
|
|
ui->asmTabsSpinBox->blockSignals(true);
|
2018-03-22 08:42:54 +00:00
|
|
|
ui->asmTabsSpinBox->setValue(Config()->getConfigInt("asm.tabs"));
|
2018-01-31 08:01:16 +00:00
|
|
|
ui->asmTabsSpinBox->blockSignals(false);
|
|
|
|
|
2018-07-17 07:25:17 +00:00
|
|
|
ui->asmTabsOffSpinBox->blockSignals(true);
|
|
|
|
ui->asmTabsOffSpinBox->setValue(Config()->getConfigInt("asm.tabs.off"));
|
|
|
|
ui->asmTabsOffSpinBox->blockSignals(false);
|
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
|
2019-06-29 05:09:51 +00:00
|
|
|
QList<ConfigCheckbox>::iterator confCheckbox;
|
|
|
|
|
|
|
|
// Set the value for each checkbox in "checkboxes" as it exists in the configuration
|
|
|
|
for (confCheckbox = checkboxes.begin(); confCheckbox != checkboxes.end(); ++confCheckbox) {
|
|
|
|
qhelpers::setCheckedWithoutSignals(confCheckbox->checkBox, Config()->getConfigBool(confCheckbox->config));
|
|
|
|
}
|
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AsmOptionsWidget::resetToDefault()
|
|
|
|
{
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->resetToDefaultAsmOptions();
|
2017-12-14 13:42:24 +00:00
|
|
|
updateAsmOptionsFromVars();
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AsmOptionsWidget::triggerAsmOptionsChanged()
|
|
|
|
{
|
|
|
|
disconnect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(updateAsmOptionsFromVars()));
|
|
|
|
Core()->triggerAsmOptionsChanged();
|
|
|
|
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(updateAsmOptionsFromVars()));
|
|
|
|
}
|
|
|
|
|
2018-07-17 07:25:17 +00:00
|
|
|
void AsmOptionsWidget::on_cmtcolSpinBox_valueChanged(int value)
|
|
|
|
{
|
|
|
|
Config()->setConfig("asm.cmt.col", value);
|
2018-01-31 08:01:16 +00:00
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
void AsmOptionsWidget::on_bytesCheckBox_toggled(bool checked)
|
|
|
|
{
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->setConfig("asm.bytes", checked);
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->bytespaceCheckBox->setEnabled(checked);
|
|
|
|
ui->lbytesCheckBox->setEnabled(checked);
|
2018-02-01 09:01:09 +00:00
|
|
|
ui->nbytesLabel->setEnabled(checked);
|
|
|
|
ui->nbytesSpinBox->setEnabled(checked);
|
2017-12-14 13:42:24 +00:00
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2018-02-01 09:01:09 +00:00
|
|
|
void AsmOptionsWidget::on_nbytesSpinBox_valueChanged(int value)
|
|
|
|
{
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->setConfig("asm.nbytes", value);
|
2018-02-01 09:01:09 +00:00
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
void AsmOptionsWidget::on_syntaxComboBox_currentIndexChanged(int index)
|
|
|
|
{
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->setConfig("asm.syntax",
|
2019-02-07 22:55:24 +00:00
|
|
|
ui->syntaxComboBox->itemData(index).toString().toUtf8().constData());
|
2017-12-14 13:42:24 +00:00
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AsmOptionsWidget::on_caseComboBox_currentIndexChanged(int index)
|
|
|
|
{
|
|
|
|
bool ucase;
|
|
|
|
bool capitalize;
|
|
|
|
|
2018-03-21 20:32:32 +00:00
|
|
|
switch (index) {
|
2017-12-14 13:42:24 +00:00
|
|
|
// lowercase
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
ucase = false;
|
|
|
|
capitalize = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// uppercase
|
|
|
|
case 1:
|
|
|
|
ucase = true;
|
|
|
|
capitalize = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
ucase = false;
|
|
|
|
capitalize = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->setConfig("asm.ucase", ucase);
|
|
|
|
Config()->setConfig("asm.capitalize", capitalize);
|
2017-12-14 13:42:24 +00:00
|
|
|
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2018-01-31 08:01:16 +00:00
|
|
|
void AsmOptionsWidget::on_asmTabsSpinBox_valueChanged(int value)
|
|
|
|
{
|
2018-03-22 08:42:54 +00:00
|
|
|
Config()->setConfig("asm.tabs", value);
|
2018-01-31 08:01:16 +00:00
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2018-07-17 07:25:17 +00:00
|
|
|
void AsmOptionsWidget::on_asmTabsOffSpinBox_valueChanged(int value)
|
|
|
|
{
|
|
|
|
Config()->setConfig("asm.tabs.off", value);
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2017-12-14 13:42:24 +00:00
|
|
|
|
|
|
|
void AsmOptionsWidget::on_varsubCheckBox_toggled(bool checked)
|
|
|
|
{
|
2018-05-24 06:21:12 +00:00
|
|
|
Config()->setConfig("asm.var.sub", checked);
|
2017-12-14 13:42:24 +00:00
|
|
|
ui->varsubOnlyCheckBox->setEnabled(checked);
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2017-12-14 15:14:33 +00:00
|
|
|
void AsmOptionsWidget::on_buttonBox_clicked(QAbstractButton *button)
|
2017-12-14 13:42:24 +00:00
|
|
|
{
|
2018-03-21 20:32:32 +00:00
|
|
|
switch (ui->buttonBox->buttonRole(button)) {
|
|
|
|
case QDialogButtonBox::ButtonRole::ResetRole:
|
|
|
|
resetToDefault();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2017-12-14 13:42:24 +00:00
|
|
|
}
|
2018-01-28 22:28:25 +00:00
|
|
|
}
|
2019-06-29 05:09:51 +00:00
|
|
|
|
|
|
|
void AsmOptionsWidget::commentsComboBoxChanged(int index)
|
|
|
|
{
|
|
|
|
// Check if comments should be set to right
|
|
|
|
Config()->setConfig("asm.cmt.right", index != 1);
|
|
|
|
// Check if comments are disabled
|
|
|
|
ui->cmtcolSpinBox->setEnabled(index != 1);
|
|
|
|
|
|
|
|
// Show\Hide comments in disassembly based on whether "Off" is selected
|
|
|
|
Config()->setConfig("asm.comments", index != 2);
|
|
|
|
// Enable comments-related checkboxes only if Comments are enabled
|
|
|
|
ui->xrefCheckBox->setEnabled(index != 2);
|
|
|
|
ui->refptrCheckBox->setEnabled(index != 2);
|
|
|
|
ui->describeCheckBox->setEnabled(index != 2);
|
|
|
|
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AsmOptionsWidget::asmComboBoxChanged(int index)
|
|
|
|
{
|
|
|
|
// Check if ESIL enabled
|
|
|
|
Config()->setConfig("asm.esil", index == 1);
|
|
|
|
|
|
|
|
// Check if Pseudocode enabled
|
|
|
|
Config()->setConfig("asm.pseudo", index == 2);
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|
|
|
|
|
2020-06-11 16:43:32 +00:00
|
|
|
void AsmOptionsWidget::offsetCheckBoxToggled(bool checked)
|
|
|
|
{
|
2020-06-16 10:54:36 +00:00
|
|
|
ui->relOffsetLabel->setEnabled(checked || Config()->getConfigBool("graph.offset"));
|
2020-06-11 16:43:32 +00:00
|
|
|
ui->relOffsetCheckBox->setEnabled(checked || Config()->getConfigBool("graph.offset"));
|
2020-06-16 10:54:36 +00:00
|
|
|
ui->relOffFlagsCheckBox->setEnabled(checked && Config()->getConfigBool("asm.reloff"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AsmOptionsWidget::relOffCheckBoxToggled(bool checked)
|
|
|
|
{
|
|
|
|
ui->relOffFlagsCheckBox->setEnabled(checked && Config()->getConfigBool("asm.offset"));
|
2020-06-11 16:43:32 +00:00
|
|
|
}
|
|
|
|
|
2019-06-29 05:09:51 +00:00
|
|
|
/**
|
|
|
|
* @brief A generic signal to handle the simple cases where a checkbox is toggled
|
|
|
|
* while it only responsible for a single independent boolean configuration eval.
|
|
|
|
* @param checkBox - The checkbox which is responsible for the siganl
|
|
|
|
* @param config - the configuration string to be toggled
|
|
|
|
*/
|
|
|
|
void AsmOptionsWidget::checkboxEnabler(QCheckBox* checkBox, QString config)
|
|
|
|
{
|
|
|
|
Config()->setConfig(config, checkBox->isChecked());
|
|
|
|
triggerAsmOptionsChanged();
|
|
|
|
}
|