1
0
Fork 0

GUI improvements (#1004)

* GUI improvements

* fix issue #939

* fix issue #1000
This commit is contained in:
Torusrxxx 2016-08-25 11:34:29 +00:00 committed by Duncan Ogilvie
parent d8328965fd
commit bb3e172efb
18 changed files with 138 additions and 86 deletions

View File

@ -3,6 +3,9 @@
#include "Configuration.h"
#include "ColumnReorderDialog.h"
#include "CachedFontMetrics.h"
#include <windows.h>
int AbstractTableView::mMouseWheelScrollDelta = 0;
AbstractTableScrollBar::AbstractTableScrollBar(QScrollBar* scrollbar)
{
@ -57,7 +60,29 @@ AbstractTableView::AbstractTableView(QWidget* parent)
memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes));
horizontalScrollBar()->setRange(0, 0);
horizontalScrollBar()->setPageStep(650);
mMouseWheelScrollDelta = 4;
if(mMouseWheelScrollDelta == 0)
{
//Initialize scroll delta from registry. Windows-specific
HKEY hDesktop;
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop\\", 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hDesktop) != ERROR_SUCCESS)
mMouseWheelScrollDelta = 4; // Failed to open the registry. Use a default value;
else
{
wchar_t Data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
DWORD regType = 0;
DWORD cbData = sizeof(Data) - sizeof(wchar_t);
if(RegQueryValueExW(hDesktop, L"WheelScrollLines", nullptr, &regType, (LPBYTE)&Data, &cbData) == ERROR_SUCCESS)
{
if(regType == REG_SZ) // Don't process other types of data
mMouseWheelScrollDelta = _wtoi(Data);
if(mMouseWheelScrollDelta == 0)
mMouseWheelScrollDelta = 4; // Malformed registry value. Use a default value.
}
else
mMouseWheelScrollDelta = 4; // Failed to query the registry. Use a default value;
RegCloseKey(hDesktop);
}
}
setMouseTracking(true);
// Slots
@ -548,13 +573,19 @@ void AbstractTableView::wheelEvent(QWheelEvent* event)
if(numSteps > 0)
{
for(int i = 0; i < mMouseWheelScrollDelta * numSteps; i++)
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
if(mMouseWheelScrollDelta > 0)
for(int i = 0; i < mMouseWheelScrollDelta * numSteps; i++)
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
else // -1 : one screen at a time
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub);
}
else
{
for(int i = 0; i < mMouseWheelScrollDelta * numSteps * -1; i++)
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
if(mMouseWheelScrollDelta > 0)
for(int i = 0; i < mMouseWheelScrollDelta * numSteps * -1; i++)
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
else // -1 : one screen at a time
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd);
}
}

View File

@ -193,7 +193,7 @@ private:
dsint mRowCount;
int mMouseWheelScrollDelta;
static int mMouseWheelScrollDelta;
dsint mTableOffset;
Header_t mHeader;

View File

@ -777,6 +777,16 @@ void Disassembly::mouseReleaseEvent(QMouseEvent* event)
wAccept = false;
}
}
if((event->button() & Qt::BackButton) != 0)
{
wAccept = true;
historyPrevious();
}
else if((event->button() & Qt::ForwardButton) != 0)
{
wAccept = true;
historyNext();
}
if(wAccept == true)
AbstractTableView::mouseReleaseEvent(event);

View File

@ -446,6 +446,16 @@ void HexDump::mouseReleaseEvent(QMouseEvent* event)
wAccept = false;
}
}
if((event->button() & Qt::BackButton) != 0)
{
wAccept = true;
historyPrev();
}
else if((event->button() & Qt::ForwardButton) != 0)
{
wAccept = true;
historyNext();
}
if(wAccept == true)
AbstractTableView::mouseReleaseEvent(event);

View File

@ -67,7 +67,7 @@ static QString stringFormatInline(const QString & format)
char result[MAX_SETTING_SIZE] = "";
if(DbgFunctions()->StringFormatInline(format.toUtf8().constData(), MAX_SETTING_SIZE, result))
return result;
return "[Formatting Error]";
return CPUArgumentWidget::tr("[Formatting Error]");
}

View File

