当前位置: 首页 > news >正文

做网站课程徐州企业建站

做网站课程,徐州企业建站,江门网站建设方案推广,南京模板建站效果类似QTextEdit#xff0c;但是显示十六进制的数据#xff0c;比如用于显示抓取串口或者bin文件的数据等等 chunks.h #ifndef CHUNKS_H #define CHUNKS_H/** \cond docNever *//*! The Chunks class is the storage backend for QHexEdit.** When QHexEdit loads data, C…效果类似QTextEdit但是显示十六进制的数据比如用于显示抓取串口或者bin文件的数据等等 chunks.h #ifndef CHUNKS_H #define CHUNKS_H/** \cond docNever *//*! The Chunks class is the storage backend for QHexEdit.** When QHexEdit loads data, Chunks access them using a QIODevice interface. When the app uses* a QByteArray interface, QBuffer is used to provide again a QIODevice like interface. No data* will be changed, therefore Chunks opens the QIODevice in QIODevice::ReadOnly mode. After every* access Chunks closes the QIODevice, thats why external applications can overwrite files while* QHexEdit shows them.** When the the user starts to edit the data, Chunks creates a local copy of a chunk of data (4* kilobytes) and notes all changes there. Parallel to that chunk, there is a second chunk,* which keep track of which bytes are changed and which not.**/#include QtCorestruct Chunk {QByteArray data;QByteArray dataChanged;qint64 absPos; };class Chunks: public QObject { Q_OBJECT public:// Constructors and file settingsChunks(QObject *parent);Chunks(QIODevice ioDevice, QObject *parent);bool setIODevice(QIODevice ioDevice);// Getting data out of ChunksQByteArray data(qint64 pos0, qint64 count-1, QByteArray *highlighted0);bool write(QIODevice iODevice, qint64 pos0, qint64 count-1);// Set and get highlighting infosvoid setDataChanged(qint64 pos, bool dataChanged);bool dataChanged(qint64 pos);// Search APIqint64 indexOf(const QByteArray ba, qint64 from);qint64 lastIndexOf(const QByteArray ba, qint64 from);// Char manipulationsbool insert(qint64 pos, char b);bool overwrite(qint64 pos, char b);bool removeAt(qint64 pos);// Utility functionschar operator[](qint64 pos);qint64 pos();qint64 size();private:int getChunkIndex(qint64 absPos);QIODevice * _ioDevice;qint64 _pos;qint64 _size;QListChunk _chunks;#ifdef MODUL_TEST public:int chunkSize(); #endif };/** \endcond docNever */#endif // CHUNKS_Hchunks.cpp #include chunks.h #include limits.h#define NORMAL 0 #define HIGHLIGHTED 1#define BUFFER_SIZE 0x10000 #define CHUNK_SIZE 0x1000 #define READ_CHUNK_MASK Q_INT64_C(0xfffffffffffff000)// ***************************************** Constructors and file settingsChunks::Chunks(QObject *parent): QObject(parent) {QBuffer *buf new QBuffer(this);setIODevice(*buf); }Chunks::Chunks(QIODevice ioDevice, QObject *parent): QObject(parent) {setIODevice(ioDevice); }bool Chunks::setIODevice(QIODevice ioDevice) {_ioDevice ioDevice;bool ok _ioDevice-open(QIODevice::ReadOnly);if (ok) // Try to open IODevice{_size _ioDevice-size();_ioDevice-close();}else // Fallback is an empty buffer{QBuffer *buf new QBuffer(this);_ioDevice buf;_size 0;}_chunks.clear();_pos 0;return ok; }// ***************************************** Getting data out of ChunksQByteArray Chunks::data(qint64 pos, qint64 maxSize, QByteArray *highlighted) {qint64 ioDelta 0;int chunkIdx 0;Chunk chunk;QByteArray buffer;// Do some checks and some arrangementsif (highlighted)highlighted-clear();if (pos _size)return buffer;if (maxSize 0)maxSize _size;elseif ((pos maxSize) _size)maxSize _size - pos;_ioDevice-open(QIODevice::ReadOnly);while (maxSize 0){chunk.absPos LLONG_MAX;bool chunksLoopOngoing true;while ((chunkIdx _chunks.count()) chunksLoopOngoing){// In this section, we track changes before our required data and// we take the editdet data, if availible. ioDelta is a difference// counter to justify the read pointer to the original data, if// data in between was deleted or inserted.chunk _chunks[chunkIdx];if (chunk.absPos pos)chunksLoopOngoing false;else{chunkIdx 1;qint64 count;qint64 chunkOfs pos - chunk.absPos;if (maxSize ((qint64)chunk.data.size() - chunkOfs)){count (qint64)chunk.data.size() - chunkOfs;ioDelta CHUNK_SIZE - chunk.data.size();}elsecount maxSize;if (count 0){buffer chunk.data.mid(chunkOfs, (int)count);maxSize - count;pos count;if (highlighted)*highlighted chunk.dataChanged.mid(chunkOfs, (int)count);}}}if ((maxSize 0) (pos chunk.absPos)){// In this section, we read data from the original source. This only will// happen, whe no copied data is availableqint64 byteCount;QByteArray readBuffer;if ((chunk.absPos - pos) maxSize)byteCount maxSize;elsebyteCount chunk.absPos - pos;maxSize - byteCount;_ioDevice-seek(pos ioDelta);readBuffer _ioDevice-read(byteCount);buffer readBuffer;if (highlighted)*highlighted QByteArray(readBuffer.size(), NORMAL);pos readBuffer.size();}}_ioDevice-close();return buffer; }bool Chunks::write(QIODevice iODevice, qint64 pos, qint64 count) {if (count -1)count _size;bool ok iODevice.open(QIODevice::WriteOnly);if (ok){for (qint64 idxpos; idx count; idx BUFFER_SIZE){QByteArray ba data(idx, BUFFER_SIZE);iODevice.write(ba);}iODevice.close();}return ok; }// ***************************************** Set and get highlighting infosvoid Chunks::setDataChanged(qint64 pos, bool dataChanged) {if ((pos 0) || (pos _size))return;int chunkIdx getChunkIndex(pos);qint64 posInBa pos - _chunks[chunkIdx].absPos;_chunks[chunkIdx].dataChanged[(int)posInBa] char(dataChanged); }bool Chunks::dataChanged(qint64 pos) {QByteArray highlighted;data(pos, 1, highlighted);return bool(highlighted.at(0)); }// ***************************************** Search APIqint64 Chunks::indexOf(const QByteArray ba, qint64 from) {qint64 result -1;QByteArray buffer;for (qint64 posfrom; (pos _size) (result 0); pos BUFFER_SIZE){buffer data(pos, BUFFER_SIZE ba.size() - 1);int findPos buffer.indexOf(ba);if (findPos 0)result pos (qint64)findPos;}return result; }qint64 Chunks::lastIndexOf(const QByteArray ba, qint64 from) {qint64 result -1;QByteArray buffer;for (qint64 posfrom; (pos 0) (result 0); pos - BUFFER_SIZE){qint64 sPos pos - BUFFER_SIZE - (qint64)ba.size() 1;if (sPos 0)sPos 0;buffer data(sPos, pos - sPos);int findPos buffer.lastIndexOf(ba);if (findPos 0)result sPos (qint64)findPos;}return result; }// ***************************************** Char manipulationsbool Chunks::insert(qint64 pos, char b) {if ((pos 0) || (pos _size))return false;int chunkIdx;if (pos _size)chunkIdx getChunkIndex(pos-1);elsechunkIdx getChunkIndex(pos);qint64 posInBa pos - _chunks[chunkIdx].absPos;_chunks[chunkIdx].data.insert(posInBa, b);_chunks[chunkIdx].dataChanged.insert(posInBa, char(1));for (int idxchunkIdx1; idx _chunks.size(); idx)_chunks[idx].absPos 1;_size 1;_pos pos;return true; }bool Chunks::overwrite(qint64 pos, char b) {if ((pos 0) || (pos _size))return false;int chunkIdx getChunkIndex(pos);qint64 posInBa pos - _chunks[chunkIdx].absPos;_chunks[chunkIdx].data[(int)posInBa] b;_chunks[chunkIdx].dataChanged[(int)posInBa] char(1);_pos pos;return true; }bool Chunks::removeAt(qint64 pos) {if ((pos 0) || (pos _size))return false;int chunkIdx getChunkIndex(pos);qint64 posInBa pos - _chunks[chunkIdx].absPos;_chunks[chunkIdx].data.remove(posInBa, 1);_chunks[chunkIdx].dataChanged.remove(posInBa, 1);for (int idxchunkIdx1; idx _chunks.size(); idx)_chunks[idx].absPos - 1;_size - 1;_pos pos;return true; }// ***************************************** Utility functionschar Chunks::operator[](qint64 pos) {return data(pos, 1)[0]; }qint64 Chunks::pos() {return _pos; }qint64 Chunks::size() {return _size; }int Chunks::getChunkIndex(qint64 absPos) {// This routine checks, if there is already a copied chunk available. If os, it// returns a reference to it. If there is no copied chunk available, original// data will be copied into a new chunk.int foundIdx -1;int insertIdx 0;qint64 ioDelta 0;for (int idx0; idx _chunks.size(); idx){Chunk chunk _chunks[idx];if ((absPos chunk.absPos) (absPos (chunk.absPos chunk.data.size()))){foundIdx idx;break;}if (absPos chunk.absPos){insertIdx idx;break;}ioDelta chunk.data.size() - CHUNK_SIZE;insertIdx idx 1;}if (foundIdx -1){Chunk newChunk;qint64 readAbsPos absPos - ioDelta;qint64 readPos (readAbsPos READ_CHUNK_MASK);_ioDevice-open(QIODevice::ReadOnly);_ioDevice-seek(readPos);newChunk.data _ioDevice-read(CHUNK_SIZE);_ioDevice-close();newChunk.absPos absPos - (readAbsPos - readPos);newChunk.dataChanged QByteArray(newChunk.data.size(), char(0));_chunks.insert(insertIdx, newChunk);foundIdx insertIdx;}return foundIdx; }#ifdef MODUL_TEST int Chunks::chunkSize() {return _chunks.size(); }#endifcommands.h #ifndef COMMANDS_H #define COMMANDS_H/** \cond docNever */#include QUndoStack#include chunks.h/*! CharCommand is a class to provid undo/redo functionality in QHexEdit. A QUndoCommand represents a single editing action on a document. CharCommand is responsable for manipulations on single chars. It can insert. overwrite and remove characters. A manipulation stores allways two actions 1. redo (or do) action 2. undo action.CharCommand also supports command compression via mergeWidht(). This enables the user to perform an undo command e.g. 3 steps in a single command. If you for example insert a new byt 34 this means for the editor doing 3 steps: insert a 00, overwrite it with 03 and the overwrite it with 34. These 3 steps are combined into a single step, insert a 34.The byte array oriented commands are just put into a set of single byte commands, which are pooled together with the macroBegin() and macroEnd() functionality of Qts QUndoStack. */class UndoStack : public QUndoStack {Q_OBJECTpublic:UndoStack(Chunks *chunks, QObject * parent0);void insert(qint64 pos, char c);void insert(qint64 pos, const QByteArray ba);void removeAt(qint64 pos, qint64 len1);void overwrite(qint64 pos, char c);void overwrite(qint64 pos, int len, const QByteArray ba);private:Chunks * _chunks;QObject * _parent; };/** \endcond docNever */#endif // COMMANDS_Hcommands.cpp #include commands.h #include QUndoCommand// Helper class to store single byte commands class CharCommand : public QUndoCommand { public:enum CCmd {insert, removeAt, overwrite};CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar,QUndoCommand *parent0);void undo();void redo();bool mergeWith(const QUndoCommand *command);int id() const { return 1234; }private:Chunks * _chunks;qint64 _charPos;bool _wasChanged;char _newChar;char _oldChar;CCmd _cmd; };CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent): QUndoCommand(parent) {_chunks chunks;_charPos charPos;_newChar newChar;_cmd cmd; }bool CharCommand::mergeWith(const QUndoCommand *command) {const CharCommand *nextCommand static_castconst CharCommand *(command);bool result false;if (_cmd ! CharCommand::removeAt){if (nextCommand-_cmd overwrite)if (nextCommand-_charPos _charPos){_newChar nextCommand-_newChar;result true;}}return result; }void CharCommand::undo() {switch (_cmd){case insert:_chunks-removeAt(_charPos);break;case overwrite:_chunks-overwrite(_charPos, _oldChar);_chunks-setDataChanged(_charPos, _wasChanged);break;case removeAt:_chunks-insert(_charPos, _oldChar);_chunks-setDataChanged(_charPos, _wasChanged);break;} }void CharCommand::redo() {switch (_cmd){case insert:_chunks-insert(_charPos, _newChar);break;case overwrite:_oldChar (*_chunks)[_charPos];_wasChanged _chunks-dataChanged(_charPos);_chunks-overwrite(_charPos, _newChar);break;case removeAt:_oldChar (*_chunks)[_charPos];_wasChanged _chunks-dataChanged(_charPos);_chunks-removeAt(_charPos);break;} }UndoStack::UndoStack(Chunks * chunks, QObject * parent): QUndoStack(parent) {_chunks chunks;_parent parent;this-setUndoLimit(1000); }void UndoStack::insert(qint64 pos, char c) {if ((pos 0) (pos _chunks-size())){QUndoCommand *cc new CharCommand(_chunks, CharCommand::insert, pos, c);this-push(cc);} }void UndoStack::insert(qint64 pos, const QByteArray ba) {if ((pos 0) (pos _chunks-size())){QString txt QString(tr(Inserting %1 bytes)).arg(ba.size());beginMacro(txt);for (int idx0; idx ba.size(); idx){QUndoCommand *cc new CharCommand(_chunks, CharCommand::insert, pos idx, ba.at(idx));this-push(cc);}endMacro();} }void UndoStack::removeAt(qint64 pos, qint64 len) {if ((pos 0) (pos _chunks-size())){if (len1){QUndoCommand *cc new CharCommand(_chunks, CharCommand::removeAt, pos, char(0));this-push(cc);}else{QString txt QString(tr(Delete %1 chars)).arg(len);beginMacro(txt);for (qint64 cnt0; cntlen; cnt){QUndoCommand *cc new CharCommand(_chunks, CharCommand::removeAt, pos, char(0));push(cc);}endMacro();}} }void UndoStack::overwrite(qint64 pos, char c) {if ((pos 0) (pos _chunks-size())){QUndoCommand *cc new CharCommand(_chunks, CharCommand::overwrite, pos, c);this-push(cc);} }void UndoStack::overwrite(qint64 pos, int len, const QByteArray ba) {if ((pos 0) (pos _chunks-size())){QString txt QString(tr(Overwrite %1 chars)).arg(len);beginMacro(txt);removeAt(pos, len);insert(pos, ba);endMacro();} }qhexedit.h #ifndef QHEXEDIT_H #define QHEXEDIT_H#include QAbstractScrollArea #include QPen #include QBrush#include chunks.h #include commands.h#ifdef QHEXEDIT_EXPORTS #define QHEXEDIT_API Q_DECL_EXPORT #elif QHEXEDIT_IMPORTS #define QHEXEDIT_API Q_DECL_IMPORT #else #define QHEXEDIT_API #endif/** \mainpage QHexEdit is a binary editor widget for Qt. *//** QHexEdit is a hex editor widget written in C for the Qt (Qt4, Qt5) framework. It is a simple editor for binary data, just like QPlainTextEdit is for text data. There are sip configuration files included, so it is easy to create bindings for PyQt and you can use this widget also in python 2 and 3.QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f) you will change the data. Changed data is highlighted and can be accessed via data().Normally QHexEdit works in the overwrite mode. You can set overwrite mode(false) and insert data. In this case the size of data() increases. It is also possible to delete bytes (del or backspace), here the size of data decreases.You can select data with keyboard hits or mouse movements. The copy-key will copy the selected data into the clipboard. The cut-key copies also but deletes it afterwards. In overwrite mode, the paste function overwrites the content of the (does not change the length) data. In insert mode, clipboard data will be inserted. The clipboard content is expected in ASCII Hex notation. Unknown characters will be ignored.QHexEdit comes with undo/redo functionality. All changes can be undone, by pressing the undo-key (usually ctr-z). They can also be redone afterwards. The undo/redo framework is cleared, when setData() sets up a new content for the editor. You can search data inside the content with indexOf() and lastIndexOf(). The replace() function is to change located subdata. This replaced data can also be undone by the undo/redo framework.QHexEdit is based on QIODevice, thats why QHexEdit can handle big amounts of data. The size of edited data can be more then two gigabytes without any restrictions. */class QHEXEDIT_API QHexEdit : public QAbstractScrollArea {Q_OBJECT/*! Property address area switch the address area on or off. Set addressArea true(show it), false (hide it).*/Q_PROPERTY(bool addressArea READ addressArea WRITE setAddressArea)/*! Property address area color sets (setAddressAreaColor()) the backgroundcolor of address areas. You can also read the color (addressAreaColor()).*/Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor)/*! Property addressOffset is added to the Numbers of the Address Area.A offset in the address area (left side) is sometimes useful, whe you showonly a segment of a complete memory picture. With setAddressOffset() you setthis property - with addressOffset() you get the current value.*/Q_PROPERTY(qint64 addressOffset READ addressOffset WRITE setAddressOffset)/*! Set and get the minimum width of the address area, width in characters.*/Q_PROPERTY(int addressWidth READ addressWidth WRITE setAddressWidth)/*! Switch the ascii area on (true, show it) or off (false, hide it).*/Q_PROPERTY(bool asciiArea READ asciiArea WRITE setAsciiArea)/*! Set and get bytes number per line.*/Q_PROPERTY(int bytesPerLine READ bytesPerLine WRITE setBytesPerLine)/*! Property cursorPosition sets or gets the position of the editor cursorin QHexEdit. Every byte in data has two cursor positions: the lower and upperNibble. Maximum cursor position is factor two of data.size().*/Q_PROPERTY(qint64 cursorPosition READ cursorPosition WRITE setCursorPosition)/*! Property data holds the content of QHexEdit. Call setData() to set thecontent of QHexEdit, data() returns the actual content. When calling setData()with a QByteArray as argument, QHexEdit creates a internal copy of the dataIf you want to edit big files please use setData(), based on QIODevice.*/Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged)/*! That property defines if the hex values looks as a-f if the value is false(default)or A-F if value is true.*/Q_PROPERTY(bool hexCaps READ hexCaps WRITE setHexCaps)/*! Property defines the dynamic calculation of bytesPerLine parameter depends of width of widget.set this property true to avoid horizontal scrollbars and show the maximal possible data. defalut value is false*/Q_PROPERTY(bool dynamicBytesPerLine READ dynamicBytesPerLine WRITE setDynamicBytesPerLine)/*! Switch the highlighting feature on or of: true (show it), false (hide it).*/Q_PROPERTY(bool highlighting READ highlighting WRITE setHighlighting)/*! Property highlighting color sets (setHighlightingColor()) the backgroundcolor of highlighted text areas. You can also read the color(highlightingColor()).*/Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor)/*! Property overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the modein which the editor works. In overwrite mode the user will overwrite existing data. Thesize of data will be constant. In insert mode the size will grow, when insertingnew data.*/Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)/*! Property selection color sets (setSelectionColor()) the backgroundcolor of selected text areas. You can also read the color(selectionColor()).*/Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)/*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the modein which the editor works. In readonly mode the the user can only navigatethrough the data and select data; modifying is not possible. Thispropertys default is false.*/Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)/*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/Q_PROPERTY(QFont font READ font WRITE setFont)public:/*! Creates an instance of QHexEdit.\param parent Parent widget of QHexEdit.*/QHexEdit(QWidget *parent0);// Access to data of qhexedit/*! Sets the data of QHexEdit. The QIODevice will be opened just before readingand closed immediately afterwards. This is to allow other programs to rewritethe file while editing it.*/bool setData(QIODevice iODevice);/*! Gives back the data as a QByteArray starting at position \param pos anddelivering \param count bytes.*/QByteArray dataAt(qint64 pos, qint64 count-1);/*! Gives back the data into a \param iODevice starting at position \param posand delivering \param count bytes.*/bool write(QIODevice iODevice, qint64 pos0, qint64 count-1);// Char handling/*! Inserts a char.\param pos Index position, where to insert\param ch Char, which is to insertThe char will be inserted and size of data grows.*/void insert(qint64 pos, char ch);/*! Removes len bytes from the content.\param pos Index position, where to remove\param len Amount of bytes to remove*/void remove(qint64 pos, qint64 len1);/*! Replaces a char.\param pos Index position, where to overwrite\param ch Char, which is to insertThe char will be overwritten and size remains constant.*/void replace(qint64 pos, char ch);// ByteArray handling/*! Inserts a byte array.\param pos Index position, where to insert\param ba QByteArray, which is to insertThe QByteArray will be inserted and size of data grows.*/void insert(qint64 pos, const QByteArray ba);/*! Replaces \param len bytes with a byte array \param ba\param pos Index position, where to overwrite\param ba QByteArray, which is inserted\param len count of bytes to overwriteThe data is overwritten and size of data may change.*/void replace(qint64 pos, qint64 len, const QByteArray ba);// Utility functions/*! Calc cursor position from graphics position* \param point from where the cursor position should be calculated* \return Cursor position*/qint64 cursorPosition(QPoint point);/*! Ensure the cursor to be visbile*/void ensureVisible();/*! Find first occurrence of ba in QHexEdit data* \param ba Data to find* \param from Point where the search starts* \return pos if fond, else -1*/qint64 indexOf(const QByteArray ba, qint64 from);/*! Returns if any changes where done on document* \return true when document is modified else false*/bool isModified();/*! Find last occurrence of ba in QHexEdit data* \param ba Data to find* \param from Point where the search starts* \return pos if fond, else -1*/qint64 lastIndexOf(const QByteArray ba, qint64 from);/*! Gives back a formatted image of the selected content of QHexEdit*/QString selectionToReadableString();/*! Return the selected content of QHexEdit as QByteArray*/QString selectedData();/*! Set Font of QHexEdit* \param font*/void setFont(const QFont font);/*! Gives back a formatted image of the content of QHexEdit*/QString toReadableString();public slots:/*! Redoes the last operation. If there is no operation to redo, i.e.there is no redo step in the undo/redo history, nothing happens.*/void redo();/*! Undoes the last operation. If there is no operation to undo, i.e.there is no undo step in the undo/redo history, nothing happens.*/void undo();signals:/*! Contains the address, where the cursor is located. */void currentAddressChanged(qint64 address);/*! Contains the size of the data to edit. */void currentSizeChanged(qint64 size);/*! The signal is emitted every time, the data is changed. */void dataChanged();/*! The signal is emitted every time, the overwrite mode is changed. */void overwriteModeChanged(bool state);/*! \cond docNever */ public:~QHexEdit();// Propertiesbool addressArea();void setAddressArea(bool addressArea);QColor addressAreaColor();void setAddressAreaColor(const QColor color);QColor addressAreaPenColor();void setAddressAreaPenColor(const QColor color);QColor dataAreaPenColor();void setDataAreaPenColor(const QColor color);qint64 addressOffset();void setAddressOffset(qint64 addressArea);int addressWidth();void setAddressWidth(int addressWidth);bool asciiArea();void setAsciiArea(bool asciiArea);int bytesPerLine();void setBytesPerLine(int count);qint64 cursorPosition();void setCursorPosition(qint64 position);QByteArray data();void setData(const QByteArray ba);void appenData(const QByteArray ba);void setHexCaps(const bool isCaps);bool hexCaps();void setDynamicBytesPerLine(const bool isDynamic);bool dynamicBytesPerLine();bool highlighting();void setHighlighting(bool mode);QColor highlightingColor();void setHighlightingColor(const QColor color);bool overwriteMode();void setOverwriteMode(bool overwriteMode);bool isReadOnly();void setReadOnly(bool readOnly);QColor selectionColor();void setSelectionColor(const QColor color);protected:// Handle eventsvoid keyPressEvent(QKeyEvent *event);void mouseMoveEvent(QMouseEvent * event);void mousePressEvent(QMouseEvent * event);void paintEvent(QPaintEvent *event);void resizeEvent(QResizeEvent *);virtual bool focusNextPrevChild(bool next);private:// Handle selectionsvoid resetSelection(qint64 pos); // set selectionStart and selectionEnd to posvoid resetSelection(); // set selectionEnd to selectionStartvoid setSelection(qint64 pos); // set min (if below init) or max (if greater init)qint64 getSelectionBegin();qint64 getSelectionEnd();// Private utility functionsvoid init();void readBuffers();QString toReadable(const QByteArray ba);private slots:void adjust(); // recalc pixel positionsvoid dataChangedPrivate(int idx0); // emit dataChanged() signalvoid refresh(); // ensureVisible() and readBuffers()void updateCursor(); // update blinking cursorprivate:// Name convention: pixel positions start with _pxint _pxCharWidth, _pxCharHeight; // char dimensions (dependend on font)int _pxPosHexX; // X-Pos of HeaxAreaint _pxPosAdrX; // X-Pos of Address Areaint _pxPosAsciiX; // X-Pos of Ascii Areaint _pxGapAdr; // gap left from AddressAreaint _pxGapAdrHex; // gap between AddressArea and HexAereaint _pxGapHexAscii; // gap between HexArea and AsciiAreaint _pxCursorWidth; // cursor widthint _pxSelectionSub; // offset selection rectint _pxCursorX; // current cursor posint _pxCursorY; // current cursor pos// Name convention: absolute byte positions in chunks start with _bqint64 _bSelectionBegin; // first position of Selectionqint64 _bSelectionEnd; // end of Selectionqint64 _bSelectionInit; // memory position of Selectionqint64 _bPosFirst; // position of first byte shownqint64 _bPosLast; // position of last byte shownqint64 _bPosCurrent; // current position// variables to store the property valuesbool _addressArea; // left area of QHexEditQColor _addressAreaColor;QColor _addressAreaPenColor;QColor _dataAreaPenColor;int _addressWidth;bool _asciiArea;qint64 _addressOffset;int _bytesPerLine;int _hexCharsInLine;bool _highlighting;bool _overwriteMode;QBrush _brushSelection;QPen _penSelection;QBrush _brushHighlighted;QPen _penHighlighted;bool _readOnly;bool _hexCaps;bool _dynamicBytesPerLine;// other variablesbool _editAreaIsAscii; // flag about the ascii mode editedint _addrDigits; // real no of addressdigits, may be addressWidthbool _blink; // help get cursor blinkingQBuffer _bData; // buffer, when setup with QByteArrayChunks *_chunks; // IODevice based access to dataQTimer _cursorTimer; // for blinking cursorqint64 _cursorPosition; // absolute position of cursor, 1 Byte 2 ticsQRect _cursorRect; // physical dimensions of cursorQByteArray _data; // QHexEdits data, when setup with QByteArrayQByteArray _dataShown; // data in the current ViewQByteArray _hexDataShown; // data in view, transformed to hexqint64 _lastEventSize; // size, which was emitted last timeQByteArray _markedShown; // marked data in viewbool _modified; // Is any data in editor modified?int _rowsShown; // lines of text shownUndoStack * _undoStack; // Stack to store edit actions for undo/redo/*! \endcond docNever */ };#endif // QHEXEDIT_Hqhexedit.cpp #include QApplication #include QClipboard #include QKeyEvent #include QPainter #include QScrollBar#include qhexedit.h #include algorithmQHexEdit::QHexEdit(QWidget *parent) : QAbstractScrollArea(parent) {_addressArea true;_addressWidth 4;_asciiArea true;_overwriteMode true;_highlighting true;_readOnly false;_cursorPosition 0;_lastEventSize 0;_hexCharsInLine 47;_bytesPerLine 16;_editAreaIsAscii false;_hexCaps true;_dynamicBytesPerLine false;_chunks new Chunks(this);_undoStack new UndoStack(_chunks, this);#ifdef Q_OS_WIN32setFont(QFont(Courier, 10, 75)); #elsesetFont(QFont(Monospace, 10)); #endifsetAddressAreaColor(this-palette().alternateBase().color());setHighlightingColor(QColor(0xff, 0xff, 0x99, 0xff));setSelectionColor(this-palette().highlight().color());connect(_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor()));connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust()));connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust()));connect(_undoStack, SIGNAL(indexChanged(int)), this, SLOT(dataChangedPrivate(int)));_cursorTimer.setInterval(500);_cursorTimer.start();setAddressWidth(4);setAddressArea(true);setAsciiArea(true);setOverwriteMode(true);setHighlighting(true);setReadOnly(false);init(); }QHexEdit::~QHexEdit() {}// ********************************************************************** Propertiesvoid QHexEdit::setAddressArea(bool addressArea) {_addressArea addressArea;adjust();setCursorPosition(_cursorPosition);viewport()-update(); }bool QHexEdit::addressArea() {return _addressArea; }void QHexEdit::setAddressAreaColor(const QColor color) {_addressAreaColor color;viewport()-update(); }QColor QHexEdit::addressAreaPenColor() {return _addressAreaPenColor; }void QHexEdit::setAddressAreaPenColor(const QColor color) {_addressAreaPenColor color;viewport()-update(); }QColor QHexEdit::dataAreaPenColor() {return _dataAreaPenColor; }void QHexEdit::setDataAreaPenColor(const QColor color) {_dataAreaPenColor color;viewport()-update(); }QColor QHexEdit::addressAreaColor() {return _addressAreaColor; }void QHexEdit::setAddressOffset(qint64 addressOffset) {_addressOffset addressOffset;adjust();setCursorPosition(_cursorPosition);viewport()-update(); }qint64 QHexEdit::addressOffset() {return _addressOffset; }void QHexEdit::setAddressWidth(int addressWidth) {_addressWidth addressWidth;adjust();setCursorPosition(_cursorPosition);viewport()-update(); }int QHexEdit::addressWidth() {qint64 size _chunks-size();int n 1;if (size Q_INT64_C(0x100000000)){ n 8; size / Q_INT64_C(0x100000000);}if (size 0x10000){ n 4; size / 0x10000;}if (size 0x100){ n 2; size / 0x100;}if (size 0x10){ n 1;}if (n _addressWidth)return n;elsereturn _addressWidth; }void QHexEdit::setAsciiArea(bool asciiArea) {if (!asciiArea)_editAreaIsAscii false;_asciiArea asciiArea;adjust();setCursorPosition(_cursorPosition);viewport()-update(); }bool QHexEdit::asciiArea() {return _asciiArea; }void QHexEdit::setBytesPerLine(int count) {_bytesPerLine count;_hexCharsInLine count * 3 - 1;adjust();setCursorPosition(_cursorPosition);viewport()-update(); }int QHexEdit::bytesPerLine() {return _bytesPerLine; }void QHexEdit::setCursorPosition(qint64 position) {// 1. delete old cursor_blink false;viewport()-update(_cursorRect);// 2. Check, if cursor in range?if (position (_chunks-size() * 2 - 1))position _chunks-size() * 2 - (_overwriteMode ? 1 : 0);if (position 0)position 0;// 3. Calc new position of cursor_bPosCurrent position / 2;_pxCursorY ((position / 2 - _bPosFirst) / _bytesPerLine 1) * _pxCharHeight;int x (position % (2 * _bytesPerLine));if (_editAreaIsAscii){_pxCursorX x / 2 * _pxCharWidth _pxPosAsciiX;_cursorPosition position 0xFFFFFFFFFFFFFFFE;}else{_pxCursorX (((x / 2) * 3) (x % 2)) * _pxCharWidth _pxPosHexX;_cursorPosition position;}if (_overwriteMode)_cursorRect QRect(_pxCursorX - horizontalScrollBar()-value(), _pxCursorY _pxCursorWidth, _pxCharWidth, _pxCursorWidth);else_cursorRect QRect(_pxCursorX - horizontalScrollBar()-value(), _pxCursorY - _pxCharHeight 4, _pxCursorWidth, _pxCharHeight);// 4. Immediately draw new cursor_blink true;viewport()-update(_cursorRect);emit currentAddressChanged(_bPosCurrent); }qint64 QHexEdit::cursorPosition(QPoint pos) {// Calc cursor position depending on a graphical positionqint64 result -1;int posX pos.x() horizontalScrollBar()-value();int posY pos.y() - 3;if ((posX _pxPosHexX) (posX (_pxPosHexX (1 _hexCharsInLine) * _pxCharWidth))){_editAreaIsAscii false;int x (posX - _pxPosHexX) / _pxCharWidth;x (x / 3) * 2 x % 3;int y (posY / _pxCharHeight) * 2 * _bytesPerLine;result _bPosFirst * 2 x y;}elseif (_asciiArea (posX _pxPosAsciiX) (posX (_pxPosAsciiX (1 _bytesPerLine) * _pxCharWidth))){_editAreaIsAscii true;int x 2 * (posX - _pxPosAsciiX) / _pxCharWidth;int y (posY / _pxCharHeight) * 2 * _bytesPerLine;result _bPosFirst * 2 x y;}return result; }qint64 QHexEdit::cursorPosition() {return _cursorPosition; }void QHexEdit::setData(const QByteArray ba) {_data ba;_bData.setData(_data);setData(_bData); }void QHexEdit::appenData(const QByteArray ba) {_data.append(ba);_bData.setData(_data);setData(_bData); }QByteArray QHexEdit::data() {return _chunks-data(0, -1); }void QHexEdit::setHighlighting(bool highlighting) {_highlighting highlighting;viewport()-update(); }bool QHexEdit::highlighting() {return _highlighting; }void QHexEdit::setHighlightingColor(const QColor color) {_brushHighlighted QBrush(color);_penHighlighted QPen(viewport()-palette().color(QPalette::WindowText));viewport()-update(); }QColor QHexEdit::highlightingColor() {return _brushHighlighted.color(); }void QHexEdit::setOverwriteMode(bool overwriteMode) {_overwriteMode overwriteMode;emit overwriteModeChanged(overwriteMode); }bool QHexEdit::overwriteMode() {return _overwriteMode; }void QHexEdit::setSelectionColor(const QColor color) {_brushSelection QBrush(color);_penSelection QPen(Qt::white);viewport()-update(); }QColor QHexEdit::selectionColor() {return _brushSelection.color(); }bool QHexEdit::isReadOnly() {return _readOnly; }void QHexEdit::setReadOnly(bool readOnly) {_readOnly readOnly; }void QHexEdit::setHexCaps(const bool isCaps) {if (_hexCaps ! isCaps){_hexCaps isCaps;viewport()-update();} }bool QHexEdit::hexCaps() {return _hexCaps; }void QHexEdit::setDynamicBytesPerLine(const bool isDynamic) {_dynamicBytesPerLine isDynamic;resizeEvent(NULL); }bool QHexEdit::dynamicBytesPerLine() {return _dynamicBytesPerLine; }// ********************************************************************** Access to data of qhexedit bool QHexEdit::setData(QIODevice iODevice) {bool ok _chunks-setIODevice(iODevice);init();dataChangedPrivate();return ok; }QByteArray QHexEdit::dataAt(qint64 pos, qint64 count) {return _chunks-data(pos, count); }bool QHexEdit::write(QIODevice iODevice, qint64 pos, qint64 count) {return _chunks-write(iODevice, pos, count); }// ********************************************************************** Char handling void QHexEdit::insert(qint64 index, char ch) {_undoStack-insert(index, ch);refresh(); }void QHexEdit::remove(qint64 index, qint64 len) {_undoStack-removeAt(index, len);refresh(); }void QHexEdit::replace(qint64 index, char ch) {_undoStack-overwrite(index, ch);refresh(); }// ********************************************************************** ByteArray handling void QHexEdit::insert(qint64 pos, const QByteArray ba) {_undoStack-insert(pos, ba);refresh(); }void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray ba) {_undoStack-overwrite(pos, len, ba);refresh(); }// ********************************************************************** Utility functions void QHexEdit::ensureVisible() {if (_cursorPosition (_bPosFirst * 2))verticalScrollBar()-setValue((int)(_cursorPosition / 2 / _bytesPerLine));if (_cursorPosition ((_bPosFirst (_rowsShown - 1)*_bytesPerLine) * 2))verticalScrollBar()-setValue((int)(_cursorPosition / 2 / _bytesPerLine) - _rowsShown 1);if (_pxCursorX horizontalScrollBar()-value())horizontalScrollBar()-setValue(_pxCursorX);if ((_pxCursorX _pxCharWidth) (horizontalScrollBar()-value() viewport()-width()))horizontalScrollBar()-setValue(_pxCursorX _pxCharWidth - viewport()-width());viewport()-update(); }qint64 QHexEdit::indexOf(const QByteArray ba, qint64 from) {qint64 pos _chunks-indexOf(ba, from);if (pos -1){qint64 curPos pos*2;setCursorPosition(curPos ba.length()*2);resetSelection(curPos);setSelection(curPos ba.length()*2);ensureVisible();}return pos; }bool QHexEdit::isModified() {return _modified; }qint64 QHexEdit::lastIndexOf(const QByteArray ba, qint64 from) {qint64 pos _chunks-lastIndexOf(ba, from);if (pos -1){qint64 curPos pos*2;setCursorPosition(curPos - 1);resetSelection(curPos);setSelection(curPos ba.length()*2);ensureVisible();}return pos; }void QHexEdit::redo() {_undoStack-redo();setCursorPosition(_chunks-pos()*(_editAreaIsAscii ? 1 : 2));refresh(); }QString QHexEdit::selectionToReadableString() {QByteArray ba _chunks-data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin());return toReadable(ba); }QString QHexEdit::selectedData() {QByteArray ba _chunks-data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex();return ba; }void QHexEdit::setFont(const QFont font) {QFont theFont(font);theFont.setStyleHint(QFont::Monospace);QWidget::setFont(theFont);QFontMetrics metrics fontMetrics();#if QT_VERSION QT_VERSION_CHECK(5, 11, 0)_pxCharWidth metrics.horizontalAdvance(QLatin1Char(2)); #else_pxCharWidth metrics.width(QLatin1Char(2)); #endif_pxCharHeight metrics.height();_pxGapAdr _pxCharWidth / 2;_pxGapAdrHex _pxCharWidth;_pxGapHexAscii 2 * _pxCharWidth;_pxCursorWidth _pxCharHeight / 7;_pxSelectionSub _pxCharHeight / 5;viewport()-update(); }QString QHexEdit::toReadableString() {QByteArray ba _chunks-data();return toReadable(ba); }void QHexEdit::undo() {_undoStack-undo();setCursorPosition(_chunks-pos()*(_editAreaIsAscii ? 1 : 2));refresh(); }// ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) {// Cursor movementsif (event-matches(QKeySequence::MoveToNextChar)){qint64 pos _cursorPosition 1;if (_editAreaIsAscii)pos 1;setCursorPosition(pos);resetSelection(pos);}if (event-matches(QKeySequence::MoveToPreviousChar)){qint64 pos _cursorPosition - 1;if (_editAreaIsAscii)pos - 1;setCursorPosition(pos);resetSelection(pos);}if (event-matches(QKeySequence::MoveToEndOfLine)){qint64 pos _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) (2 * _bytesPerLine) - 1;setCursorPosition(pos);resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToStartOfLine)){qint64 pos _cursorPosition - (_cursorPosition % (2 * _bytesPerLine));setCursorPosition(pos);resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToPreviousLine)){setCursorPosition(_cursorPosition - (2 * _bytesPerLine));resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToNextLine)){setCursorPosition(_cursorPosition (2 * _bytesPerLine));resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToNextPage)){setCursorPosition(_cursorPosition (((_rowsShown - 1) * 2 * _bytesPerLine)));resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToPreviousPage)){setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * _bytesPerLine)));resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToEndOfDocument)){setCursorPosition(_chunks-size() * 2 );resetSelection(_cursorPosition);}if (event-matches(QKeySequence::MoveToStartOfDocument)){setCursorPosition(0);resetSelection(_cursorPosition);}// Select commandsif (event-matches(QKeySequence::SelectAll)){resetSelection(0);setSelection(2 * _chunks-size() 1);}if (event-matches(QKeySequence::SelectNextChar)){qint64 pos _cursorPosition 1;if (_editAreaIsAscii)pos 1;setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectPreviousChar)){qint64 pos _cursorPosition - 1;if (_editAreaIsAscii)pos - 1;setSelection(pos);setCursorPosition(pos);}if (event-matches(QKeySequence::SelectEndOfLine)){qint64 pos _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) (2 * _bytesPerLine) - 1;setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectStartOfLine)){qint64 pos _cursorPosition - (_cursorPosition % (2 * _bytesPerLine));setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectPreviousLine)){qint64 pos _cursorPosition - (2 * _bytesPerLine);setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectNextLine)){qint64 pos _cursorPosition (2 * _bytesPerLine);setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectNextPage)){qint64 pos _cursorPosition (((viewport()-height() / _pxCharHeight) - 1) * 2 * _bytesPerLine);setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectPreviousPage)){qint64 pos _cursorPosition - (((viewport()-height() / _pxCharHeight) - 1) * 2 * _bytesPerLine);setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectEndOfDocument)){qint64 pos _chunks-size() * 2;setCursorPosition(pos);setSelection(pos);}if (event-matches(QKeySequence::SelectStartOfDocument)){qint64 pos 0;setCursorPosition(pos);setSelection(pos);}// Edit Commandsif (!_readOnly){/* Cut */if (event-matches(QKeySequence::Cut)){QByteArray ba _chunks-data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex();for (qint64 idx 32; idx ba.size(); idx 33)ba.insert(idx, \n);QClipboard *clipboard QApplication::clipboard();clipboard-setText(ba);if (_overwriteMode){qint64 len getSelectionEnd() - getSelectionBegin();replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0)));}else{remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin());}setCursorPosition(2 * getSelectionBegin());resetSelection(2 * getSelectionBegin());} else/* Paste */if (event-matches(QKeySequence::Paste)){QClipboard *clipboard QApplication::clipboard();QByteArray ba QByteArray().fromHex(clipboard-text().toLatin1());if (_overwriteMode){ba ba.left(std::minqint64(ba.size(), (_chunks-size() - _bPosCurrent)));replace(_bPosCurrent, ba.size(), ba);}elseinsert(_bPosCurrent, ba);setCursorPosition(_cursorPosition 2 * ba.size());resetSelection(getSelectionBegin());} else/* Delete char */if (event-matches(QKeySequence::Delete)){if (getSelectionBegin() ! getSelectionEnd()){_bPosCurrent getSelectionBegin();if (_overwriteMode){QByteArray ba QByteArray(getSelectionEnd() - getSelectionBegin(), char(0));replace(_bPosCurrent, ba.size(), ba);}else{remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin());}}else{if (_overwriteMode)replace(_bPosCurrent, char(0));elseremove(_bPosCurrent, 1);}setCursorPosition(2 * _bPosCurrent);resetSelection(2 * _bPosCurrent);} else/* Backspace */if ((event-key() Qt::Key_Backspace) (event-modifiers() Qt::NoModifier)){if (getSelectionBegin() ! getSelectionEnd()){_bPosCurrent getSelectionBegin();setCursorPosition(2 * _bPosCurrent);if (_overwriteMode){QByteArray ba QByteArray(getSelectionEnd() - getSelectionBegin(), char(0));replace(_bPosCurrent, ba.size(), ba);}else{remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin());}resetSelection(2 * _bPosCurrent);}else{bool behindLastByte false;if ((_cursorPosition / 2) _chunks-size())behindLastByte true;_bPosCurrent - 1;if (_overwriteMode)replace(_bPosCurrent, char(0));elseremove(_bPosCurrent, 1);if (!behindLastByte)_bPosCurrent - 1;setCursorPosition(2 * _bPosCurrent);resetSelection(2 * _bPosCurrent);}} else/* undo */if (event-matches(QKeySequence::Undo)){undo();} else/* redo */if (event-matches(QKeySequence::Redo)){redo();} elseif ((QApplication::keyboardModifiers() Qt::NoModifier) ||(QApplication::keyboardModifiers() Qt::KeypadModifier) ||(QApplication::keyboardModifiers() Qt::ShiftModifier) ||(QApplication::keyboardModifiers() (Qt::AltModifier | Qt::ControlModifier)) ||(QApplication::keyboardModifiers() Qt::GroupSwitchModifier)){/* Hex and ascii input */int key;if (_editAreaIsAscii)key (uchar)event-text()[0].toLatin1();elsekey int(event-text()[0].toLower().toLatin1());if ((((key 0 key 9) || (key a key f)) _editAreaIsAscii false)|| (key _editAreaIsAscii)){if (getSelectionBegin() ! getSelectionEnd()){if (_overwriteMode){qint64 len getSelectionEnd() - getSelectionBegin();replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0)));} else{remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin());_bPosCurrent getSelectionBegin();}setCursorPosition(2 * _bPosCurrent);resetSelection(2 * _bPosCurrent);}// If insert mode, then insert a byteif (_overwriteMode false)if ((_cursorPosition % 2) 0)insert(_bPosCurrent, char(0));// Change contentif (_chunks-size() 0){char ch key;if (!_editAreaIsAscii){QByteArray hexValue _chunks-data(_bPosCurrent, 1).toHex();if ((_cursorPosition % 2) 0)hexValue[0] key;elsehexValue[1] key;ch QByteArray().fromHex(hexValue)[0];}replace(_bPosCurrent, ch);if (_editAreaIsAscii)setCursorPosition(_cursorPosition 2);elsesetCursorPosition(_cursorPosition 1);resetSelection(_cursorPosition);}}}}/* Copy */if (event-matches(QKeySequence::Copy)){QByteArray ba _chunks-data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex();for (qint64 idx 32; idx ba.size(); idx 33)ba.insert(idx, \n);QClipboard *clipboard QApplication::clipboard();clipboard-setText(ba);}// Switch between insert/overwrite modeif ((event-key() Qt::Key_Insert) (event-modifiers() Qt::NoModifier)){setOverwriteMode(!overwriteMode());setCursorPosition(_cursorPosition);}// switch from hex to ascii editif (event-key() Qt::Key_Tab !_editAreaIsAscii){_editAreaIsAscii true;setCursorPosition(_cursorPosition);}// switch from ascii to hex editif (event-key() Qt::Key_Backtab _editAreaIsAscii){_editAreaIsAscii false;setCursorPosition(_cursorPosition);}refresh();QAbstractScrollArea::keyPressEvent(event); }void QHexEdit::mouseMoveEvent(QMouseEvent * event) {_blink false;viewport()-update();qint64 actPos cursorPosition(event-pos());if (actPos 0){setCursorPosition(actPos);setSelection(actPos);} }void QHexEdit::mousePressEvent(QMouseEvent * event) {_blink false;viewport()-update();qint64 cPos cursorPosition(event-pos());if (cPos 0){if (event-button() ! Qt::RightButton)resetSelection(cPos);setCursorPosition(cPos);} }void QHexEdit::paintEvent(QPaintEvent *event) {QPainter painter(viewport());auto oldPen painter.pen();oldPen.setColor(_dataAreaPenColor);painter.setPen(oldPen);int pxOfsX horizontalScrollBar()-value();if (event-rect() ! _cursorRect){int pxPosStartY _pxCharHeight;// draw some patterns if neededpainter.fillRect(event-rect(), viewport()-palette().color(QPalette::Base));if (_addressArea)painter.fillRect(QRect(-pxOfsX, event-rect().top(), _pxPosHexX - _pxGapAdrHex/2, height()), _addressAreaColor);/*if (_asciiArea){int linePos _pxPosAsciiX - (_pxGapHexAscii / 2);painter.setPen(Qt::gray);painter.drawLine(linePos - pxOfsX, event-rect().top(), linePos - pxOfsX, height());}*/painter.setPen(viewport()-palette().color(QPalette::WindowText));// paint address areaif (_addressArea){QString address;oldPen.setColor(_addressAreaPenColor);painter.setPen(oldPen);for (int row0, pxPosY _pxCharHeight*2; row (_dataShown.size()/_bytesPerLine); row, pxPosY _pxCharHeight){address QString(%1).arg(_bPosFirst row*_bytesPerLine _addressOffset, _addrDigits, 16, QChar(0));painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, hexCaps() ? address.toUpper() : address);}}// paint hex and ascii areaoldPen.setColor(_dataAreaPenColor);painter.setPen(oldPen);QPen colStandard QPen(viewport()-palette().color(QPalette::WindowText));painter.setBackgroundMode(Qt::TransparentMode);int pxPosX1 _pxPosHexX - pxOfsX;for (int i 0, pxPosY pxPosStartY; i 15; i){QString address;address QString(%1).arg(i,2,16,QLatin1Char(0));painter.drawText(pxPosX1, pxPosY, address.toUpper());pxPosX1 3*_pxCharWidth;}for (int row 0, pxPosY pxPosStartY*2; row _rowsShown; row, pxPosY _pxCharHeight){QByteArray hex;int pxPosX _pxPosHexX - pxOfsX;int pxPosAsciiX2 _pxPosAsciiX - pxOfsX;qint64 bPosLine row * _bytesPerLine;for (int colIdx 0; ((bPosLine colIdx) _dataShown.size() (colIdx _bytesPerLine)); colIdx){QColor c viewport()-palette().color(QPalette::Base);painter.setPen(colStandard);qint64 posBa _bPosFirst bPosLine colIdx;if ((getSelectionBegin() posBa) (getSelectionEnd() posBa)){c _brushSelection.color();painter.setPen(_penSelection);}else{if (_highlighting)if (_markedShown.at((int)(posBa - _bPosFirst))){c _brushHighlighted.color();painter.setPen(_penHighlighted);}}// render hex valueQRect r;if (colIdx 0)r.setRect(pxPosX, pxPosY - _pxCharHeight _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight);elser.setRect(pxPosX - _pxCharWidth, pxPosY - _pxCharHeight _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight);painter.fillRect(r, c);hex _hexDataShown.mid((bPosLine colIdx) * 2, 2);painter.drawText(pxPosX, pxPosY, hexCaps()?hex.toUpper():hex);pxPosX 3*_pxCharWidth;// render ascii valueif (_asciiArea){int ch (uchar)_dataShown.at(bPosLine colIdx);if ( ch || ch ~ )ch .;r.setRect(pxPosAsciiX2, pxPosY - _pxCharHeight _pxSelectionSub, _pxCharWidth, _pxCharHeight);painter.fillRect(r, c);painter.drawText(pxPosAsciiX2, pxPosY, QChar(ch));pxPosAsciiX2 _pxCharWidth;}}}painter.setBackgroundMode(Qt::TransparentMode);painter.setPen(viewport()-palette().color(QPalette::WindowText));}// _cursorPosition counts in 2, _bPosFirst counts in 1int hexPositionInShowData _cursorPosition - 2 * _bPosFirst;// due to scrolling the cursor can go out of the currently displayed dataif ((hexPositionInShowData 0) (hexPositionInShowData _hexDataShown.size())){// paint cursorif (_readOnly){// make the background stick outQColor color viewport()-palette().dark().color();painter.fillRect(QRect(_pxCursorX - pxOfsX, _pxCursorY - _pxCharHeight _pxSelectionSub, _pxCharWidth, _pxCharHeight), color);}else{if (_blink hasFocus())painter.fillRect(_cursorRect, this-palette().color(QPalette::WindowText));}if (_editAreaIsAscii){// every 2 hex there is 1 asciiint asciiPositionInShowData hexPositionInShowData / 2;if ((asciiPositionInShowData-16)0){int ch (uchar)_dataShown.at(asciiPositionInShowData-16);if (ch || ch ~)ch .;painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, QChar(ch));}elsepainter.drawText(_pxCursorX - pxOfsX, _pxCursorY, QChar( ));}else{if ((hexPositionInShowData-32) 0)painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, hexCaps() ? _hexDataShown.mid(hexPositionInShowData-32, 1).toUpper() : _hexDataShown.mid(hexPositionInShowData-32, 1));else{QString address;address QString(%1).arg(hexPositionInShowData%2 0 ? 0 : hexPositionInShowData/2,1,16,QLatin1Char(0));painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, address.toUpper());}}}// emit event, if size has changedif (_lastEventSize ! _chunks-size()){_lastEventSize _chunks-size();emit currentSizeChanged(_lastEventSize);} }void QHexEdit::resizeEvent(QResizeEvent *) {if (_dynamicBytesPerLine){int pxFixGaps 0;if (_addressArea)pxFixGaps addressWidth() * _pxCharWidth _pxGapAdr;pxFixGaps _pxGapAdrHex;if (_asciiArea)pxFixGaps _pxGapHexAscii;// 1 because the last hex value do not have space. so it is effective one char moreint charWidth (viewport()-width() - pxFixGaps ) / _pxCharWidth 1;// 2 hex alfa-digits 1 space 1 ascii per byte 4; if ascii is disabled then 3// to prevent devision by zero use the min value 1setBytesPerLine(std::max(charWidth / (_asciiArea ? 4 : 3),1));}adjust(); }bool QHexEdit::focusNextPrevChild(bool next) {if (_addressArea){if ( (next _editAreaIsAscii) || (!next !_editAreaIsAscii ))return QWidget::focusNextPrevChild(next);elsereturn false;}else{return QWidget::focusNextPrevChild(next);} }// ********************************************************************** Handle selections void QHexEdit::resetSelection() {_bSelectionBegin _bSelectionInit;_bSelectionEnd _bSelectionInit; }void QHexEdit::resetSelection(qint64 pos) {pos pos / 2 ;if (pos 0)pos 0;if (pos _chunks-size())pos _chunks-size();_bSelectionInit pos;_bSelectionBegin pos;_bSelectionEnd pos; }void QHexEdit::setSelection(qint64 pos) {pos pos / 2;if (pos 0)pos 0;if (pos _chunks-size())pos _chunks-size();if (pos _bSelectionInit){_bSelectionEnd pos;_bSelectionBegin _bSelectionInit;}else{_bSelectionBegin pos;_bSelectionEnd _bSelectionInit;} }qint64 QHexEdit::getSelectionBegin() {return _bSelectionBegin-16; }qint64 QHexEdit::getSelectionEnd() {return _bSelectionEnd-16; }// ********************************************************************** Private utility functions void QHexEdit::init() {_undoStack-clear();setAddressOffset(0);resetSelection(0);setCursorPosition(0);verticalScrollBar()-setValue(0);_modified false; }void QHexEdit::adjust() {// recalc Graphicsif (_addressArea){_addrDigits addressWidth();_pxPosHexX _pxGapAdr _addrDigits*_pxCharWidth _pxGapAdrHex;}else_pxPosHexX _pxGapAdrHex;_pxPosAdrX _pxGapAdr;_pxPosAsciiX _pxPosHexX _hexCharsInLine * _pxCharWidth _pxGapHexAscii;// set horizontalScrollBar()int pxWidth _pxPosAsciiX;if (_asciiArea)pxWidth _bytesPerLine*_pxCharWidth;horizontalScrollBar()-setRange(0, pxWidth - viewport()-width());horizontalScrollBar()-setPageStep(viewport()-width());// set verticalScrollbar()_rowsShown ((viewport()-height()-4)/_pxCharHeight);if((viewport()-height()-4)%_pxCharHeight 0)_rowsShown;int lineCount (int)(_chunks-size() / (qint64)_bytesPerLine) 3;verticalScrollBar()-setRange(0, lineCount - _rowsShown);verticalScrollBar()-setPageStep(_rowsShown);int value verticalScrollBar()-value();_bPosFirst (qint64)value * _bytesPerLine;_bPosLast _bPosFirst (qint64)(_rowsShown * _bytesPerLine) - 1;if (_bPosLast _chunks-size())_bPosLast _chunks-size() - 1;readBuffers();setCursorPosition(_cursorPosition); }void QHexEdit::dataChangedPrivate(int) {_modified _undoStack-index() ! 0;adjust();emit dataChanged(); }void QHexEdit::refresh() {ensureVisible();readBuffers(); }void QHexEdit::readBuffers() {_dataShown _chunks-data(_bPosFirst, _bPosLast - _bPosFirst _bytesPerLine 1, _markedShown);_hexDataShown QByteArray(_dataShown.toHex()); }QString QHexEdit::toReadable(const QByteArray ba) {QString result;for (int i0; i ba.size(); i 16){QString addrStr QString(%1).arg(_addressOffset i, addressWidth(), 16, QChar(0));QString hexStr;QString ascStr;for (int j0; j16; j){if ((i j) ba.size()){hexStr.append( ).append(ba.mid(ij, 1).toHex());char ch ba[i j];if ((ch 0x20) || (ch 0x7e))ch .;ascStr.append(QChar(ch));}}result addrStr QString(%1).arg(hexStr, -48) QString(%1).arg(ascStr, -17) \n;}return result; }void QHexEdit::updateCursor() {if (_blink)_blink false;else_blink true;viewport()-update(_cursorRect); }
http://www.hkea.cn/news/14556369/

