258 lines
7.9 KiB
C++
258 lines
7.9 KiB
C++
#include "CalculatorDialog.h"
|
|
#include "ui_CalculatorDialog.h"
|
|
#include "ValidateExpressionThread.h"
|
|
|
|
CalculatorDialog::CalculatorDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CalculatorDialog)
|
|
{
|
|
ui->setupUi(this);
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
|
|
connect(this, SIGNAL(validAddress(bool)), ui->btnGoto, SLOT(setEnabled(bool)));
|
|
connect(this, SIGNAL(validAddress(bool)), ui->btnGotoDump, SLOT(setEnabled(bool)));
|
|
emit validAddress(false);
|
|
ui->txtBin->setInputMask(QString("bbbb ").repeated(sizeof(duint) * 2));
|
|
ui->txtExpression->setText("0");
|
|
ui->txtExpression->selectAll();
|
|
ui->txtExpression->setFocus();
|
|
mValidateThread = new ValidateExpressionThread(this);
|
|
mValidateThread->setOnExpressionChangedCallback(std::bind(&CalculatorDialog::validateExpression, this, std::placeholders::_1));
|
|
|
|
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint)));
|
|
connect(ui->txtExpression, SIGNAL(textChanged(QString)), mValidateThread, SLOT(textChanged(QString)));
|
|
}
|
|
|
|
CalculatorDialog::~CalculatorDialog()
|
|
{
|
|
mValidateThread->stop();
|
|
mValidateThread->wait();
|
|
delete ui;
|
|
}
|
|
|
|
void CalculatorDialog::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 CalculatorDialog::showEvent(QShowEvent* event)
|
|
{
|
|
Q_UNUSED(event);
|
|
mValidateThread->start();
|
|
}
|
|
|
|
void CalculatorDialog::hideEvent(QHideEvent* event)
|
|
{
|
|
Q_UNUSED(event);
|
|
mValidateThread->stop();
|
|
mValidateThread->wait();
|
|
}
|
|
|
|
void CalculatorDialog::setExpressionFocus()
|
|
{
|
|
ui->txtExpression->selectAll();
|
|
ui->txtExpression->setFocus();
|
|
}
|
|
|
|
void CalculatorDialog::expressionChanged(bool validExpression, bool validPointer, dsint value)
|
|
{
|
|
if(!validExpression)
|
|
{
|
|
ui->txtBin->setText("");
|
|
ui->txtSignedDec->setText("");
|
|
ui->txtUnsignedDec->setText("");
|
|
ui->txtHex->setText("");
|
|
ui->txtOct->setText("");
|
|
ui->txtAscii->setText("");
|
|
ui->txtUnicode->setText("");
|
|
ui->txtExpression->setStyleSheet("border: 2px solid red");
|
|
emit validAddress(false);
|
|
}
|
|
else
|
|
{
|
|
ui->txtExpression->setStyleSheet("");
|
|
ui->txtHex->setText(inFormat(value, N_HEX));
|
|
ui->txtSignedDec->setText(inFormat(value, N_SDEC));
|
|
ui->txtUnsignedDec->setText(inFormat(value, N_UDEC));
|
|
int cursorpos = ui->txtBin->cursorPosition();
|
|
ui->txtBin->setText(inFormat(value, N_BIN));
|
|
ui->txtBin->setCursorPosition(cursorpos);
|
|
ui->txtOct->setText(inFormat(value, N_OCT));
|
|
if(value == (value & 0xFF))
|
|
{
|
|
QChar c((ushort)value);
|
|
if(c.isPrint())
|
|
ui->txtAscii->setText(QString(c));
|
|
else
|
|
ui->txtAscii->setText("???");
|
|
}
|
|
else
|
|
ui->txtAscii->setText("???");
|
|
ui->txtAscii->setCursorPosition(0);
|
|
ui->txtAscii->selectAll();
|
|
if((value == (value & 0xFFFF))) //UNICODE?
|
|
{
|
|
QChar c = QChar((ushort)value);
|
|
if(c.isPrint())
|
|
ui->txtUnicode->setText(QString(c));
|
|
else
|
|
ui->txtUnicode->setText("????");
|
|
}
|
|
else
|
|
{
|
|
ui->txtUnicode->setText("????");
|
|
}
|
|
ui->txtUnicode->setCursorPosition(0);
|
|
ui->txtUnicode->selectAll();
|
|
emit validAddress(validPointer);
|
|
}
|
|
}
|
|
|
|
void CalculatorDialog::on_txtExpression_textChanged(const QString & arg1)
|
|
{
|
|
Q_UNUSED(arg1);
|
|
ui->txtHex->setStyleSheet("");
|
|
ui->txtSignedDec->setStyleSheet("");
|
|
ui->txtUnsignedDec->setStyleSheet("");
|
|
ui->txtOct->setStyleSheet("");
|
|
ui->txtBin->setStyleSheet("");
|
|
ui->txtAscii->setStyleSheet("");
|
|
ui->txtUnicode->setStyleSheet("");
|
|
emit validAddress(false);
|
|
}
|
|
|
|
QString CalculatorDialog::inFormat(const duint val, CalculatorDialog::NUMBERFORMAT NF) const
|
|
{
|
|
switch(NF)
|
|
{
|
|
default:
|
|
case N_HEX:
|
|
return QString("%1").arg(val, 1, 16, QChar('0')).toUpper();
|
|
case N_SDEC:
|
|
return QString("%1").arg((dsint)val);
|
|
case N_UDEC:
|
|
return QString("%1").arg(val);
|
|
case N_BIN:
|
|
{
|
|
QString binary = QString("%1").arg(val, 8 * sizeof(duint), 2, QChar('0')).toUpper();
|
|
QString ans = "";
|
|
for(int i = 0; i < sizeof(duint) * 8; i++)
|
|
{
|
|
if((i % 4 == 0) && (i != 0))
|
|
ans += " ";
|
|
ans += binary[i];
|
|
}
|
|
return ans;
|
|
}
|
|
case N_OCT:
|
|
return QString("%1").arg(val, 1, 8, QChar('0')).toUpper();
|
|
case N_ASCII:
|
|
return QString("%1").arg(QChar((ushort)val));
|
|
}
|
|
}
|
|
|
|
void CalculatorDialog::on_btnGoto_clicked()
|
|
{
|
|
DbgCmdExecDirect(QString("disasm " + ui->txtExpression->text()).toUtf8().constData());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtHex_textEdited(const QString & arg1)
|
|
{
|
|
bool ok = false;
|
|
ULONGLONG val = arg1.toULongLong(&ok, 16);
|
|
if(!ok)
|
|
{
|
|
ui->txtHex->setStyleSheet("border: 2px solid red");
|
|
return;
|
|
}
|
|
ui->txtHex->setStyleSheet("");
|
|
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtSignedDec_textEdited(const QString & arg1)
|
|
{
|
|
bool ok = false;
|
|
LONGLONG val = arg1.toLongLong(&ok, 10);
|
|
if(!ok)
|
|
{
|
|
ui->txtUnsignedDec->setStyleSheet("border: 2px solid red");
|
|
return;
|
|
}
|
|
ui->txtUnsignedDec->setStyleSheet("");
|
|
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtUnsignedDec_textEdited(const QString & arg1)
|
|
{
|
|
bool ok = false;
|
|
LONGLONG val = arg1.toULongLong(&ok, 10);
|
|
if(!ok)
|
|
{
|
|
ui->txtUnsignedDec->setStyleSheet("border: 2px solid red");
|
|
return;
|
|
}
|
|
ui->txtUnsignedDec->setStyleSheet("");
|
|
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtOct_textEdited(const QString & arg1)
|
|
{
|
|
bool ok = false;
|
|
ULONGLONG val = arg1.toULongLong(&ok, 8);
|
|
if(!ok)
|
|
{
|
|
ui->txtOct->setStyleSheet("border: 2px solid red");
|
|
return;
|
|
}
|
|
ui->txtOct->setStyleSheet("");
|
|
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtBin_textEdited(const QString & arg1)
|
|
{
|
|
bool ok = false;
|
|
QString text = arg1;
|
|
text = text.replace(" ", "");
|
|
ULONGLONG val = text.toULongLong(&ok, 2);
|
|
if(!ok)
|
|
{
|
|
ui->txtBin->setStyleSheet("border: 2px solid red");
|
|
return;
|
|
}
|
|
ui->txtBin->setStyleSheet("");
|
|
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
|
|
}
|
|
|
|
void CalculatorDialog::on_txtAscii_textEdited(const QString & arg1)
|
|
{
|
|
QString text = arg1;
|
|
ui->txtAscii->setStyleSheet("");
|
|
ui->txtExpression->setText(QString().sprintf("%X", text[0].unicode()));
|
|
ui->txtAscii->setCursorPosition(0);
|
|
ui->txtAscii->selectAll();
|
|
}
|
|
|
|
void CalculatorDialog::on_txtUnicode_textEdited(const QString & arg1)
|
|
{
|
|
QString text = arg1;
|
|
ui->txtUnicode->setStyleSheet("");
|
|
ui->txtExpression->setText(QString().sprintf("%X", text[0].unicode()));
|
|
ui->txtUnicode->setCursorPosition(0);
|
|
ui->txtUnicode->selectAll();
|
|
}
|
|
|
|
void CalculatorDialog::on_txtAscii_clicked()
|
|
{
|
|
ui->txtAscii->selectAll();
|
|
}
|
|
|
|
void CalculatorDialog::on_txtUnicode_clicked()
|
|
{
|
|
ui->txtUnicode->selectAll();
|
|
}
|
|
|
|
void CalculatorDialog::on_btnGotoDump_clicked()
|
|
{
|
|
DbgCmdExecDirect(QString("dump " + ui->txtExpression->text()).toUtf8().constData());
|
|
}
|