File indexing completed on 2024-05-19 05:55:47
0001 /* 0002 SPDX-FileCopyrightText: 2016 RafaĆ Rzepecki <divided.mind@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 0006 */ 0007 0008 #include "kwhexview.h" 0009 0010 #include <QTextStream> 0011 0012 KWHexView::KWHexView(QWidget* parent): QPlainTextEdit(parent) 0013 { 0014 setReadOnly(true); 0015 setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 0016 setWordWrapMode(QTextOption::NoWrap); 0017 } 0018 0019 enum { hexStride = 4 }; 0020 0021 template<class It> 0022 static QString toHex(It it, It end) 0023 { 0024 QString text; 0025 QTextStream ts(&text); 0026 0027 ts << 0028 Qt::hex 0029 << qSetFieldWidth(2) << qSetPadChar(QLatin1Char('0')); 0030 0031 while (it < end) { 0032 const auto sEnd = qMin(it + hexStride, end); 0033 while (it < sEnd) 0034 ts << static_cast<quint8>(*(it++)); 0035 ts << qSetFieldWidth(0) << " " << qSetFieldWidth(2); 0036 } 0037 0038 return text; 0039 } 0040 0041 template<class It> 0042 static QString toText(It begin, It end) 0043 { 0044 QString text = QString::fromLatin1(begin, end - begin); 0045 0046 for (auto &ch: text) 0047 if (!ch.isPrint()) ch = QLatin1Char('.'); 0048 0049 return text; 0050 } 0051 0052 int KWHexView::calculateStride() 0053 { 0054 const auto w = viewport()->width(); 0055 const auto em = fontMetrics().averageCharWidth(); 0056 const auto chars = w / em - 1; 0057 auto stride = chars / 3 / hexStride * hexStride; 0058 0059 while (stride * 3 + (stride / hexStride) + 1 > chars) 0060 stride -= hexStride; 0061 0062 return qMax(static_cast<int>(hexStride), stride); 0063 } 0064 0065 void KWHexView::setData(const QByteArray& ba) 0066 { 0067 data = ba; 0068 showData(); 0069 } 0070 0071 void KWHexView::showData() 0072 { 0073 QString text; 0074 QTextStream ts(&text); 0075 0076 ts << Qt::left; 0077 0078 const auto stride = calculateStride(); 0079 const auto hexwidth = stride * 2 + (stride / hexStride) + 1; 0080 0081 for (auto it = data.begin(); it < data.end(); it += stride) { 0082 auto end = qMin(it + stride, data.end()); 0083 ts << qSetFieldWidth(hexwidth) << toHex(it, end); 0084 ts << qSetFieldWidth(0) << toText(it, end) << QLatin1Char('\n'); 0085 } 0086 ts.flush(); 0087 setPlainText(text); 0088 } 0089 0090 void KWHexView::resizeEvent(QResizeEvent* e) 0091 { 0092 QPlainTextEdit::resizeEvent(e); 0093 if (e->size() != e->oldSize()) showData(); 0094 } 0095 0096 #include "moc_kwhexview.cpp"