forked from qt-creator/qt-creator
bineditor: make all "lazy"
This commit is contained in:
@@ -89,7 +89,6 @@ BinEditor::BinEditor(QWidget *parent)
|
|||||||
: QAbstractScrollArea(parent)
|
: QAbstractScrollArea(parent)
|
||||||
{
|
{
|
||||||
m_ieditor = 0;
|
m_ieditor = 0;
|
||||||
m_inLazyMode = false;
|
|
||||||
m_baseAddr = 0;
|
m_baseAddr = 0;
|
||||||
m_blockSize = 4096;
|
m_blockSize = 4096;
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
@@ -161,39 +160,35 @@ void BinEditor::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BinEditor::addLazyData(quint64 block, const QByteArray &data)
|
void BinEditor::addData(quint64 block, const QByteArray &data)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_inLazyMode);
|
|
||||||
Q_ASSERT(data.size() == m_blockSize);
|
Q_ASSERT(data.size() == m_blockSize);
|
||||||
const quint64 addr = block * m_blockSize;
|
const quint64 addr = block * m_blockSize;
|
||||||
if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) {
|
if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) {
|
||||||
if (m_lazyData.size() * m_blockSize >= 64 * 1024 * 1024)
|
if (m_data.size() * m_blockSize >= 64 * 1024 * 1024)
|
||||||
m_lazyData.clear();
|
m_data.clear();
|
||||||
const int translatedBlock = (addr - m_baseAddr) / m_blockSize;
|
const int translatedBlock = (addr - m_baseAddr) / m_blockSize;
|
||||||
m_lazyData.insert(translatedBlock, data);
|
m_data.insert(translatedBlock, data);
|
||||||
m_lazyRequests.remove(translatedBlock);
|
m_requests.remove(translatedBlock);
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
int block = pos / m_blockSize;
|
int block = pos / m_blockSize;
|
||||||
QMap<int, QByteArray>::const_iterator it = m_modifiedData.find(block);
|
BlockMap::const_iterator it = m_modifiedData.find(block);
|
||||||
if (it != m_modifiedData.constEnd())
|
if (it != m_modifiedData.constEnd())
|
||||||
return true;
|
return true;
|
||||||
it = m_lazyData.find(block);
|
it = m_data.find(block);
|
||||||
if (it != m_lazyData.end())
|
if (it != m_data.end())
|
||||||
return true;
|
return true;
|
||||||
if (!m_lazyRequests.contains(block)) {
|
if (!m_requests.contains(block)) {
|
||||||
m_lazyRequests.insert(block);
|
m_requests.insert(block);
|
||||||
emit const_cast<BinEditor*>(this)->
|
emit const_cast<BinEditor*>(this)->
|
||||||
lazyDataRequested(editorInterface(), m_baseAddr / m_blockSize + block,
|
dataRequested(editor(), m_baseAddr / m_blockSize + block,
|
||||||
synchronous);
|
synchronous);
|
||||||
if (!m_lazyRequests.contains(block))
|
if (!m_requests.contains(block))
|
||||||
return true; // synchronous data source
|
return true; // synchronous data source
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -201,34 +196,26 @@ bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
|||||||
|
|
||||||
bool BinEditor::requestOldDataAt(int pos) const
|
bool BinEditor::requestOldDataAt(int pos) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode)
|
|
||||||
return false;
|
|
||||||
int block = pos / m_blockSize;
|
int block = pos / m_blockSize;
|
||||||
QMap<int, QByteArray>::const_iterator it = m_oldLazyData.find(block);
|
BlockMap::const_iterator it = m_oldData.find(block);
|
||||||
return it != m_oldLazyData.end();
|
return it != m_oldData.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
char BinEditor::dataAt(int pos, bool old) const
|
char BinEditor::dataAt(int pos, bool old) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode)
|
|
||||||
return m_data.at(pos);
|
|
||||||
int block = pos / m_blockSize;
|
int block = pos / m_blockSize;
|
||||||
return blockData(block, old).at(pos - (block*m_blockSize));
|
return blockData(block, old).at(pos - (block*m_blockSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::changeDataAt(int pos, char c)
|
void BinEditor::changeDataAt(int pos, char c)
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode) {
|
|
||||||
m_data[pos] = c;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int block = pos / m_blockSize;
|
int block = pos / m_blockSize;
|
||||||
QMap<int, QByteArray>::iterator it = m_modifiedData.find(block);
|
BlockMap::iterator it = m_modifiedData.find(block);
|
||||||
if (it != m_modifiedData.end()) {
|
if (it != m_modifiedData.end()) {
|
||||||
it.value()[pos - (block*m_blockSize)] = c;
|
it.value()[pos - (block*m_blockSize)] = c;
|
||||||
} else {
|
} else {
|
||||||
it = m_lazyData.find(block);
|
it = m_data.find(block);
|
||||||
if (it != m_lazyData.end()) {
|
if (it != m_data.end()) {
|
||||||
QByteArray data = it.value();
|
QByteArray data = it.value();
|
||||||
data[pos - (block*m_blockSize)] = c;
|
data[pos - (block*m_blockSize)] = c;
|
||||||
m_modifiedData.insert(block, data);
|
m_modifiedData.insert(block, data);
|
||||||
@@ -238,9 +225,6 @@ void BinEditor::changeDataAt(int pos, char c)
|
|||||||
|
|
||||||
QByteArray BinEditor::dataMid(int from, int length, bool old) const
|
QByteArray BinEditor::dataMid(int from, int length, bool old) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode)
|
|
||||||
return m_data.mid(from, length);
|
|
||||||
|
|
||||||
int end = from + length;
|
int end = from + length;
|
||||||
int block = from / m_blockSize;
|
int block = from / m_blockSize;
|
||||||
|
|
||||||
@@ -256,19 +240,13 @@ QByteArray BinEditor::dataMid(int from, int length, bool old) const
|
|||||||
QByteArray BinEditor::blockData(int block, bool old) const
|
QByteArray BinEditor::blockData(int block, bool old) const
|
||||||
{
|
{
|
||||||
if (old) {
|
if (old) {
|
||||||
QMap<int, QByteArray>::const_iterator it = m_modifiedData.find(block);
|
BlockMap::const_iterator it = m_modifiedData.find(block);
|
||||||
return it != m_modifiedData.constEnd()
|
return it != m_modifiedData.constEnd()
|
||||||
? it.value() : m_oldLazyData.value(block, m_emptyBlock);
|
? it.value() : m_oldData.value(block, m_emptyBlock);
|
||||||
}
|
}
|
||||||
if (!m_inLazyMode) {
|
BlockMap::const_iterator it = m_modifiedData.find(block);
|
||||||
QByteArray data = m_data.mid(block * m_blockSize, m_blockSize);
|
|
||||||
if (data.size() < m_blockSize)
|
|
||||||
data.resize(m_blockSize);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
QMap<int, QByteArray>::const_iterator it = m_modifiedData.find(block);
|
|
||||||
return it != m_modifiedData.constEnd()
|
return it != m_modifiedData.constEnd()
|
||||||
? it.value() : m_lazyData.value(block, m_emptyBlock);
|
? it.value() : m_data.value(block, m_emptyBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::setFontSettings(const TextEditor::FontSettings &fs)
|
void BinEditor::setFontSettings(const TextEditor::FontSettings &fs)
|
||||||
@@ -358,100 +336,63 @@ bool BinEditor::isReadOnly() const
|
|||||||
return m_readOnly;
|
return m_readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::setData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
m_inLazyMode = false;
|
|
||||||
m_baseAddr = 0;
|
|
||||||
m_lazyData.clear();
|
|
||||||
m_oldLazyData.clear();
|
|
||||||
m_modifiedData.clear();
|
|
||||||
m_lazyRequests.clear();
|
|
||||||
m_data = data;
|
|
||||||
m_size = data.size();
|
|
||||||
m_addressBytes = 4;
|
|
||||||
|
|
||||||
m_unmodifiedState = 0;
|
|
||||||
m_undoStack.clear();
|
|
||||||
m_redoStack.clear();
|
|
||||||
|
|
||||||
init();
|
|
||||||
m_cursorPosition = 0;
|
|
||||||
verticalScrollBar()->setValue(0);
|
|
||||||
|
|
||||||
emit cursorPositionChanged(m_cursorPosition);
|
|
||||||
viewport()->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray BinEditor::data() const
|
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BinEditor::save(const QString &oldFileName, const QString &newFileName)
|
bool BinEditor::save(const QString &oldFileName, const QString &newFileName)
|
||||||
{
|
{
|
||||||
if (m_inLazyMode) {
|
if (oldFileName != newFileName) {
|
||||||
if (oldFileName != newFileName) {
|
QString tmpName;
|
||||||
QString tmpName;
|
{
|
||||||
{
|
QTemporaryFile tmp;
|
||||||
QTemporaryFile tmp;
|
if (!tmp.open())
|
||||||
if (!tmp.open())
|
|
||||||
return false;
|
|
||||||
tmpName = tmp.fileName();
|
|
||||||
}
|
|
||||||
if (!QFile::copy(oldFileName, tmpName))
|
|
||||||
return false;
|
|
||||||
if (QFile::exists(newFileName) && !QFile::remove(newFileName))
|
|
||||||
return false;
|
|
||||||
if (!QFile::rename(tmpName, newFileName))
|
|
||||||
return false;
|
return false;
|
||||||
|
tmpName = tmp.fileName();
|
||||||
}
|
}
|
||||||
QFile output(newFileName);
|
if (!QFile::copy(oldFileName, tmpName))
|
||||||
if (!output.open(QIODevice::ReadWrite)) // QtBug: WriteOnly truncates.
|
|
||||||
return false;
|
return false;
|
||||||
const qint64 size = output.size();
|
if (QFile::exists(newFileName) && !QFile::remove(newFileName))
|
||||||
for (QMap<int, QByteArray>::const_iterator it = m_modifiedData.constBegin();
|
|
||||||
it != m_modifiedData.constEnd(); ++it) {
|
|
||||||
if (!output.seek(it.key() * m_blockSize))
|
|
||||||
return false;
|
|
||||||
if (output.write(it.value()) < m_blockSize)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We may have padded the displayed data, so we have to make sure
|
|
||||||
// changes to that area are not actually written back to disk.
|
|
||||||
if (!output.resize(size))
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
if (!QFile::rename(tmpName, newFileName))
|
||||||
QFile output(newFileName);
|
|
||||||
if (!output.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
|
||||||
return false;
|
|
||||||
if (output.write(m_data) < m_size)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
QFile output(newFileName);
|
||||||
|
if (!output.open(QIODevice::ReadWrite)) // QtBug: WriteOnly truncates.
|
||||||
|
return false;
|
||||||
|
const qint64 size = output.size();
|
||||||
|
for (BlockMap::const_iterator it = m_modifiedData.constBegin();
|
||||||
|
it != m_modifiedData.constEnd(); ++it) {
|
||||||
|
if (!output.seek(it.key() * m_blockSize))
|
||||||
|
return false;
|
||||||
|
if (output.write(it.value()) < m_blockSize)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We may have padded the displayed data, so we have to make sure
|
||||||
|
// changes to that area are not actually written back to disk.
|
||||||
|
if (!output.resize(size))
|
||||||
|
return false;
|
||||||
|
|
||||||
setModified(false);
|
setModified(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::setLazyData(quint64 startAddr, int range, int blockSize)
|
void BinEditor::setSizes(quint64 startAddr, int range, bool fixedSize, int blockSize)
|
||||||
{
|
{
|
||||||
m_inLazyMode = true;
|
|
||||||
m_blockSize = blockSize;
|
m_blockSize = blockSize;
|
||||||
|
m_fixedSize = fixedSize;
|
||||||
Q_ASSERT((blockSize/16) * 16 == blockSize);
|
Q_ASSERT((blockSize/16) * 16 == blockSize);
|
||||||
m_emptyBlock = QByteArray(blockSize, '\0');
|
m_emptyBlock = QByteArray(blockSize, '\0');
|
||||||
m_data.clear();
|
|
||||||
m_modifiedData.clear();
|
m_modifiedData.clear();
|
||||||
m_lazyRequests.clear();
|
m_requests.clear();
|
||||||
|
|
||||||
// In lazy mode, users can edit data in the range
|
// Users can edit data in the range
|
||||||
// [startAddr - range/2, startAddr + range/2].
|
// [startAddr - range/2, startAddr + range/2].
|
||||||
m_baseAddr = static_cast<quint64>(range/2) > startAddr
|
m_baseAddr = quint64(range/2) > startAddr ? 0 : startAddr - range/2;
|
||||||
? 0 : startAddr - range/2;
|
|
||||||
m_baseAddr = (m_baseAddr / blockSize) * blockSize;
|
m_baseAddr = (m_baseAddr / blockSize) * blockSize;
|
||||||
|
|
||||||
const quint64 maxRange = Q_UINT64_C(0xffffffffffffffff) - m_baseAddr + 1;
|
const quint64 maxRange = Q_UINT64_C(0xffffffffffffffff) - m_baseAddr + 1;
|
||||||
m_size = m_baseAddr != 0 && static_cast<quint64>(range) >= maxRange
|
m_size = m_baseAddr != 0 && quint64(range) >= maxRange
|
||||||
? maxRange : range;
|
? maxRange : range;
|
||||||
m_addressBytes = (m_baseAddr + m_size < quint64(1) << 32
|
m_addressBytes = (m_baseAddr + m_size < quint64(1) << 32
|
||||||
&& m_baseAddr + m_size >= m_baseAddr) ? 4 : 8;
|
&& m_baseAddr + m_size >= m_baseAddr) ? 4 : 8;
|
||||||
|
|
||||||
m_unmodifiedState = 0;
|
m_unmodifiedState = 0;
|
||||||
m_undoStack.clear();
|
m_undoStack.clear();
|
||||||
@@ -471,15 +412,12 @@ void BinEditor::resizeEvent(QResizeEvent *)
|
|||||||
void BinEditor::scrollContentsBy(int dx, int dy)
|
void BinEditor::scrollContentsBy(int dx, int dy)
|
||||||
{
|
{
|
||||||
viewport()->scroll(isRightToLeft() ? -dx : dx, dy * m_lineHeight);
|
viewport()->scroll(isRightToLeft() ? -dx : dx, dy * m_lineHeight);
|
||||||
if (m_inLazyMode) {
|
const QScrollBar * const scrollBar = verticalScrollBar();
|
||||||
const QScrollBar * const scrollBar = verticalScrollBar();
|
const int scrollPos = scrollBar->value();
|
||||||
const int scrollPos = scrollBar->value();
|
if (dy <= 0 && scrollPos == scrollBar->maximum())
|
||||||
if (dy <= 0 && scrollPos == scrollBar->maximum())
|
emit newRangeRequested(editor(), baseAddress() + m_size);
|
||||||
emit newRangeRequested(editorInterface(),
|
else if (dy >= 0 && scrollPos == scrollBar->minimum())
|
||||||
baseAddress() + dataSize());
|
emit newRangeRequested(editor(), baseAddress());
|
||||||
else if (dy >= 0 && scrollPos == scrollBar->minimum())
|
|
||||||
emit newRangeRequested(editorInterface(), baseAddress());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::changeEvent(QEvent *e)
|
void BinEditor::changeEvent(QEvent *e)
|
||||||
@@ -576,10 +514,6 @@ void BinEditor::updateLines(int fromPosition, int toPosition)
|
|||||||
|
|
||||||
int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const
|
int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode && caseSensitive) {
|
|
||||||
return m_data.indexOf(pattern, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
int trailing = pattern.size();
|
int trailing = pattern.size();
|
||||||
if (trailing > m_blockSize)
|
if (trailing > m_blockSize)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -613,9 +547,6 @@ int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensiti
|
|||||||
|
|
||||||
int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const
|
int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const
|
||||||
{
|
{
|
||||||
if (!m_inLazyMode && caseSensitive)
|
|
||||||
return m_data.lastIndexOf(pattern, from);
|
|
||||||
|
|
||||||
int trailing = pattern.size();
|
int trailing = pattern.size();
|
||||||
if (trailing > m_blockSize)
|
if (trailing > m_blockSize)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1058,10 +989,28 @@ void BinEditor::selectAll()
|
|||||||
|
|
||||||
void BinEditor::clear()
|
void BinEditor::clear()
|
||||||
{
|
{
|
||||||
setData(QByteArray());
|
m_baseAddr = 0;
|
||||||
|
m_data.clear();
|
||||||
|
m_oldData.clear();
|
||||||
|
m_modifiedData.clear();
|
||||||
|
m_requests.clear();
|
||||||
|
m_size = 0;
|
||||||
|
m_addressBytes = 4;
|
||||||
|
|
||||||
|
m_unmodifiedState = 0;
|
||||||
|
m_undoStack.clear();
|
||||||
|
m_redoStack.clear();
|
||||||
|
|
||||||
|
init();
|
||||||
|
m_cursorPosition = 0;
|
||||||
|
verticalScrollBar()->setValue(0);
|
||||||
|
|
||||||
|
emit cursorPositionChanged(m_cursorPosition);
|
||||||
|
viewport()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinEditor::event(QEvent *e) {
|
bool BinEditor::event(QEvent *e)
|
||||||
|
{
|
||||||
if (e->type() == QEvent::KeyPress) {
|
if (e->type() == QEvent::KeyPress) {
|
||||||
switch (static_cast<QKeyEvent*>(e)->key()) {
|
switch (static_cast<QKeyEvent*>(e)->key()) {
|
||||||
case Qt::Key_Tab:
|
case Qt::Key_Tab:
|
||||||
@@ -1071,16 +1020,14 @@ bool BinEditor::event(QEvent *e) {
|
|||||||
ensureCursorVisible();
|
ensureCursorVisible();
|
||||||
e->accept();
|
e->accept();
|
||||||
return true;
|
return true;
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down: {
|
||||||
if (m_inLazyMode) {
|
const QScrollBar * const scrollBar = verticalScrollBar();
|
||||||
const QScrollBar * const scrollBar = verticalScrollBar();
|
if (scrollBar->value() >= scrollBar->maximum() - 1) {
|
||||||
if (scrollBar->value() >= scrollBar->maximum() - 1) {
|
emit newRangeRequested(editor(), baseAddress() + m_size);
|
||||||
emit newRangeRequested(editorInterface(),
|
return true;
|
||||||
baseAddress() + dataSize());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
} else if (e->type() == QEvent::ToolTip) {
|
} else if (e->type() == QEvent::ToolTip) {
|
||||||
@@ -1220,20 +1167,14 @@ void BinEditor::keyPressEvent(QKeyEvent *e)
|
|||||||
|
|
||||||
case Qt::Key_Home:
|
case Qt::Key_Home:
|
||||||
if (e->modifiers() & Qt::ControlModifier) {
|
if (e->modifiers() & Qt::ControlModifier) {
|
||||||
if (m_inLazyMode)
|
emit startOfFileRequested(editor());
|
||||||
emit startOfFileRequested(editorInterface());
|
|
||||||
else
|
|
||||||
setCursorPosition(0);
|
|
||||||
} else {
|
} else {
|
||||||
setCursorPosition(m_cursorPosition/16 * 16, moveMode);
|
setCursorPosition(m_cursorPosition/16 * 16, moveMode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_End:
|
case Qt::Key_End:
|
||||||
if (e->modifiers() & Qt::ControlModifier) {
|
if (e->modifiers() & Qt::ControlModifier) {
|
||||||
if (m_inLazyMode)
|
emit endOfFileRequested(editor());
|
||||||
emit endOfFileRequested(editorInterface());
|
|
||||||
else
|
|
||||||
setCursorPosition(m_size - 1);
|
|
||||||
} else {
|
} else {
|
||||||
setCursorPosition(m_cursorPosition/16 * 16 + 15, moveMode);
|
setCursorPosition(m_cursorPosition/16 * 16 + 15, moveMode);
|
||||||
}
|
}
|
||||||
@@ -1474,10 +1415,10 @@ void BinEditor::setupJumpToMenuAction(QMenu *menu, QAction *actionHere,
|
|||||||
|
|
||||||
void BinEditor::jumpToAddress(quint64 address)
|
void BinEditor::jumpToAddress(quint64 address)
|
||||||
{
|
{
|
||||||
if (address >= m_baseAddr && address < m_baseAddr + m_data.size())
|
if (address >= m_baseAddr && address < m_baseAddr + m_size)
|
||||||
setCursorPosition(address - m_baseAddr);
|
setCursorPosition(address - m_baseAddr);
|
||||||
else if (m_inLazyMode)
|
else
|
||||||
emit newRangeRequested(editorInterface(), address);
|
emit newRangeRequested(editor(), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::setNewWindowRequestAllowed()
|
void BinEditor::setNewWindowRequestAllowed()
|
||||||
@@ -1487,9 +1428,9 @@ void BinEditor::setNewWindowRequestAllowed()
|
|||||||
|
|
||||||
void BinEditor::updateContents()
|
void BinEditor::updateContents()
|
||||||
{
|
{
|
||||||
m_oldLazyData = m_lazyData;
|
m_oldData = m_data;
|
||||||
m_lazyData.clear();
|
m_data.clear();
|
||||||
setLazyData(baseAddress() + cursorPosition(), dataSize(), m_blockSize);
|
setSizes(baseAddress() + cursorPosition(), m_size, m_blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint BinEditor::offsetToPos(int offset)
|
QPoint BinEditor::offsetToPos(int offset)
|
||||||
@@ -1504,7 +1445,7 @@ void BinEditor::asIntegers(int offset, int count, quint64 &beValue,
|
|||||||
{
|
{
|
||||||
beValue = leValue = 0;
|
beValue = leValue = 0;
|
||||||
const QByteArray &data = dataMid(offset, count, old);
|
const QByteArray &data = dataMid(offset, count, old);
|
||||||
for (int pos = 0; pos < count; ++pos) {
|
for (int pos = 0; pos < data.size(); ++pos) {
|
||||||
const quint64 val = static_cast<quint64>(data.at(pos)) & 0xff;
|
const quint64 val = static_cast<quint64>(data.at(pos)) & 0xff;
|
||||||
beValue += val << (pos * 8);
|
beValue += val << (pos * 8);
|
||||||
leValue += val << ((count - pos - 1) * 8);
|
leValue += val << ((count - pos - 1) * 8);
|
||||||
|
@@ -66,16 +66,11 @@ public:
|
|||||||
BinEditor(QWidget *parent = 0);
|
BinEditor(QWidget *parent = 0);
|
||||||
~BinEditor();
|
~BinEditor();
|
||||||
|
|
||||||
void setData(const QByteArray &data);
|
|
||||||
QByteArray data() const;
|
|
||||||
|
|
||||||
inline int dataSize() const { return m_size; }
|
|
||||||
quint64 baseAddress() const { return m_baseAddr; }
|
quint64 baseAddress() const { return m_baseAddr; }
|
||||||
|
|
||||||
inline bool inLazyMode() const { return m_inLazyMode; }
|
Q_INVOKABLE void setSizes(quint64 startAddr, int range, bool fixedSize, int blockSize = 4096);
|
||||||
Q_INVOKABLE void setLazyData(quint64 startAddr, int range, int blockSize = 4096);
|
int dataBlockSize() const { return m_blockSize; }
|
||||||
inline int lazyDataBlockSize() const { return m_blockSize; }
|
Q_INVOKABLE void addData(quint64 block, const QByteArray &data);
|
||||||
Q_INVOKABLE void addLazyData(quint64 block, const QByteArray &data);
|
|
||||||
Q_INVOKABLE void setNewWindowRequestAllowed();
|
Q_INVOKABLE void setNewWindowRequestAllowed();
|
||||||
Q_INVOKABLE void updateContents();
|
Q_INVOKABLE void updateContents();
|
||||||
bool save(const QString &oldFileName, const QString &newFileName);
|
bool save(const QString &oldFileName, const QString &newFileName);
|
||||||
@@ -107,8 +102,8 @@ public:
|
|||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
|
|
||||||
Core::IEditor *editorInterface() const { return m_ieditor; }
|
Core::IEditor *editor() const { return m_ieditor; }
|
||||||
void setEditorInterface(Core::IEditor *ieditor) { m_ieditor = ieditor; }
|
void setEditor(Core::IEditor *ieditor) { m_ieditor = ieditor; }
|
||||||
|
|
||||||
bool hasSelection() const { return m_cursorPosition != m_anchorPosition; }
|
bool hasSelection() const { return m_cursorPosition != m_anchorPosition; }
|
||||||
int selectionStart() const { return qMin(m_anchorPosition, m_cursorPosition); }
|
int selectionStart() const { return qMin(m_anchorPosition, m_cursorPosition); }
|
||||||
@@ -136,7 +131,7 @@ Q_SIGNALS:
|
|||||||
void copyAvailable(bool);
|
void copyAvailable(bool);
|
||||||
void cursorPositionChanged(int position);
|
void cursorPositionChanged(int position);
|
||||||
|
|
||||||
void lazyDataRequested(Core::IEditor *editor, quint64 block, bool synchronous);
|
void dataRequested(Core::IEditor *editor, quint64 block, bool synchronous);
|
||||||
void newWindowRequested(quint64 address);
|
void newWindowRequested(quint64 address);
|
||||||
void newRangeRequested(Core::IEditor *, quint64 address);
|
void newRangeRequested(Core::IEditor *, quint64 address);
|
||||||
void startOfFileRequested(Core::IEditor *);
|
void startOfFileRequested(Core::IEditor *);
|
||||||
@@ -158,13 +153,12 @@ protected:
|
|||||||
void contextMenuEvent(QContextMenuEvent *event);
|
void contextMenuEvent(QContextMenuEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_inLazyMode;
|
typedef QMap<int, QByteArray> BlockMap;
|
||||||
QByteArray m_data;
|
BlockMap m_data;
|
||||||
QMap<int, QByteArray> m_lazyData;
|
BlockMap m_oldData;
|
||||||
QMap<int, QByteArray> m_oldLazyData;
|
|
||||||
int m_blockSize;
|
int m_blockSize;
|
||||||
QMap<int, QByteArray> m_modifiedData;
|
BlockMap m_modifiedData;
|
||||||
mutable QSet<int> m_lazyRequests;
|
mutable QSet<int> m_requests;
|
||||||
QByteArray m_emptyBlock;
|
QByteArray m_emptyBlock;
|
||||||
QByteArray m_lowerBlock;
|
QByteArray m_lowerBlock;
|
||||||
int m_size;
|
int m_size;
|
||||||
@@ -198,6 +192,7 @@ private:
|
|||||||
int m_numVisibleLines;
|
int m_numVisibleLines;
|
||||||
|
|
||||||
quint64 m_baseAddr;
|
quint64 m_baseAddr;
|
||||||
|
bool m_fixedSize;
|
||||||
|
|
||||||
bool m_cursorVisible;
|
bool m_cursorVisible;
|
||||||
int m_cursorPosition;
|
int m_cursorPosition;
|
||||||
|
@@ -183,7 +183,7 @@ public:
|
|||||||
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
|
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
|
||||||
{
|
{
|
||||||
m_editor = parent;
|
m_editor = parent;
|
||||||
connect(m_editor, SIGNAL(lazyDataRequested(Core::IEditor *, quint64, bool)),
|
connect(m_editor, SIGNAL(dataRequested(Core::IEditor *, quint64, bool)),
|
||||||
this, SLOT(provideData(Core::IEditor *, quint64)));
|
this, SLOT(provideData(Core::IEditor *, quint64)));
|
||||||
connect(m_editor, SIGNAL(newRangeRequested(Core::IEditor*,quint64)),
|
connect(m_editor, SIGNAL(newRangeRequested(Core::IEditor*,quint64)),
|
||||||
this, SLOT(provideNewRange(Core::IEditor*,quint64)));
|
this, SLOT(provideNewRange(Core::IEditor*,quint64)));
|
||||||
@@ -201,8 +201,7 @@ public:
|
|||||||
= fileName.isEmpty() ? m_fileName : fileName;
|
= fileName.isEmpty() ? m_fileName : fileName;
|
||||||
if (m_editor->save(m_fileName, fileNameToUse)) {
|
if (m_editor->save(m_fileName, fileNameToUse)) {
|
||||||
m_fileName = fileNameToUse;
|
m_fileName = fileNameToUse;
|
||||||
m_editor->editorInterface()->
|
m_editor->editor()->setDisplayName(QFileInfo(fileNameToUse).fileName());
|
||||||
setDisplayName(QFileInfo(fileNameToUse).fileName());
|
|
||||||
emit changed();
|
emit changed();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -212,7 +211,7 @@ public:
|
|||||||
|
|
||||||
void rename(const QString &newName) {
|
void rename(const QString &newName) {
|
||||||
m_fileName = newName;
|
m_fileName = newName;
|
||||||
m_editor->editorInterface()->setDisplayName(QFileInfo(fileName()).fileName());
|
m_editor->editor()->setDisplayName(QFileInfo(fileName()).fileName());
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,13 +220,8 @@ public:
|
|||||||
if (offset < static_cast<quint64>(file.size())
|
if (offset < static_cast<quint64>(file.size())
|
||||||
&& file.open(QIODevice::ReadOnly)) {
|
&& file.open(QIODevice::ReadOnly)) {
|
||||||
m_fileName = fileName;
|
m_fileName = fileName;
|
||||||
qint64 maxRange = 64 * 1024 * 1024;
|
m_editor->setSizes(offset, file.size(), true);
|
||||||
if (file.size() <= maxRange)
|
m_editor->editor()->setDisplayName(QFileInfo(fileName).fileName());
|
||||||
m_editor->setData(file.readAll());
|
|
||||||
else
|
|
||||||
m_editor->setLazyData(offset, maxRange);
|
|
||||||
m_editor->editorInterface()->
|
|
||||||
setDisplayName(QFileInfo(fileName).fileName());
|
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -238,13 +232,13 @@ private slots:
|
|||||||
void provideData(Core::IEditor *, quint64 block) {
|
void provideData(Core::IEditor *, quint64 block) {
|
||||||
QFile file(m_fileName);
|
QFile file(m_fileName);
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
int blockSize = m_editor->lazyDataBlockSize();
|
int blockSize = m_editor->dataBlockSize();
|
||||||
file.seek(block * blockSize);
|
file.seek(block * blockSize);
|
||||||
QByteArray data = file.read(blockSize);
|
QByteArray data = file.read(blockSize);
|
||||||
const int dataSize = data.size();
|
const int dataSize = data.size();
|
||||||
if (dataSize != blockSize)
|
if (dataSize != blockSize)
|
||||||
data += QByteArray(blockSize - dataSize, 0);
|
data += QByteArray(blockSize - dataSize, 0);
|
||||||
m_editor->addLazyData(block, data);
|
m_editor->addData(block, data);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,7 +353,7 @@ public:
|
|||||||
Core::Context context() const { return m_context; }
|
Core::Context context() const { return m_context; }
|
||||||
|
|
||||||
bool createNew(const QString & /* contents */ = QString()) {
|
bool createNew(const QString & /* contents */ = QString()) {
|
||||||
m_editor->setData(QByteArray());
|
m_editor->clear();
|
||||||
m_file->setFilename(QString());
|
m_file->setFilename(QString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -432,7 +426,7 @@ Core::IEditor *BinEditorFactory::createEditor(QWidget *parent)
|
|||||||
{
|
{
|
||||||
BinEditor *editor = new BinEditor(parent);
|
BinEditor *editor = new BinEditor(parent);
|
||||||
m_owner->initializeEditor(editor);
|
m_owner->initializeEditor(editor);
|
||||||
return editor->editorInterface();
|
return editor->editor();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList BinEditorFactory::mimeTypes() const
|
QStringList BinEditorFactory::mimeTypes() const
|
||||||
@@ -475,7 +469,7 @@ void BinEditorPlugin::initializeEditor(BinEditor *editor)
|
|||||||
{
|
{
|
||||||
BinEditorInterface *editorInterface = new BinEditorInterface(editor);
|
BinEditorInterface *editorInterface = new BinEditorInterface(editor);
|
||||||
QObject::connect(editor, SIGNAL(modificationChanged(bool)), editorInterface, SIGNAL(changed()));
|
QObject::connect(editor, SIGNAL(modificationChanged(bool)), editorInterface, SIGNAL(changed()));
|
||||||
editor->setEditorInterface(editorInterface);
|
editor->setEditor(editorInterface);
|
||||||
|
|
||||||
m_context.add(Constants::C_BINEDITOR);
|
m_context.add(Constants::C_BINEDITOR);
|
||||||
if (!m_undoAction) {
|
if (!m_undoAction) {
|
||||||
|
@@ -93,7 +93,7 @@ void MemoryAgent::createBinEditor(quint64 addr)
|
|||||||
editor->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
|
editor->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
|
||||||
editor->setProperty(Debugger::Constants::OPENED_WITH_MEMORY, true);
|
editor->setProperty(Debugger::Constants::OPENED_WITH_MEMORY, true);
|
||||||
connect(editor->widget(),
|
connect(editor->widget(),
|
||||||
SIGNAL(lazyDataRequested(Core::IEditor *, quint64,bool)),
|
SIGNAL(dataRequested(Core::IEditor *, quint64,bool)),
|
||||||
SLOT(fetchLazyData(Core::IEditor *, quint64,bool)));
|
SLOT(fetchLazyData(Core::IEditor *, quint64,bool)));
|
||||||
connect(editor->widget(),
|
connect(editor->widget(),
|
||||||
SIGNAL(newWindowRequested(quint64)),
|
SIGNAL(newWindowRequested(quint64)),
|
||||||
@@ -109,8 +109,11 @@ void MemoryAgent::createBinEditor(quint64 addr)
|
|||||||
SLOT(handleEndOfFileRequested(Core::IEditor*)));
|
SLOT(handleEndOfFileRequested(Core::IEditor*)));
|
||||||
m_editors << editor;
|
m_editors << editor;
|
||||||
QMetaObject::invokeMethod(editor->widget(), "setNewWindowRequestAllowed");
|
QMetaObject::invokeMethod(editor->widget(), "setNewWindowRequestAllowed");
|
||||||
QMetaObject::invokeMethod(editor->widget(), "setLazyData",
|
QMetaObject::invokeMethod(editor->widget(), "setSizes",
|
||||||
Q_ARG(quint64, addr), Q_ARG(int, DataRange), Q_ARG(int, BinBlockSize));
|
Q_ARG(quint64, addr),
|
||||||
|
Q_ARG(int, DataRange),
|
||||||
|
Q_ARG(bool, false),
|
||||||
|
Q_ARG(int, BinBlockSize));
|
||||||
} else {
|
} else {
|
||||||
showMessageBox(QMessageBox::Warning,
|
showMessageBox(QMessageBox::Warning,
|
||||||
tr("No memory viewer available"),
|
tr("No memory viewer available"),
|
||||||
@@ -131,15 +134,17 @@ void MemoryAgent::addLazyData(QObject *editorToken, quint64 addr,
|
|||||||
{
|
{
|
||||||
IEditor *editor = qobject_cast<IEditor *>(editorToken);
|
IEditor *editor = qobject_cast<IEditor *>(editorToken);
|
||||||
if (editor && editor->widget()) {
|
if (editor && editor->widget()) {
|
||||||
QMetaObject::invokeMethod(editor->widget(), "addLazyData",
|
QMetaObject::invokeMethod(editor->widget(), "addData",
|
||||||
Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
|
Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAgent::provideNewRange(IEditor *editor, quint64 address)
|
void MemoryAgent::provideNewRange(IEditor *editor, quint64 address)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(editor->widget(), "setLazyData",
|
QMetaObject::invokeMethod(editor->widget(), "setSizes",
|
||||||
Q_ARG(quint64, address), Q_ARG(int, DataRange),
|
Q_ARG(quint64, address),
|
||||||
|
Q_ARG(int, DataRange),
|
||||||
|
Q_ARG(bool, false),
|
||||||
Q_ARG(int, BinBlockSize));
|
Q_ARG(int, BinBlockSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user