File indexing completed on 2025-01-05 05:23:53
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2023 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "bytearrayviewhtmlstreamencoder.hpp" 0010 0011 // lib 0012 #include "oktetakastengui_export.hpp" 0013 #include "offsetcolumnhtmlrenderer.hpp" 0014 #include "valuebytearraycolumnhtmlrenderer.hpp" 0015 #include "charbytearraycolumnhtmlrenderer.hpp" 0016 #include "bytearrayrowscolumnhtmlrenderer.hpp" 0017 #include <bytearrayview.hpp> 0018 // Okteta gui 0019 #include <Okteta/ByteArrayTableLayout> 0020 #include <Okteta/AbstractByteArrayView> 0021 // Okteta core 0022 #include <Okteta/AbstractByteArrayModel> 0023 #include <Okteta/Character> 0024 // KF 0025 #include <KLocalizedString> 0026 // Qt 0027 #include <QTextStream> 0028 // Std 0029 #include <utility> 0030 0031 namespace Kasten { 0032 0033 ByteArrayViewHtmlStreamEncoderSettings::ByteArrayViewHtmlStreamEncoderSettings() = default; 0034 0035 ByteArrayViewHtmlStreamEncoder::ByteArrayViewHtmlStreamEncoder() 0036 : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "View in HTML"), QStringLiteral("text/html"), QStringLiteral("text/html")) 0037 {} 0038 0039 ByteArrayViewHtmlStreamEncoder::~ByteArrayViewHtmlStreamEncoder() = default; 0040 0041 bool ByteArrayViewHtmlStreamEncoder::encodeDataToStream(QIODevice* device, 0042 const ByteArrayView* byteArrayView, 0043 const Okteta::AbstractByteArrayModel* byteArrayModel, 0044 const Okteta::AddressRange& range) 0045 { 0046 bool success = true; 0047 0048 // settings 0049 mSettings.codecName = byteArrayView->charCodingName(); 0050 mSettings.valueCoding = (Okteta::ValueCoding)byteArrayView->valueCoding(); 0051 mSettings.undefinedChar = byteArrayView->undefinedChar(); 0052 mSettings.substituteChar = byteArrayView->substituteChar(); 0053 mSettings.firstLineOffset = byteArrayView->firstLineOffset(); 0054 mSettings.startOffset = byteArrayView->startOffset(); 0055 mSettings.delta = byteArrayView->noOfBytesPerLine(); 0056 const int viewModus = byteArrayView->viewModus(); 0057 0058 // setup 0059 Okteta::ByteArrayTableLayout layout(byteArrayView->noOfBytesPerLine(), mSettings.firstLineOffset, 0060 mSettings.startOffset, 0, byteArrayModel->size()); 0061 0062 Okteta::CoordRange coordRange; 0063 coordRange.set(layout.coordRangeOfIndizes(range)); 0064 0065 const int noOfBytesPerLine = byteArrayView->noOfBytesPerLine(); 0066 const int noOfGroupedBytes = byteArrayView->noOfGroupedBytes(); 0067 const int visibleByteArrayCodings = byteArrayView->visibleByteArrayCodings(); 0068 0069 QVector<AbstractColumnHtmlRenderer*> columnHtmlRendererList; 0070 0071 if (byteArrayView->offsetColumnVisible()) { 0072 columnHtmlRendererList.append( 0073 new OffsetColumnHtmlRenderer(byteArrayView->offsetCoding(), mSettings.firstLineOffset, mSettings.delta, (viewModus == 0))); 0074 } 0075 0076 if (viewModus == 0) { 0077 if (visibleByteArrayCodings & Okteta::AbstractByteArrayView::ValueCodingId) { 0078 columnHtmlRendererList.append( 0079 new ValueByteArrayColumnHtmlRenderer(byteArrayModel, range.start(), coordRange, 0080 noOfBytesPerLine, noOfGroupedBytes, 0081 mSettings.valueCoding)); 0082 } 0083 0084 if (visibleByteArrayCodings & Okteta::AbstractByteArrayView::CharCodingId) { 0085 columnHtmlRendererList.append( 0086 new CharByteArrayColumnHtmlRenderer(byteArrayModel, range.start(), coordRange, 0087 noOfBytesPerLine, 0088 mSettings.codecName, mSettings.substituteChar, mSettings.undefinedChar)); 0089 } 0090 } else { 0091 columnHtmlRendererList.append( 0092 new ByteArrayRowsColumnHtmlRenderer(byteArrayModel, range.start(), coordRange, 0093 noOfBytesPerLine, noOfGroupedBytes, 0094 visibleByteArrayCodings, 0095 mSettings.valueCoding, 0096 mSettings.codecName, mSettings.substituteChar, mSettings.undefinedChar)); 0097 } 0098 0099 int subLinesCount = 1; 0100 for (const AbstractColumnHtmlRenderer* renderer : std::as_const(columnHtmlRendererList)) { 0101 if (renderer->noOfSublinesNeeded() > subLinesCount) { 0102 subLinesCount = renderer->noOfSublinesNeeded(); 0103 } 0104 } 0105 0106 // encode 0107 QTextStream textStream(device); 0108 textStream.setCodec("UTF-8"); 0109 0110 textStream << "<html><head><meta charset=\"utf-8\"><meta name=\"generator\" content=\"Okteta ByteArrayViewHtmlStreamEncoder " OKTETAKASTENGUI_VERSION_STRING "\"></head><table>" << Qt::endl; 0111 0112 textStream << "<tr>"; 0113 0114 int l = coordRange.start().line(); 0115 for (const AbstractColumnHtmlRenderer* renderer : std::as_const(columnHtmlRendererList)) { 0116 renderer->renderFirstLine(&textStream, l); 0117 } 0118 0119 textStream << "</tr>" << Qt::endl; 0120 0121 int subLine = 1; 0122 while (true) { 0123 if (subLine == subLinesCount) { 0124 ++l; 0125 if (l > coordRange.end().line()) { 0126 break; 0127 } 0128 subLine = 0; 0129 } 0130 0131 textStream << "<tr>"; 0132 0133 const bool isSubline = (subLine > 0); 0134 for (const AbstractColumnHtmlRenderer* renderer : std::as_const(columnHtmlRendererList)) { 0135 renderer->renderNextLine(&textStream, isSubline); 0136 } 0137 0138 textStream << "</tr>" << Qt::endl; 0139 ++subLine; 0140 } 0141 0142 textStream << "</table></html>" << Qt::endl; 0143 0144 // clean up 0145 qDeleteAll(columnHtmlRendererList); 0146 0147 return success; 0148 } 0149 0150 } 0151 0152 #include "moc_bytearrayviewhtmlstreamencoder.cpp"