void TextField::deleteSelection() { if(getSelectionStart() == getSelectionEnd()) { return; } positionCaret(getSelectionEnd()); int e = getSelectionEnd(); int s = getSelectionStart(); for (int i = e; i > s; i--) { removeLastCharacter(); } setSelection(0,0); }
QString QHexEdit::selectionToReadableString() { QByteArray ba; for (qint64 i = getSelectionBegin(); i <= getSelectionEnd(); i++) ba.append(reader ? reader(i) : 0); return toReadable(ba); }
void TextField::paintComponent( const PaintEvent &paintEvent ) { int caretLoc = getCaretLocation(); int textLoc = getTextOffset(); Rectangle sideclip = getInnerRectangle(); sideclip = Rectangle(sideclip.getX() + getLeftPadding() , sideclip.getY() + 2,sideclip.getSize().getWidth() - getLeftPadding() - getRightPadding() + 1, sideclip.getHeight() - 4); if(isReadOnly()) { paintEvent.graphics()->drawFilledRectangle( getSizeRectangle(),frameColor); } else { paintEvent.graphics()->drawFilledRectangle( getSizeRectangle(),getBackColor()); } paintEvent.graphics()->pushClippingRect(sideclip); if(getSelectionStart() != getSelectionEnd() && (isFocused() || !isHidingSelection()) ) { Rectangle selRect = Rectangle( getSelectionLocation(), (getInnerHeight() / 2) - (getFont()->getLineHeight() / 2), getSelectionWidth(), getFont()->getLineHeight()); paintEvent.graphics()->drawFilledRectangle( selRect,getSelectionBackColor()); } paintEvent.graphics()->drawText(Point(textLoc, + ((getInnerSize().getHeight() - getFont()->getLineHeight()) / 2)),getText().c_str(), getFontColor(),getFont()); if(isFocused()) { if(isBlinking()) paintEvent.graphics()->drawLine(Point(caretLoc + 1, ((getInnerSize().getHeight() / 2) + (getFont()->getLineHeight() / 2))), Point(caretLoc + 1, ((getInnerSize().getHeight() / 2) - (getFont()->getLineHeight() / 2))), Color(0,0,0)); } paintEvent.graphics()->popClippingRect(); }
void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option); Q_UNUSED(widget); if (!doc) return; painter->setClipRect(boundingRect()); // draw selection QAbstractTextDocumentLayout::PaintContext ctx; QAbstractTextDocumentLayout::Selection sel; if (hasSelection()) { sel.cursor = QTextCursor(doc); sel.cursor.setPosition(getSelectionStart()); sel.cursor.setPosition(getSelectionEnd(), QTextCursor::KeepAnchor); } const QColor selectionColor = QColor::fromRgbF(0.23, 0.68, 0.91); sel.format.setBackground(selectionColor.lighter(selectionHasFocus ? 100 : 160)); sel.format.setForeground(selectionHasFocus ? Qt::white : Qt::black); ctx.selections.append(sel); ctx.palette.setColor(QPalette::Text, color); // draw text doc->documentLayout()->draw(painter, ctx); }
bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); if (getSelectionStart() < cur && getSelectionEnd() >= cur) return true; return false; }
void TextField::setSize( const Dimension& size ) { Widget::setSize(size); scrollToCaret(false,false); relocateCaret(); setSelection(getSelectionStart(),getSelectionEnd()); }
const std::string TextField::getSelectedText() const { if(getSelectionStart() == getSelectionEnd()) { return std::string(""); } else { return unicodeFunctions.subStr(getText(), getSelectionStart(),getSelectionLength()); } }
void Text::selectionMouseMove(QPointF scenePos) { if (!doc) return; int cur = cursorFromPos(scenePos); if (cur >= 0) { selectionEnd = cur; selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } update(); }
void UIHexEditorWnd::keyPressEdit(QKeyEvent *event, u64 posAddr) { int key = int(event->text()[0].toLatin1()); if (textEdit) { if ((key>='0' && key<='9') || (key>='a' && key <= 'z') || (key>='A' && key <= 'Z')) { if (getSelectionStart() != getSelectionEnd()) { posAddr = getSelectionStart(); clear(posAddr, getSelectionEnd() - posAddr); setCursorPos(2*posAddr); resetSelection(2*posAddr); } // Patch byte overwrite((u32)cursorAddr >> 1, (u8)key); setCursorPos(cursorAddr + 2); resetSelection(cursorAddr); } } else { if ((key>='0' && key<='9') || (key>='a' && key <= 'f') || (key>='A' && key <= 'F'))
void Text::selectionDoubleClick(QPointF scenePos) { if (!doc) return; int cur = cursorFromPos(scenePos); if (cur >= 0) { QTextCursor cursor(doc); cursor.setPosition(cur); cursor.select(QTextCursor::WordUnderCursor); selectionAnchor = cursor.selectionStart(); selectionEnd = cursor.selectionEnd(); selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } update(); }
void Text::selectionTripleClick(QPointF scenePos) { if (!doc) return; int cur = cursorFromPos(scenePos); if (cur >= 0) { QTextCursor cursor(doc); cursor.setPosition(cur); cursor.select(QTextCursor::BlockUnderCursor); selectionAnchor = cursor.selectionStart(); selectionEnd = cursor.selectionEnd(); if (cursor.block().isValid() && cursor.block().blockNumber() != 0) selectionAnchor++; selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } update(); }
// ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) { // Cursor movements if (event->matches(QKeySequence::MoveToNextChar)) { setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousChar)) { setCursorPosition(_cursorPosition - 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfLine)) { setCursorPosition(_cursorPosition | (2 * BYTES_PER_LINE -1)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfLine)) { setCursorPosition(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousLine)) { setCursorPosition(_cursorPosition - (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextLine)) { setCursorPosition(_cursorPosition + (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextPage)) { setCursorPosition(_cursorPosition + (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousPage)) { setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfDocument)) { setCursorPosition(_chunks->size() * 2); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfDocument)) { setCursorPosition(0); resetSelection(_cursorPosition); } // Select commands if (event->matches(QKeySequence::SelectAll)) { resetSelection(0); setSelection(2*_chunks->size() + 1); } if (event->matches(QKeySequence::SelectNextChar)) { qint64 pos = _cursorPosition + 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousChar)) { qint64 pos = _cursorPosition - 1; setSelection(pos); setCursorPosition(pos); } if (event->matches(QKeySequence::SelectEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousLine)) { qint64 pos = _cursorPosition - (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextLine)) { qint64 pos = _cursorPosition + (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextPage)) { qint64 pos = _cursorPosition + (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousPage)) { qint64 pos = _cursorPosition - (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); 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 Commands if (!_readOnly) { if ((QApplication::keyboardModifiers() == Qt::NoModifier) || (QApplication::keyboardModifiers() == Qt::KeypadModifier)) { /* Hex input */ int key = int(event->text()[0].toLatin1()); if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) { 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 byte if (_overwriteMode == false) if ((_cursorPosition % 2) == 0) insert(_bPosCurrent, char(0)); // Change content if (_chunks->size() > 0) { QByteArray hexValue = _chunks->data(_bPosCurrent, 1).toHex(); if ((_cursorPosition % 2) == 0) hexValue[0] = key; else hexValue[1] = key; replace(_bPosCurrent, QByteArray().fromHex(hexValue)[0]); setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } } } /* 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()); } /* Paste */ if (event->matches(QKeySequence::Paste)) { QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); if (_overwriteMode) replace(_bPosCurrent, ba.size(), ba); else insert(_bPosCurrent, ba); setCursorPosition(_cursorPosition + 2 * ba.size()); resetSelection(getSelectionBegin()); } /* 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)); else remove(_bPosCurrent, 1); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } /* 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)); else remove(_bPosCurrent, 1); if (!behindLastByte) _bPosCurrent -= 1; setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } } /* undo */ if (event->matches(QKeySequence::Undo)) { undo(); } /* redo */ if (event->matches(QKeySequence::Redo)) { redo(); } } /* 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 mode if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) { setOverwriteMode(!overwriteMode()); setCursorPosition(_cursorPosition); } // Refresh Event if ((event->key() == Qt::Key_F5)) executableViewer->getMainWindow()->refresh(); refresh(); }
} // Patch byte overwrite((u32)cursorAddr >> 1, (u8)key); setCursorPos(cursorAddr + 2); resetSelection(cursorAddr); } } else { if ((key>='0' && key<='9') || (key>='a' && key <= 'f') || (key>='A' && key <= 'F')) { if (getSelectionStart() != getSelectionEnd()) { posAddr = getSelectionStart(); clear(posAddr, getSelectionEnd() - posAddr); setCursorPos(2*posAddr); resetSelection(2*posAddr); } // Patch byte overwrite((s64)cursorAddr, (char)key); setCursorPos(cursorAddr + 1); resetSelection(cursorAddr); } } if (event->key()==Qt::Key_Tab) { textEdit ^= true; } if (event->matches(QKeySequence::Copy))
void QHexEditPrivate::paintEvent(QPaintEvent *event) { QPainter painter(this); // draw some patterns if needed painter.fillRect(event->rect(), this->palette().color(QPalette::Base)); if (_addressArea) painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor); if (_asciiArea) { int linePos = _xPosAscii - (GAP_HEX_ASCII / 2); painter.setPen(Qt::gray); painter.drawLine(linePos, event->rect().top(), linePos, height()); } painter.setPen(this->palette().color(QPalette::WindowText)); // calc position int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE; if (firstLineIdx < 0) firstLineIdx = 0; int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; if (lastLineIdx > _xData.size()) lastLineIdx = _xData.size(); int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; // paint address area if (_addressArea) { for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { QString address = QString("%1") .arg(lineIdx + _xData.addressOffset(), _xData.realAddressNumbers(), 16, QChar('0')); painter.drawText(_xPosAdr, yPos, address); } } // paint hex area QByteArray hexBa(_xData.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); QBrush highLighted = QBrush(_highlightingColor); QPen colHighlighted = QPen(this->palette().color(QPalette::WindowText)); QBrush selected = QBrush(_selectionColor); QPen colSelected = QPen(Qt::white); QPen colStandard = QPen(this->palette().color(QPalette::WindowText)); painter.setBackgroundMode(Qt::TransparentMode); for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { QByteArray hex; int xPos = _xPosHex; for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) { int posBa = lineIdx + colIdx; if ((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) { painter.setBackground(selected); painter.setBackgroundMode(Qt::OpaqueMode); painter.setPen(colSelected); } else { if (_highlighting) { // hilight diff bytes painter.setBackground(highLighted); if (_xData.dataChanged(posBa)) { painter.setPen(colHighlighted); painter.setBackgroundMode(Qt::OpaqueMode); } else { painter.setPen(colStandard); painter.setBackgroundMode(Qt::TransparentMode); } } } // render hex value if (colIdx == 0) { hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2); painter.drawText(xPos, yPos, hex.toUpper()); xPos += 2 * _charWidth; } else { hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" "); painter.drawText(xPos, yPos, hex.toUpper()); xPos += 3 * _charWidth; } } } painter.setBackgroundMode(Qt::TransparentMode); painter.setPen(this->palette().color(QPalette::WindowText)); // paint ascii area if (_asciiArea) { for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { int xPosAscii = _xPosAscii; for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) { painter.drawText(xPosAscii, yPos, _xData.asciiChar(lineIdx + colIdx)); xPosAscii += _charWidth; } } } // paint cursor if (_blink && !_readOnly && hasFocus()) { if (_overwriteMode) painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); else painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); } if (_size != _xData.size()) { _size = _xData.size(); emit currentSizeChanged(_size); } }
void QHexEditPrivate::keyPressEvent(QKeyEvent *event) { int charX = (_cursorX - _xPosHex) / _charWidth; int posX = (charX / 3) * 2 + (charX % 3); int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; /*****************************************************************************/ /* Cursor movements */ /*****************************************************************************/ if (event->matches(QKeySequence::MoveToNextChar)) { setCursorPos(_cursorPosition + 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousChar)) { setCursorPos(_cursorPosition - 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfLine)) { setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfLine)) { setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousLine)) { setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextLine)) { setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextPage)) { setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousPage)) { setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfDocument)) { setCursorPos(_xData.size() * 2); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfDocument)) { setCursorPos(0); resetSelection(_cursorPosition); } /*****************************************************************************/ /* Select commands */ /*****************************************************************************/ if (event->matches(QKeySequence::SelectAll)) { resetSelection(0); setSelection(2*_xData.size() + 1); } if (event->matches(QKeySequence::SelectNextChar)) { int pos = _cursorPosition + 1; setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousChar)) { int pos = _cursorPosition - 1; setSelection(pos); setCursorPos(pos); } if (event->matches(QKeySequence::SelectEndOfLine)) { int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfLine)) { int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousLine)) { int pos = _cursorPosition - (2 * BYTES_PER_LINE); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextLine)) { int pos = _cursorPosition + (2 * BYTES_PER_LINE); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextPage)) { int pos = _cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousPage)) { int pos = _cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectEndOfDocument)) { int pos = _xData.size() * 2; setCursorPos(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfDocument)) { int pos = 0; setCursorPos(pos); setSelection(pos); } /*****************************************************************************/ /* Edit Commands */ /*****************************************************************************/ if (!_readOnly) { /* Hex input */ int key = int(event->text()[0].toAscii()); if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) { if (getSelectionBegin() != getSelectionEnd()) { posBa = getSelectionBegin(); remove(posBa, getSelectionEnd() - posBa); setCursorPos(2*posBa); resetSelection(2*posBa); } // If insert mode, then insert a byte if (_overwriteMode == false) if ((charX % 3) == 0) { insert(posBa, char(0)); } // Change content if (_xData.size() > 0) { QByteArray hexValue = _xData.data().mid(posBa, 1).toHex(); if ((charX % 3) == 0) hexValue[0] = key; else hexValue[1] = key; replace(posBa, QByteArray().fromHex(hexValue)[0]); setCursorPos(_cursorPosition + 1); resetSelection(_cursorPosition); } } /* Cut & Paste */ if (event->matches(QKeySequence::Cut)) { QString result = QString(); for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) { result += _xData.data().mid(idx, 1).toHex() + " "; if ((idx % 16) == 15) result.append("\n"); } remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(result); setCursorPos(getSelectionBegin()); resetSelection(getSelectionBegin()); } if (event->matches(QKeySequence::Paste)) { QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); insert(_cursorPosition / 2, ba); setCursorPos(_cursorPosition + 2 * ba.length()); resetSelection(getSelectionBegin()); } /* Delete char */ if (event->matches(QKeySequence::Delete)) { if (getSelectionBegin() != getSelectionEnd()) { posBa = getSelectionBegin(); remove(posBa, getSelectionEnd() - posBa); setCursorPos(2*posBa); resetSelection(2*posBa); } else { if (_overwriteMode) replace(posBa, char(0)); else remove(posBa, 1); } } /* Backspace */ if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) { if (getSelectionBegin() != getSelectionEnd()) { posBa = getSelectionBegin(); remove(posBa, getSelectionEnd() - posBa); setCursorPos(2*posBa); resetSelection(2*posBa); } else { if (posBa > 0) { if (_overwriteMode) replace(posBa - 1, char(0)); else remove(posBa - 1, 1); setCursorPos(_cursorPosition - 2); } } } /* undo */ if (event->matches(QKeySequence::Undo)) { undo(); } /* redo */ if (event->matches(QKeySequence::Redo)) { redo(); } } if (event->matches(QKeySequence::Copy)) { QString result = QString(); for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) { result += _xData.data().mid(idx, 1).toHex() + " "; if ((idx % 16) == 15) result.append('\n'); } QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(result.toUpper()); } // Switch between insert/overwrite mode if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) { _overwriteMode = !_overwriteMode; setCursorPos(_cursorPosition); overwriteModeChanged(_overwriteMode); } ensureVisible(); update(); }
QString QHexEditPrivate::selectionToReadableString() { return _xData.toRedableString(getSelectionBegin(), getSelectionEnd()); }
void TextField::handleKeyboard( KeyEvent &keyEvent ) { if(handleHotkeys(keyEvent)) { return; } //delete the next character if(keyEvent.getKey() == KEY_DELETE) { if(getCaretPosition() == getTextLength() && getSelectionStart() == getSelectionEnd()) { return; } if(isReadOnly()) { return; } if(getSelectionStart() == getSelectionEnd()) { removeNextCharacter(); } else { deleteSelection(); } setBlinking(true); invalidateBlink(); return; } //delete the previous character if(keyEvent.getKey() == KEY_BACKSPACE) { if(getCaretPosition() == 0 && getSelectionStart() == getSelectionEnd()) { return; } if(isReadOnly()) { return; } if(getSelectionStart() == getSelectionEnd()) { removeLastCharacter(); } else { deleteSelection(); } setBlinking(true); invalidateBlink(); return; } if(keyEvent.getUnichar() >= ' ') { if(isReadOnly()) { setBlinking(true); invalidateBlink(); return; } if( isNumeric()) { if(keyEvent.getUnichar() >= 0x30 && keyEvent.getUnichar() <= 0x39 ) { deleteSelection(); addToNextCharacter(keyEvent.getUnichar()); setBlinking(true); invalidateBlink(); } else if(wantedDecimal() && keyEvent.getUnichar() == 0x2e ) { //check if there is already a decimal const char *text = getText().c_str(); for (int i = 0; i < getTextLength(); ++i) { if(text[i] == 0x2e) { return; } } deleteSelection(); addToNextCharacter(keyEvent.getUnichar()); setBlinking(true); invalidateBlink(); } else if(wantedMinus() && keyEvent.getUnichar() == 0x2d ) { //check if we are in the first position if(getCaretPosition() != 0) { return; } //check if there is already a minus const char *text = getText().c_str(); for (int i = 0; i < getTextLength(); ++i) { if(text[i] == 0x2d) { return; } } deleteSelection(); addToNextCharacter(keyEvent.getUnichar()); setBlinking(true); invalidateBlink(); } return; } deleteSelection(); addToNextCharacter(keyEvent.getUnichar()); setBlinking(true); invalidateBlink(); return; } switch (keyEvent.getExtendedKey()) { case EXT_KEY_RIGHT: if(getCaretPosition() == getTextLength() && getSelectionStart() != getSelectionEnd() && keyEvent.shift()) { return; } else if(getCaretPosition() == getTextLength() && getSelectionStart() == getSelectionEnd()) { return; } positionCaret(getCaretPosition() + 1); if(keyEvent.shift()) { if(getSelectionStart() == getSelectionEnd()) { setSelection(getCaretPosition() - 1, getCaretPosition()); } else { if(getCaretPosition() - 1 < getSelectionEnd()) setSelection(getSelectionEnd(), getCaretPosition()); else setSelection(getSelectionStart(), getCaretPosition()); } } else if(getSelectionStart() != getSelectionEnd()) { int caretPos = getSelectionEnd(); setSelection(0,0); positionCaret(caretPos); } setBlinking(true); invalidateBlink(); break; case EXT_KEY_LEFT: if(getCaretPosition() == 0 && getSelectionStart() != getSelectionEnd() && keyEvent.shift()) { return; } else if(getCaretPosition() == 0 && getSelectionStart() == getSelectionEnd()) { return; } positionCaret(getCaretPosition() - 1); if(keyEvent.shift()) { if(getSelectionStart() == getSelectionEnd()) { setSelection(getCaretPosition() + 1, getCaretPosition()); } else { if(getCaretPosition() + 1 < getSelectionEnd()) setSelection(getSelectionEnd(), getCaretPosition()); else setSelection(getSelectionStart(), getCaretPosition()); } } else if(getSelectionStart() != getSelectionEnd()) { int caretPos = getSelectionStart(); setSelection(0,0); positionCaret(caretPos); } setBlinking(true); invalidateBlink(); break; } }
void TextField::setSelection( int start, int end ) { if(!isSelectable()) { if(getSelectionStart() != getSelectionEnd()) { start = 0; end = 0; } else { return; } } if(start == end) { selStart = 0; selEnd = 0; selWidth = 0; } if(start == -1 && end == -1) { start = 0; end = getTextLength(); } else if( end == -1) { end = getTextLength(); } if( start > end) { int temp = start; start = end; end = temp; } if(start < 0) { start = 0; } if( end > getTextLength() ) { end = getTextLength(); } for(std::vector<TextFieldListener*>::iterator it = tFieldListeners.begin(); it != tFieldListeners.end(); ++it) { (*it)->selectionChanged(this,start,end); } selStart = start; selEnd = end; selLength = end - start; selPos = getFont()->getTextWidth(unicodeFunctions.subStr(getText(), 0,start)) + getTextOffset(); selWidth = getFont()->getTextWidth(unicodeFunctions.subStr(getText(), start,selLength)); }
void QHexEditPrivate::paintEvent(QPaintEvent *event) { QPainter painter(this); // draw some patterns if needed painter.fillRect(event->rect(), this->palette().color(QPalette::Base)); if (_addressArea) painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor); if (_asciiArea) { int linePos = _xPosAscii - (GAP_HEX_ASCII / 2); painter.setPen(Qt::gray); painter.drawLine(linePos, event->rect().top(), linePos, height()); } painter.setPen(this->palette().color(QPalette::WindowText)); // calc position int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE; if (firstLineIdx < 0) firstLineIdx = 0; int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; if (lastLineIdx > _data.size()) lastLineIdx = _data.size(); int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; // paint address area if (_addressArea) { for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { QString address = QString("%1") .arg(lineIdx + _addressOffset, _realAddressNumbers, 16, QChar('0')); // address.insert(address.length()-4,':'); painter.drawText(_xPosAdr, yPos, address.toUpper()); } } // paint hex area QByteArray hexBa(_data.mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); QBrush highLighted = QBrush(_highlightingColor); QPen colHighlighted = QPen(this->palette().color(QPalette::WindowText)); QBrush selected = QBrush(_selectionColor); QPen colSelected = QPen(Qt::white); QPen colStandard = QPen(this->palette().color(QPalette::WindowText)); painter.setBackgroundMode(Qt::TransparentMode); for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { QByteArray hex; int xPos = _xPosHex; QString hl_block; int hl_block_i; if (_highlighting) { painter.setPen(Qt::yellow); hl_block_i=0; hl_block="██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██"; for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++) { int posBa = lineIdx + colIdx; if (_changedData[posBa]) { hl_block[hl_block_i] = QChar(' '); hl_block[hl_block_i+1] = QChar(' '); } hl_block_i=hl_block_i+3; } if(hl_block_i!=0) { while(hl_block_i<hl_block.size()) { hl_block[hl_block_i] = QChar(' '); hl_block_i++; } painter.drawText(xPos, yPos, hl_block); } } if (_exteralHl.size()!=0) { painter.setPen(Qt::green); hl_block_i=0; hl_block="██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██"; for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++) { int posBa = lineIdx + colIdx; if (_exteralHl[posBa]=='\0') { hl_block[hl_block_i] = QChar(' '); hl_block[hl_block_i+1] = QChar(' '); } hl_block_i=hl_block_i+3; } if(hl_block_i!=0) { while(hl_block_i<hl_block.size()) { hl_block[hl_block_i] = QChar(' '); hl_block_i++; } painter.drawText(xPos, yPos, hl_block); } } // if (_selected) painter.setPen(Qt::cyan); hl_block_i=0; hl_block="██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██"; for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++) { int posBa = lineIdx + colIdx; if (!((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa))) { hl_block[hl_block_i] = QChar(' '); hl_block[hl_block_i+1] = QChar(' '); } hl_block_i=hl_block_i+3; } if(hl_block_i!=0) { while(hl_block_i<hl_block.size()) { hl_block[hl_block_i] = QChar(' '); hl_block_i++; } painter.drawText(xPos, yPos, hl_block); } painter.setPen(this->palette().color(QPalette::WindowText)); hex = hexBa.mid((lineIdx - firstLineIdx) * 2, BYTES_PER_LINE * 2); QString new_hex=" "; //BYTES_PER_LINE*3 int i_new_hex = 0; for(int i_hex=0;i_hex<hex.size();i_hex++,i_new_hex++) { new_hex[i_new_hex] = hex[i_hex]; if((i_hex+1)%2 == 0)i_new_hex++; } painter.drawText(xPos, yPos, new_hex.toUpper()); } painter.setBackgroundMode(Qt::TransparentMode); painter.setPen(this->palette().color(QPalette::WindowText)); // paint ascii area if (_asciiArea) { for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) { QByteArray ascii = _data.mid(lineIdx, BYTES_PER_LINE); for (int idx=0; idx < ascii.size(); idx++) if (((char)ascii[idx] < 0x20) or ((char)ascii[idx] > 0x7e)) ascii[idx] = '.'; painter.drawText(_xPosAscii, yPos, ascii); } } // paint cursor if (_blink) { if (_overwriteMode) painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); else painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); } if (_size != _data.size()) { _size = _data.size(); emit currentSizeChanged(_size); } QString adr; adr.setNum(_cursorPosition/2,16); adr = adr.toUpper(); while(adr.length()<8) { adr.prepend("0"); } QString val; val.setNum(_data[_cursorPosition/2],16); val = val.toUpper(); if(val.length()<2)val.prepend("0"); val = val.mid(val.length()-2,2); QString bval; bval.setNum(_data[_cursorPosition/2],2); while(bval.length()<8)bval.prepend("0"); if(bval.length()>8) { bval = bval.mid(bval.length()-8,8); } emit updateText("Address: "+adr+" Value: "+val+" Binary: "+bval); }
// ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) { // Cursor movements if (event->matches(QKeySequence::MoveToNextChar)) { setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousChar)) { setCursorPosition(_cursorPosition - 1); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfLine)) { setCursorPosition(_cursorPosition | (2 * BYTES_PER_LINE -1)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfLine)) { setCursorPosition(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousLine)) { setCursorPosition(_cursorPosition - (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextLine)) { setCursorPosition(_cursorPosition + (2 * BYTES_PER_LINE)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextPage)) { setCursorPosition(_cursorPosition + (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousPage)) { setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfDocument)) { setCursorPosition(_editorSize * 2); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfDocument)) { setCursorPosition(0); resetSelection(_cursorPosition); } // Select commands if (event->matches(QKeySequence::SelectAll)) { resetSelection(0); setSelection(2*_editorSize + 1); } if (event->matches(QKeySequence::SelectNextChar)) { qint64 pos = _cursorPosition + 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousChar)) { qint64 pos = _cursorPosition - 1; setSelection(pos); setCursorPosition(pos); } if (event->matches(QKeySequence::SelectEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousLine)) { qint64 pos = _cursorPosition - (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextLine)) { qint64 pos = _cursorPosition + (2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextPage)) { qint64 pos = _cursorPosition + (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousPage)) { qint64 pos = _cursorPosition - (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectEndOfDocument)) { qint64 pos = _editorSize * 2; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfDocument)) { qint64 pos = 0; setCursorPosition(pos); setSelection(pos); } // Edit Commands if (!_readOnly) { if ((QApplication::keyboardModifiers() == Qt::NoModifier) || (QApplication::keyboardModifiers() == Qt::KeypadModifier)) { /* Hex input */ int key = int(event->text()[0].toLatin1()); if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) { if (getSelectionBegin() != getSelectionEnd()) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); setCursorPosition(2*_bPosCurrent); resetSelection(2*_bPosCurrent); } // Change content if (_editorSize > 0) { const char byte = reader ? reader(_bPosCurrent) : 0; QByteArray hexValue = QByteArray(&byte, 1).toHex(); if ((_cursorPosition % 2) == 0) hexValue[0] = key; else hexValue[1] = key; replace(_bPosCurrent, QByteArray().fromHex(hexValue)[0]); setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } } } /* Cut */ if (event->matches(QKeySequence::Cut)) { QByteArray bytes; for (qint64 i = getSelectionBegin(); i <= getSelectionEnd(); i++) bytes.append(reader ? reader(i) : 0); QByteArray ba = bytes.toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); setCursorPosition(2*getSelectionBegin()); resetSelection(2*getSelectionBegin()); } /* Paste */ if (event->matches(QKeySequence::Paste)) { QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); replace(_bPosCurrent, ba.size(), ba); setCursorPosition(_cursorPosition + 2 * ba.size()); resetSelection(getSelectionBegin()); } /* Delete char */ if (event->matches(QKeySequence::Delete)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); } else { replace(_bPosCurrent, char(0)); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } /* Backspace */ if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); setCursorPosition(2 * _bPosCurrent); QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); resetSelection(2 * _bPosCurrent); } else { _bPosCurrent -= 1; replace(_bPosCurrent, char(0)); _bPosCurrent -= 1; setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } } /* undo */ if (event->matches(QKeySequence::Undo)) { undo(); } /* redo */ if (event->matches(QKeySequence::Redo)) { redo(); } } /* Copy */ if (event->matches(QKeySequence::Copy)) { QByteArray bytes; for (qint64 i = getSelectionBegin(); i <= getSelectionEnd(); i++) bytes.append(reader ? reader(i) : 0); QByteArray ba = bytes.toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); } refresh(); }
void QHexEdit::paintEvent(QPaintEvent *event) { QPainter painter(viewport()); if (event->rect() != _cursorRect) { // process some useful calculations int pxOfsX = horizontalScrollBar()->value(); int pxPosStartY = _pxCharHeight; // draw some patterns if needed painter.fillRect(event->rect(), viewport()->palette().color(QPalette::Base)); if (_addressArea) painter.fillRect(QRect(-pxOfsX, event->rect().top(), _pxPosHexX - _pxGapAdrHex/2 - pxOfsX, 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 area if (_addressArea) { QString address; for (int row=0, pxPosY = _pxCharHeight; row <= (_dataShown.size()/BYTES_PER_LINE); row++, pxPosY +=_pxCharHeight) { address = QString("%1").arg(_bPosFirst + row*BYTES_PER_LINE + _addressOffset, _addrDigits, 16, QChar('0')); painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, address); } } // paint hex and ascii area QPen colStandard = QPen(viewport()->palette().color(QPalette::WindowText)); painter.setBackgroundMode(Qt::TransparentMode); for (int row = 0, pxPosY = pxPosStartY; row <= _rowsShown; row++, pxPosY +=_pxCharHeight) { QByteArray hex; int pxPosX = _pxPosHexX - pxOfsX; int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX; qint64 bPosLine = row * BYTES_PER_LINE; for (int colIdx = 0; ((bPosLine + colIdx) < _dataShown.size() && (colIdx < BYTES_PER_LINE)); 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 value QRect r; if (colIdx == 0) r.setRect(pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight); else r.setRect(pxPosX - _pxCharWidth, pxPosY - _pxCharHeight + _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight); painter.fillRect(r, c); hex = _hexDataShown.mid((bPosLine + colIdx) * 2, 2); painter.drawText(pxPosX, pxPosY, hex); pxPosX += 3*_pxCharWidth; // render ascii value if (_asciiArea) { char ch = _dataShown.at(bPosLine + colIdx); if ((ch < 0x20) || (ch > 0x7e)) 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)); } // paint cursor if (_blink && !_readOnly && hasFocus()) painter.fillRect(_cursorRect, this->palette().color(QPalette::WindowText)); else painter.drawText(_pxCursorX, _pxCursorY, _hexDataShown.mid(_cursorPosition - _bPosFirst * 2, 1)); // emit event, if size has changed if (_lastEventSize != _chunks->size()) { _lastEventSize = _chunks->size(); emit currentSizeChanged(_lastEventSize); } }
QString QHexEdit::selectedData() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); return ba; }
QString QHexEdit::selectionToReadableString() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); return toReadable(ba); }
void QHexEdit::paintEvent(QPaintEvent *event) { QPainter painter(viewport()); int pxOfsX = horizontalScrollBar()->value(); if (event->rect() != _cursorRect) { int pxPosStartY = _pxCharHeight; // draw some patterns if needed painter.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 area if (_addressArea) { QString address; for (int row=0, pxPosY = _pxCharHeight; row <= (_dataShown.size()/_bytesPerLine); row++, pxPosY +=_pxCharHeight) { address = QString("%1").arg(_bPosFirst + row*_bytesPerLine + _addressOffset, _addrDigits, 16, QChar('0')); painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, address); } } // paint hex and ascii area QPen colStandard = QPen(viewport()->palette().color(QPalette::WindowText)); painter.setBackgroundMode(Qt::TransparentMode); for (int row = 0, pxPosY = pxPosStartY; 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 value QRect r; if (colIdx == 0) r.setRect(pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight); else r.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 value if (_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 1 int hexPositionInShowData = _cursorPosition - 2 * _bPosFirst; // due to scrolling the cursor can go out of the currently displayed data if ((hexPositionInShowData >= 0) && (hexPositionInShowData < _hexDataShown.size())) { // paint cursor if (_readOnly) { // make the background stick out QColor 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 ascii int asciiPositionInShowData = hexPositionInShowData / 2; int ch = (uchar)_dataShown.at(asciiPositionInShowData); if (ch < ' ' || ch > '~') ch = '.'; painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, QChar(ch)); } else { painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, _hexDataShown.mid(hexPositionInShowData, 1)); } } // emit event, if size has changed if (_lastEventSize != _chunks->size()) { _lastEventSize = _chunks->size(); emit currentSizeChanged(_lastEventSize); } }
// ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) { // Cursor movements if (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 commands if (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 Commands if (!_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::min<qint64>(ba.size(), (_chunks->size() - _bPosCurrent))); replace(_bPosCurrent, ba.size(), ba); } else insert(_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)); else remove(_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)); else remove(_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(); } else if ((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(); else key = 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 byte if (_overwriteMode == false) if ((_cursorPosition % 2) == 0) insert(_bPosCurrent, char(0)); // Change content if (_chunks->size() > 0) { char ch = key; if (!_editAreaIsAscii){ QByteArray hexValue = _chunks->data(_bPosCurrent, 1).toHex(); if ((_cursorPosition % 2) == 0) hexValue[0] = key; else hexValue[1] = key; ch = QByteArray().fromHex(hexValue)[0]; } replace(_bPosCurrent, ch); if (_editAreaIsAscii) setCursorPosition(_cursorPosition + 2); else setCursorPosition(_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 mode if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) { setOverwriteMode(!overwriteMode()); setCursorPosition(_cursorPosition); } // switch from hex to ascii edit if (event->key() == Qt::Key_Tab && !_editAreaIsAscii){ _editAreaIsAscii = true; setCursorPosition(_cursorPosition); } // switch from ascii to hex edit if (event->key() == Qt::Key_Backtab && _editAreaIsAscii){ _editAreaIsAscii = false; setCursorPosition(_cursorPosition); } refresh(); }