Skip to content

Commit b265a3a

Browse files
committed
fix: 2025/10/31 功能冻结缺陷修复;
1 parent 4798716 commit b265a3a

28 files changed

Lines changed: 1599 additions & 1470 deletions

3rdparty/QHexView/document/buffer/qfilebuffer.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,16 @@ bool QFileBuffer::save(QIODevice *iodevice) {
6262
if (auto file = qobject_cast<QFile *>(iodevice)) {
6363
QSaveFile sf(file->fileName());
6464
sf.setDirectWriteFallback(true);
65+
if (!sf.open(QIODevice::WriteOnly)) {
66+
return false;
67+
}
6568
auto r = _chunks->write(&sf);
6669
if (r) {
6770
sf.commit();
6871
} else {
6972
sf.cancelWriting();
7073
}
71-
return true;
74+
return r;
7275
} else {
7376
// not a QFile?
7477
if (!iodevice->open(QIODevice::WriteOnly |
@@ -107,15 +110,19 @@ bool QFileBuffer::save(QIODevice *iodevice) {
107110
return true;
108111
} else {
109112
// not a QFile?
110-
if (!iodevice->open(QIODevice::WriteOnly |
113+
if (!iodevice->isWritable()) {
114+
// there is no meaning for unwritable device
115+
return false;
116+
}
117+
118+
iodevice->close(); // close first then reopen
119+
if (!iodevice->open(QIODevice::ReadWrite |
111120
QIODevice::Truncate)) {
112121
return false;
113122
}
114123

115124
if (_chunks) {
116-
auto r = _chunks->write(iodevice);
117-
iodevice->close();
118-
return r;
125+
return _chunks->write(iodevice);
119126
}
120127
}
121128
}

3rdparty/QHexView/document/buffer/qhexbuffer.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,15 @@ bool QHexBuffer::close() {
5252
return true;
5353
}
5454

55-
if (_ioDevice->isOpen()) {
56-
_ioDevice->close();
57-
delete _ioDevice;
58-
_ioDevice = nullptr;
59-
60-
// intenal buffer?
61-
if (m_buffer) {
62-
m_buffer = nullptr;
63-
}
64-
return true;
55+
_ioDevice->close();
56+
delete _ioDevice;
57+
_ioDevice = nullptr;
58+
59+
// intenal buffer?
60+
if (m_buffer) {
61+
m_buffer = nullptr;
6562
}
66-
return false;
63+
return true;
6764
}
6865

6966
uchar QHexBuffer::at(qsizetype idx) const {

3rdparty/QHexView/document/qhexcursor.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,6 @@ void QHexCursor::moveTo(qsizetype line, int column, int nibbleindex,
152152

153153
if (clearSelection) {
154154
m_sels.clear();
155-
}
156-
157-
if (clearSelection) {
158155
Q_EMIT selectionChanged();
159156
}
160157

@@ -167,12 +164,9 @@ void QHexCursor::select(qsizetype line, int column, SelectionModes modes) {
167164
m_selection.column = qMax(0, column); // fix the bug by wingsummer
168165
m_selection.lineWidth = m_position.lineWidth;
169166
m_selection.nibbleindex = 0;
170-
171167
modes.setFlag(SelectionPreview, false);
172-
m_preMode = SelectionMode(int(modes));
173168
} else {
174169
QHexSelection sel;
175-
176170
sel.begin = m_position;
177171
sel.begin.nibbleindex = 1;
178172

@@ -197,6 +191,7 @@ void QHexCursor::select(qsizetype line, int column, SelectionModes modes) {
197191
}
198192
}
199193

194+
m_preMode = SelectionMode(int(modes));
200195
Q_EMIT selectionChanged();
201196
}
202197

3rdparty/QHexView/document/qhexcursor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class QHexCursor : public QObject {
180180
quint8 m_lineWidth;
181181
QHexPosition m_position, m_selection;
182182

183-
SelectionMode m_preMode;
183+
SelectionMode m_preMode = SelectionNormal;
184184
QHexRegionObjectList<QHexPosition, QHexSelection> m_sels;
185185
};
186186

3rdparty/QHexView/document/qhexdocument.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ QByteArray QHexDocument::read(qsizetype offset, qsizetype len) const {
822822

823823
bool QHexDocument::saveTo(QIODevice *device, bool cleanUndo) {
824824
auto r = m_buffer->save(device);
825-
if (cleanUndo) {
825+
if (r && cleanUndo) {
826826
m_undostack->setClean(); // added by wingsummer
827827
}
828828
return r;

3rdparty/QHexView/document/qhexmetadata.cpp

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,19 +190,9 @@ bool QHexMetadata::removeLineMetadata(const QHexMetadataItem &item) {
190190
for (auto &l : m_linemeta) {
191191
l.remove(item);
192192
}
193-
194-
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
195-
m_linemeta.erase(std::remove_if(
196-
m_linemeta.begin(), m_linemeta.end(),
197-
[](const QHash<QHexMetadataItem, QHexLineMetadata> &item) {
198-
return item.isEmpty();
199-
}));
200-
#else
201193
m_linemeta.removeIf(
202194
[](const QPair<qsizetype, QHash<QHexMetadataItem, QHexLineMetadata>>
203195
&item) { return item.second.isEmpty(); });
204-
#endif
205-
206196
Q_EMIT metadataChanged();
207197
return true;
208198
}
@@ -218,13 +208,7 @@ void QHexMetadata::removeMetadata(qsizetype offset) {
218208
return r;
219209
};
220210

221-
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
222-
m_metadata.erase(
223-
std::remove_if(m_metadata.begin(), m_metadata.end(), rmfn));
224-
#else
225211
m_metadata.removeIf(rmfn);
226-
#endif
227-
228212
Q_EMIT metadataChanged();
229213
}
230214

@@ -543,22 +527,18 @@ bool QHexMetadata::comment(qsizetype begin, qsizetype end,
543527
QVector<QHexMetadataItem> QHexMetadata::mayBrokenMetaData(qsizetype begin,
544528
qsizetype end) {
545529
QVector<QHexMetadataItem> ret;
546-
std::copy_if(
547-
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
548-
m_metadata.begin(), m_metadata.end(),
549-
#else
550-
m_metadata.constBegin(), m_metadata.constEnd(),
551-
#endif
552-
std::back_inserter(ret), [begin, end](const QHexMetadataItem &item) {
553-
return !(end < item.begin || begin > item.end);
554-
});
530+
std::copy_if(m_metadata.constBegin(), m_metadata.constEnd(),
531+
std::back_inserter(ret),
532+
[begin, end](const QHexMetadataItem &item) {
533+
return !(end < item.begin || begin > item.end);
534+
});
555535
return ret;
556536
}
557537

558538
void QHexMetadata::addMetadata(const QHexMetadataItem &mi) {
559539
auto old = m_metadata;
560540
auto r = m_metadata.mergeAdd(mi);
561-
for (auto &idx : r.changed) {
541+
for (auto &idx : r.removed) {
562542
removeLineMetadata(old.at(idx));
563543
}
564544
for (auto &idx : r.inserted) {
@@ -607,7 +587,7 @@ bool QHexMetadata::checkValidMetadata(qsizetype begin, qsizetype end,
607587
const QColor &fgcolor,
608588
const QColor &bgcolor,
609589
const QString &comment) {
610-
if (begin > end)
590+
if (begin > end || begin < 0)
611591
return false;
612592

613593
if (!fgcolor.isValid() || fgcolor.alpha() != 255) {

3rdparty/QHexView/document/qhexregionobject.h

Lines changed: 86 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ struct QHexRegionObject {
218218

219219
if (sel.end < oldend) {
220220
// break into two ranges
221-
P s;
222-
s.begin = sel.end;
221+
P s = *static_cast<const P *>(this);
222+
s.begin = next(sel.end);
223223
s.end = oldend;
224224

225225
if (locker) {
@@ -240,25 +240,21 @@ struct QHexRegionObject {
240240
QMutex *locker = nullptr) {
241241
Q_ASSERT(isValid());
242242
Q_ASSERT(isNormalized());
243-
if (canMerge(sel)) {
244-
if (locker) {
245-
locker->lock();
246-
}
243+
if (!canMerge(sel)) {
244+
return false;
245+
}
247246

248-
if (this->begin < sel.end) {
249-
this->begin = qMin(this->begin, next(sel.begin));
250-
this->end = qMax(next(this->end), sel.end);
251-
} else {
252-
this->begin = qMin(next(this->begin), sel.begin);
253-
this->end = qMax(this->end, next(sel.end));
254-
}
247+
if (locker) {
248+
locker->lock();
249+
}
255250

256-
if (locker) {
257-
locker->unlock();
258-
}
259-
return true;
251+
this->begin = qMin(this->begin, sel.begin);
252+
this->end = qMax(this->end, sel.end);
253+
254+
if (locker) {
255+
locker->unlock();
260256
}
261-
return false;
257+
return true;
262258
};
263259

264260
bool isValid() const { return _valid; }
@@ -274,9 +270,9 @@ class QHexRegionObjectList : public QVector<P> {
274270

275271
public:
276272
struct MergeAddItem {
277-
// indices of items changed in old list
278-
QVector<qsizetype> changed;
279-
// indices of new items inserted in new list
273+
// original indices (in the list BEFORE this call) that were removed.
274+
QVector<qsizetype> removed;
275+
// indices in the final list (AFTER this call) of newly inserted.
280276
QVector<qsizetype> inserted;
281277
};
282278

@@ -299,59 +295,96 @@ class QHexRegionObjectList : public QVector<P> {
299295

300296
// clean up invalid selections
301297
auto cleanup = [](const P &s) { return !s.isValid(); };
302-
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
303298
this->removeIf(cleanup);
304-
#else
305-
this->erase(std::remove_if(this->begin(), this->end(), cleanup));
306-
#endif
307-
308299
QtConcurrent::blockingMap(
309300
buffer, [&locker, this](P &s) { mergeAdd(s, &locker); });
310301
}
311302

312-
// @return items changed index in old QHexRegionObjectList
313303
MergeAddItem mergeAdd(const P &sel, QMutex *locker = nullptr) {
314-
bool res = false;
315304
Q_ASSERT(sel.isNormalized());
316-
317305
MergeAddItem ret;
318-
QList<P> regionSlices;
319306

320-
auto total = this->size();
307+
P sel0 = sel;
308+
qsizetype removedSoFar = 0;
309+
QList<P> regionSlices;
310+
QList<P> insertsFromRemoved;
321311
qsizetype i = 0;
322-
for (i = 0; i < total; ++i) {
323-
auto p = this->at(i);
324-
auto r = p.mergeRegion(sel, locker);
312+
while (i < this->size()) {
313+
auto &p = this->operator[](i);
314+
315+
if (sel0.contains(p)) {
316+
qsizetype origIndex = static_cast<qsizetype>(i) +
317+
static_cast<qsizetype>(removedSoFar);
318+
ret.removed.append(origIndex);
319+
320+
this->takeAt(i);
321+
++removedSoFar;
322+
continue;
323+
}
324+
325+
auto r = p.mergeRegion(sel0, locker);
325326
if (std::holds_alternative<bool>(r)) {
326-
res = std::get<bool>(r);
327-
ret.changed.append(i);
328-
if (res) {
329-
break;
327+
bool flag = std::get<bool>(r);
328+
qsizetype origIndex = static_cast<qsizetype>(i) +
329+
static_cast<qsizetype>(removedSoFar);
330+
331+
ret.removed.append(origIndex);
332+
333+
P taken = this->takeAt(i);
334+
++removedSoFar;
335+
336+
if (flag) {
337+
sel0 = taken;
338+
continue;
339+
} else {
340+
insertsFromRemoved.append(taken);
341+
continue;
330342
}
331343
} else {
332344
auto v = std::get<P>(r);
333-
ret.changed.append(i);
334345
regionSlices.append(v);
335346
break;
336347
}
337348
}
338349

339-
for (auto &v : regionSlices) {
340-
auto idx = std::distance(
341-
this->constBegin(),
342-
std::upper_bound(this->constBegin(), this->constEnd(), v));
343-
ret.inserted.append(idx);
344-
this->insert(idx, v);
350+
QVector<P> toInsert;
351+
for (auto &v : regionSlices)
352+
toInsert.append(v);
353+
for (auto &v : insertsFromRemoved)
354+
toInsert.append(v);
355+
356+
auto equal_by_less = [](const P &a, const P &b) -> bool {
357+
return !(a < b) && !(b < a);
358+
};
359+
bool sel_present = false;
360+
for (const auto &e : toInsert) {
361+
if (equal_by_less(e, sel0)) {
362+
sel_present = true;
363+
break;
364+
}
365+
}
366+
if (!sel_present)
367+
toInsert.append(sel0);
368+
369+
QVector<P> finalInsert;
370+
for (const auto &v : toInsert) {
371+
bool found = false;
372+
for (const auto &u : finalInsert) {
373+
if (equal_by_less(u, v)) {
374+
found = true;
375+
break;
376+
}
377+
}
378+
if (!found)
379+
finalInsert.append(v);
345380
}
346381

347-
if (res) {
348-
auto m = this->takeAt(i);
349-
mergeAdd(m, locker);
350-
} else {
351-
this->insert(std::distance(this->constBegin(),
352-
std::upper_bound(this->constBegin(),
353-
this->constEnd(), sel)),
354-
sel);
382+
for (const auto &v : finalInsert) {
383+
auto it = std::upper_bound(this->constBegin(), this->constEnd(), v);
384+
qsizetype idx =
385+
static_cast<qsizetype>(std::distance(this->constBegin(), it));
386+
this->insert(idx, v);
387+
ret.inserted.append(idx);
355388
}
356389

357390
return ret;

0 commit comments

Comments
 (0)