File indexing completed on 2024-03-24 17:26:47
0001 /* 0002 This file is part of the Okteta Gui library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2008-2009, 2019 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 #ifndef OKTETA_BYTEARRAYROWCOLUMNRENDERER_P_HPP 0010 #define OKTETA_BYTEARRAYROWCOLUMNRENDERER_P_HPP 0011 0012 #include "bytearrayrowcolumnrenderer.hpp" 0013 #include "abstractcolumnrenderer_p.hpp" 0014 // lib 0015 #include "oktetagui.hpp" 0016 // Okteta core 0017 #include <Okteta/AbstractByteArrayModel> 0018 #include <Okteta/Bookmarkable> 0019 #include <Okteta/Character> 0020 // Qt 0021 #include <QFontMetrics> 0022 0023 class QColor; 0024 class QBrush; 0025 0026 namespace Okteta { 0027 0028 class Bookmarkable; 0029 0030 static constexpr AbstractByteArrayView::CodingTypes DefaultVisibleCodings = 0031 (AbstractByteArrayView::CodingTypes)(AbstractByteArrayView::ValueCodingId | AbstractByteArrayView::CharCodingId); 0032 0033 0034 class ByteArrayRowColumnRendererPrivate : public AbstractColumnRendererPrivate 0035 { 0036 public: 0037 ByteArrayRowColumnRendererPrivate(ByteArrayRowColumnRenderer* q, 0038 AbstractColumnStylist* stylist, 0039 AbstractByteArrayModel* byteArrayModel, ByteArrayTableLayout* layout, 0040 ByteArrayTableRanges* ranges); 0041 0042 ~ByteArrayRowColumnRendererPrivate() override; 0043 0044 public: // AbstractColumnRenderer API 0045 void renderFirstLine(QPainter* painter, const PixelXRange& Xs, Line firstLineIndex); 0046 void renderNextLine(QPainter* painter); 0047 0048 public: 0049 void prepareRendering(const PixelXRange& Xs); 0050 0051 public: 0052 // void renderLine( QPainter* painter, int lineIndex ); 0053 void renderLinePositions(QPainter* painter, Line lineIndex, const LinePositionRange& linePositions); 0054 /** paints a cursor based on the type of the byte. 0055 * @param painter The QPainter. 0056 * @param byteIndex Index of the byte to paint the cursor for. If -1 a space is used as char. 0057 * @param codingId The coding identifier. 0058 */ 0059 void renderCursor(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId); 0060 /** paints the byte with background. 0061 * @param painter The QPainter. 0062 * @param byteIndex Index of the byte to paint. If -1 only the background is painted. 0063 * @param codingId The coding identifier. 0064 */ 0065 void renderByte(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId); 0066 /** paints the byte with background and a frame around. 0067 * @param painter The QPainter. 0068 * @param byteIndex Index of the byte to paint the frame for. If -1 a space is used as char. 0069 * @param codingId The coding identifier. 0070 * @param style the style of the framing 0071 */ 0072 void renderFramedByte(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId, ByteArrayRowColumnRenderer::FrameStyle style); 0073 0074 void renderEditedByte(QPainter* painter, Byte byte, const QString& editBuffer); 0075 0076 public: // modification access 0077 /** sets the spacing in the hex column 0078 * @param byteSpacingWidth spacing between the bytes in pixels 0079 * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping 0080 * @param groupSpacingWidth spacing between the groups in pixels 0081 * returns true if there was a change 0082 */ 0083 bool setSpacing(PixelX byteSpacingWidth, Size noOfGroupedBytes = 0, PixelX groupSpacingWidth = 0); 0084 /** sets the spacing between the bytes in the hex column 0085 * @param byteSpacingWidth spacing between the bytes in pixels 0086 * returns true if there was a change 0087 */ 0088 bool setByteSpacingWidth(PixelX byteSpacingWidth); 0089 /** sets the number of grouped bytes in the hex column 0090 * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping 0091 * returns true if there was a change 0092 */ 0093 bool setNoOfGroupedBytes(Size noOfGroupedBytes); 0094 /** sets the spacing between the groups of bytes in the hex column 0095 * @param groupSpacingWidth spacing between the groups in pixels 0096 * returns true if there was a change 0097 */ 0098 bool setGroupSpacingWidth(PixelX groupSpacingWidth); 0099 /** sets the metrics of the used font 0100 */ 0101 void setFontMetrics(const QFontMetrics& fontMetrics); 0102 /** */ 0103 void set(AbstractByteArrayModel* byteArrayModel); 0104 /** creates new buffer for x-values; to be called on any change of NoOfBytesPerLine or metrics */ 0105 void resetXBuffer(); 0106 /** sets the codec to be used by the char column. */ 0107 void setCharCodec(const CharCodec* charCodec); 0108 0109 void setValueCodec(ValueCoding valueCoding, const ValueCodec* valueCodec); 0110 /** sets the spacing in the middle of a binary byte in the value column 0111 * @param binaryGapWidth spacing in the middle of a binary in pixels 0112 * returns true if there was a change 0113 */ 0114 bool setBinaryGapWidth(PixelX binaryGapWidth); 0115 0116 void setByteTypeColored(bool byteTypeColored); 0117 0118 /** sets whether "unprintable" chars (>32) should be displayed in the char column 0119 * with their corresponding character. 0120 * @param showingNonprinting 0121 * returns true if there was a change 0122 */ 0123 bool setShowingNonprinting(bool showingNonprinting = true); 0124 /** sets the substitute character for "unprintable" chars 0125 * returns true if there was a change 0126 */ 0127 bool setSubstituteChar(QChar substituteChar); 0128 /** sets the undefined character for "undefined" chars 0129 * returns true if there was a change 0130 */ 0131 bool setUndefinedChar(QChar undefinedChar); 0132 0133 void setVisibleCodings(int visibleCodings); 0134 0135 public: // functional logic 0136 /** returns byte linePositions covered by pixels with absolute x-coord x */ 0137 LinePositionRange linePositionsOfX(PixelX x, PixelX width) const; 0138 /** returns byte pos at pixel with absolute x-coord x */ 0139 LinePosition linePositionOfX(PixelX x) const; 0140 /** returns byte pos at pixel with absolute x-coord x, and sets the flag to true if we are closer to the right */ 0141 LinePosition magneticLinePositionOfX(PixelX x) const; 0142 /** returns absolute x-coord of byte at position posInLine */ 0143 PixelX xOfLinePosition(LinePosition posInLine) const; 0144 /** returns right absolute x-coord of byte at position posInLine */ 0145 PixelX rightXOfLinePosition(LinePosition posInLine) const; 0146 /** returns byte pos at pixel with relative x-coord x */ 0147 LinePosition linePositionOfColumnX(PixelX x) const; 0148 /** returns byte linePositions covered by pixels with relative x-coord x */ 0149 LinePositionRange linePositionsOfColumnXs(PixelX x, PixelX width) const; 0150 /** returns relative x-coord of byte at position posInLine */ 0151 PixelX columnXOfLinePosition(LinePosition posInLine) const; 0152 /** returns right relative x-coord of byte at position posInLine */ 0153 PixelX columnRightXOfLinePosition(LinePosition posInLine) const; 0154 /** returns the linePositions that overlap with the x-coords relative to the view */ 0155 LinePositionRange visibleLinePositions(PixelX x, PixelX width) const; 0156 /** returns the */ 0157 PixelXRange xsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const; 0158 /** */ 0159 PixelXRange columnXsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const; 0160 0161 QRect byteRect(Coord coord) const; 0162 QRect byteRect(Coord coord, AbstractByteArrayView::CodingTypeId codingId) const; 0163 0164 AbstractByteArrayView::CodingTypeId codingIdofY(PixelY y) const; 0165 PixelY yOfCodingId(AbstractByteArrayView::CodingTypeId codingId) const; 0166 0167 public: // value access 0168 PixelX byteWidth() const; 0169 PixelX digitWidth() const; 0170 PixelX groupSpacingWidth() const; 0171 PixelX byteSpacingWidth() const; 0172 Size noOfGroupedBytes() const; 0173 PixelY digitHeight() const; 0174 PixelY rowHeight() const; 0175 0176 PixelX binaryGapWidth() const; 0177 0178 /** returns true if "unprintable" chars (>32) are displayed in the char column 0179 * with their corresponding character, default is false 0180 */ 0181 bool isShowingNonprinting() const; 0182 /** returns the actually used substitute character for "unprintable" chars, default is '.' */ 0183 QChar substituteChar() const; 0184 /** returns the actually used undefined character for "undefined" chars, default is '?' */ 0185 QChar undefinedChar() const; 0186 0187 LinePosition firstLinePos() const; 0188 LinePosition lastLinePos() const; 0189 LinePositionRange visibleLinePositions() const; 0190 const ByteArrayTableLayout* layout() const; 0191 bool isByteTypeColored() const; 0192 0193 AbstractByteArrayView::CodingTypes visibleCodings() const; 0194 0195 private: // API to be redefined 0196 void renderByteText(QPainter* painter, 0197 Byte byte, Character charByte, int codings, const QColor& color) const; 0198 /** default implementation sets byte width to one digit width */ 0199 void recalcByteWidth(); 0200 0201 private: 0202 void renderPlain(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex); 0203 void renderSelection(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag); 0204 void renderMarking(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag); 0205 void renderRange(QPainter* painter, const QBrush& brush, const LinePositionRange& linePositions, int flag); 0206 void renderSelectionSpaceBehind(QPainter* painter, LinePosition linePosition); 0207 void renderSpaceBehind(QPainter* painter, const QBrush& brush, LinePosition linePosition); 0208 void renderBookmark(QPainter* painter, const QBrush& brush); 0209 0210 void renderCode(QPainter* painter, const QString& code, const QColor& color) const; 0211 0212 void recalcX(); 0213 0214 bool getNextSelectedAddressRange(AddressRange* selectedRange, unsigned int* flag, const AddressRange& range) const; 0215 bool getNextMarkedAddressRange(AddressRange* markedRange, unsigned int* flag, const AddressRange& range) const; 0216 0217 private: 0218 /** pointer to the buffer */ 0219 AbstractByteArrayModel* mByteArrayModel; 0220 /** pointer to the layout */ 0221 const ByteArrayTableLayout* mLayout; 0222 /** pointer to the ranges */ 0223 ByteArrayTableRanges* mRanges; 0224 /** */ 0225 Bookmarkable* mBookmarks; 0226 /** */ 0227 const CharCodec* mCharCodec; 0228 0229 AbstractByteArrayView::CodingTypes mVisibleCodings; 0230 /** */ 0231 PixelX mDigitWidth = 0; 0232 /** */ 0233 PixelY mDigitBaseLine = 0; 0234 /** */ 0235 PixelY mDigitHeight = 0; 0236 0237 QFontMetrics mFontMetrics; 0238 0239 private: // individual data 0240 /** total width of byte display in pixel */ 0241 PixelX mByteWidth = 0; 0242 /** width of inserting cursor in pixel */ 0243 // PixelX mCursorWidth; 0244 /** size of the line margin */ 0245 PixelX mByteSpacingWidth; 0246 /** width of spacing in pixel */ 0247 PixelX mGroupSpacingWidth; 0248 0249 /** number of grouped bytes */ 0250 Size mNoOfGroupedBytes; 0251 0252 /** pointer to array with buffered linePositions (relative to column position) 0253 * any spacing gets assigned to the byte left to it -> ...|c|c|c |c|c... 0254 */ 0255 PixelX* mLinePosLeftPixelX = nullptr; 0256 PixelX* mLinePosRightPixelX = nullptr; 0257 /** index of right position */ 0258 LinePosition mLastLinePos = 0; 0259 0260 /** */ 0261 bool mByteTypeColored = true; 0262 0263 private: // value specifics 0264 /** */ 0265 ValueCoding mValueCoding; 0266 /** */ 0267 const ValueCodec* mValueCodec = nullptr; 0268 /** */ 0269 PixelX mBinaryGapWidth; 0270 0271 private: // buffered data 0272 /** buffer to hold the formatted valueCoding */ 0273 mutable QString mDecodedByteText; 0274 /** calculated: Offset in pixels of the second half of the binary */ 0275 PixelX mBinaryHalfOffset; 0276 0277 private: // char specifics 0278 /** */ 0279 bool mShowingNonprinting; 0280 /** */ 0281 QChar mSubstituteChar; 0282 /** */ 0283 QChar mUndefinedChar; 0284 0285 private: // buffering rendering data 0286 LinePositionRange mRenderLinePositions; 0287 Line mRenderLine; 0288 PixelX mRenderX; 0289 PixelX mRenderWidth; 0290 0291 private: 0292 ByteArrayRowColumnRenderer* const q_ptr; 0293 Q_DECLARE_PUBLIC(ByteArrayRowColumnRenderer) 0294 }; 0295 0296 0297 inline ByteArrayRowColumnRendererPrivate::ByteArrayRowColumnRendererPrivate(ByteArrayRowColumnRenderer* q, 0298 AbstractColumnStylist* stylist, 0299 AbstractByteArrayModel* byteArrayModel, 0300 ByteArrayTableLayout* layout, 0301 ByteArrayTableRanges* ranges) 0302 : AbstractColumnRendererPrivate(stylist) 0303 , mByteArrayModel(byteArrayModel) 0304 , mLayout(layout) 0305 , mRanges(ranges) 0306 , mBookmarks(qobject_cast<Bookmarkable*>(byteArrayModel)) 0307 , mVisibleCodings(DefaultVisibleCodings) 0308 , mFontMetrics(QFont()) 0309 , mByteSpacingWidth(DefaultByteSpacingWidth) 0310 , mGroupSpacingWidth(DefaultGroupSpacingWidth) 0311 , mNoOfGroupedBytes(DefaultNoOfGroupedBytes) 0312 , mBinaryGapWidth(DefaultBinaryGapWidth) 0313 , mShowingNonprinting(DefaultShowingNonprinting) 0314 , mSubstituteChar(DefaultSubstituteChar) 0315 , mUndefinedChar(DefaultUndefinedChar) 0316 , q_ptr(q) 0317 { 0318 } 0319 0320 inline ByteArrayRowColumnRendererPrivate::~ByteArrayRowColumnRendererPrivate() 0321 { 0322 delete [] mLinePosLeftPixelX; 0323 delete [] mLinePosRightPixelX; 0324 } 0325 0326 inline AbstractByteArrayView::CodingTypes ByteArrayRowColumnRendererPrivate::visibleCodings() const { return mVisibleCodings; } 0327 0328 inline PixelX ByteArrayRowColumnRendererPrivate::byteWidth() const { return mByteWidth; } 0329 inline PixelX ByteArrayRowColumnRendererPrivate::digitWidth() const { return mDigitWidth; } 0330 inline PixelX ByteArrayRowColumnRendererPrivate::byteSpacingWidth() const { return mByteSpacingWidth; } 0331 inline PixelX ByteArrayRowColumnRendererPrivate::groupSpacingWidth() const { return mGroupSpacingWidth; } 0332 inline PixelY ByteArrayRowColumnRendererPrivate::digitHeight() const { return mDigitHeight; } 0333 inline Size ByteArrayRowColumnRendererPrivate::noOfGroupedBytes() const { return mNoOfGroupedBytes; } 0334 0335 inline LinePosition ByteArrayRowColumnRendererPrivate::firstLinePos() const { return mRenderLinePositions.start(); } 0336 inline LinePosition ByteArrayRowColumnRendererPrivate::lastLinePos() const { return mRenderLinePositions.end(); } 0337 inline LinePositionRange ByteArrayRowColumnRendererPrivate::visibleLinePositions() const { return mRenderLinePositions; } 0338 0339 inline const ByteArrayTableLayout* ByteArrayRowColumnRendererPrivate::layout() const { return mLayout; } 0340 0341 inline void ByteArrayRowColumnRendererPrivate::setCharCodec(const CharCodec* charCodec) 0342 { 0343 mCharCodec = charCodec; 0344 } 0345 0346 inline void ByteArrayRowColumnRendererPrivate::setByteTypeColored(bool byteTypeColored) 0347 { 0348 mByteTypeColored = byteTypeColored; 0349 } 0350 inline bool ByteArrayRowColumnRendererPrivate::isByteTypeColored() const { return mByteTypeColored; } 0351 0352 inline PixelX ByteArrayRowColumnRendererPrivate::binaryGapWidth() const { return mBinaryGapWidth; } 0353 0354 inline bool ByteArrayRowColumnRendererPrivate::isShowingNonprinting() const { return mShowingNonprinting; } 0355 inline QChar ByteArrayRowColumnRendererPrivate::substituteChar() const { return mSubstituteChar; } 0356 inline QChar ByteArrayRowColumnRendererPrivate::undefinedChar() const { return mUndefinedChar; } 0357 0358 inline bool ByteArrayRowColumnRendererPrivate::setSubstituteChar(QChar substituteChar) 0359 { 0360 if (mSubstituteChar == substituteChar) { 0361 return false; 0362 } 0363 0364 mSubstituteChar = substituteChar; 0365 return true; 0366 } 0367 0368 inline bool ByteArrayRowColumnRendererPrivate::setUndefinedChar(QChar undefinedChar) 0369 { 0370 if (mUndefinedChar == undefinedChar) { 0371 return false; 0372 } 0373 0374 mUndefinedChar = undefinedChar; 0375 return true; 0376 } 0377 0378 inline bool ByteArrayRowColumnRendererPrivate::setShowingNonprinting(bool showingNonprinting) 0379 { 0380 if (mShowingNonprinting == showingNonprinting) { 0381 return false; 0382 } 0383 0384 mShowingNonprinting = showingNonprinting; 0385 return true; 0386 } 0387 0388 } 0389 0390 #endif