AssembleDialog : Changed the instruction validation when Keep Size is enabled to be checked with a ValidateExpressionThread
ValidateExpressionThread : Added a method to see the callback when expression has changed to make it more generic
This commit is contained in:
parent
4c08df508b
commit
736e99ff56
|
|
@ -10,14 +10,21 @@ AssembleDialog::AssembleDialog(QWidget *parent) :
|
|||
{
|
||||
ui->setupUi(this);
|
||||
setModal(true);
|
||||
setFixedSize(this->size()); //fixed size
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint);
|
||||
#endif
|
||||
setFixedSize(this->size()); //fixed size
|
||||
|
||||
mSelectedInstrVa = 0;
|
||||
bKeepSizeChecked = false;
|
||||
bFillWithNopsChecked = false;
|
||||
selectedInstrVa = 0;
|
||||
|
||||
mValidateThread = new ValidateExpressionThread(this);
|
||||
mValidateThread->setOnExpressionChangedCallback(std::bind(&AssembleDialog::validateInstruction, this, std::placeholders::_1));
|
||||
|
||||
connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(textChangedSlot(QString)));
|
||||
connect(mValidateThread, SIGNAL(instructionChanged(dsint,QString)), this, SLOT(instructionChangedSlot(dsint, QString)));
|
||||
}
|
||||
|
||||
AssembleDialog::~AssembleDialog()
|
||||
|
|
@ -54,84 +61,126 @@ void AssembleDialog::setFillWithNopsLabel(const QString &text)
|
|||
|
||||
void AssembleDialog::setSelectedInstrVa(const duint va)
|
||||
{
|
||||
this->selectedInstrVa = va;
|
||||
this->mSelectedInstrVa = va;
|
||||
}
|
||||
|
||||
void AssembleDialog::compareTypedInstructionToSelected()
|
||||
{
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
BASIC_INSTRUCTION_INFO basicInstrInfo;
|
||||
int typedInstructionSize = 0, selectedInstructionSize = 0;
|
||||
|
||||
// Get selected instruction info (size here)
|
||||
DbgDisasmFastAt(this->selectedInstrVa, &basicInstrInfo);
|
||||
selectedInstructionSize = basicInstrInfo.size;
|
||||
|
||||
// Get typed in instruction size
|
||||
if(!DbgFunctions()->Assemble(this->selectedInstrVa, NULL, &typedInstructionSize, editText.toUtf8().constData(), error) || selectedInstructionSize == 0)
|
||||
{
|
||||
this->setKeepSizeLabel("<font color='orange'><b>Instruction decoding error : " + QString(error) + "</b></font>");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(typedInstructionSize > selectedInstructionSize)
|
||||
{
|
||||
int sizeDifference = typedInstructionSize - selectedInstructionSize;
|
||||
QString errorMessage = "<font color='red'><b>Instruction bigger by " + QString::number(sizeDifference);
|
||||
(sizeDifference == 1) ? errorMessage += QString(" byte</b></font>") : errorMessage += QString(" bytes</b></font>");
|
||||
|
||||
this->setKeepSizeLabel(errorMessage);
|
||||
this->setOkButtonEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sizeDifference = selectedInstructionSize - typedInstructionSize;
|
||||
QString message;
|
||||
if(!sizeDifference)
|
||||
message = "<font color='#00cc00'><b>Instruction is same size</b></font>";
|
||||
else
|
||||
{
|
||||
message = "<font color='#00cc00'><b>Instruction smaller by " + QString::number(sizeDifference);
|
||||
(sizeDifference == 1) ? message += QString(" byte</b></font>") : message += QString(" bytes</b></font>");
|
||||
}
|
||||
this->setKeepSizeLabel(message);
|
||||
this->setOkButtonEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AssembleDialog::setOkButtonEnabled(bool enabled)
|
||||
{
|
||||
ui->pushButtonOk->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void AssembleDialog::validateInstruction(QString expression)
|
||||
{
|
||||
//void instructionChanged(bool validInstruction, dsint sizeDifference, QString error)
|
||||
dsint sizeDifference = 0;
|
||||
int typedInstructionSize = 0;
|
||||
int selectedInstructionSize = 0;
|
||||
bool validInstruction = false;
|
||||
QByteArray error(MAX_ERROR_SIZE, 0);
|
||||
BASIC_INSTRUCTION_INFO basicInstrInfo;
|
||||
|
||||
// Get selected instruction info (size here)
|
||||
DbgDisasmFastAt(mSelectedInstrVa, &basicInstrInfo);
|
||||
selectedInstructionSize = basicInstrInfo.size;
|
||||
|
||||
// Get typed in instruction size
|
||||
if(!DbgFunctions()->Assemble(this->mSelectedInstrVa, NULL, &typedInstructionSize, editText.toUtf8().constData(), error.data()) || selectedInstructionSize == 0)
|
||||
{
|
||||
emit mValidateThread->emitInstructionChanged(0, QString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
// Valid instruction
|
||||
validInstruction = true;
|
||||
|
||||
sizeDifference = typedInstructionSize - selectedInstructionSize;
|
||||
|
||||
emit mValidateThread->emitInstructionChanged(sizeDifference, "");
|
||||
}
|
||||
|
||||
void AssembleDialog::hideEvent(QHideEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
mValidateThread->stop();
|
||||
mValidateThread->wait();
|
||||
}
|
||||
|
||||
void AssembleDialog::textChangedSlot(QString text)
|
||||
{
|
||||
if(ui->checkBoxKeepSize->isChecked())
|
||||
mValidateThread->textChanged(text);
|
||||
}
|
||||
|
||||
void AssembleDialog::instructionChangedSlot(dsint sizeDifference, QString error)
|
||||
{
|
||||
if(ui->checkBoxKeepSize->isChecked())
|
||||
{
|
||||
// If there was an error
|
||||
if(error.length())
|
||||
{
|
||||
this->setKeepSizeLabel("<font color='orange'><b>Instruction decoding error : " + error + "</b></font>");
|
||||
return;
|
||||
}
|
||||
// No error
|
||||
else
|
||||
{
|
||||
|
||||
// SizeDifference > 0 <=> Typed instruction is bigger
|
||||
if(sizeDifference > 0)
|
||||
{
|
||||
QString message = "<font color='red'><b>Instruction bigger by " + QString::number(sizeDifference);
|
||||
if(sizeDifference == 1)
|
||||
message += QString(" byte</b></font>");
|
||||
else
|
||||
message += QString(" bytes</b></font>");
|
||||
|
||||
this->setKeepSizeLabel(message);
|
||||
this->setOkButtonEnabled(false);
|
||||
}
|
||||
// SizeDifference < 0 <=> Typed instruction is smaller
|
||||
else if(sizeDifference < 0)
|
||||
{
|
||||
QString message = "<font color='#00cc00'><b>Instruction smaller by " + QString::number(sizeDifference);
|
||||
if(sizeDifference == -1)
|
||||
message += QString(" byte</b></font>");
|
||||
else
|
||||
message += QString(" bytes</b></font>");
|
||||
|
||||
this->setKeepSizeLabel(message);
|
||||
this->setOkButtonEnabled(true);
|
||||
}
|
||||
// SizeDifference == 0 <=> Both instruction have same size
|
||||
else
|
||||
{
|
||||
QString message = "<font color='#00cc00'><b>Instruction is same size</b></font>";
|
||||
|
||||
this->setKeepSizeLabel(message);
|
||||
this->setOkButtonEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssembleDialog::on_lineEdit_textChanged(const QString &arg1)
|
||||
{
|
||||
editText = arg1;
|
||||
|
||||
if(ui->checkBoxKeepSize->isChecked() && editText.size())
|
||||
compareTypedInstructionToSelected();
|
||||
mValidateThread->start(editText);
|
||||
}
|
||||
|
||||
void AssembleDialog::on_checkBoxKeepSize_clicked(bool checked)
|
||||
{
|
||||
// If first time ticking this checkbox, warn user about possible short dialog freeze when typing invalid instruction
|
||||
if(checked && !AssembleDialog::bWarningShowedOnce)
|
||||
{
|
||||
int answer = QMessageBox::question(this, "Possible dialog freeze", "Enabling this option may cause this dialog to freeze for a short amount of time when typing invalid instruction. Do you still want to enable this ?", QMessageBox::Yes | QMessageBox::No);
|
||||
if(answer == QMessageBox::No)
|
||||
{
|
||||
ui->checkBoxKeepSize->setChecked(false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
AssembleDialog::bWarningShowedOnce = true;
|
||||
}
|
||||
|
||||
if(checked && editText.size())
|
||||
compareTypedInstructionToSelected();
|
||||
{
|
||||
mValidateThread->start();
|
||||
mValidateThread->textChanged(ui->lineEdit->text()); // Have to add this or textChanged isn't called inside start()
|
||||
}
|
||||
else
|
||||
{
|
||||
mValidateThread->stop();
|
||||
mValidateThread->wait();
|
||||
ui->labelKeepSize->setText("");
|
||||
ui->pushButtonOk->setEnabled(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QDialog>
|
||||
#include <functional>
|
||||
#include "Bridge.h"
|
||||
#include "ValidateExpressionThread.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
|
@ -30,17 +31,22 @@ public:
|
|||
void setFillWithNopsLabel(const QString & text);
|
||||
|
||||
void setSelectedInstrVa(const duint va);
|
||||
void compareTypedInstructionToSelected();
|
||||
void setOkButtonEnabled(bool enabled);
|
||||
|
||||
void validateInstruction(QString expression);
|
||||
void hideEvent(QHideEvent *event);
|
||||
|
||||
private slots:
|
||||
void textChangedSlot(QString text);
|
||||
void instructionChangedSlot(dsint sizeDifference, QString error);
|
||||
void on_lineEdit_textChanged(const QString &arg1);
|
||||
void on_checkBoxKeepSize_clicked(bool checked);
|
||||
void on_checkBoxFillWithNops_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::AssembleDialog *ui;
|
||||
duint selectedInstrVa;
|
||||
duint mSelectedInstrVa;
|
||||
ValidateExpressionThread *mValidateThread;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ GotoDialog::GotoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::GotoDialog
|
|||
validRangeEnd = 0;
|
||||
fileOffset = false;
|
||||
mValidateThread = new ValidateExpressionThread(this);
|
||||
mValidateThread->setOnExpressionChangedCallback(std::bind(&GotoDialog::validateExpression, this, std::placeholders::_1));
|
||||
|
||||
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint)));
|
||||
connect(ui->editExpression, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString)));
|
||||
connect(this, SIGNAL(finished(int)), this, SLOT(finishedSlot(int)));
|
||||
|
|
@ -44,6 +46,14 @@ void GotoDialog::hideEvent(QHideEvent* event)
|
|||
mValidateThread->wait();
|
||||
}
|
||||
|
||||
void GotoDialog::validateExpression(QString expression)
|
||||
{
|
||||
duint value;
|
||||
bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value);
|
||||
bool validPointer = validExpression && DbgMemIsValidReadPtr(value);
|
||||
this->mValidateThread->emitExpressionChanged(validExpression, validPointer, value);
|
||||
}
|
||||
|
||||
void GotoDialog::expressionChanged(bool validExpression, bool validPointer, dsint value)
|
||||
{
|
||||
QString expression = ui->editExpression->text();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public:
|
|||
QString modName;
|
||||
void showEvent(QShowEvent* event);
|
||||
void hideEvent(QHideEvent* event);
|
||||
void validateExpression(QString expression);
|
||||
|
||||
private slots:
|
||||
void expressionChanged(bool validExpression, bool validPointer, dsint value);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
ValidateExpressionThread::ValidateExpressionThread(QObject* parent) : QThread(parent), mExpressionChanged(false), mStopThread(false)
|
||||
{
|
||||
this->mOnExpressionChangedCallback = nullptr;
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::start(QString initialValue)
|
||||
|
|
@ -16,6 +17,16 @@ void ValidateExpressionThread::stop()
|
|||
mStopThread = true;
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::emitExpressionChanged(bool validExpression, bool validPointer, dsint value)
|
||||
{
|
||||
emit expressionChanged(validExpression, validPointer, value);
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::emitInstructionChanged(dsint sizeDifference, QString error)
|
||||
{
|
||||
emit instructionChanged(sizeDifference, error);
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::textChanged(QString text)
|
||||
{
|
||||
mExpressionMutex.lock();
|
||||
|
|
@ -27,6 +38,11 @@ void ValidateExpressionThread::textChanged(QString text)
|
|||
mExpressionMutex.unlock();
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::setOnExpressionChangedCallback(EXPRESSIONCHANGEDCB callback)
|
||||
{
|
||||
mOnExpressionChangedCallback = callback;
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::run()
|
||||
{
|
||||
while(!mStopThread)
|
||||
|
|
@ -36,12 +52,9 @@ void ValidateExpressionThread::run()
|
|||
bool changed = mExpressionChanged;
|
||||
mExpressionChanged = false;
|
||||
mExpressionMutex.unlock();
|
||||
if(changed)
|
||||
if(changed && mOnExpressionChangedCallback != nullptr)
|
||||
{
|
||||
duint value;
|
||||
bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value);
|
||||
bool validPointer = validExpression && DbgMemIsValidReadPtr(value);
|
||||
emit expressionChanged(validExpression, validPointer, value);
|
||||
mOnExpressionChangedCallback(expression);
|
||||
}
|
||||
Sleep(50);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <functional>
|
||||
#include "Imports.h"
|
||||
|
||||
typedef std::function<void(QString expression) > EXPRESSIONCHANGEDCB;
|
||||
|
||||
class ValidateExpressionThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -12,18 +15,23 @@ public:
|
|||
ValidateExpressionThread(QObject* parent = 0);
|
||||
void start(QString initialValue = QString());
|
||||
void stop();
|
||||
void emitExpressionChanged(bool validExpression, bool validPointer, dsint value);
|
||||
void emitInstructionChanged(dsint sizeDifference, QString error);
|
||||
|
||||
signals:
|
||||
void expressionChanged(bool validExpression, bool validPointer, dsint value);
|
||||
void instructionChanged(dsint sizeDifference, QString error);
|
||||
|
||||
public slots:
|
||||
void textChanged(QString text);
|
||||
void setOnExpressionChangedCallback(EXPRESSIONCHANGEDCB callback);
|
||||
|
||||
private:
|
||||
QMutex mExpressionMutex;
|
||||
QString mExpressionText;
|
||||
bool mExpressionChanged;
|
||||
volatile bool mStopThread;
|
||||
EXPRESSIONCHANGEDCB mOnExpressionChangedCallback;
|
||||
|
||||
void run();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue