From 5758ffcafbc2d0b3554cc635408e6fd1366bf743 Mon Sep 17 00:00:00 2001 From: Itay Cohen Date: Sat, 29 Jun 2019 08:09:51 +0300 Subject: [PATCH] Initial refactoring and improvement for Assembly Options Dialog (#1627) * set asm.refptr default to false * Cleanup of AsmPreferences * Use a single slot to handle boolean checkboxes --- src/common/Configuration.cpp | 1 + src/dialogs/preferences/AsmOptionsWidget.cpp | 227 +++--- src/dialogs/preferences/AsmOptionsWidget.h | 33 +- src/dialogs/preferences/AsmOptionsWidget.ui | 701 +++++++++++-------- 4 files changed, 503 insertions(+), 459 deletions(-) diff --git a/src/common/Configuration.cpp b/src/common/Configuration.cpp index 7805fb21..b8c74226 100644 --- a/src/common/Configuration.cpp +++ b/src/common/Configuration.cpp @@ -116,6 +116,7 @@ static const QHash asmOptions = { { "asm.tabs", 5 }, { "asm.tabs.off", 5 }, { "asm.marks", false }, + { "asm.refptr", false }, { "esil.breakoninvalid", true }, { "graph.offset", false} }; diff --git a/src/dialogs/preferences/AsmOptionsWidget.cpp b/src/dialogs/preferences/AsmOptionsWidget.cpp index d6442c90..140c4b35 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.cpp +++ b/src/dialogs/preferences/AsmOptionsWidget.cpp @@ -21,9 +21,45 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) ui->syntaxComboBox->addItem(syntax, syntax); ui->syntaxComboBox->blockSignals(false); - updateAsmOptionsFromVars(); + checkboxes = { + { ui->describeCheckBox, "asm.descirbe" }, + { 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" }, + { 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" }, + }; + + QList::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) ;}); + } + + connect(ui->commentsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, + &AsmOptionsWidget::commentsComboBoxChanged); + connect(ui->asmComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, + &AsmOptionsWidget::asmComboBoxChanged); connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(updateAsmOptionsFromVars())); + updateAsmOptionsFromVars(); } AsmOptionsWidget::~AsmOptionsWidget() {} @@ -31,40 +67,22 @@ AsmOptionsWidget::~AsmOptionsWidget() {} void AsmOptionsWidget::updateAsmOptionsFromVars() { - qhelpers::setCheckedWithoutSignals(ui->esilCheckBox, Config()->getConfigBool("asm.esil")); - qhelpers::setCheckedWithoutSignals(ui->pseudoCheckBox, Config()->getConfigBool("asm.pseudo")); - qhelpers::setCheckedWithoutSignals(ui->offsetCheckBox, Config()->getConfigBool("asm.offset")); - qhelpers::setCheckedWithoutSignals(ui->xrefCheckBox, Config()->getConfigBool("asm.xrefs")); - qhelpers::setCheckedWithoutSignals(ui->indentCheckBox, Config()->getConfigBool("asm.indent")); - qhelpers::setCheckedWithoutSignals(ui->describeCheckBox, Config()->getConfigBool("asm.describe")); - qhelpers::setCheckedWithoutSignals(ui->slowCheckBox, Config()->getConfigBool("asm.slow")); - qhelpers::setCheckedWithoutSignals(ui->linesCheckBox, Config()->getConfigBool("asm.lines")); - qhelpers::setCheckedWithoutSignals(ui->fcnlinesCheckBox, Config()->getConfigBool("asm.lines.fcn")); - qhelpers::setCheckedWithoutSignals(ui->flgoffCheckBox, Config()->getConfigBool("asm.flags.offset")); - qhelpers::setCheckedWithoutSignals(ui->emuCheckBox, Config()->getConfigBool("asm.emu")); - qhelpers::setCheckedWithoutSignals(ui->emuStrCheckBox, Config()->getConfigBool("emu.str")); - qhelpers::setCheckedWithoutSignals(ui->varsumCheckBox, Config()->getConfigBool("asm.var.summary")); - qhelpers::setCheckedWithoutSignals(ui->sizeCheckBox, Config()->getConfigBool("asm.size")); - bool cmtRightEnabled = Config()->getConfigBool("asm.cmt.right"); - qhelpers::setCheckedWithoutSignals(ui->cmtrightCheckBox, cmtRightEnabled); ui->cmtcolSpinBox->blockSignals(true); ui->cmtcolSpinBox->setValue(Config()->getConfigInt("asm.cmt.col")); ui->cmtcolSpinBox->blockSignals(false); ui->cmtcolSpinBox->setEnabled(cmtRightEnabled); bool bytesEnabled = Config()->getConfigBool("asm.bytes"); - qhelpers::setCheckedWithoutSignals(ui->bytesCheckBox, bytesEnabled); - qhelpers::setCheckedWithoutSignals(ui->bytespaceCheckBox, Config()->getConfigBool("asm.bytespace")); ui->bytespaceCheckBox->setEnabled(bytesEnabled); - qhelpers::setCheckedWithoutSignals(ui->lbytesCheckBox, Config()->getConfigBool("asm.lbytes")); ui->lbytesCheckBox->setEnabled(bytesEnabled); ui->nbytesSpinBox->blockSignals(true); ui->nbytesSpinBox->setValue(Config()->getConfigInt("asm.nbytes")); ui->nbytesSpinBox->blockSignals(false); ui->nbytesLabel->setEnabled(bytesEnabled); ui->nbytesSpinBox->setEnabled(bytesEnabled); - + bool varsubEnabled = Config()->getConfigBool("asm.var.sub"); + ui->varsubOnlyCheckBox->setEnabled(varsubEnabled); QString currentSyntax = Config()->getConfigString("asm.syntax"); for (int i = 0; i < ui->syntaxComboBox->count(); i++) { @@ -94,13 +112,14 @@ void AsmOptionsWidget::updateAsmOptionsFromVars() ui->asmTabsOffSpinBox->setValue(Config()->getConfigInt("asm.tabs.off")); ui->asmTabsOffSpinBox->blockSignals(false); - qhelpers::setCheckedWithoutSignals(ui->bblineCheckBox, Config()->getConfigBool("asm.bb.line")); - bool varsubEnabled = Config()->getConfigBool("asm.var.sub"); - qhelpers::setCheckedWithoutSignals(ui->varsubCheckBox, varsubEnabled); - qhelpers::setCheckedWithoutSignals(ui->varsubOnlyCheckBox, - Config()->getConfigBool("asm.var.subonly")); - ui->varsubOnlyCheckBox->setEnabled(varsubEnabled); + QList::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)); + } + } void AsmOptionsWidget::resetToDefault() @@ -117,97 +136,12 @@ void AsmOptionsWidget::triggerAsmOptionsChanged() connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(updateAsmOptionsFromVars())); } - -void AsmOptionsWidget::on_esilCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.esil", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_pseudoCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.pseudo", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_offsetCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.offset", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_xrefCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.xrefs", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_indentCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.indent", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_describeCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.describe", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_slowCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.slow", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_linesCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.lines", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_fcnlinesCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.lines.fcn", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_flgoffCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.flags.off", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_emuCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.emu", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_emuStrCheckBox_toggled(bool checked) -{ - Config()->setConfig("emu.str", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_cmtrightCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.cmt.right", checked); - ui->cmtcolSpinBox->setEnabled(checked); - triggerAsmOptionsChanged(); -} - void AsmOptionsWidget::on_cmtcolSpinBox_valueChanged(int value) { Config()->setConfig("asm.cmt.col", value); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_varsumCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.var.summary", checked); - triggerAsmOptionsChanged(); -} void AsmOptionsWidget::on_bytesCheckBox_toggled(bool checked) { @@ -219,24 +153,6 @@ void AsmOptionsWidget::on_bytesCheckBox_toggled(bool checked) triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_sizeCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.size", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_bytespaceCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.bytespace", checked); - triggerAsmOptionsChanged(); -} - -void AsmOptionsWidget::on_lbytesCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.lbytes", checked); - triggerAsmOptionsChanged(); -} - void AsmOptionsWidget::on_nbytesSpinBox_valueChanged(int value) { Config()->setConfig("asm.nbytes", value); @@ -293,11 +209,6 @@ void AsmOptionsWidget::on_asmTabsOffSpinBox_valueChanged(int value) triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_bblineCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.bb.line", checked); - triggerAsmOptionsChanged(); -} void AsmOptionsWidget::on_varsubCheckBox_toggled(bool checked) { @@ -306,13 +217,6 @@ void AsmOptionsWidget::on_varsubCheckBox_toggled(bool checked) triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_varsubOnlyCheckBox_toggled(bool checked) -{ - Config()->setConfig("asm.var.subonly", checked); - triggerAsmOptionsChanged(); -} - - void AsmOptionsWidget::on_buttonBox_clicked(QAbstractButton *button) { switch (ui->buttonBox->buttonRole(button)) { @@ -323,3 +227,42 @@ void AsmOptionsWidget::on_buttonBox_clicked(QAbstractButton *button) break; } } + +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(); +} + +/** + * @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(); +} diff --git a/src/dialogs/preferences/AsmOptionsWidget.h b/src/dialogs/preferences/AsmOptionsWidget.h index 0f044efe..0bdb06ff 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.h +++ b/src/dialogs/preferences/AsmOptionsWidget.h @@ -24,6 +24,11 @@ public: private: std::unique_ptr ui; + struct ConfigCheckbox { + QCheckBox *checkBox; + QString config; + }; + QList checkboxes; void triggerAsmOptionsChanged(); @@ -32,35 +37,23 @@ private slots: void updateAsmOptionsFromVars(); - void on_esilCheckBox_toggled(bool checked); - void on_pseudoCheckBox_toggled(bool checked); - void on_offsetCheckBox_toggled(bool checked); - void on_xrefCheckBox_toggled(bool checked); - void on_indentCheckBox_toggled(bool checked); - void on_describeCheckBox_toggled(bool checked); - void on_slowCheckBox_toggled(bool checked); - void on_linesCheckBox_toggled(bool checked); - void on_fcnlinesCheckBox_toggled(bool checked); - void on_flgoffCheckBox_toggled(bool checked); - void on_emuCheckBox_toggled(bool checked); - void on_emuStrCheckBox_toggled(bool checked); - void on_cmtrightCheckBox_toggled(bool checked); + void on_cmtcolSpinBox_valueChanged(int value); - void on_varsumCheckBox_toggled(bool checked); - void on_bytesCheckBox_toggled(bool checked); - void on_sizeCheckBox_toggled(bool checked); - void on_bytespaceCheckBox_toggled(bool checked); - void on_lbytesCheckBox_toggled(bool checked); + void on_syntaxComboBox_currentIndexChanged(int index); void on_caseComboBox_currentIndexChanged(int index); void on_asmTabsSpinBox_valueChanged(int value); void on_asmTabsOffSpinBox_valueChanged(int value); void on_nbytesSpinBox_valueChanged(int value); - void on_bblineCheckBox_toggled(bool checked); + + void on_bytesCheckBox_toggled(bool checked); void on_varsubCheckBox_toggled(bool checked); - void on_varsubOnlyCheckBox_toggled(bool checked); void on_buttonBox_clicked(QAbstractButton *button); + + void commentsComboBoxChanged(int index); + void asmComboBoxChanged(int index); + void checkboxEnabler(QCheckBox *checkbox, QString config); }; diff --git a/src/dialogs/preferences/AsmOptionsWidget.ui b/src/dialogs/preferences/AsmOptionsWidget.ui index 4457445c..3b05299f 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.ui +++ b/src/dialogs/preferences/AsmOptionsWidget.ui @@ -6,316 +6,423 @@ 0 0 - 545 - 526 + 616 + 664 Disassembly - - - - 1 - - - - Style - - - - - - Show ESIL instead of assembly (asm.esil) - - - - - - - Show pseudocode instead of assembly (asm.pseudo) - - - - - - - Show offsets (asm.offset) - - - - - - - Show xrefs (asm.xrefs) - - - - - - - Indent disassembly based on reflines depth (asm.indent) - - - - - - - Show opcode description (asm.describe) - - - - - - - - - - - - Syntax (asm.syntax): - - - - - - - - Lowercase - - - - - Uppercase (asm.ucase) - - - - - Capitalize (asm.capitalize) - - - - - - - - - - 16 - - - - - Separate bytes with whitespace (asm.bytespace) - - - - - - - Align bytes to the left (asm.lbytes) - - - - - - - - - - - Tabs in assembly (asm.tabs): - - - - - - - 100 - - - 5 - - - - - - - - - - - Tabs before assembly (asm.tabs.off): - - - - - - - 100 - - - 5 - - - - - - - - - Show empty line after every basic block (asm.bb.line) - - - - - - - Show comments at right of assembly (asm.cmt.right) - - - - - - - - - Column to align comments (asm.cmt.col): - - - - - - - 100 - - - 5 - - - - - - - - - - Metadata - - - - - - Slow Analysis (asm.slow) - - - - - - - Show jump lines (asm.lines) - - - - - - - Show function boundary lines (asm.lines.fcn) - - - - - - - Show offset before flags (asm.flags.off) - - - - - - - Run ESIL emulation analysis (asm.emu) - - - - - - - Show only strings if any in the asm.emu output (emu.str) - - - - - - - Show size of opcodes in disassembly (asm.size) - - - - - - - Show bytes (asm.bytes) - - - - - - - Show variables summary instead of full list (asm.var.summary) - - - - - - - 16 - - - - - true - - - Number of bytes to display (asm.nbytes): - - - - - - - true - - - - - - - - - Substitute variables (asm.var.sub) - - - - - - - Substitute entire variable expressions with names (asm.var.subonly) - - - - - - - 16 + + + + + 0 + 0 + + + + 0 + + + + Style + + + + + + + 0 + 0 + + + + Disassembly + + + + + + + + Indent disassembly based on reflines depth (asm.indent) + + + + + + + Show empty line after every basic block (asm.bb.line) + + + + + + + + Lowercase + + + + + Uppercase (asm.ucase) + + + + + Capitalize (asm.capitalize) + + + + + + + + Show Disassembly as: + + + + + + + Syntax (asm.syntax): + + + + + + + + Normal + + + + + ESIL (asm.esil) + + + + + Pseudocode (asm.pseudo) + + + + + + + + Tabs in assembly (asm.tabs): + + + + + + + 100 + + + 5 + + + + + + + Show offsets (asm.offset) + + + + + + + Tabs before assembly (asm.tabs.off): + + + + + + + + + + 100 + + + 5 + + + + + + + Separate bytes with whitespace (asm.bytespace) + + + + + + + Align bytes to the left (asm.lbytes) + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + + + + 0 + 1 + + + + Comments + + + + + + + + Show opcode description (asm.describe) + + + + + + + + Normal + + + + + Above instructions + + + + + Off + + + + + + + + Show comments: + + + + + + + 100 + + + 5 + + + + + + + Column to align comments (asm.cmt.col): + + + + + + + Show x-refs (asm.xrefs) + + + + + + + Show refpointer information (asm.refptr) + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + + + + Metadata + + + + + + Slow Analysis (asm.slow) + + + + + + + Show jump lines (asm.lines) + + + + + + + Show function boundary lines (asm.lines.fcn) + + + + + + + Show offset before flags (asm.flags.off) + + + + + + + Run ESIL emulation analysis (asm.emu) + + + + + + + Show only strings if any in the asm.emu output (emu.str) + + + + + + + Show size of opcodes in disassembly (asm.size) + + + + + + + Show variables summary instead of full list (asm.var.summary) + + + + + + + Show bytes (asm.bytes) + + + + + + + 16 + + + + + true + + + Number of bytes to display (asm.nbytes): + + + + + + + true + + + + + + + + + Substitute variables (asm.var.sub) + + + + + + + Substitute entire variable expressions with names (asm.var.subonly) + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + +