diff --git a/src/gui/Src/BasicView/AbstractStdTable.cpp b/src/gui/Src/BasicView/AbstractStdTable.cpp index 872b284f..14ed4454 100644 --- a/src/gui/Src/BasicView/AbstractStdTable.cpp +++ b/src/gui/Src/BasicView/AbstractStdTable.cpp @@ -1032,7 +1032,13 @@ void AbstractStdTable::headerButtonPressedSlot(duint col) { if(!mIsColumnSortingAllowed) return; - if(mSort.column != col) + + if(mSort.column == -1 && col == mAddressColumn) + { + mSort.column = col; + mSort.ascending = false; + } + else if(mSort.column != col) { mSort.column = col; mSort.ascending = true; @@ -1040,6 +1046,8 @@ void AbstractStdTable::headerButtonPressedSlot(duint col) else mSort.ascending = !mSort.ascending; reloadData(); + + emit sortChangedSignal(); } void AbstractStdTable::reloadData() diff --git a/src/gui/Src/BasicView/AbstractStdTable.h b/src/gui/Src/BasicView/AbstractStdTable.h index 61cf403c..4c595d04 100644 --- a/src/gui/Src/BasicView/AbstractStdTable.h +++ b/src/gui/Src/BasicView/AbstractStdTable.h @@ -76,6 +76,7 @@ signals: void keyPressedSignal(QKeyEvent* event); void doubleClickedSignal(); void contextMenuSignal(const QPoint & pos); + void sortChangedSignal(); public slots: void copyLineSlot(); diff --git a/src/gui/Src/Gui/MemoryMapView.cpp b/src/gui/Src/Gui/MemoryMapView.cpp index c38a90f3..34cc8d66 100644 --- a/src/gui/Src/Gui/MemoryMapView.cpp +++ b/src/gui/Src/Gui/MemoryMapView.cpp @@ -19,14 +19,14 @@ MemoryMapView::MemoryMapView(StdTable* parent) { setDrawDebugOnly(true); enableMultiSelection(true); + setAddressColumn(ColAddress); int charwidth = getCharWidth(); - - addColumnAt(8 + charwidth * 2 * sizeof(duint), tr("Address"), true, tr("Address")); //addr - addColumnAt(8 + charwidth * 2 * sizeof(duint), tr("Size"), false, tr("Size")); //size - addColumnAt(charwidth * 9, tr("Party"), false); // party - addColumnAt(8 + charwidth * 32, tr("Info"), false, tr("Page Information")); //page information - addColumnAt(8 + charwidth * 28, tr("Content"), false, tr("Content of section")); //content of section + addColumnAt(8 + charwidth * 2 * sizeof(duint), tr("Address"), true, tr("Address"), SortBy::AsHex); //addr + addColumnAt(8 + charwidth * 2 * sizeof(duint), tr("Size"), true, tr("Size"), SortBy::AsHex); //size + addColumnAt(charwidth * 9, tr("Party"), true); // party + addColumnAt(8 + charwidth * 32, tr("Info"), true, tr("Page Information")); //page information + addColumnAt(8 + charwidth * 28, tr("Content"), true, tr("Content of section")); //content of section addColumnAt(8 + charwidth * 5, tr("Type"), true, tr("Allocation Type")); //allocation type addColumnAt(8 + charwidth * 11, tr("Protection"), true, tr("Current Protection")); //current protection addColumnAt(8 + charwidth * 8, tr("Initial"), true, tr("Allocation Protection")); //allocation protection @@ -41,6 +41,8 @@ MemoryMapView::MemoryMapView(StdTable* parent) connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint))); connect(Bridge::getBridge(), SIGNAL(focusMemmap()), this, SLOT(setFocus())); connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); + connect(this, SIGNAL(selectionChanged(duint)), this, SLOT(selectionChangedSlot(duint))); + connect(this, SIGNAL(sortChangedSignal()), this, SLOT(fixSelectionRangeSlot())); setupContextMenu(); } @@ -196,6 +198,50 @@ void MemoryMapView::setupContextMenu() connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); } +void MemoryMapView::selectionChangedSlot(duint index) +{ + Q_UNUSED(index); + + mSelectionStart = getCellUserdata(mSelection.firstSelectedIndex, ColAddress); + mSelectionEnd = mSelectionStart + getCellUserdata(mSelection.firstSelectedIndex, ColSize); + mSelectionCount = mSelection.toIndex - mSelection.fromIndex; + mSelectionSort = mSort.column; +} + +void MemoryMapView::fixSelectionRangeSlot() +{ + for(duint row = 0; row < getRowCount(); row++) + { + auto start = getCellUserdata(row, ColAddress); + auto end = start + getCellUserdata(row, ColSize); + if(start == mSelectionStart && end == mSelectionEnd) + { + // Restore the selection + mSelection.firstSelectedIndex = row; + mSelection.fromIndex = mSelection.toIndex = row; + if(mSelectionSort == mSort.column) + { + mSelection.toIndex += mSelectionCount; + updateViewport(); + } + else + { + // Scroll to the selected range when the sort changes + auto rangefrom = getTableOffset(); + auto rangeto = rangefrom + getViewableRowsCount() - 1; + if(mSelection.fromIndex < rangefrom) //offset lays before the current view + setTableOffset(mSelection.fromIndex); + else if(mSelection.toIndex > (rangeto - 1)) //offset lays after the current view + setTableOffset(mSelection.toIndex - getViewableRowsCount() + 1); + else + updateViewport(); + } + + break; + } + } +} + void MemoryMapView::refreshShortcutsSlot() { mMemoryExecuteSingleshoot->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); @@ -526,7 +572,9 @@ void MemoryMapView::refreshMapSlot() } if(memoryMap.page != 0) BridgeFree(memoryMap.page); + reloadData(); //refresh memory map + fixSelectionRangeSlot(); } void MemoryMapView::stateChangedSlot(DBGSTATE state) diff --git a/src/gui/Src/Gui/MemoryMapView.h b/src/gui/Src/Gui/MemoryMapView.h index 443fe481..43a4fef2 100644 --- a/src/gui/Src/Gui/MemoryMapView.h +++ b/src/gui/Src/Gui/MemoryMapView.h @@ -16,6 +16,8 @@ signals: void showReferences(); public slots: + void selectionChangedSlot(duint index); + void fixSelectionRangeSlot(); void refreshShortcutsSlot(); void stateChangedSlot(DBGSTATE state); void followDumpSlot(); @@ -105,5 +107,9 @@ private: QAction* mReferences; QMenu* mPluginMenu; - duint mCipBase; + duint mCipBase = 0; + duint mSelectionStart = 0; + duint mSelectionEnd = 0; + duint mSelectionCount = 0; + duint mSelectionSort = -1; };