mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
fix: close project actually destroys dock, editor perf single-pass line attributes
- Set WA_DeleteOnClose on doc docks so all close paths trigger cleanup - Create fresh empty class when last project closes - Add splitDockWidget/resizeDocks to project_new() so workspace doesn't eat editor space - Merge applyMarginText, applyMarkers, applyFoldLevels into single-pass applyLineAttributes - Cache line texts for heatmap/symbol coloring passes (avoid redundant Scintilla IPC) - Zero-alloc scroll width scan replaces QString::split
This commit is contained in:
121
src/editor.cpp
121
src/editor.cpp
@@ -973,15 +973,22 @@ void RcxEditor::applyDocument(const ComposeResult& result) {
|
|||||||
m_sci->setText(result.text);
|
m_sci->setText(result.text);
|
||||||
m_sci->setReadOnly(true);
|
m_sci->setReadOnly(true);
|
||||||
|
|
||||||
// Set horizontal scroll width to match the longest line (ignoring trailing spaces)
|
// Set horizontal scroll width to match the longest line (ignoring trailing spaces).
|
||||||
|
// Single-pass scan avoids QString::split() allocation of entire QStringList.
|
||||||
{
|
{
|
||||||
int maxLen = 0;
|
int maxLen = 0, curLen = 0, lastNonSpace = 0;
|
||||||
const QStringList lines = result.text.split(QChar('\n'));
|
for (int i = 0; i < result.text.size(); i++) {
|
||||||
for (const auto& line : lines) {
|
QChar ch = result.text[i];
|
||||||
int len = (int)line.size();
|
if (ch == '\n') {
|
||||||
while (len > 0 && line[len - 1] == QChar(' ')) --len;
|
maxLen = qMax(maxLen, lastNonSpace);
|
||||||
maxLen = std::max(len, maxLen);
|
curLen = 0;
|
||||||
|
lastNonSpace = 0;
|
||||||
|
} else {
|
||||||
|
++curLen;
|
||||||
|
if (ch != ' ') lastNonSpace = curLen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
maxLen = qMax(maxLen, lastNonSpace);
|
||||||
QFontMetrics fm(editorFont());
|
QFontMetrics fm(editorFont());
|
||||||
int pixelWidth = fm.horizontalAdvance(QString(maxLen, QChar('0')));
|
int pixelWidth = fm.horizontalAdvance(QString(maxLen, QChar('0')));
|
||||||
m_sci->SendScintilla(QsciScintillaBase::SCI_SETSCROLLWIDTH,
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETSCROLLWIDTH,
|
||||||
@@ -995,12 +1002,20 @@ void RcxEditor::applyDocument(const ComposeResult& result) {
|
|||||||
// Force full re-lex to fix stale syntax coloring after edits
|
// Force full re-lex to fix stale syntax coloring after edits
|
||||||
m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, (uintptr_t)0, (long)-1);
|
m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, (uintptr_t)0, (long)-1);
|
||||||
|
|
||||||
applyMarginText(result.meta);
|
applyLineAttributes(result.meta);
|
||||||
applyMarkers(result.meta);
|
|
||||||
applyFoldLevels(result.meta);
|
|
||||||
applyHexDimming(result.meta);
|
applyHexDimming(result.meta);
|
||||||
applyHeatmapHighlight(result.meta);
|
|
||||||
applySymbolColoring(result.meta);
|
// Build line-text cache for indicator passes (avoids redundant Scintilla IPC)
|
||||||
|
QVector<QString> lineTexts(result.meta.size());
|
||||||
|
for (int i = 0; i < result.meta.size(); i++) {
|
||||||
|
const auto& lm = result.meta[i];
|
||||||
|
if (lm.heatLevel > 0 || isFuncPtr(lm.nodeKind) ||
|
||||||
|
lm.nodeKind == NodeKind::Pointer32 ||
|
||||||
|
lm.nodeKind == NodeKind::Pointer64)
|
||||||
|
lineTexts[i] = getLineText(m_sci, i);
|
||||||
|
}
|
||||||
|
applyHeatmapHighlight(result.meta, lineTexts);
|
||||||
|
applySymbolColoring(result.meta, lineTexts);
|
||||||
applyCommandRowPills();
|
applyCommandRowPills();
|
||||||
|
|
||||||
// Reset hint line - applySelectionOverlay will repaint indicators
|
// Reset hint line - applySelectionOverlay will repaint indicators
|
||||||
@@ -1051,22 +1066,47 @@ void RcxEditor::applyDocument(const ComposeResult& result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RcxEditor::applyMarginText(const QVector<LineMeta>& meta) {
|
void RcxEditor::applyLineAttributes(const QVector<LineMeta>& meta) {
|
||||||
if (m_relativeOffsets)
|
// Margin text
|
||||||
return reformatMargins();
|
if (m_relativeOffsets) {
|
||||||
|
reformatMargins();
|
||||||
|
} else {
|
||||||
|
m_sci->clearMarginText(-1);
|
||||||
|
}
|
||||||
|
|
||||||
m_sci->clearMarginText(-1);
|
// Clear markers
|
||||||
|
for (int m = M_CONT; m <= M_STRUCT_BG; m++)
|
||||||
|
m_sci->markerDeleteAll(m);
|
||||||
|
m_sci->markerDeleteAll(M_CMD_ROW);
|
||||||
|
|
||||||
|
// Single pass: margin text (absolute mode), markers, fold levels
|
||||||
for (int i = 0; i < meta.size(); i++) {
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
const auto& lm = meta[i];
|
const auto& lm = meta[i];
|
||||||
if (lm.offsetText.isEmpty()) continue;
|
|
||||||
|
|
||||||
QByteArray text = lm.offsetText.toUtf8();
|
// Margin text (only in absolute offset mode; reformatMargins handles relative)
|
||||||
m_sci->SendScintilla(QsciScintillaBase::SCI_MARGINSETTEXT,
|
if (!m_relativeOffsets && !lm.offsetText.isEmpty()) {
|
||||||
(uintptr_t)i, text.constData());
|
QByteArray text = lm.offsetText.toUtf8();
|
||||||
QByteArray styles(text.size(), '\0'); // style 0 = dim
|
m_sci->SendScintilla(QsciScintillaBase::SCI_MARGINSETTEXT,
|
||||||
m_sci->SendScintilla(QsciScintillaBase::SCI_MARGINSETSTYLES,
|
(uintptr_t)i, text.constData());
|
||||||
(uintptr_t)i, styles.constData());
|
QByteArray styles(text.size(), '\0');
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_MARGINSETSTYLES,
|
||||||
|
(uintptr_t)i, styles.constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Markers
|
||||||
|
if (lm.lineKind == LineKind::CommandRow) {
|
||||||
|
m_sci->markerAdd(i, M_CMD_ROW);
|
||||||
|
} else {
|
||||||
|
uint32_t mask = lm.markerMask;
|
||||||
|
for (int m = M_CONT; m <= M_STRUCT_BG; m++) {
|
||||||
|
if (mask & (1u << m))
|
||||||
|
m_sci->markerAdd(i, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold level
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETFOLDLEVEL,
|
||||||
|
(unsigned long)i, (long)lm.foldLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1187,31 +1227,6 @@ void RcxEditor::reformatMargins() {
|
|||||||
m_sci->setReadOnly(true);
|
m_sci->setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RcxEditor::applyMarkers(const QVector<LineMeta>& meta) {
|
|
||||||
for (int m = M_CONT; m <= M_STRUCT_BG; m++) {
|
|
||||||
m_sci->markerDeleteAll(m);
|
|
||||||
}
|
|
||||||
m_sci->markerDeleteAll(M_CMD_ROW);
|
|
||||||
for (int i = 0; i < meta.size(); i++) {
|
|
||||||
if (meta[i].lineKind == LineKind::CommandRow) {
|
|
||||||
m_sci->markerAdd(i, M_CMD_ROW);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
uint32_t mask = meta[i].markerMask;
|
|
||||||
for (int m = M_CONT; m <= M_STRUCT_BG; m++) {
|
|
||||||
if (mask & (1u << m)) {
|
|
||||||
m_sci->markerAdd(i, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RcxEditor::applyFoldLevels(const QVector<LineMeta>& meta) {
|
|
||||||
for (int i = 0; i < meta.size(); i++) {
|
|
||||||
m_sci->SendScintilla(QsciScintillaBase::SCI_SETFOLDLEVEL,
|
|
||||||
(unsigned long)i, (long)meta[i].foldLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lineRangeNoEol(QsciScintilla* sci, int line, long& start, long& len) {
|
static inline void lineRangeNoEol(QsciScintilla* sci, int line, long& start, long& len) {
|
||||||
start = sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)line);
|
start = sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)line);
|
||||||
@@ -1524,7 +1539,8 @@ static QString getLineText(QsciScintilla* sci, int line) {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RcxEditor::applyHeatmapHighlight(const QVector<LineMeta>& meta) {
|
void RcxEditor::applyHeatmapHighlight(const QVector<LineMeta>& meta,
|
||||||
|
const QVector<QString>& lineTexts) {
|
||||||
static constexpr int heatIndicators[] = { IND_HEAT_COLD, IND_HEAT_WARM, IND_HEAT_HOT };
|
static constexpr int heatIndicators[] = { IND_HEAT_COLD, IND_HEAT_WARM, IND_HEAT_HOT };
|
||||||
|
|
||||||
for (int i = 0; i < meta.size(); i++) {
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
@@ -1546,7 +1562,7 @@ void RcxEditor::applyHeatmapHighlight(const QVector<LineMeta>& meta) {
|
|||||||
int activeInd = heatIndicators[qBound(0, heat - 1, 2)];
|
int activeInd = heatIndicators[qBound(0, heat - 1, 2)];
|
||||||
|
|
||||||
// Apply heat-level indicator to value span (narrowed for pointer-like nodes)
|
// Apply heat-level indicator to value span (narrowed for pointer-like nodes)
|
||||||
QString lineText = getLineText(m_sci, i);
|
const QString& lineText = lineTexts[i];
|
||||||
ColumnSpan vs = narrowPtrValueSpan(lm,
|
ColumnSpan vs = narrowPtrValueSpan(lm,
|
||||||
valueSpan(lm, lineText.size(), typeW, nameW), lineText);
|
valueSpan(lm, lineText.size(), typeW, nameW), lineText);
|
||||||
if (!vs.valid) continue;
|
if (!vs.valid) continue;
|
||||||
@@ -1561,14 +1577,15 @@ void RcxEditor::applyHeatmapHighlight(const QVector<LineMeta>& meta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RcxEditor::applySymbolColoring(const QVector<LineMeta>& meta) {
|
void RcxEditor::applySymbolColoring(const QVector<LineMeta>& meta,
|
||||||
|
const QVector<QString>& lineTexts) {
|
||||||
for (int i = 0; i < meta.size(); i++) {
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
const LineMeta& lm = meta[i];
|
const LineMeta& lm = meta[i];
|
||||||
if (!isFuncPtr(lm.nodeKind)
|
if (!isFuncPtr(lm.nodeKind)
|
||||||
&& lm.nodeKind != NodeKind::Pointer32
|
&& lm.nodeKind != NodeKind::Pointer32
|
||||||
&& lm.nodeKind != NodeKind::Pointer64)
|
&& lm.nodeKind != NodeKind::Pointer64)
|
||||||
continue;
|
continue;
|
||||||
QString lineText = getLineText(m_sci, i);
|
const QString& lineText = lineTexts[i];
|
||||||
// Find " // " within the value region and color "// sym" portion green
|
// Find " // " within the value region and color "// sym" portion green
|
||||||
ColumnSpan vs = valueSpan(lm, lineText.size(), lm.effectiveTypeW, lm.effectiveNameW);
|
ColumnSpan vs = valueSpan(lm, lineText.size(), lm.effectiveTypeW, lm.effectiveNameW);
|
||||||
if (!vs.valid) continue;
|
if (!vs.valid) continue;
|
||||||
|
|||||||
@@ -179,13 +179,11 @@ private:
|
|||||||
void setupMarkers();
|
void setupMarkers();
|
||||||
void allocateMarginStyles();
|
void allocateMarginStyles();
|
||||||
|
|
||||||
void applyMarginText(const QVector<LineMeta>& meta);
|
void applyLineAttributes(const QVector<LineMeta>& meta);
|
||||||
void reformatMargins();
|
void reformatMargins();
|
||||||
void applyMarkers(const QVector<LineMeta>& meta);
|
|
||||||
void applyFoldLevels(const QVector<LineMeta>& meta);
|
|
||||||
void applyHexDimming(const QVector<LineMeta>& meta);
|
void applyHexDimming(const QVector<LineMeta>& meta);
|
||||||
void applyHeatmapHighlight(const QVector<LineMeta>& meta);
|
void applyHeatmapHighlight(const QVector<LineMeta>& meta, const QVector<QString>& lineTexts);
|
||||||
void applySymbolColoring(const QVector<LineMeta>& meta);
|
void applySymbolColoring(const QVector<LineMeta>& meta, const QVector<QString>& lineTexts);
|
||||||
void applyBaseAddressColoring(const QVector<LineMeta>& meta);
|
void applyBaseAddressColoring(const QVector<LineMeta>& meta);
|
||||||
void applyCommandRowPills();
|
void applyCommandRowPills();
|
||||||
|
|
||||||
|
|||||||
@@ -3227,6 +3227,13 @@ QDockWidget* MainWindow::project_new(const QString& classKeyword) {
|
|||||||
currentCtrl->activeSourceIndex());
|
currentCtrl->activeSourceIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure workspace dock is split alongside editor with sensible proportions
|
||||||
|
if (m_docDocks.size() == 1 && m_workspaceDock) {
|
||||||
|
splitDockWidget(m_workspaceDock, m_docDocks.first(), Qt::Horizontal);
|
||||||
|
resizeDocks({m_workspaceDock}, {128}, Qt::Horizontal);
|
||||||
|
m_workspaceDock->show();
|
||||||
|
}
|
||||||
|
|
||||||
rebuildWorkspaceModel();
|
rebuildWorkspaceModel();
|
||||||
return dock;
|
return dock;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user