相关文章:

  • 个人网站设计app的网站域名
  • 不是做有网站都叫jwth在阿里云安装wordpress
  • 广州制作企业网站网站用户黏度表现在
  • 梅州免费建站网上书城网站开发外文参考文献
  • 网站域名登陆地址用vs2012做网站
  • 网站推广销售腾讯会员被告怎么办wordpress所见既得
  • 有关网站建设的文章句子足球队世界排名榜
  • 深圳杰恩创意设计有限公司网站明天网页游戏开服表
  • 网站建设专员 岗位职责c 网站开发 视频教程
  • 集团公司网站方案门户网站信息流广告怎么做
  • 织梦响应式网站怎么做网站开发的技术支持
  • 优猫券网站怎么做个人网站怎样做超链接
  • 网站建设工作小组分工网站全站优化
  • 湖南地税局官网站水利建设基金设计师培训班
  • 台州网站建设慕枫福建住房和城乡建设局网站
  • 免费的网站软件正能量推荐百度竞价排名公式
  • 中国网站制作企业排行榜凡科互动官网登录入口网页版
  • 怎么接网站开发外包怎么建设自己网站首页
  • 繁峙做网站建设免费快速建站工具
  • 网站盈利模式有哪几种wordpress远程发布
  • 自适应型网站建设费用企业网查询是什么
  • seo网站结构图新乡专业seo电话
  • 做自媒体必备的8个网站电脑网页打不开但是有网什么原因
  • 宛城区微网站建设做网站的时候宽度都怎么弄
  • 杭州余杭区网站建设做网站 买空间
  • 为网站网站做宣传1688官网
  • 有机大米网站建设方案购物网站开发意义
  • ui网站模板淘宝优惠券怎么做网站
  • 骨干专业建设验收网站住房城乡建设网站查询
  • 程序员接外包网站厦门市市场开发建设服务中心网站