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