@ -817,20 +817,7 @@ void CPUDisassembly::toggleFunctionSlot()
duint function_end = 0;
if(!DbgFunctionOverlaps(start, end))
{
QString start_text = QString("%1").arg(start, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString end_text = QString("%1").arg(end, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
char labeltext[MAX_LABEL_SIZE] = "";
QString label_text = "";
if(DbgGetLabelAt(start, SEG_DEFAULT, labeltext))
label_text = " (" + QString(labeltext) + ")";
QMessageBox msg(QMessageBox::Question, tr("Define function?"), start_text + "-" + end_text + label_text, QMessageBox::Yes | QMessageBox::No);
msg.setWindowIcon(DIcon("compile.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
if(msg.exec() != QMessageBox::Yes)
return;
QString cmd = "functionadd " + start_text + "," + end_text;
QString cmd = QString("functionadd ") + ToPtrString(start) + "," + ToPtrString(end);
DbgCmdExec(cmd.toUtf8().constData());
}
else
@ -840,20 +827,7 @@ void CPUDisassembly::toggleFunctionSlot()
if(DbgFunctionGet(i, &function_start, &function_end))
break;
}
QString start_text = QString("%1").arg(function_start, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString end_text = QString("%1").arg(function_end, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
char labeltext[MAX_LABEL_SIZE] = "";
QString label_text = "";
if(DbgGetLabelAt(function_start, SEG_DEFAULT, labeltext))
label_text = " (" + QString(labeltext) + ")";
QMessageBox msg(QMessageBox::Warning, tr("Delete function?"), start_text + "-" + end_text + label_text, QMessageBox::Ok | QMessageBox::Cancel);
msg.setWindowIcon(DIcon("compile-warning.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
if(msg.exec() != QMessageBox::Ok)
return;
QString cmd = "functiondel " + start_text;
QString cmd = QString("functiondel ") + ToPtrString(function_start);
DbgCmdExec(cmd.toUtf8().constData());
}
}
@ -870,17 +844,7 @@ void CPUDisassembly::toggleArgumentSlot()
{
QString start_text = QString("%1").arg(start, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString end_text = QString("%1").arg(end, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
char labeltext[MAX_LABEL_SIZE] = "";
QString label_text = "";
if(DbgGetLabelAt(start, SEG_DEFAULT, labeltext))
label_text = " (" + QString(labeltext) + ")";
QMessageBox msg(QMessageBox::Question, tr("Define argument?"), start_text + "-" + end_text + label_text, QMessageBox::Yes | QMessageBox::No);
msg.setWindowIcon(DIcon("compile.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
if(msg.exec() != QMessageBox::Yes)
return;
QString cmd = "argumentadd " + start_text + "," + end_text;
DbgCmdExec(cmd.toUtf8().constData());
}
@ -892,18 +856,7 @@ void CPUDisassembly::toggleArgumentSlot()
break;
}
QString start_text = QString("%1").arg(argument_start, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString end_text = QString("%1").arg(argument_end, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
char labeltext[MAX_LABEL_SIZE] = "";
QString label_text = "";
if(DbgGetLabelAt(argument_start, SEG_DEFAULT, labeltext))
label_text = " (" + QString(labeltext) + ")";
QMessageBox msg(QMessageBox::Warning, tr("Delete argument?"), start_text + "-" + end_text + label_text, QMessageBox::Ok | QMessageBox::Cancel);
msg.setWindowIcon(DIcon("compile-warning.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
if(msg.exec() != QMessageBox::Ok)
return;
QString cmd = "argumentdel " + start_text;
DbgCmdExec(cmd.toUtf8().constData());
}

View File

@ -168,6 +168,7 @@ void CPUDump::setupContextMenu()
mMenuBuilder->addAction(makeShortcutAction(DIcon("sync.png"), tr("&Sync with expression"), SLOT(syncWithExpressionSlot()), "ActionSyncWithExpression"));
mMenuBuilder->addAction(makeAction(DIcon("animal-dog.png"), ArchValue(tr("Watch DWORD"), tr("Watch QWORD")), SLOT(watchSlot())));
mMenuBuilder->addAction(makeShortcutAction(DIcon("entropy.png"), tr("Entrop&y..."), SLOT(entropySlot()), "ActionEntropy"));
mMenuBuilder->addAction(makeAction(tr("Allocate Memory"), SLOT(allocMemorySlot())));
MenuBuilder* wGotoMenu = new MenuBuilder(this);
wGotoMenu->addAction(makeShortcutAction(DIcon("geolocation-goto.png"), tr("&Expression"), SLOT(gotoExpressionSlot()), "ActionGotoExpression"));
@ -1340,6 +1341,37 @@ void CPUDump::watchSlot()
DbgCmdExec(QString("AddWatch \"[%1]\", \"uint\"").arg(ToPtrString(rvaToVa(getSelectionStart()))).toUtf8().constData());
}
void CPUDump::allocMemorySlot()
{
WordEditDialog mLineEdit(this);
mLineEdit.setup(tr("Size"), 0x1000, sizeof(duint));
if(mLineEdit.exec() == QDialog::Accepted)
{
duint memsize = mLineEdit.getVal();
if(memsize == 0) // 1GB
{
SimpleWarningBox(this, tr("Warning"), tr("You're trying to allocate a zero-sized buffer just now."));
return;
}
if(memsize > 1024 * 1024 * 1024)
{
SimpleErrorBox(this, tr("Error"), tr("The size of buffer you're trying to allocate exceeds 1GB. Please check your expression to ensure nothing is wrong."));
return;
}
DbgCmdExecDirect(QString("alloc %1").arg(ToPtrString(memsize)).toUtf8().constData());
duint addr = DbgValFromString("$result");
if(addr != 0)
{
DbgCmdExec("Dump $result");
}
else
{
SimpleErrorBox(this, tr("Error"), tr("Memory allocation failed!"));
return;
}
}
}
void CPUDump::gotoNextSlot()
{
historyNext();

View File

@ -99,6 +99,7 @@ public slots:
void entropySlot();
void syncWithExpressionSlot();
void followInDumpNSlot();
void allocMemorySlot();
void gotoNextSlot();
void gotoPrevSlot();

View File

@ -178,7 +178,7 @@ void FavouriteTools::on_btnDescriptionFavouriteTool_clicked()
if(!table->rowCount())
return;
QString description = table->item(table->currentRow(), 2)->text();
if(SimpleInputBox(this, tr("Enter the description"), description, description))
if(SimpleInputBox(this, tr("Enter the description"), description, description, tr("This string will appear in the menu.")))
table->item(table->currentRow(), 2)->setText(description);
}
@ -225,7 +225,7 @@ void FavouriteTools::on_btnDescriptionFavouriteScript_clicked()
if(!table->rowCount())
return;
QString description = table->item(table->currentRow(), 2)->text();
if(SimpleInputBox(this, tr("Enter the description"), description, description))
if(SimpleInputBox(this, tr("Enter the description"), description, description, tr("This string will appear in the menu.")))
table->item(table->currentRow(), 2)->setText(description);
}
@ -242,7 +242,7 @@ void FavouriteTools::on_btnDownFavouriteScript_clicked()
void FavouriteTools::on_btnAddFavouriteCommand_clicked()
{
QString cmd;
if(SimpleInputBox(this, tr("Enter the command that you want to create a shortcut for :"), "", cmd))
if(SimpleInputBox(this, tr("Enter the command that you want to create a shortcut for :"), "", cmd, tr("Example: bphws ESP")))
{
int rows = ui->listCommand->rowCount();
ui->listCommand->setRowCount(rows + 1);

View File

@ -40,6 +40,11 @@ void LineEditDialog::setText(const QString & text)
ui->textEdit->selectAll();
}
void LineEditDialog::setPlaceholderText(const QString & text)
{
ui->textEdit->setPlaceholderText(text);
}
void LineEditDialog::enableCheckBox(bool bEnable)
{
if(bEnable)

View File

@ -18,6 +18,7 @@ public:
QString editText;
bool bChecked;
void setText(const QString & text);
void setPlaceholderText(const QString & text);
void enableCheckBox(bool bEnable);
void setCheckBox(bool bSet);
void setCheckBoxText(const QString & text);

View File

@ -80,6 +80,10 @@ void LogView::contextMenuEvent(QContextMenuEvent* event)
else
actionToggleLogging->setText(tr("Enable &Logging"));
wMenu.addAction(actionToggleLogging);
if(logRedirection == NULL)
actionRedirectLog->setText(tr("&Redirect Log..."));
else
actionRedirectLog->setText(tr("Stop &Redirection"));
wMenu.addAction(actionRedirectLog);
wMenu.exec(event->globalPos());
@ -119,22 +123,27 @@ void LogView::clearLogSlot()
void LogView::redirectLogSlot()
{
if(logRedirection != NULL)
fclose(logRedirection);
logRedirection = NULL;
BrowseDialog browse(this, tr("Redirect log to file"), tr("Enter the file to which you want to redirect log messages."), tr("Log files(*.txt);;All files(*.*)"), QCoreApplication::applicationDirPath(), true);
if(browse.exec() == QDialog::Accepted)
{
logRedirection = _wfopen(browse.path.toStdWString().c_str(), L"ab");
if(logRedirection == NULL)
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(browse.path).toUtf8().constData());
else
fclose(logRedirection);
logRedirection = NULL;
}
else
{
BrowseDialog browse(this, tr("Redirect log to file"), tr("Enter the file to which you want to redirect log messages."), tr("Log files(*.txt);;All files(*.*)"), QCoreApplication::applicationDirPath(), true);
if(browse.exec() == QDialog::Accepted)
{
if(ftell(logRedirection) == 0)
logRedirection = _wfopen(browse.path.toStdWString().c_str(), L"ab");
if(logRedirection == NULL)
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(browse.path).toUtf8().constData());
else
{
unsigned short BOM = 0xfeff;
fwrite(&BOM, 2, 1, logRedirection);
if(ftell(logRedirection) == 0)
{
unsigned short BOM = 0xfeff;
fwrite(&BOM, 2, 1, logRedirection);
}
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(browse.path).toUtf8().constData());
}
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(browse.path).toUtf8().constData());
}
}
}

View File

@ -753,20 +753,18 @@ void MainWindow::execTicnd()
{
if(!DbgIsDebugging())
return;
LineEditDialog mLineEdit(this);
mLineEdit.setWindowTitle(tr("Enter trace into finishing condition."));
if(mLineEdit.exec() == QDialog::Accepted)
DbgCmdExec(QString("ticnd \"%1\"").arg(mLineEdit.editText).toUtf8().constData());
QString text;
if(SimpleInputBox(this, tr("Enter trace into finishing condition."), "", text, tr("Example: eax == 0 && ebx == 0")))
DbgCmdExec(QString("ticnd \"%1\"").arg(text).toUtf8().constData());
}
void MainWindow::execTocnd()
{
if(!DbgIsDebugging())
return;
LineEditDialog mLineEdit(this);
mLineEdit.setWindowTitle(tr("Enter trace over finishing condition."));
if(mLineEdit.exec() == QDialog::Accepted)
DbgCmdExec(QString("tocnd \"%1\"").arg(mLineEdit.editText).toUtf8().constData());
QString text;
if(SimpleInputBox(this, tr("Enter trace over finishing condition."), "", text, tr("Example: eax == 0 && ebx == 0")))
DbgCmdExec(QString("tocnd \"%1\"").arg(text).toUtf8().constData());
}
void MainWindow::displayMemMapWidget()

View File

@ -1925,7 +1925,7 @@ void RegistersView::displayEditDialog()
LineEditDialog mLineEdit(this);
mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected)));
mLineEdit.setWindowTitle("Edit FPU register");
mLineEdit.setWindowTitle(tr("Edit FPU register"));
mLineEdit.setWindowIcon(DIcon("log.png"));
mLineEdit.setCursorPosition(0);
mLineEdit.ForceSize(GetSizeRegister(mSelected) * 2);

View File

@ -184,7 +184,7 @@ void WatchView::contextMenuSlot(const QPoint & pos)
void WatchView::addWatchSlot()
{
QString name;
if(SimpleInputBox(this, tr("Enter the expression to watch"), "", name))
if(SimpleInputBox(this, tr("Enter the expression to watch"), "", name, tr("Example: [EAX]")))
DbgCmdExecDirect(QString("AddWatch ").append(name).toUtf8().constData());
updateWatch();
}
@ -198,7 +198,8 @@ void WatchView::delWatchSlot()
void WatchView::renameWatchSlot()
{
QString name;
if(SimpleInputBox(this, tr("Enter the name of the watch variable"), getCellContent(getInitialSelection(), 0), name))
QString originalName = getCellContent(getInitialSelection(), 0);
if(SimpleInputBox(this, tr("Enter the name of the watch variable"), originalName, name, originalName))
DbgCmdExecDirect(QString("SetWatchName ").append(getSelectedId() + "," + name).toUtf8().constData());
updateWatch();
}
@ -206,7 +207,7 @@ void WatchView::renameWatchSlot()
void WatchView::editWatchSlot()
{
QString expr;
if(SimpleInputBox(this, tr("Enter the expression to watch"), "", expr))
if(SimpleInputBox(this, tr("Enter the expression to watch"), "", expr, tr("Example: [EAX]")))
DbgCmdExecDirect(QString("SetWatchExpression ").append(getSelectedId()).append(",").append(expr).toUtf8().constData());
updateWatch();
}

View File

@ -22,11 +22,12 @@ QByteArray & ByteReverse(QByteArray & array)
return array;
}
bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue, QString & output)
bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue, QString & output, const QString & placeholderText)
{
LineEditDialog mEdit(parent);
mEdit.setWindowIcon(parent->windowIcon());
mEdit.setText(defaultValue);
mEdit.setPlaceholderText(placeholderText);
mEdit.setWindowTitle(title);
mEdit.setCheckBox(false);
if(mEdit.exec() == QDialog::Accepted)

View File

@ -8,7 +8,7 @@ class QByteArray;
void SetApplicationIcon(WId winId);
QByteArray & ByteReverse(QByteArray & array);
bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue, QString & output);
bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue, QString & output, const QString & placeholderText);
void SimpleErrorBox(QWidget* parent, const QString & title, const QString & text);
void SimpleWarningBox(QWidget* parent, const QString & title, const QString & text);

View File

@ -314,7 +314,7 @@ FORMS += \
##
## Libraries
##
LIBS += -luser32
LIBS += -luser32 -ladvapi32
!contains(QMAKE_HOST.arch, x86_64) {
# Windows x86 (32bit) specific build