File indexing completed on 2024-03-24 17:26:44
0001 /* 0002 This file is part of the Okteta Gui library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2008-2010 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_ABSTRACTBYTEARRAYVIEW_HPP 0010 #define OKTETA_ABSTRACTBYTEARRAYVIEW_HPP 0011 0012 // lib 0013 #include "columnsview.hpp" 0014 // Okteta core 0015 #include <Okteta/AddressRange> 0016 // Qt 0017 #include <QClipboard> 0018 0019 class QMenu; 0020 class QMimeData; 0021 class QByteArray; 0022 0023 namespace Okteta { 0024 class Bookmark; 0025 class ValueCodec; 0026 class CharCodec; 0027 class AbstractByteArrayModel; 0028 class ArrayChangeMetricsList; 0029 0030 class AbstractController; 0031 class AbstractWheelController; 0032 class ByteArrayTableLayout; 0033 class ByteArrayTableCursor; 0034 class ByteArrayTableRanges; 0035 0036 class AbstractByteArrayViewPrivate; 0037 0038 // TODO: for now inherit from ColumnsView, but later on invert this, 0039 // so it's AbstractByteArrayView < ColumnsView < {ByteArrayRowView,ByteArrayColumnView} 0040 class OKTETAGUI_EXPORT AbstractByteArrayView : public ColumnsView 0041 { 0042 friend class TabController; 0043 friend class KeyNavigator; 0044 friend class AbstractEditor; 0045 friend class ValueEditor; 0046 friend class CharEditor; 0047 friend class Dropper; 0048 friend class MouseNavigator; 0049 friend class MousePaster; 0050 friend class Dragger; 0051 friend class TapNavigator; 0052 0053 Q_OBJECT 0054 Q_PROPERTY(bool OverwriteMode READ isOverwriteMode WRITE setOverwriteMode NOTIFY overwriteModeChanged) 0055 Q_PROPERTY(bool OverwriteOnly READ isOverwriteOnly WRITE setOverwriteOnly) 0056 Q_PROPERTY(bool Modified READ isModified WRITE setModified DESIGNABLE false) 0057 Q_PROPERTY(bool ReadOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) 0058 0059 // Q_PROPERTY( bool hasSelectedData READ hasSelectedData ) 0060 // Q_PROPERTY( QByteArray SelectedData READ selectedData ) 0061 Q_PROPERTY(bool TabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus) 0062 Q_PROPERTY(LayoutStyle LayoutStyle READ layoutStyle WRITE setLayoutStyle NOTIFY layoutStyleChanged) 0063 Q_PROPERTY(int NoOfBytesPerLine READ noOfBytesPerLine WRITE setNoOfBytesPerLine NOTIFY noOfBytesPerLineChanged) 0064 Q_PROPERTY(int StartOffset READ startOffset WRITE setStartOffset) 0065 Q_PROPERTY(int FirstLineOffset READ firstLineOffset WRITE setFirstLineOffset) 0066 Q_PROPERTY(bool OffsetColumnVisible READ offsetColumnVisible WRITE toggleOffsetColumn NOTIFY offsetColumnVisibleChanged) 0067 Q_PROPERTY(OffsetCoding OffsetCoding READ offsetCoding WRITE setOffsetCoding NOTIFY offsetCodingChanged) 0068 Q_PROPERTY(CodingTypes VisibleCodings READ visibleCodings WRITE setVisibleCodings NOTIFY visibleByteArrayCodingsChanged) 0069 0070 Q_PROPERTY(bool ByteTypeColored READ isByteTypeColored WRITE setByteTypeColored) 0071 // value column 0072 Q_PROPERTY(ValueCoding Coding READ valueCoding WRITE setValueCoding NOTIFY valueCodingChanged) 0073 Q_PROPERTY(int ByteSpacingWidth READ byteSpacingWidth WRITE setByteSpacingWidth) 0074 Q_PROPERTY(int NoOfGroupedBytes READ noOfGroupedBytes WRITE setNoOfGroupedBytes NOTIFY noOfGroupedBytesChanged) 0075 Q_PROPERTY(int GroupSpacingWidth READ groupSpacingWidth WRITE setGroupSpacingWidth) 0076 Q_PROPERTY(int BinaryGapWidth READ binaryGapWidth WRITE setBinaryGapWidth) 0077 // char column 0078 Q_PROPERTY(bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting NOTIFY showsNonprintingChanged) 0079 Q_PROPERTY(QChar SubstituteChar READ substituteChar WRITE setSubstituteChar NOTIFY substituteCharChanged) 0080 0081 public: 0082 enum OffsetCoding 0083 { 0084 HexadecimalOffset = 0, 0085 DecimalOffset = 1, 0086 MaxOffsetCodingId = 0xFF 0087 }; 0088 Q_ENUM(OffsetCoding) 0089 enum ValueCoding 0090 { 0091 HexadecimalCoding = 0, 0092 DecimalCoding = 1, 0093 OctalCoding = 2, 0094 BinaryCoding = 3, 0095 MaxCodingId = 0xFFFF 0096 }; 0097 Q_ENUM(ValueCoding) 0098 enum CharCoding 0099 { 0100 LocalEncoding = 0, 0101 ISO8859_1Encoding = 1, 0102 EBCDIC1047Encoding = 2, 0103 StartOfOwnEncoding = 0x8000, 0104 MaxEncodingId = 0xFFFF 0105 }; 0106 Q_ENUM(CharCoding) 0107 enum LayoutStyle 0108 { 0109 FixedLayoutStyle = 0, 0110 WrapOnlyByteGroupsLayoutStyle = 1, 0111 FullSizeLayoutStyle = 2, 0112 LastUserLayout = 0xFF 0113 }; 0114 Q_ENUM(LayoutStyle) 0115 0116 enum CodingTypeId 0117 { 0118 NoCodingId = 0, 0119 ValueCodingId = 1, 0120 CharCodingId = 2 0121 }; 0122 enum CodingTypes 0123 { 0124 OnlyValueCoding = ValueCodingId, 0125 OnlyCharCoding = CharCodingId, 0126 ValueAndCharCodings = ValueCodingId | CharCodingId 0127 }; 0128 Q_ENUM(CodingTypes) 0129 0130 protected: 0131 OKTETAGUI_NO_EXPORT AbstractByteArrayView(AbstractByteArrayViewPrivate* d, QWidget* parent); 0132 0133 public: 0134 ~AbstractByteArrayView() override; 0135 0136 public: // value access 0137 Okteta::AbstractByteArrayModel* byteArrayModel() const; 0138 bool isModified() const; 0139 0140 bool isOverwriteMode() const; 0141 bool isOverwriteOnly() const; 0142 bool isReadOnly() const; 0143 0144 /** returns the index of the cursor position */ 0145 Address cursorPosition() const; 0146 /***/ 0147 bool isCursorBehind() const; 0148 0149 Address startOffset() const; 0150 Address firstLineOffset() const; 0151 int noOfBytesPerLine() const; 0152 0153 LayoutStyle layoutStyle() const; 0154 0155 bool tabChangesFocus() const; 0156 0157 CodingTypes visibleCodings() const; 0158 CodingTypeId activeCoding() const; 0159 0160 bool offsetColumnVisible() const; 0161 OffsetCoding offsetCoding() const; 0162 0163 /** returns true if there is a selected range in the array */ 0164 bool hasSelectedData() const; 0165 AddressRange selection() const; 0166 0167 AddressRange marking() const; 0168 0169 ValueCoding valueCoding() const; 0170 /** 0171 * @return encoding used for the chars 0172 */ 0173 CharCoding charCoding() const; 0174 /** 0175 * @return name of the encoding used for the chars 0176 */ 0177 const QString& charCodingName() const; 0178 0179 double zoomLevel() const; 0180 0181 public: // value access API 0182 // value column 0183 virtual int /*PixelX*/ byteSpacingWidth() const = 0; 0184 virtual int noOfGroupedBytes() const = 0; 0185 virtual int /*PixelX*/ groupSpacingWidth() const = 0; 0186 virtual int /*PixelX*/ binaryGapWidth() const = 0; 0187 0188 // char column 0189 /** reports if "non-printing" chars are displayed in the char column 0190 * with their original character. Default is false 0191 * @return @c true if original chars are displayed, otherwise @c false 0192 */ 0193 virtual bool showsNonprinting() const = 0; 0194 /** gives the used substitute character for "unprintable" chars, default is '.' 0195 * @return substitute character 0196 */ 0197 virtual QChar substituteChar() const = 0; 0198 /** returns the actually used undefined character for "undefined" chars, default is '?' */ 0199 virtual QChar undefinedChar() const = 0; 0200 0201 virtual bool isByteTypeColored() const = 0; 0202 0203 public: 0204 virtual void setByteArrayModel(Okteta::AbstractByteArrayModel* byteArrayModel); 0205 0206 // setting parameters 0207 // value column parameters 0208 /** sets the spacing between the bytes in the value column 0209 * @param byteSpacingWidth spacing between the bytes in pixels 0210 * default is 3 0211 */ 0212 virtual void setByteSpacingWidth(int /*PixelX*/ byteSpacingWidth) = 0; 0213 /** sets the number of grouped bytes in the value column 0214 * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping 0215 * default is 4 0216 */ 0217 virtual void setNoOfGroupedBytes(int noOfGroupedBytes) = 0; 0218 /** sets the spacing between the groups of bytes in the value column 0219 * @param groupSpacingWidth spacing between the groups in pixels 0220 * default is 9 0221 */ 0222 virtual void setGroupSpacingWidth(int /*PixelX*/ groupSpacingWidth) = 0; 0223 /** sets the spacing in the middle of a binary byte in the value column 0224 * @param binaryGapWidth spacing in the middle of a binary in pixels 0225 * returns true if there was a change 0226 */ 0227 virtual void setBinaryGapWidth(int binaryGapWidth) = 0; 0228 /** sets the spacing in the value column 0229 * @param byteSpacingWidth spacing between the bytes in pixels 0230 * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping 0231 * @param groupSpacingWidth spacing between the groups in pixels 0232 * Default is 4 for NoOfGroupedBytes 0233 */ 0234 virtual void setBufferSpacing(int /*PixelX*/ byteSpacingWidth, int noOfGroupedBytes = 0, int /*PixelX*/ groupSpacingWidth = 0) = 0; 0235 /** sets the format of the value column. Default is Okteta::HexadecimalCoding */ 0236 virtual void setValueCoding(ValueCoding valueCoding) = 0; 0237 // char column parameters 0238 /** sets whether control chars or "non-printing" chars should be displayed in the char column 0239 * with their corresponding character. Currently this simply means all chars with value <32, 0240 * as known from the ASCII. 0241 * @param showsNonprinting 0242 * returns true if there was a change 0243 */ 0244 virtual void setShowsNonprinting(bool showsNonprinting = true) = 0; 0245 /** sets the substitute character for "non-printing" chars 0246 * returns true if there was a change 0247 */ 0248 virtual void setSubstituteChar(QChar substituteChar) = 0; 0249 /** sets the undefined character for "undefined" chars 0250 * returns true if there was a change 0251 */ 0252 virtual void setUndefinedChar(QChar undefinedChar) = 0; 0253 /** sets the encoding of the char column. Default is Okteta::LocalEncoding. 0254 * If the encoding is not available the format will not be changed. */ 0255 virtual void setCharCoding(CharCoding charCoding) = 0; 0256 /** sets the encoding of the char column. Default is Okteta::LocalEncoding. 0257 * If the encoding is not available the format will not be changed. 0258 * @param charCodingName name of the encoding 0259 */ 0260 virtual void setCharCoding(const QString& charCodingName) = 0; 0261 virtual void setByteTypeColored(bool isColored) = 0; 0262 0263 public: 0264 /** sets whether the data should be treated modified or not */ 0265 void setModified(bool modified); 0266 0267 /** sets the resizestyle for the value column. Default is Okteta::FixedLayoutStyle */ 0268 void setLayoutStyle(LayoutStyle layoutStyle); 0269 /** sets whether the widget is readonly or not, Default is true. 0270 * If the databuffer which is worked on can't be written the widget stays readonly 0271 */ 0272 void setReadOnly(bool readOnly); 0273 /** sets whether the widget is overwriteonly or not. Default is false. */ 0274 void setOverwriteOnly(bool overwriteOnly); 0275 /** sets whether the widget is in overwrite mode or not. Default is true. */ 0276 void setOverwriteMode(bool overwriteMode); 0277 0278 /** sets the number of bytes per line, switching the resize style to Okteta::FixedLayoutStyle */ 0279 void setNoOfBytesPerLine(int noOfBytesPerLine); 0280 /** sets absolut offset of the data */ 0281 void setStartOffset(Address startOffset); 0282 /** sets offset of the char in the upper left corner */ 0283 void setFirstLineOffset(Address firstLineOffset); 0284 0285 /** sets whether on a tab key there should be switched from the char column back to the value column 0286 * or be switched to the next focusable widget. Default is false 0287 */ 0288 void setTabChangesFocus(bool tabChangesFocus = true); 0289 0290 /***/ 0291 void setActiveCoding(CodingTypeId codingId); 0292 /** */ 0293 void setVisibleCodings(int visibleCodings); 0294 0295 /** switches the Offset column on/off */ 0296 void toggleOffsetColumn(bool offsetColumnVisible); 0297 /** sets the format of the offset column. Default is Okteta::HexadecimalCoding */ 0298 void setOffsetCoding(OffsetCoding offsetCoding); 0299 0300 public: 0301 /** 0302 * @return deep copy of the selected data 0303 */ 0304 QByteArray selectedData() const; 0305 QMimeData* selectionAsMimeData() const; 0306 0307 public: // modification access 0308 void pasteData(const QMimeData* data); 0309 /** removes the selected data, takes care of the cursor */ 0310 void removeSelectedData(); 0311 /** inserts */ 0312 void insert(const QByteArray& data); 0313 0314 /** puts the cursor to the position of index, handles all drawing 0315 * @param index 0316 * @param isBehind 0317 */ 0318 void setCursorPosition(Address index, bool isBehind = false); 0319 void setSelectionCursorPosition(Address index); 0320 0321 /** de-/selects all data */ 0322 void selectAll(bool select); 0323 0324 void setSelection(Address start, Address end); 0325 void setSelection(const AddressRange& selection); 0326 /** selects word at index, returns true if there is one */ 0327 bool selectWord(/*unsigned*/ Address index /*, Chartype*/); 0328 0329 void setMarking(Address start, Address end); 0330 void setMarking(const AddressRange& marking); 0331 0332 /** 0333 * @param range an address range 0334 * @param ensureStartVisible if @c true scrolls the view as much as needed to have the start of the range 0335 * fully visible, otherwise to the end of the range 0336 */ 0337 void ensureVisible(const AddressRange& range, bool ensureStartVisible = false); 0338 /** scrolls the view as much as needed to have the cursor fully visible */ 0339 void ensureCursorVisible(); 0340 /** puts the cursor in the column at the pos of Point (in absolute coord), does not handle the drawing */ 0341 void placeCursor(const QPoint& point); 0342 0343 public: 0344 bool canReadData(const QMimeData* data) const; 0345 0346 public: // zooming 0347 void zoomIn(int pointInc); 0348 void zoomIn(); 0349 void zoomOut(int pointDec); 0350 void zoomOut(); 0351 void zoomTo(int pointSize); 0352 void unZoom(); 0353 void setZoomLevel(double level); 0354 0355 public: // cursor control 0356 /** we have focus again, start the timer */ 0357 void startCursor(); 0358 /** we lost focus, stop the timer */ 0359 void stopCursor(); 0360 /** simply pauses any blinking, i.e. ignores any calls to blinkCursor */ 0361 void pauseCursor(); 0362 /** undoes pauseCursor */ 0363 void unpauseCursor(); 0364 0365 public: 0366 // clipboard interaction 0367 virtual void copy(); 0368 virtual void cut(); 0369 virtual void paste(); 0370 0371 public: 0372 QRect cursorRect() const; 0373 QMenu* createStandardContextMenu(const QPoint& position); 0374 0375 public: // QWidget API 0376 QSize sizeHint() const override; 0377 0378 public: // logic value service 0379 /** detects the index of the byte at the given point 0380 * @param point in viewport coordinate system 0381 * @return index of the byte that covers the point 0382 */ 0383 Address indexByPoint(const QPoint& point) const; 0384 0385 Q_SIGNALS: 0386 /** Index of the byte that was clicked */ 0387 void clicked(Okteta::Address index); 0388 /** Index of the byte that was double clicked */ 0389 void doubleClicked(Okteta::Address index); 0390 0391 void cursorPositionChanged(Okteta::Address index); 0392 /** */ 0393 void overwriteModeChanged(bool newOverwriteMode); 0394 /** */ 0395 void readOnlyChanged(bool isReadOnly); 0396 /** selection has changed */ 0397 void hasSelectedDataChanged(bool hasSelectedData); 0398 void selectionChanged(const Okteta::AddressRange& selection); 0399 /** there is a cut available or not */ 0400 void cutAvailable(bool Really); 0401 /** there is a copy available or not */ 0402 void copyAvailable(bool Really); 0403 /** */ 0404 void charCodecChanged(const QString& codecName); 0405 /** */ 0406 void valueCodingChanged(int valueCoding); 0407 void focusChanged(bool hasFocus); 0408 0409 void offsetColumnVisibleChanged(bool visible); 0410 void offsetCodingChanged(int offsetCoding); 0411 void visibleByteArrayCodingsChanged(int columns); 0412 void layoutStyleChanged(int layoutStyle); 0413 void noOfBytesPerLineChanged(int noOfBytesPerLine); 0414 void showsNonprintingChanged(bool showsNonprinting); 0415 void substituteCharChanged(QChar substituteChar); 0416 void undefinedCharChanged(QChar undefinedChar); 0417 void noOfGroupedBytesChanged(int noOfGroupedBytes); 0418 0419 void zoomLevelChanged(double level); 0420 0421 protected: 0422 void finishByteEdit(); 0423 void emitSelectionSignals(); 0424 void updateChanged(); 0425 void copyToClipboard(QClipboard::Mode mode) const; 0426 void pasteFromClipboard(QClipboard::Mode mode); 0427 0428 protected: 0429 const Okteta::ValueCodec* valueCodec() const; 0430 const Okteta::CharCodec* charCodec() const; 0431 ByteArrayTableCursor* tableCursor() const; 0432 ByteArrayTableRanges* tableRanges() const; 0433 ByteArrayTableLayout* layout() const; 0434 0435 protected: // QWidget API 0436 void keyPressEvent(QKeyEvent* keyEvent) override; 0437 void mousePressEvent(QMouseEvent* mousePressEvent) override; 0438 void mouseReleaseEvent(QMouseEvent* mouseReleaseEvent) override; 0439 void mouseMoveEvent(QMouseEvent* mouseMoveEvent) override; 0440 void mouseDoubleClickEvent(QMouseEvent* mouseDoubleClickEvent) override; 0441 /// reimplemented to catch Tab and BackTab keys, which otherwise gets stolen 0442 bool event(QEvent* event) override; 0443 void showEvent(QShowEvent* showEvent) override; 0444 void focusInEvent(QFocusEvent* focusEvent) override; 0445 void focusOutEvent(QFocusEvent* focusEvent) override; 0446 void resizeEvent(QResizeEvent* resizeEvent) override; 0447 void dragEnterEvent(QDragEnterEvent* dragEnterEvent) override; 0448 void dragMoveEvent(QDragMoveEvent* dragMoveEvent) override; 0449 void dragLeaveEvent(QDragLeaveEvent* dragLeaveEvent) override; 0450 void dropEvent(QDropEvent* dropEvent) override; 0451 void contextMenuEvent(QContextMenuEvent* contextMenuEvent) override; 0452 void timerEvent(QTimerEvent* timerEvent) override; 0453 0454 protected: // QAbstractScrollArea API 0455 void wheelEvent(QWheelEvent* e) override; 0456 bool viewportEvent(QEvent* event) override; 0457 0458 protected: // ColumnsView API 0459 void setNoOfLines(int newNoOfLines) override; 0460 0461 protected: // Q_SLOTS QWidget API 0462 void changeEvent(QEvent* event) override; 0463 0464 private: 0465 Q_PRIVATE_SLOT(d_func(), void onBookmarksChange(const QVector<Okteta::Bookmark> &bookmarks)) 0466 Q_PRIVATE_SLOT(d_func(), void onRevertedToVersionIndex(int versionIndex)) 0467 // Q_PRIVATE_SLOT( d_func(), void onClipboardChanged() ) 0468 0469 private: 0470 Q_DECLARE_PRIVATE(AbstractByteArrayView) 0471 }; 0472 0473 } 0474 0475 #endif