Holding selection in MemoryMap

This commit is contained in:
foralost 2023-12-17 11:03:14 +01:00
parent bd3c2a41ed
commit 5940e38e13
4 changed files with 117 additions and 1 deletions

View File

@ -1040,6 +1040,8 @@ void AbstractStdTable::headerButtonPressedSlot(duint col)
else else
mSort.ascending = !mSort.ascending; mSort.ascending = !mSort.ascending;
reloadData(); reloadData();
emit sortHappenedSignal();
} }
void AbstractStdTable::reloadData() void AbstractStdTable::reloadData()

View File

@ -76,6 +76,7 @@ signals:
void keyPressedSignal(QKeyEvent* event); void keyPressedSignal(QKeyEvent* event);
void doubleClickedSignal(); void doubleClickedSignal();
void contextMenuSignal(const QPoint & pos); void contextMenuSignal(const QPoint & pos);
void sortHappenedSignal();
public slots: public slots:
void copyLineSlot(); void copyLineSlot();

View File

@ -41,10 +41,17 @@ MemoryMapView::MemoryMapView(StdTable* parent)
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint))); connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
connect(Bridge::getBridge(), SIGNAL(focusMemmap()), this, SLOT(setFocus())); connect(Bridge::getBridge(), SIGNAL(focusMemmap()), this, SLOT(setFocus()));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
connect(this, SIGNAL(sortHappenedSignal()), this, SLOT(sortHappenedSlot()));
connect(this, SIGNAL(selectionChanged(duint)), this, SLOT(selectionChangedSlot(duint)));
setupContextMenu(); setupContextMenu();
} }
void MemoryMapView::sortHappenedSlot()
{
selectAddressRange(mSelectedAddressRange);
}
void MemoryMapView::setupContextMenu() void MemoryMapView::setupContextMenu()
{ {
//Follow in Dump //Follow in Dump
@ -196,6 +203,11 @@ void MemoryMapView::setupContextMenu()
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
} }
void MemoryMapView::selectionChangedSlot(duint index)
{
mSelectedAddressRange = getAddressRangeFromSelection(getSelection());
}
void MemoryMapView::refreshShortcutsSlot() void MemoryMapView::refreshShortcutsSlot()
{ {
mMemoryExecuteSingleshoot->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); mMemoryExecuteSingleshoot->setShortcut(ConfigShortcut("ActionToggleBreakpoint"));
@ -426,6 +438,98 @@ static QString getProtectionString(DWORD protect)
} }
} }
void MemoryMapView::selectAddressRange(const std::pair<duint, duint> & addressRange)
{
if(addressRange.first == 0 || addressRange.second == 0)
return;
const auto savedAddressRange = addressRange;
QList<duint> selectedRows{};
for(duint i = mSort.ascending ? 0 : (getRowCount() - 1); i < getRowCount(); mSort.ascending ? i++ : i--)
{
auto currRowAddress = getCellUserdata(i, ColAddress);
auto currRowSize = getCellUserdata(i, ColSize);
std::pair<duint, duint> currAddressRange{currRowAddress, currRowAddress + currRowSize};
if(currAddressRange.second != 0)
currAddressRange.second--;
if((currAddressRange.first >= savedAddressRange.first && savedAddressRange.first <= currAddressRange.second) &&
(currAddressRange.second <= savedAddressRange.second && savedAddressRange.second >= currAddressRange.first))
{
selectedRows.append(i);
}
else if(!selectedRows.empty())
{
break;
}
}
if(selectedRows.empty())
return;
SelectionData toSet{};
if(mSort.ascending)
{
toSet.firstSelectedIndex = selectedRows.at(0);
toSet.toIndex = *(selectedRows.cend() - 1);
}
else
{
toSet.firstSelectedIndex = *(selectedRows.cend() - 1);
toSet.toIndex = selectedRows.at(0);
}
toSet.fromIndex = toSet.firstSelectedIndex;
tryEmitAddressSelectionChange(toSet, savedAddressRange);
}
void MemoryMapView::tryEmitAddressSelectionChange(const SelectionData & newSelection, const std::pair<duint, duint> & basedUpon)
{
if(basedUpon.first == mSelectedAddressRange.first && basedUpon.second == mSelectedAddressRange.second)
{
if(newSelection.firstSelectedIndex != mSelection.firstSelectedIndex ||
newSelection.fromIndex != mSelection.fromIndex ||
newSelection.toIndex != mSelection.toIndex)
{
mSelection = newSelection;
emit selectionChanged(newSelection.firstSelectedIndex);
}
}
}
std::pair<duint, duint> MemoryMapView::getAddressRangeFromSelection(QList<duint> & selection)
{
if(selection.empty())
return {};
std::map<duint, duint> entries;
for(duint i : selection)
{
entries.emplace(
std::pair<duint, duint>
(getCellUserdata(i, ColAddress), i));
}
duint startAddress = entries.cbegin()->first;
auto lastValidElement = --entries.cend();
duint lastAddressRow = lastValidElement->second;
duint lastAddressSize = getCellUserdata(lastAddressRow, ColSize);
duint lastAddress = lastValidElement->first + lastAddressSize;
if(lastAddress != 0) // watchout for 0
lastAddress--; // decrementing by one to make it [addr, addr + size - 1] instead of [addr, addr + size)
return {startAddress, lastAddress};
}
void MemoryMapView::refreshMapSlot() void MemoryMapView::refreshMapSlot()
{ {
MEMMAP memoryMap = {}; MEMMAP memoryMap = {};
@ -526,7 +630,10 @@ void MemoryMapView::refreshMapSlot()
} }
if(memoryMap.page != 0) if(memoryMap.page != 0)
BridgeFree(memoryMap.page); BridgeFree(memoryMap.page);
reloadData(); //refresh memory map reloadData(); //refresh memory map
selectAddressRange(mSelectedAddressRange);
} }
void MemoryMapView::stateChangedSlot(DBGSTATE state) void MemoryMapView::stateChangedSlot(DBGSTATE state)

View File

@ -16,6 +16,7 @@ signals:
void showReferences(); void showReferences();
public slots: public slots:
void selectionChangedSlot(duint index);
void refreshShortcutsSlot(); void refreshShortcutsSlot();
void stateChangedSlot(DBGSTATE state); void stateChangedSlot(DBGSTATE state);
void followDumpSlot(); void followDumpSlot();
@ -41,9 +42,13 @@ public slots:
void selectionGetSlot(SELECTIONDATA* selection); void selectionGetSlot(SELECTIONDATA* selection);
void selectionSetSlot(const SELECTIONDATA* selection); void selectionSetSlot(const SELECTIONDATA* selection);
void disassembleAtSlot(duint va, duint cip); void disassembleAtSlot(duint va, duint cip);
void sortHappenedSlot();
private: private:
void setSwitchViewName(); void setSwitchViewName();
std::pair<duint, duint> getAddressRangeFromSelection(QList<duint> & selection);
void tryEmitAddressSelectionChange(const SelectionData & newSelection, const std::pair<duint, duint> & newAddressRange);
void selectAddressRange(const std::pair<duint, duint> & addressRange);
enum enum
{ {
@ -67,6 +72,7 @@ private:
return getCellContent(getInitialSelection(), ColAddress); return getCellContent(getInitialSelection(), ColAddress);
} }
std::pair<duint, duint> mSelectedAddressRange;
QAction* makeCommandAction(QAction* action, const QString & command); QAction* makeCommandAction(QAction* action, const QString & command);
GotoDialog* mGoto = nullptr; GotoDialog* mGoto = nullptr;