#include "qhexview.h"
#include "document/buffer/qmemorybuffer.h"
#include <QFontDatabase>
#include <QApplication>
#include <QPaintEvent>
#include <QHelpEvent>
#include <QScrollBar>
#include <QPainter>
#include <QToolTip>
#include <cmath>
#include <QThread>
#include <QDebug>
#define CURSOR_BLINK_INTERVAL 500 // ms 光标闪烁时间
#define DOCUMENT_WHEEL_LINES 3
QHexView::QHexView(QWidget *parent) : QAbstractScrollArea(parent), m_document(nullptr), m_renderer(nullptr), m_readonly(false)
{
// QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont);
// if(f.styleHint() != QFont::TypeWriter)
// {
// f.setFamily("Monospace"); // Force Monospaced font
// f.setStyleHint(QFont::TypeWriter);
// }
// this->setFont(f);
// setFont(QFont("Monospace"));
auto font =QFont(QString::fromLocal8Bit("新宋体"));
font.setPixelSize(12);
setFont(font);
this->setFocusPolicy(Qt::StrongFocus);
this->setMouseTracking(true);
this->verticalScrollBar()->setSingleStep(10);
this->verticalScrollBar()->setPageStep(10);
m_blinktimer = new QTimer(this);
m_blinktimer->setInterval(CURSOR_BLINK_INTERVAL);
connect(m_blinktimer, &QTimer::timeout, this, &QHexView::blinkCursor);
this->setDocument(QHexDocument::fromMemory<QMemoryBuffer>(QByteArray(), this));
}
QHexDocument *QHexView::document() { return m_document; }
void QHexView::setDocument(QHexDocument *document)
{
if(m_renderer)
m_renderer->deleteLater();
if(m_document)
m_document->deleteLater();
m_document = document;
m_renderer = new QHexRenderer(m_document, this->fontMetrics(), this);
connect(m_document, &QHexDocument::documentChanged, this, [&]() {
this->adjustScrollBars();
this->viewport()->update();
});
connect(m_document->cursor(), &QHexCursor::positionChanged, this, &QHexView::moveToSelection);
connect(m_document->cursor(), &QHexCursor::insertionModeChanged, this, &QHexView::renderCurrentLine);
this->adjustScrollBars();
this->viewport()->update();
}
void QHexView::setReadOnly(bool b)
{
m_readonly = b;
if(m_document) m_document->cursor()->setInsertionMode(QHexCursor::OverwriteMode);
}
void QHexView::adjustScrollBarValue(quint64 line)
{
QScrollBar *vscrollbar = this->verticalScrollBar();
int sizeFactor = this->documentSizeFactor();
quint64 docLines = m_renderer->documentLines();
if(line < docLines){
vscrollbar->setValue(line/sizeFactor);
}
}
void QHexView::alignmentHead(bool head)
{
QScrollBar *vscrollbar = this->verticalScrollBar();
if(head){
vscrollbar->setValue(0);
}
else{
vscrollbar->setValue(vscrollbar->maximum());
}
}
void QHexView::setTheme(bool darkTheme)
{
m_isDarkTheme = darkTheme;
if(m_renderer){
m_renderer->setTheme(darkTheme);
}
update();
}
void QHexView::setHexLineWidth(quint8 value)
{
if(m_document){
m_document->setHexLineWidth(value);
update();
}
}
bool QHexView::event(QEvent *e)
{
if(m_renderer && (e->type() == QEvent::FontChange))
{
m_renderer->updateMetrics(QFontMetricsF(this->font()));
return true;
}
if(m_document && m_renderer && (e->type() == QEvent::ToolTip))
{
QHelpEvent* helpevent = static_cast<QHelpEvent*>(e);
QHexPosition position;
QPoint abspos = absolutePosition(helpevent->pos());
if(m_renderer->hitTest(abspos, &position, this->firstVisibleLine()))
{
QString comments = m_document->metadata()->comments(position.line, position.column);
if(!comments.isEmpty())
QToolTip::showText(helpevent->globalPos(), comments, this);
}
return true;
}
return QAbstractScrollArea::event(e);
}
void QHexView::keyPressEvent(QKeyEvent *e)
{
if(!m_renderer || !m_document)
{
QAbstractScrollArea::keyPressEvent(e);
return;
}
QHexCursor* cur = m_document->cursor();
m_blinktimer->stop();
m_renderer->enableCursor();
bool handled = this->processMove(cur, e);
if(!handled) handled = this->processAction(cur, e);
if(!handled) handled = this->processTextInput(cur, e);
if(!handled) QAbstractScrollArea::keyPressEvent(e);
// m_blinktimer->start();
}
QPoint QHexView::absolutePosition(const QPoint & pos) const
{
QPoint shift(horizontalScrollBar()->value(), 0);
return pos + shift;
}
void QHexView::mousePressEvent(QMouseEvent *e)
{
QAbstractScrollArea::mousePressEvent(e);
if(!m_renderer || (e->buttons() != Qt::LeftButton))
return;
/***
* 按钮点击
*/
auto rect1 = QRect(m_renderer->getAsciiX()+ 1,5,14,14);
auto rect2 = QRect(m_renderer->getAsciiEnd() - 1 - 14,5,14,14);
if(rect1.contains(e->pos())){
m_bHeadIconPressed = true;
}
if(rect2.contains(e->pos())){
m_bBottomIconPressed = true;
}
QHexPosition position;
QPoint abspos = absolutePosition(e->pos());
if(!m_renderer->hitTest(abspos, &position, this->firstVisibleLine()))
return;
m_renderer->selectArea(abspos);
if(m_renderer->editableArea(m_renderer->selectedArea()))
m_document->cursor()->moveTo(position);
//点击的时候清除选中背景 add by lyy
auto data = m_document->metadata();
data->clear();
e->accept();
}
void QHexView::mouseMoveEvent(QMouseEvent *e)
{
QAbstractScrollArea::mouseMoveEvent(e);
if(!m_renderer || !m_document) return;
QPoint abspos = absolutePosition(e->pos());
if(e->buttons() == Qt::LeftButton)
{
if(m_blinktimer->isActive())
{
m_blinktimer->stop();
m_renderer->enableCursor(false);
}
QHexCursor* cursor = m_document->cursor();
QHexPosition position;
if(!m_renderer->hitTest(abspos, &position, this->firstVisibleLine()))
return;
cursor->select(position.line, position.column, 0);
e->accept();
}
if(e->buttons() != Qt::NoButton) return;
int hittest = m_renderer->hitTestArea(abspos);
if(m_renderer->editableArea(hittest))
this->setCursor(Qt::IBeamCursor);
else
this->setCursor(Qt::ArrowCursor);
}
void QHexView::mouseReleaseEvent(QMouseEvent *e)
{
QAbstractScrollArea::mouseReleaseEvent(e);
/***
* 按钮点击
*/
auto rect1 = QRect(m_renderer->getAsciiX()+ 1,5,14,14);
auto rect2 = QRect(m_renderer->getAsciiEnd() - 1 - 14,5,14,14);
if(rect1.contains(e->pos()) && m_bHeadIconPressed){
alignmentHead(true);
}
if(rect2.contains(e->pos()) && m_bBottomIconPressed){
alignmentHead(false);
}
m_bHeadIconPressed = false;
m_bBottomIconPressed = false;
if(e->button() != Qt::LeftButton) return;
// if(!m_blinktimer->isActive()) m_blinktimer->start();
e->accept();
}
void QHexView::focusInEvent(QFocusEvent *e)
{
QAbstractScrollArea::focusInEvent(e);
if(!m_renderer) return;
m_renderer->enableCursor();
// m_blinktimer->start();
}
void QHexView::focusOutEvent(QFocusEvent *e)
{
QAbstractScrollArea::focusOutEvent(e);
if(!m_renderer) return;
m_blinktimer->stop();
m_renderer->enableCursor(false);
}
void QHexView::wheelEvent(QWheelEvent *e)
{
if(e->angleDelta().y() == 0)
{
int value = this->verticalScrollBar()->value();
if(e->angleDelta().x() < 0) // Scroll Down
this->verticalScrollBar()->setValue(value + DOCUMENT_WHEEL_LINES);
else if(e->angleDelta().x() > 0) // Scroll Up
this->verticalScrollBar()->setValue(value - DOCUMENT_WHEEL_LINES);
return;
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
在QML项目中实现一个显示文件十六进制数据展示的demo,可直接引入项目使用。 支持高亮某段数据,快速定位,头部底部对齐,主题切换,截图保存,切换展示宽度等功能。在开源代码的基础上进行扩展,并移植到QML中进行使用。 博客主页:https://blog.csdn.net/luoyayun361
资源推荐
资源详情
资源评论
收起资源包目录
HexViewQMLDemo.zip (57个子文件)
HexViewQMLDemo
HexViewQMLDemo.pro 762B
icon.qrc 893B
main.cpp 739B
qml.qrc 92B
QHexView
HexViewItem.cpp 6KB
qhexview.cpp 22KB
qhexview.h 2KB
QHexView.pri 1KB
hexviewcontainer.h 1013B
hexviewcontainer.cpp 3KB
HexViewItem.h 1KB
document
qhexmetadata.cpp 4KB
qhexcursor.h 2KB
qhexmetadata.h 2KB
qhexcursor.cpp 4KB
qhexrenderer.h 3KB
qhexdocument.cpp 6KB
qhexdocument.h 4KB
commands
insertcommand.cpp 356B
removecommand.h 319B
insertcommand.h 331B
replacecommand.h 380B
hexcommand.h 373B
replacecommand.cpp 421B
hexcommand.cpp 160B
removecommand.cpp 410B
qhexrenderer.cpp 20KB
buffer
qhexbuffer.h 982B
qmemoryrefbuffer.h 770B
qfilebuffer.h 856B
qmemoryrefbuffer.cpp 3KB
qfilebuffer.cpp 3KB
qhexbuffer.cpp 808B
qmemorybuffer.cpp 1KB
qmemorybuffer.h 775B
bin
HexViewQMLDemo.exe 141KB
file1.wav 1.07MB
hexview_screenshot0.png 9KB
hexview_screenshot1.png 11KB
file2.wav 2.38MB
main.qml 3KB
icon
dark
scroll_down@2x.png 749B
scroll_up_press.png 499B
scroll_down.png 401B
scroll_down_press.png 525B
scroll_up@2x.png 748B
scroll_up.png 378B
scroll_up_press@2x.png 935B
scroll_down_press@2x.png 943B
light
scroll_down@2x.png 917B
scroll_up_press.png 499B
scroll_down.png 497B
scroll_down_press.png 525B
scroll_up@2x.png 925B
scroll_up.png 481B
scroll_up_press@2x.png 935B
scroll_down_press@2x.png 943B
共 57 条
- 1
资源评论
luoyayun361
- 粉丝: 2w+
- 资源: 55
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功