Added find pattern functionality to Qt hex editor.

This commit is contained in:
mjbudd77 2020-11-16 23:35:33 -05:00
parent 4968e50202
commit 7127b858e1
2 changed files with 273 additions and 9 deletions

View File

@ -14,6 +14,7 @@
#include <QColorDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QPushButton>
#include "../../types.h"
#include "../../fceu.h"
@ -535,6 +536,143 @@ void HexBookMarkMenuAction::activateCB(void)
qedit->setAddr( bm->addr );
}
//----------------------------------------------------------------------------
HexEditorFindDialog_t::HexEditorFindDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout, *vbox;
QHBoxLayout *hbox;
QPushButton *nextBtn;
QGroupBox *dirGroup, *typeGroup;
QDialog::setWindowTitle( tr("Find") );
this->parent = (HexEditorDialog_t*)parent;
mainLayout = new QVBoxLayout();
hbox = new QHBoxLayout();
searchBox = new QLineEdit();
nextBtn = new QPushButton( tr("Find Next") );
dirGroup = new QGroupBox( tr("Direction") );
typeGroup = new QGroupBox( tr("Type") );
hbox->addWidget( new QLabel( tr("Find What:") ) );
hbox->addWidget( searchBox );
hbox->addWidget( nextBtn );
mainLayout->addLayout( hbox );
hbox = new QHBoxLayout();
hbox->addWidget( dirGroup );
hbox->addWidget( typeGroup );
mainLayout->addLayout( hbox );
vbox = new QVBoxLayout();
upBtn = new QRadioButton( tr("Up") );
dnBtn = new QRadioButton( tr("Down") );
dnBtn->setChecked(true);
vbox->addWidget( upBtn );
vbox->addWidget( dnBtn );
dirGroup->setLayout( vbox );
vbox = new QVBoxLayout();
hexBtn = new QRadioButton( tr("Hex") );
txtBtn = new QRadioButton( tr("Text") );
vbox->addWidget( hexBtn );
vbox->addWidget( txtBtn );
hexBtn->setChecked(true);
typeGroup->setLayout( vbox );
setLayout( mainLayout );
connect( nextBtn, SIGNAL(clicked(void)), this, SLOT(runSearch(void)) );
}
//----------------------------------------------------------------------------
HexEditorFindDialog_t::~HexEditorFindDialog_t(void)
{
parent->findDialog = NULL;
}
//----------------------------------------------------------------------------
void HexEditorFindDialog_t::closeEvent(QCloseEvent *event)
{
printf("Hex Editor Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void HexEditorFindDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void HexEditorFindDialog_t::runSearch(void)
{
int i=0;
unsigned char v;
std::string s = searchBox->text().toStdString();
std::vector <unsigned char> varray;
if ( s.size() == 0 )
{
return;
}
//printf("Run Search: '%s'\n", s.c_str() );
if ( hexBtn->isChecked() )
{
i=0;
while ( s[i] != 0 )
{
while ( isspace(s[i]) ) i++;
v = 0;
if ( isxdigit(s[i]) )
{
v = convFromXchar(s[i]) << 4; i++;
}
else
{
return;
}
if ( isxdigit(s[i]) )
{
v |= convFromXchar(s[i]); i++;
}
else
{
return;
}
varray.push_back(v);
while ( isspace(s[i]) ) i++;
}
}
else
{
i=0;
while ( s[i] != 0 )
{
v = s[i];
varray.push_back(v);
i++;
}
}
fceuWrapperLock();
parent->editor->findPattern( varray, upBtn->isChecked() );
fceuWrapperUnLock();
}
//----------------------------------------------------------------------------
HexEditorDialog_t::HexEditorDialog_t(QWidget *parent)
: QDialog( parent, Qt::Window )
{
@ -631,7 +769,7 @@ HexEditorDialog_t::HexEditorDialog_t(QWidget *parent)
act = new QAction(tr("Find"), this);
act->setShortcut(QKeySequence(tr("Ctrl+F")));
act->setStatusTip(tr("Find"));
//connect(act, SIGNAL(triggered()), this, SLOT(saveRomFile(void)) );
connect(act, SIGNAL(triggered()), this, SLOT(openFindDialog(void)) );
editMenu->addAction(act);
@ -756,6 +894,8 @@ HexEditorDialog_t::HexEditorDialog_t(QWidget *parent)
connect( hbar, SIGNAL(valueChanged(int)), this, SLOT(hbarChanged(int)) );
connect( vbar, SIGNAL(valueChanged(int)), this, SLOT(vbarChanged(int)) );
findDialog = NULL;
editor->memModeUpdate();
periodicTimer = new QTimer( this );
@ -868,16 +1008,16 @@ void HexEditorDialog_t::populateBookmarkMenu(void)
//----------------------------------------------------------------------------
void HexEditorDialog_t::closeEvent(QCloseEvent *event)
{
printf("Hex Editor Close Window Event\n");
done(0);
printf("Hex Editor Close Window Event\n");
done(0);
deleteLater();
event->accept();
event->accept();
}
//----------------------------------------------------------------------------
void HexEditorDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
@ -1207,6 +1347,16 @@ void HexEditorDialog_t::updatePeriodic(void)
}
}
//----------------------------------------------------------------------------
void HexEditorDialog_t::openFindDialog(void)
{
if ( findDialog == NULL )
{
findDialog = new HexEditorFindDialog_t(this);
findDialog->show();
}
}
//----------------------------------------------------------------------------
void HexEditorDialog_t::openGotoAddrDialog(void)
{
editor->openGotoAddrDialog();
@ -1319,8 +1469,10 @@ QHexEdit::QHexEdit(QWidget *parent)
txtHlgtAnchorLine = -1;
txtHlgtStartChar = -1;
txtHlgtStartLine = -1;
txtHlgtStartAddr = -1;
txtHlgtEndChar = -1;
txtHlgtEndLine = -1;
txtHlgtEndAddr = -1;
clipboard = QGuiApplication::clipboard();
}
@ -1574,7 +1726,7 @@ void QHexEdit::loadHighlightToClipboard(void)
for (a=startAddr; a<=endAddr; a++)
{
sprintf( c, "%02X ", GetMem(a) );
sprintf( c, "%02X ", memAccessFunc(a) );
s.append(c);
}
@ -1583,6 +1735,80 @@ void QHexEdit::loadHighlightToClipboard(void)
loadClipboard( s.c_str() );
}
//----------------------------------------------------------------------------
int QHexEdit::findPattern( std::vector <unsigned char> &varray, int dir )
{
int addr, inc, match;
inc = dir ? -1 : 1;
addr = cursorAddr;
match = 0;
//printf("Looking for pattern %zi\n", varray.size() );
while ( !match )
{
addr = (addr + inc);
if ( addr < 0 )
{
addr = mb.size() - 1;
}
else if ( addr >= mb.size() )
{
addr = 0;
}
if ( addr == cursorAddr )
{
return -1;
}
match = 1;
for (int i=0; i<varray.size(); i++)
{
if ( (addr+i) >= mb.size() )
{
match = 0; break;
}
if ( memAccessFunc(addr+i) != varray[i] )
{
match = 0; break;
}
}
}
if ( match )
{
int endAddr = addr + varray.size() - 1;
//printf("Found Match at $%04X\n", addr );
txtHlgtStartChar = (addr%16);
txtHlgtStartLine = (addr/16);
txtHlgtStartAddr = addr;
txtHlgtEndChar = (endAddr%16);
txtHlgtEndLine = (endAddr/16);
txtHlgtEndAddr = (endAddr);
cursorAddr = addr;
cursorPosX = txtHlgtStartChar*2;
if ( txtHlgtStartLine < lineOffset )
{
lineOffset = txtHlgtStartLine;
vbar->setValue( lineOffset );
}
else if ( txtHlgtStartLine >= (lineOffset+viewLines-3) )
{
lineOffset = txtHlgtStartLine - viewLines + 3;
if ( lineOffset >= maxLineOffset )
{
lineOffset = maxLineOffset;
}
vbar->setValue( lineOffset );
}
cursorPosY = txtHlgtStartLine - lineOffset;
}
return 0;
}
//----------------------------------------------------------------------------
QPoint QHexEdit::convPixToCursor( QPoint p )
{
QPoint c(0,0);
@ -1957,6 +2183,9 @@ void QHexEdit::setHighlightEndCoord( int x, int y )
txtHlgtEndChar = txtHlgtAnchorChar;
}
}
txtHlgtStartAddr = (txtHlgtStartLine*16) + txtHlgtStartChar;
txtHlgtEndAddr = (txtHlgtEndLine *16) + txtHlgtEndChar;
//printf(" (%i,%i) -> (%i,%i) \n", txtHlgtStartChar, txtHlgtStartLine, txtHlgtEndChar, txtHlgtEndLine );
return;
}
@ -2588,6 +2817,12 @@ int QHexEdit::getRomAddrColor( int addr, QColor &fg, QColor &bg )
{
return -1;
}
if ( (txtHlgtStartAddr != txtHlgtEndAddr) && (addr >= txtHlgtStartAddr) && (addr <= txtHlgtEndAddr) )
{
fg = QColor("white");
bg = QColor("blue");
return 0;
}
if (cdloggerdataSize == 0)
{
return -1;

View File

@ -14,7 +14,9 @@
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QLineEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QLabel>
#include <QMenu>
#include <QFrame>
@ -119,6 +121,7 @@ class QHexEdit : public QWidget
int FreezeRam( const char *name, uint32_t a, uint8_t v, int c, int s, int type );
void loadHighlightToClipboard(void);
void pasteFromClipboard(void);
int findPattern( std::vector <unsigned char> &varray, int dir );
enum {
MODE_NES_RAM = 0,
@ -199,8 +202,10 @@ class QHexEdit : public QWidget
int txtHlgtAnchorLine;
int txtHlgtStartChar;
int txtHlgtStartLine;
int txtHlgtStartAddr;
int txtHlgtEndChar;
int txtHlgtEndLine;
int txtHlgtEndAddr;
bool cursorBlink;
bool reverseVideo;
@ -223,6 +228,28 @@ class QHexEdit : public QWidget
};
class HexEditorFindDialog_t : public QDialog
{
Q_OBJECT
public:
HexEditorFindDialog_t(QWidget *parent = 0);
~HexEditorFindDialog_t(void);
QLineEdit *searchBox;
QRadioButton *upBtn;
QRadioButton *dnBtn;
QRadioButton *hexBtn;
QRadioButton *txtBtn;
protected:
void closeEvent(QCloseEvent *bar);
HexEditorDialog_t *parent;
public slots:
void closeWindow(void);
void runSearch(void);
};
class HexEditorDialog_t : public QDialog
{
Q_OBJECT
@ -237,8 +264,9 @@ class HexEditorDialog_t : public QDialog
void openDebugSymbolEditWindow( int addr );
QHexEdit *editor;
protected:
HexEditorFindDialog_t *findDialog;
protected:
void closeEvent(QCloseEvent *bar);
QScrollBar *vbar;
@ -254,7 +282,7 @@ class HexEditorDialog_t : public QDialog
private:
public slots:
public slots:
void closeWindow(void);
private slots:
void updatePeriodic(void);
@ -275,6 +303,7 @@ class HexEditorDialog_t : public QDialog
void openGotoAddrDialog(void);
void copyToClipboard(void);
void pasteFromClipboard(void);
void openFindDialog(void);
};
int hexEditorNumWindows(void);