feat: 引入编辑器渲染接口;

This commit is contained in:
寂静的羽夏 2025-07-19 20:17:40 +08:00
parent f40d9525b0
commit 0ba470c858
38 changed files with 2148 additions and 1074 deletions

View File

@ -86,11 +86,11 @@ void QHexDocument::setMetaCommentVisible(bool b) {
Q_EMIT metaCommentVisibleChanged(b);
}
bool QHexDocument::metabgVisible() { return m_metabg; }
bool QHexDocument::metabgVisible() const { return m_metabg; }
bool QHexDocument::metafgVisible() { return m_metafg; }
bool QHexDocument::metafgVisible() const { return m_metafg; }
bool QHexDocument::metaCommentVisible() { return m_metacomment; }
bool QHexDocument::metaCommentVisible() const { return m_metacomment; }
void QHexDocument::insertBookMarkAdjust(qsizetype offset, qsizetype length) {
QMap<qsizetype, QString> bms;
@ -218,7 +218,7 @@ void QHexDocument::removeBookMarkAdjustRevert(
_bookmarks.insert(rmbms);
}
bool QHexDocument::isDocSaved() { return m_undostack->isClean(); }
bool QHexDocument::isDocSaved() const { return m_undostack->isClean(); }
void QHexDocument::setDocSaved(bool b) {
if (b) {
@ -230,9 +230,9 @@ void QHexDocument::setDocSaved(bool b) {
Q_EMIT documentSaved(b);
}
bool QHexDocument::isReadOnly() { return m_readonly; }
bool QHexDocument::isKeepSize() { return m_keepsize; }
bool QHexDocument::isLocked() { return m_islocked; }
bool QHexDocument::isReadOnly() const { return m_readonly; }
bool QHexDocument::isKeepSize() const { return m_keepsize; }
bool QHexDocument::isLocked() const { return m_islocked; }
void QHexDocument::setLockKeepSize(bool b) { m_lockKeepSize = b; }

View File

@ -58,9 +58,9 @@ public:
bool setLockedFile(bool b);
bool setKeepSize(bool b);
bool isReadOnly();
bool isKeepSize();
bool isLocked();
bool isReadOnly() const;
bool isKeepSize() const;
bool isLocked() const;
void setLockKeepSize(bool b);
bool lockKeepSize() const;
@ -110,16 +110,16 @@ public:
QList<qsizetype> &results,
const std::function<bool()> &pred = [] { return true; });
bool isDocSaved();
bool isDocSaved() const;
void setDocSaved(bool b = true);
void setMetafgVisible(bool b);
void setMetabgVisible(bool b);
void setMetaCommentVisible(bool b);
bool metafgVisible();
bool metabgVisible();
bool metaCommentVisible();
bool metafgVisible() const;
bool metabgVisible() const;
bool metaCommentVisible() const;
void insertBookMarkAdjust(qsizetype offset, qsizetype length);
QMap<qsizetype, QString> removeBookMarkAdjust(qsizetype offset,

View File

@ -92,14 +92,16 @@ void QHexRenderer::renderFrame(QPainter *painter) {
int asciix = this->getAsciiColumnX();
int endx = this->getEndColumnX();
painter->setPen(m_borderColor);
// x coordinates are in absolute space
// y coordinates are in viewport space
// see QHexView::paintEvent where the painter has been shifted horizontally
auto h = this->headerLineCount() * this->lineHeight();
if (m_headerVisible)
painter->drawLine(0, this->headerLineCount() * this->lineHeight() - 1,
endx,
this->headerLineCount() * this->lineHeight() - 1);
painter->drawLine(0, h, endx, h);
if (m_addressVisible)
painter->drawLine(hexx, rect.top(), hexx, rect.bottom());
@ -872,6 +874,12 @@ void QHexRenderer::drawHeader(QPainter *painter) {
painter->restore();
}
void QHexRenderer::setBorderColor(const QColor &newBorderColor) {
m_borderColor = newBorderColor;
}
QColor QHexRenderer::borderColor() const { return m_borderColor; }
QHexCursor *QHexRenderer::cursor() const { return m_cursor; }
void QHexRenderer::setCursor(QHexCursor *newCursor) { m_cursor = newCursor; }

View File

@ -101,6 +101,9 @@ public:
QColor selBackgroundColor() const;
void setSelBackgroundColor(const QColor &newSelBackgroundColor);
QColor borderColor() const;
void setBorderColor(const QColor &newBorderColor);
QHexCursor *cursor() const;
void setCursor(QHexCursor *newCursor);
@ -111,6 +114,8 @@ private:
QByteArray getLine(qsizetype line) const;
qsizetype rendererLength() const;
public:
int getAddressWidth() const;
int getHexColumnX() const;
int getAsciiColumnX() const;
@ -178,6 +183,7 @@ private:
QColor m_bytesColor = Qt::black;
QColor m_selectionColor = Qt::white;
QColor m_selBackgroundColor = Qt::blue;
QColor m_borderColor = Qt::white;
/*==============================*/
};

View File

@ -323,7 +323,9 @@ void QHexView::keyPressEvent(QKeyEvent *e) {
}
QPoint QHexView::absolutePosition(const QPoint &pos) const {
QPoint shift(horizontalScrollBar()->value(), 0);
auto margins = viewport()->contentsMargins();
QPoint shift(horizontalScrollBar()->value() - margins.left(),
-margins.top() * m_renderer->lineHeight());
return pos + shift;
}
@ -567,9 +569,18 @@ QColor QHexView::selBackgroundColor() const {
return m_renderer->selBackgroundColor();
}
QColor QHexView::borderColor() const { return m_renderer->borderColor(); }
void QHexView::setSelBackgroundColor(const QColor &newSelBackgroundColor) {
m_renderer->setSelBackgroundColor(newSelBackgroundColor);
Q_EMIT selBackgroundColorChanged();
this->viewport()->update();
}
void QHexView::setBorderColor(const QColor &newBorderColor) {
m_renderer->setBorderColor(newBorderColor);
Q_EMIT borderColorChanged();
this->viewport()->update();
}
void QHexView::setFontSize(qreal size) {
@ -577,6 +588,7 @@ void QHexView::setFontSize(qreal size) {
auto font = this->font();
font.setPointSizeF(size * m_scaleRate);
this->setFont(font);
this->viewport()->update();
}
QColor QHexView::selectionColor() const { return m_renderer->selectionColor(); }
@ -584,6 +596,7 @@ QColor QHexView::selectionColor() const { return m_renderer->selectionColor(); }
void QHexView::setSelectionColor(const QColor &newSelectionColor) {
m_renderer->setSelectionColor(newSelectionColor);
Q_EMIT selectionColorChanged();
this->viewport()->update();
}
QColor QHexView::bytesAlterBackground() const {
@ -593,6 +606,7 @@ QColor QHexView::bytesAlterBackground() const {
void QHexView::setBytesAlterBackground(const QColor &newBytesAlterBackground) {
m_renderer->setBytesAlterBackground(newBytesAlterBackground);
Q_EMIT bytesAlterBackgroundChanged();
this->viewport()->update();
}
QColor QHexView::bytesColor() const { return m_renderer->bytesColor(); }
@ -600,6 +614,7 @@ QColor QHexView::bytesColor() const { return m_renderer->bytesColor(); }
void QHexView::setBytesColor(const QColor &newBytesColor) {
m_renderer->setBytesColor(newBytesColor);
Q_EMIT bytesColorChanged();
this->viewport()->update();
}
QColor QHexView::bytesBackground() const {
@ -609,6 +624,7 @@ QColor QHexView::bytesBackground() const {
void QHexView::setBytesBackground(const QColor &newBytesBackground) {
m_renderer->setBytesBackground(newBytesBackground);
Q_EMIT bytesBackgroundChanged();
this->viewport()->update();
}
QColor QHexView::addressColor() const { return m_renderer->addressColor(); }
@ -616,6 +632,7 @@ QColor QHexView::addressColor() const { return m_renderer->addressColor(); }
void QHexView::setAddressColor(const QColor &newAddressColor) {
m_renderer->setAddressColor(newAddressColor);
Q_EMIT addressColorChanged();
this->viewport()->update();
}
QColor QHexView::headerColor() const { return m_renderer->headerColor(); }
@ -623,6 +640,7 @@ QColor QHexView::headerColor() const { return m_renderer->headerColor(); }
void QHexView::setHeaderColor(const QColor &newHeaderColor) {
m_renderer->setHeaderColor(newHeaderColor);
Q_EMIT headerColorChanged();
this->viewport()->update();
}
void QHexView::mousePressEvent(QMouseEvent *e) {
@ -764,21 +782,27 @@ void QHexView::paintEvent(QPaintEvent *e) {
const int lineHeight = m_renderer->lineHeight();
const int headerCount = m_renderer->headerLineCount();
auto m = viewport()->contentsMargins();
// these are lines from the point of view of the visible rect
// where the first "headerCount" are taken by the header
const int first = (r.top() / lineHeight); // included
const int lastPlusOne = (r.bottom() / lineHeight) + 1; // excluded
const int first = (r.top() / lineHeight); // included
const int lastPlusOne =
(r.bottom() / lineHeight) + 1 - m.top() - m.bottom(); // excluded
// compute document lines, adding firstVisible and removing the header
// the max is necessary if the rect covers the header
const qsizetype begin = firstVisible + std::max(first - headerCount, 0);
const qsizetype end = firstVisible + std::max(lastPlusOne - headerCount, 0);
Q_EMIT onPaintCustomEventBegin();
painter.save();
painter.translate(-this->horizontalScrollBar()->value(), 0);
auto xOff = this->horizontalScrollBar()->value();
painter.translate(-xOff + m.left(), m.top() * m_renderer->lineHeight());
m_renderer->render(&painter, begin, end, firstVisible);
m_renderer->renderFrame(&painter);
painter.restore();
Q_EMIT onPaintCustomEvent(xOff, firstVisible, begin, end);
}
void QHexView::moveToSelection() {
@ -1160,6 +1184,7 @@ void QHexView::adjustScrollBars() {
auto docLines = m_renderer->documentLines();
auto visLines = this->visibleLines();
auto margins = viewport()->contentsMargins();
// modified by wingsummer,fix the scrollbar bug
if (docLines > visLines && !m_document->isEmpty()) {
@ -1180,11 +1205,13 @@ void QHexView::adjustScrollBars() {
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// +1 to see the rightmost vertical line, +2 seems more pleasant to the
// eyes
hscrollbar->setMaximum(documentWidth - viewportWidth + 2);
hscrollbar->setMaximum(documentWidth - viewportWidth + 2 +
margins.left() + margins.right());
} else {
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
hscrollbar->setValue(0);
hscrollbar->setMaximum(documentWidth);
hscrollbar->setMaximum(documentWidth + margins.left() +
margins.right());
}
}
@ -1203,9 +1230,10 @@ qsizetype QHexView::lastVisibleLine() const {
}
qsizetype QHexView::visibleLines() const {
auto visLines =
qsizetype(std::ceil(this->height() / m_renderer->lineHeight() -
m_renderer->headerLineCount()));
auto margins = viewport()->contentsMargins();
auto visLines = qsizetype(std::ceil(
this->height() / m_renderer->lineHeight() -
m_renderer->headerLineCount() - margins.top() - margins.bottom()));
return std::min(visLines, m_renderer->documentLines());
}

View File

@ -47,6 +47,8 @@ class QHexView : public QAbstractScrollArea {
NOTIFY selectionColorChanged FINAL)
Q_PROPERTY(QColor selBackgroundColor READ selBackgroundColor WRITE
setSelBackgroundColor NOTIFY selBackgroundColorChanged FINAL)
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY
borderColorChanged FINAL)
Q_PROPERTY(qreal scaleRate READ scaleRate WRITE setScaleRate NOTIFY
scaleRateChanged FINAL)
@ -54,18 +56,10 @@ public:
explicit QHexView(QWidget *parent = nullptr);
virtual ~QHexView();
public:
QSharedPointer<QHexDocument> document();
QHexRenderer *renderer();
void setDocument(const QSharedPointer<QHexDocument> &document,
QHexCursor *cursor = nullptr);
/*=============================*/
// added by wingsummer
bool setLockedFile(bool b);
bool setKeepSize(bool b);
void setLockKeepSize(bool b);
bool lockKeepSize() const;
bool isReadOnly();
@ -81,58 +75,66 @@ public:
qsizetype selectionCount();
bool hasSelection();
void setAsciiVisible(bool b);
bool asciiVisible();
void setAddressVisible(bool b);
bool addressVisible();
void setHeaderVisible(bool b);
bool headerVisible();
quintptr addressBase();
void setAddressBase(quintptr base);
bool isSaved();
static QFont getHexeditorFont();
void getStatus();
QColor headerColor() const;
void setHeaderColor(const QColor &newHeaderColor);
QColor addressColor() const;
void setAddressColor(const QColor &newAddressColor);
QColor bytesBackground() const;
void setBytesBackground(const QColor &newBytesBackground);
QColor bytesAlterBackground() const;
void setBytesAlterBackground(const QColor &newBytesAlterBackground);
QColor bytesColor() const;
void setBytesColor(const QColor &newBytesColor);
QColor selectionColor() const;
void setSelectionColor(const QColor &newSelectionColor);
QColor selBackgroundColor() const;
void setSelBackgroundColor(const QColor &newSelBackgroundColor);
QColor borderColor() const;
void setFontSize(qreal size);
qreal fontSize() const;
void setScaleRate(qreal rate);
qreal scaleRate() const;
qsizetype findNext(qsizetype begin, const QByteArray &ba);
qsizetype findPrevious(qsizetype begin, const QByteArray &ba);
bool RemoveSelection(int nibbleindex = 1);
bool removeSelection();
bool atEnd() const;
QByteArray selectedBytes(qsizetype index) const;
QByteArray previewSelectedBytes() const;
QByteArrayList selectedBytes() const;
qsizetype copyLimit() const;
QHexCursor *cursor() const;
public slots:
void setDocument(const QSharedPointer<QHexDocument> &document,
QHexCursor *cursor = nullptr);
bool RemoveSelection(int nibbleindex = 1);
bool removeSelection();
bool setLockedFile(bool b);
bool setKeepSize(bool b);
void setLockKeepSize(bool b);
void setAddressBase(quintptr base);
void setHeaderColor(const QColor &newHeaderColor);
void setAddressColor(const QColor &newAddressColor);
void setBytesBackground(const QColor &newBytesBackground);
void setBytesAlterBackground(const QColor &newBytesAlterBackground);
void setBytesColor(const QColor &newBytesColor);
void setSelectionColor(const QColor &newSelectionColor);
void setSelBackgroundColor(const QColor &newSelBackgroundColor);
void setBorderColor(const QColor &newBorderColor);
void setFontSize(qreal size);
void setScaleRate(qreal rate);
qsizetype findNext(qsizetype begin, const QByteArray &ba);
qsizetype findPrevious(qsizetype begin, const QByteArray &ba);
void setAsciiVisible(bool b);
void setAddressVisible(bool b);
void setHeaderVisible(bool b);
bool cut(bool hex);
bool copy(bool hex = false);
bool paste(bool hex = false);
@ -142,11 +144,8 @@ public:
void Replace(qsizetype offset, uchar b, int nibbleindex);
void Replace(qsizetype offset, const QByteArray &data, int nibbleindex = 0);
qsizetype copyLimit() const;
void setCopyLimit(qsizetype newCopylimit);
QHexCursor *cursor() const;
private:
void establishSignal(QHexDocument *doc);
@ -177,6 +176,11 @@ signals:
void bytesColorChanged();
void selectionColorChanged();
void selBackgroundColorChanged();
void borderColorChanged();
void onPaintCustomEventBegin();
void onPaintCustomEvent(int XOffset, qsizetype firstVisible,
qsizetype begin, qsizetype end);
protected:
virtual bool event(QEvent *e);

View File

@ -29,6 +29,7 @@ add_definitions(-DAS_NO_THREADS)
if(BUILD_TEST_PLUGIN)
add_subdirectory(TestPlugin)
add_subdirectory(TestBadPlugin)
add_subdirectory(TestHexExt)
add_subdirectory(TestManager)
endif()
@ -305,7 +306,9 @@ set(CLASS_SRC
src/class/winggeneric.h
src/class/winggeneric.cpp
src/class/changedstringlist.h
src/class/changedstringlist.cpp)
src/class/changedstringlist.cpp
src/class/editorviewcontext.h
src/class/editorviewcontext.cpp)
set(INTERNAL_PLG_SRC
src/class/wingangelapi.h src/class/wingangelapi.cpp

View File

@ -106,7 +106,7 @@
&emsp;&emsp;如果你想将本软件的代码用于闭源的商业代码,想要解除`GPL`系列的必须开源的限制,请必须亲自咨询我,商讨商业授权相关事宜。
&emsp;&emsp;对于插件开发相关的,对应的开源协议就不一样了。只针对本仓库下的`WingPlugin`的代码遵守`BSD 3-Clause`协议,以允许闭源商业开发。对于本仓库下的`TestPlugin`的代码(除`TranslationUtils.cmake`这一个文件遵守`BSD 3-Clause`)遵守`MIT`协议。
&emsp;&emsp;对于插件开发相关的,对应的开源协议就不一样了。只针对本仓库下的`WingPlugin`的代码遵守`BSD 3-Clause`协议,以允许闭源商业开发。对于本仓库下的`TestPlugin`/`TestBadPlugin`/`TestHexExt`/`TestManager`的代码(除`TranslationUtils.cmake`这一个文件遵守`BSD 3-Clause`)遵守`MIT`协议。
### 使用声明

View File

@ -106,7 +106,7 @@ This software complies with the `AGPL-3.0` agreement. Please do not use it for p
If you want to use the code of this software for closed-source commercial code and want to lift the restriction of the `GPL` series that it must be open source, please consult me in person to discuss commercial licensing matters.
For plugin development, the corresponding open source agreements are different. Only the code of `WingPlugin` in this repository comply with the `BSD 3-Clause` agreement to allow closed-source commercial development. The code of `TestPlugin` in this repository (except the file `TranslationUtils.cmake` which complies with `BSD 3-Clause`) complies with the `MIT` agreement.
For plugin development, the corresponding open source agreements are different. Only the code of `WingPlugin` in this repository comply with the `BSD 3-Clause` agreement to allow closed-source commercial development. The code of `TestPlugin`/`TestBadPlugin`/`TestHexExt`/`TestManager` in this repository (except the file `TranslationUtils.cmake` which complies with `BSD 3-Clause`) complies with the `MIT` agreement.
### Usage Statement

55
TestHexExt/CMakeLists.txt Normal file
View File

@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 3.16)
project(TestHexExt)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
# Test mode, please configure the main program directory to facilitate debugging
# 便
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
option(TEST_MODE TRUE)
# For Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Widgets
REQUIRED)
find_package(Qt6 REQUIRED COMPONENTS Core)
add_library(TestHexExt SHARED TestHexExt.json testhexext.h testhexext.cpp)
set_target_properties(TestHexExt PROPERTIES SUFFIX ".winghexe")
if(TEST_MODE)
# If you want to be able to debug easily every time you compile, please set
# this variable. Because this test plugin is a subproject of the main
# project, use CMAKE_BINARY_DIR
# 便 CMAKE_BINARY_DIR
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
set(WINGHEX_PATH "${CMAKE_BINARY_DIR}")
set(WINGHEX_PLUGIN_PATH "${WINGHEX_PATH}")
add_custom_command(
TARGET TestHexExt
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${WINGHEX_PLUGIN_PATH}
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:TestHexExt>
${WINGHEX_PLUGIN_PATH})
endif()
target_link_libraries(TestHexExt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
WingPlugin)
target_link_libraries(TestHexExt PRIVATE Qt6::Core)

View File

@ -0,0 +1,9 @@
{
"Id": "TestHexExt",
"SDK": 18,
"Version": "0.0.1",
"Vendor": "WingCloudStudio",
"Author": "wingsummer",
"License": "MIT",
"Url": "https://github.com/Wing-summer/WingHexExplorer2"
}

107
TestHexExt/testhexext.cpp Normal file
View File

@ -0,0 +1,107 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
** =============================================================================
*/
#include "testhexext.h"
#include <QAction>
#include <QMenu>
#include <QPainter>
TestHexExt::TestHexExt() : WingHex::IWingHexEditorPlugin() {
m_context = new QMenu(QStringLiteral("TestHexExt"));
auto a = new QAction(QStringLiteral("LineCol"), m_context);
a->setCheckable(true);
a->setChecked(true);
connect(a, &QAction::toggled, this, &TestHexExt::setColVisible);
m_context->addAction(a);
}
bool TestHexExt::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set);
return true;
}
void TestHexExt::unload(std::unique_ptr<QSettings> &set) { Q_UNUSED(set); }
const QString TestHexExt::comment() const {
return QStringLiteral("A simple line pannel");
}
QMenu *TestHexExt::registeredHexContextMenu() const { return m_context; }
QList<WingHex::WingRibbonToolBoxInfo>
TestHexExt::registeredRibbonTools() const {
// TODO
return {};
}
QMargins TestHexExt::contentMargins(WingHex::HexEditorContext *context) const {
if (!_visCol) {
return {};
}
auto lines = context->documentLines();
auto str = QString::number(lines);
auto fm = context->fontMetrics();
constexpr auto padding = 4;
auto len = fm.horizontalAdvance(str) + padding;
return {int(len), 0, 0, 1};
}
void TestHexExt::onPaintEvent(QPainter *painter, const QWidget *w,
WingHex::HexEditorContext *context) {
if (!_visCol) {
return;
}
painter->save();
painter->translate(-context->currentHorizontalOffset(), 0);
auto lines = context->documentLines();
auto str = QString::number(lines);
auto fm = context->fontMetrics();
constexpr auto padding = 4;
auto header = QStringLiteral("Line");
auto minLen = fm.horizontalAdvance(header) + padding;
auto colLen = qMax(fm.horizontalAdvance(str) + padding, minLen);
auto border = context->borderColor();
painter->setPen(border);
if (context->headerAreaVisible()) {
auto headerHeight = context->headerHeight();
painter->drawLine(0, headerHeight, colLen, headerHeight);
painter->save();
painter->setPen(context->headerColor());
QRectF rect(0, 0, colLen, headerHeight);
painter->drawText(rect, header, QTextOption(Qt::AlignCenter));
painter->restore();
context->renderHexBackground(painter, {0, 0}, colLen);
}
painter->drawLine(colLen, 0, colLen, w->height());
// draw Line Numbers
painter->setPen(context->addressColor());
context->renderContent(
painter, {0, 0}, colLen,
[](QPainter *painter, const QRect &lineRect, qsizetype curLine) {
painter->drawText(lineRect, QString::number(curLine),
QTextOption(Qt::AlignCenter));
});
painter->restore();
}
void TestHexExt::setColVisible(bool b) { _visCol = b; }

67
TestHexExt/testhexext.h Normal file
View File

@ -0,0 +1,67 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
** =============================================================================
*/
#ifndef TESTHEXEXT_H
#define TESTHEXEXT_H
#include "WingPlugin/iwinghexeditorplugin.h"
/**
* @brief The TestHexExt class
* @brief This plugin will draw a line number panel
*/
class TestHexExt : public WingHex::IWingHexEditorPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.wingsummer.iwinghexext" FILE "TestHexExt.json")
Q_INTERFACES(WingHex::IWingHexEditorPlugin)
public:
TestHexExt();
// IWingPluginCoreBase interface
public:
virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override;
public:
virtual const QString comment() const override;
virtual QMenu *registeredHexContextMenu() const override;
virtual QList<WingHex::WingRibbonToolBoxInfo>
registeredRibbonTools() const override;
// additional offset that applies HexEditor
virtual QMargins
contentMargins(WingHex::HexEditorContext *context) const override;
public:
virtual void onPaintEvent(QPainter *painter, const QWidget *w,
WingHex::HexEditorContext *context) override;
private slots:
void setColVisible(bool b);
private:
QMenu *m_context;
bool _visCol = true;
};
#endif // TESTHEXEXT_H

View File

@ -269,60 +269,60 @@
<context>
<name>TestPlugin</name>
<message>
<location filename="../testplugin.cpp" line="68"/>
<location filename="../testplugin.cpp" line="69"/>
<source>Test</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="79"/>
<location filename="../testplugin.cpp" line="82"/>
<location filename="../testplugin.cpp" line="85"/>
<location filename="../testplugin.cpp" line="144"/>
<location filename="../testplugin.cpp" line="81"/>
<location filename="../testplugin.cpp" line="84"/>
<location filename="../testplugin.cpp" line="87"/>
<location filename="../testplugin.cpp" line="146"/>
<source>TestPlugin</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="89"/>
<location filename="../testplugin.cpp" line="91"/>
<source>Button - </source>
<translation> - </translation>
</message>
<message>
<location filename="../testplugin.cpp" line="92"/>
<location filename="../testplugin.cpp" line="94"/>
<source>Click</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="147"/>
<location filename="../testplugin.cpp" line="149"/>
<source>A Test Plugin for WingHexExplorer2.</source>
<translation>2</translation>
</message>
<message>
<location filename="../testplugin.cpp" line="176"/>
<location filename="../testplugin.cpp" line="184"/>
<location filename="../testplugin.cpp" line="193"/>
<location filename="../testplugin.cpp" line="214"/>
<location filename="../testplugin.cpp" line="230"/>
<location filename="../testplugin.cpp" line="237"/>
<location filename="../testplugin.cpp" line="244"/>
<location filename="../testplugin.cpp" line="251"/>
<location filename="../testplugin.cpp" line="258"/>
<location filename="../testplugin.cpp" line="287"/>
<location filename="../testplugin.cpp" line="295"/>
<location filename="../testplugin.cpp" line="303"/>
<location filename="../testplugin.cpp" line="311"/>
<location filename="../testplugin.cpp" line="320"/>
<location filename="../testplugin.cpp" line="327"/>
<location filename="../testplugin.cpp" line="178"/>
<location filename="../testplugin.cpp" line="186"/>
<location filename="../testplugin.cpp" line="195"/>
<location filename="../testplugin.cpp" line="216"/>
<location filename="../testplugin.cpp" line="232"/>
<location filename="../testplugin.cpp" line="239"/>
<location filename="../testplugin.cpp" line="246"/>
<location filename="../testplugin.cpp" line="253"/>
<location filename="../testplugin.cpp" line="260"/>
<location filename="../testplugin.cpp" line="289"/>
<location filename="../testplugin.cpp" line="297"/>
<location filename="../testplugin.cpp" line="305"/>
<location filename="../testplugin.cpp" line="313"/>
<location filename="../testplugin.cpp" line="322"/>
<location filename="../testplugin.cpp" line="329"/>
<source>InvalidParamsCount</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="207"/>
<location filename="../testplugin.cpp" line="223"/>
<location filename="../testplugin.cpp" line="209"/>
<location filename="../testplugin.cpp" line="225"/>
<source>InvalidParam</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="278"/>
<location filename="../testplugin.cpp" line="280"/>
<source>AllocArrayFailed</source>
<translation></translation>
</message>

View File

@ -26,6 +26,7 @@
#include <QApplication>
#include <QMenu>
#include <QPainter>
WING_DECLARE_STATIC_API;
@ -75,11 +76,12 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
QIcon btnIcon(QStringLiteral(":/images/TestPlugin/images/btn.png"));
_rtbinfo << createRibbonToolBox(WingHex::WingRibbonCatagories::PLUGIN,
createToolBox(tr("TestPlugin"), tb));
_rtbinfo << createRibbonToolBox(
WingHex::WingRibbonCatagories::PLUGIN,
WingHex::createToolBox(tr("TestPlugin"), tb));
auto rtb =
createRibbonToolBox(QStringLiteral("TestPlugin"), tr("TestPlugin"));
auto rtb = WingHex::createRibbonToolBox(QStringLiteral("TestPlugin"),
tr("TestPlugin"));
for (int i = 0; i < 3; ++i) {
TBInfo::Toolbox tbtb;
tbtb.name = tr("TestPlugin") + QStringLiteral("(%1)").arg(i);
@ -581,3 +583,23 @@ void TestPlugin::onRegisterScriptObj(WingHex::IWingAngel *o) {
asWINGFUNCTION(TestPlugin::testRaiseScriptException),
WingHex::IWingAngel::asCallConvTypes::asCALL_GENERIC);
}
void TestPlugin::onPaintHexEditorView(QPainter *painter, QWidget *w,
WingHex::HexEditorContext *context) {
Q_UNUSED(context);
painter->save();
auto font = painter->font();
auto metric = QFontMetrics(font);
auto str = QStringLiteral("TestPlugin");
auto len = metric.horizontalAdvance(str);
auto height = metric.height();
auto pen = painter->pen();
auto color = pen.color();
color.setAlpha(180);
pen.setColor(color);
painter->setPen(pen);
constexpr auto padding = 2;
auto rect = w->rect();
painter->drawText(rect.right() - len - padding, height + padding, str);
painter->restore();
}

View File

@ -68,6 +68,10 @@ public:
public:
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
virtual void
onPaintHexEditorView(QPainter *painter, QWidget *w,
WingHex::HexEditorContext *context) override;
private:
QVariant test_a(const QVariantList &params);
QVariant test_b(const QVariantList &params);

@ -1 +1 @@
Subproject commit 3942f52c8ee7e828ba56328106eb6c03ae14a623
Subproject commit 19604dfffe05008c22f3ec77b7d09f6525836ed9

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "editorviewcontext.h"
EditorViewContext::EditorViewContext(QHexView *view)
: WingHex::HexEditorContext(), _view(view) {
Q_ASSERT(view);
}
QFontMetricsF EditorViewContext::fontMetrics() const {
return _view->fontMetrics();
}
QColor EditorViewContext::headerColor() const { return _view->headerColor(); }
QColor EditorViewContext::addressColor() const { return _view->addressColor(); }
QColor EditorViewContext::bytesBackground() const {
return _view->bytesBackground();
}
QColor EditorViewContext::bytesAlterBackground() const {
return _view->bytesAlterBackground();
}
QColor EditorViewContext::bytesColor() const { return _view->bytesColor(); }
QColor EditorViewContext::selectionColor() const {
return _view->selectionColor();
}
QColor EditorViewContext::selBackgroundColor() const {
return _view->selBackgroundColor();
}
bool EditorViewContext::stringAreaVisible() const {
return _view->asciiVisible();
}
bool EditorViewContext::addressAreaVisible() const {
return _view->addressVisible();
}
bool EditorViewContext::headerAreaVisible() const {
return _view->headerVisible();
}
QColor EditorViewContext::borderColor() const { return _view->borderColor(); }
qsizetype EditorViewContext::documentLastLine() const {
auto render = _view->renderer();
return render->documentLastLine();
}
qsizetype EditorViewContext::documentLastColumn() const {
auto render = _view->renderer();
return render->documentLastColumn();
}
qsizetype EditorViewContext::documentLines() const {
auto render = _view->renderer();
return render->documentLines();
}
int EditorViewContext::documentWidth() const {
auto render = _view->renderer();
return render->documentWidth();
}
int EditorViewContext::lineHeight() const {
auto render = _view->renderer();
return render->lineHeight();
}
int EditorViewContext::borderSize() const {
auto render = _view->renderer();
return render->borderSize();
}
int EditorViewContext::hexLineWidth() const {
auto render = _view->renderer();
return render->hexLineWidth();
}
int EditorViewContext::areaIndent() const {
auto doc = _view->document();
return doc->areaIndent();
}
int EditorViewContext::addressWidth() const {
auto render = _view->renderer();
return render->getAddressWidth();
}
int EditorViewContext::headerHeight() const {
auto render = _view->renderer();
return render->headerLineCount() * render->lineHeight();
}
int EditorViewContext::hexColumnX() const {
auto render = _view->renderer();
return render->getHexColumnX();
}
int EditorViewContext::stringColumnX() const {
auto render = _view->renderer();
return render->getAsciiColumnX();
}
int EditorViewContext::endColumnX() const {
auto render = _view->renderer();
return render->getEndColumnX();
}
qreal EditorViewContext::cellWidth() const {
auto render = _view->renderer();
return render->getCellWidth();
}
int EditorViewContext::nCellsWidth(int n) const {
auto render = _view->renderer();
return render->getNCellsWidth(n);
}
QRect EditorViewContext::lineRect(qsizetype line, qsizetype firstline) const {
auto render = _view->renderer();
return render->getLineRect(line, firstline);
}
WingHex::HexPosition EditorViewContext::position() const {
WingHex::HexPosition pos;
auto cursor = _view->cursor();
auto p = cursor->position();
pos.line = p.line;
pos.lineWidth = p.lineWidth;
pos.column = p.column;
pos.nibbleindex = p.nibbleindex;
return pos;
}
qsizetype EditorViewContext::selectionCount() const {
auto cursor = _view->cursor();
return cursor->selectionCount();
}
WingHex::HexPosition EditorViewContext::selectionStart(qsizetype index) const {
WingHex::HexPosition pos;
auto cursor = _view->cursor();
auto p = cursor->selectionStart(index);
pos.line = p.line;
pos.lineWidth = p.lineWidth;
pos.column = p.column;
pos.nibbleindex = p.nibbleindex;
return pos;
}
WingHex::HexPosition EditorViewContext::selectionEnd(qsizetype index) const {
WingHex::HexPosition pos;
auto cursor = _view->cursor();
auto p = cursor->selectionEnd(index);
pos.line = p.line;
pos.lineWidth = p.lineWidth;
pos.column = p.column;
pos.nibbleindex = p.nibbleindex;
return pos;
}
qsizetype EditorViewContext::selectionLength(qsizetype index) const {
auto cursor = _view->cursor();
return cursor->selectionLength(index);
}
bool EditorViewContext::isInInsertionMode() const {
auto cursor = _view->cursor();
return cursor->insertionMode() == QHexCursor::InsertMode;
}
qsizetype EditorViewContext::currentLine() const {
auto cursor = _view->cursor();
return cursor->currentLine();
}
int EditorViewContext::currentColumn() const {
auto cursor = _view->cursor();
return cursor->currentColumn();
}
int EditorViewContext::currentNibble() const {
auto cursor = _view->cursor();
return cursor->currentNibble();
}
qsizetype EditorViewContext::currentSelectionLength() const {
auto cursor = _view->cursor();
return cursor->currentSelectionLength();
}
bool EditorViewContext::isLineSelected(qsizetype line) const {
auto cursor = _view->cursor();
return cursor->isLineSelected(line);
}
bool EditorViewContext::isSelected(const WingHex::HexPosition &pos) const {
auto cursor = _view->cursor();
QHexPosition p;
p.line = pos.line;
p.lineWidth = pos.lineWidth;
p.column = pos.column;
p.nibbleindex = pos.nibbleindex;
return cursor->isSelected(p);
}
bool EditorViewContext::hasSelection() const {
auto cursor = _view->cursor();
return cursor->hasSelection();
}
bool EditorViewContext::hasInternalSelection() const {
auto cursor = _view->cursor();
return cursor->hasInternalSelection();
}
qsizetype EditorViewContext::beginLine() const { return _beginLine; }
qsizetype EditorViewContext::endLine() const { return _endLine; }
qsizetype EditorViewContext::firstVisibleLine() const {
return _firstVisibleLine;
}
int EditorViewContext::currentHorizontalOffset() const {
return _horizontalOffset;
}
QByteArray EditorViewContext::read(qsizetype offset, qsizetype len) const {
auto doc = _view->document();
return doc->read(offset, len);
}
char EditorViewContext::readAt(qsizetype offset) const {
auto doc = _view->document();
return doc->at(offset);
}
quintptr EditorViewContext::baseAddress() const {
auto doc = _view->document();
return doc->baseAddress();
}
bool EditorViewContext::metafgVisible() const {
auto doc = _view->document();
return doc->metafgVisible();
}
bool EditorViewContext::metabgVisible() const {
auto doc = _view->document();
return doc->metabgVisible();
}
bool EditorViewContext::metaCommentVisible() const {
auto doc = _view->document();
return doc->metaCommentVisible();
}
bool EditorViewContext::isReadOnly() const {
auto doc = _view->document();
return doc->isReadOnly();
}
bool EditorViewContext::isKeepSize() const {
auto doc = _view->document();
return doc->isKeepSize();
}
bool EditorViewContext::isLocked() const {
auto doc = _view->document();
return doc->isLocked();
}
bool EditorViewContext::lockKeepSize() const {
auto doc = _view->document();
return doc->lockKeepSize();
}
void EditorViewContext::update() { _view->viewport()->update(); }
void EditorViewContext::setBeginLine(qsizetype newBeginLine) {
_beginLine = newBeginLine;
}
void EditorViewContext::setEndLine(qsizetype newEndLine) {
_endLine = newEndLine;
}
void EditorViewContext::setFirstVisibleLine(qsizetype newFirstVisibleLine) {
_firstVisibleLine = newFirstVisibleLine;
}
void EditorViewContext::setCurrentHorizontalOffset(int horizontalOffset) {
_horizontalOffset = horizontalOffset;
}

View File

@ -0,0 +1,113 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#ifndef EDITORVIEWCONTEXT_H
#define EDITORVIEWCONTEXT_H
#include "QHexView/qhexview.h"
#include "WingPlugin/hexeditorcontext.h"
class EditorViewContext : public WingHex::HexEditorContext {
public:
explicit EditorViewContext(QHexView *view);
// HexEditorPalette interface
public:
virtual QFontMetricsF fontMetrics() const override;
virtual QColor headerColor() const override;
virtual QColor addressColor() const override;
virtual QColor bytesBackground() const override;
virtual QColor bytesAlterBackground() const override;
virtual QColor bytesColor() const override;
virtual QColor selectionColor() const override;
virtual QColor selBackgroundColor() const override;
virtual bool stringAreaVisible() const override;
virtual bool addressAreaVisible() const override;
virtual bool headerAreaVisible() const override;
virtual QColor borderColor() const override;
public:
virtual qsizetype documentLastLine() const override;
virtual qsizetype documentLastColumn() const override;
virtual qsizetype documentLines() const override;
virtual int documentWidth() const override;
virtual int lineHeight() const override;
virtual int borderSize() const override;
virtual int hexLineWidth() const override;
virtual int areaIndent() const override;
virtual int addressWidth() const override;
public:
virtual int headerHeight() const override;
virtual int hexColumnX() const override;
virtual int stringColumnX() const override;
virtual int endColumnX() const override;
virtual qreal cellWidth() const override;
virtual int nCellsWidth(int n) const override;
virtual QRect lineRect(qsizetype line, qsizetype firstline) const override;
public:
virtual WingHex::HexPosition position() const override;
virtual qsizetype selectionCount() const override;
virtual WingHex::HexPosition selectionStart(qsizetype index) const override;
virtual WingHex::HexPosition selectionEnd(qsizetype index) const override;
virtual qsizetype selectionLength(qsizetype index) const override;
virtual bool isInInsertionMode() const override;
virtual qsizetype currentLine() const override;
virtual int currentColumn() const override;
virtual int currentNibble() const override;
virtual qsizetype currentSelectionLength() const override;
virtual bool isLineSelected(qsizetype line) const override;
virtual bool isSelected(const WingHex::HexPosition &pos) const override;
virtual bool hasSelection() const override;
virtual bool hasInternalSelection() const override;
virtual qsizetype beginLine() const override;
virtual qsizetype endLine() const override;
virtual qsizetype firstVisibleLine() const override;
virtual int currentHorizontalOffset() const override;
public:
virtual QByteArray read(qsizetype offset, qsizetype len) const override;
virtual char readAt(qsizetype offset) const override;
virtual quintptr baseAddress() const override;
virtual bool metafgVisible() const override;
virtual bool metabgVisible() const override;
virtual bool metaCommentVisible() const override;
virtual bool isReadOnly() const override;
virtual bool isKeepSize() const override;
virtual bool isLocked() const override;
virtual bool lockKeepSize() const override;
public slots:
virtual void update() override;
public:
void setBeginLine(qsizetype newBeginLine);
void setEndLine(qsizetype newEndLine);
void setFirstVisibleLine(qsizetype newFirstVisibleLine);
void setCurrentHorizontalOffset(int horizontalOffset);
private:
QHexView *_view;
qsizetype _beginLine = 0;
qsizetype _endLine = 0;
qsizetype _firstVisibleLine = 0;
int _horizontalOffset = 0;
};
#endif // EDITORVIEWCONTEXT_H

View File

@ -2631,6 +2631,14 @@ bool PluginSystem::checkErrAllAllowAndReport(const QObject *sender,
return false;
}
const std::optional<PluginInfo> &PluginSystem::hexEditorExtensionInfo() const {
return _manHexInfo;
}
IWingHexEditorPlugin *PluginSystem::hexEditorExtension() const {
return _hexExt;
}
QMap<PluginSystem::BlockReason, QList<PluginInfo>>
PluginSystem::blockedDevPlugins() const {
return _blkdevs;
@ -3687,6 +3695,16 @@ bool PluginSystem::dispatchEvent(IWingPlugin::RegisteredEvent event,
}
}
break;
case WingHex::IWingPlugin::RegisteredEvent::HexEditorViewPaint: {
auto painter =
reinterpret_cast<QPainter *>(params.at(0).value<quintptr>());
auto w = reinterpret_cast<QWidget *>(params.at(1).value<quintptr>());
auto palette = reinterpret_cast<HexEditorContext *>(
params.at(2).value<quintptr>());
for (auto &plg : _evplgs[event]) {
plg->onPaintHexEditorView(painter, w, palette);
}
} break;
default:
return false;
}
@ -3886,6 +3904,89 @@ void PluginSystem::try2LoadManagerPlugin() {
}
}
void PluginSystem::try2LoadHexExtPlugin() {
QDir dir(qApp->applicationDirPath());
auto mplgs = dir.entryInfoList({"*.winghexe"}, QDir::Files);
if (mplgs.isEmpty()) {
return;
}
if (mplgs.size() > 1) {
Logger::warning(tr("HexExtNeedSingleton"));
return;
}
auto mplg = mplgs.front();
auto path = mplg.absoluteFilePath();
QPluginLoader loader(path);
auto lmeta = loader.metaData();
auto m = parsePluginMetadata(lmeta["MetaData"].toObject());
auto cret = checkPluginMetadata(m, false);
switch (cret) {
case PluginStatus::Valid:
break;
case PluginStatus::SDKVersion:
Logger::critical(tr("ErrLoadPluginSDKVersion"));
return;
case PluginStatus::InvalidID:
Logger::critical(tr("InvalidPluginID"));
return;
case PluginStatus::BrokenVersion:
Logger::critical(tr("InvalidPluginBrokenInfo"));
return;
case PluginStatus::DupID:
case PluginStatus::LackDependencies:
// monitor is the first plugin to load and
// should not have any dependency
Q_ASSERT(false);
return;
}
auto p = qobject_cast<IWingHexEditorPlugin *>(loader.instance());
if (p) {
QDir udir(Utilities::getAppDataPath());
auto plgset = QStringLiteral("plgset");
udir.mkdir(plgset);
if (!udir.cd(plgset)) {
throw CrashCode::PluginSetting;
}
auto setp = std::make_unique<QSettings>(udir.absoluteFilePath(m.id),
QSettings::Format::IniFormat);
if (!p->init(setp)) {
setp->deleteLater();
Logger::critical(tr("ErrLoadInitPlugin"));
return;
}
applyFunctionTables(p, _plgFns);
_hexExt = p;
registerPluginDetectMarco(m.id);
// translate the meta-data
m.author = p->retranslate(m.author);
m.vendor = p->retranslate(m.vendor);
m.license = p->retranslate(m.license);
_manHexInfo = m;
{
auto menu = p->registeredHexContextMenu();
if (menu) {
_win->m_hexContextMenu.append(menu);
}
}
registerRibbonTools(p->registeredRibbonTools());
registeredSettingPages(QVariant::fromValue(p),
p->registeredSettingPages());
}
}
void PluginSystem::registerPluginDetectMarco(const QString &id) {
static auto sep = QStringLiteral("_");
_scriptMarcos.append(sep + id + sep);
@ -3947,6 +4048,10 @@ void PluginSystem::registerEvents(IWingPlugin *plg) {
if (evs.testFlag(IWingPlugin::RegisteredEvent::PluginFileClosed)) {
_evplgs[IWingPlugin::RegisteredEvent::PluginFileClosed].append(plg);
}
if (evs.testFlag(IWingPlugin::RegisteredEvent::HexEditorViewPaint)) {
_evplgs[IWingPlugin::RegisteredEvent::HexEditorViewPaint].append(plg);
}
}
void PluginSystem::applyFunctionTables(QObject *plg, const CallTable &fns) {
@ -4292,12 +4397,21 @@ void PluginSystem::setMainWindow(MainWindow *win) { _win = win; }
QWidget *PluginSystem::mainWindow() const { return _win; }
void PluginSystem::loadAllPlugin() {
void PluginSystem::loadAllPlugins() {
Q_ASSERT(_win);
try2LoadManagerPlugin();
auto &set = SettingManager::instance();
bool enableSet = set.enablePlugin();
if (enableSet) {
if (set.enableMonitor()) {
try2LoadManagerPlugin();
}
if (set.enableHexExt()) {
try2LoadHexExtPlugin();
}
}
_enabledExtIDs = set.enabledExtPlugins();
_enabledDevIDs = set.enabledDevPlugins();
@ -4358,38 +4472,40 @@ void PluginSystem::loadAllPlugin() {
Logger::newLine();
bool ok = false;
if (enableSet) {
bool ok = false;
auto disAll =
qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN_SYSTEM", &ok);
if (!ok || (ok && disAll == 0)) {
bool enabledrv = true, enableplg = true;
auto disdrv =
qEnvironmentVariableIntValue("WING_DISABLE_EXTDRV", &ok);
if (ok && disdrv != 0) {
enabledrv = false;
}
auto disAll =
qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN_SYSTEM", &ok);
if (!ok || (ok && disAll == 0)) {
bool enabledrv = true, enableplg = true;
auto disdrv = qEnvironmentVariableIntValue("WING_DISABLE_EXTDRV", &ok);
if (ok && disdrv != 0) {
enabledrv = false;
}
if (enabledrv) {
loadDevicePlugin();
}
if (enabledrv) {
loadDevicePlugin();
}
auto displg = qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN", &ok);
if ((ok && displg != 0) || !set.enablePlugin()) {
enableplg = false;
}
if (Utilities::isRoot()) {
if (!set.enablePlgInRoot()) {
auto displg =
qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN", &ok);
if ((ok && displg != 0) || !set.enablePlugin()) {
enableplg = false;
}
}
if (enableplg) {
loadExtPlugin();
if (Utilities::isRoot()) {
if (!set.enablePlgInRoot()) {
enableplg = false;
}
}
if (enableplg) {
loadExtPlugin();
}
}
Logger::newLine();
}
Logger::newLine();
}
void PluginSystem::destory() {
@ -4423,6 +4539,16 @@ void PluginSystem::destory() {
udir.absoluteFilePath(_manInfo->id), QSettings::Format::IniFormat);
_manager->unload(set);
delete _manager;
_manInfo.reset();
}
if (_hexExt && _manHexInfo) {
auto set =
std::make_unique<QSettings>(udir.absoluteFilePath(_manHexInfo->id),
QSettings::Format::IniFormat);
_hexExt->unload(set);
delete _hexExt;
_manHexInfo.reset();
}
}

View File

@ -32,6 +32,7 @@
#include <QVariant>
#include "WingPlugin/iwingdevice.h"
#include "WingPlugin/iwinghexeditorplugin.h"
#include "WingPlugin/iwingmanager.h"
#include "class/wingangelapi.h"
#include "control/editorview.h"
@ -144,8 +145,8 @@ public:
void setMainWindow(MainWindow *win);
QWidget *mainWindow() const;
void loadAllPlugin();
void unloadAllPlugin();
void loadAllPlugins();
void unloadAllPlugins();
void doneRegisterScriptObj();
@ -189,6 +190,8 @@ private:
void try2LoadManagerPlugin();
void try2LoadHexExtPlugin();
template <typename T>
std::optional<PluginInfo> loadPlugin(const QFileInfo &filename,
const QDir &setdir);
@ -259,12 +262,16 @@ public:
IWingManager *monitorManager() const;
const std::optional<PluginInfo> &monitorManagerInfo() const;
IWingHexEditorPlugin *hexEditorExtension() const;
QMap<BlockReason, QList<PluginInfo>> blockedPlugins() const;
QMap<BlockReason, QList<PluginInfo>> blockedDevPlugins() const;
const std::optional<PluginInfo> &monitorManagerInfo() const;
const std::optional<PluginInfo> &hexEditorExtensionInfo() const;
private:
template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {
@ -758,6 +765,9 @@ private:
IWingManager *_manager = nullptr;
std::optional<PluginInfo> _manInfo;
IWingHexEditorPlugin *_hexExt = nullptr;
std::optional<PluginInfo> _manHexInfo;
WingAngelAPI *_angelplg = nullptr;
QStringList _scriptMarcos;

View File

@ -130,9 +130,12 @@ void ScriptManager::refreshUsrScriptsDbCats() {
} else {
for (auto &info :
scriptDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
QDir dir(info.absoluteFilePath());
auto files = dir.entryList({"*.as"}, QDir::Files);
m_usrScriptsDbCats << info.fileName();
auto meta = ensureDirMeta(info);
meta.isSys = false;
meta.isEmptyDir = files.isEmpty();
_usrDirMetas.insert(info.fileName(), meta);
}
}
@ -145,9 +148,12 @@ void ScriptManager::refreshSysScriptsDbCats() {
if (sysScriptDir.exists()) {
for (auto &info :
sysScriptDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
QDir dir(info.absoluteFilePath());
auto files = dir.entryList({"*.as"}, QDir::Files);
m_sysScriptsDbCats << info.fileName();
auto meta = ensureDirMeta(info);
meta.isSys = true;
meta.isEmptyDir = files.isEmpty();
_sysDirMetas.insert(info.fileName(), meta);
}
}
@ -236,17 +242,17 @@ ScriptManager::buildUpScriptRunnerContext(RibbonButtonGroup *group,
}
auto meta = sm.sysDirMeta(cat);
addPannelAction(
group, ICONRES(QStringLiteral("scriptfolder")), meta.name,
buildUpScriptDirMenu(group, sm.getSysScriptFileNames(cat), true));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, sm.getSysScriptFileNames(cat),
true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolder")));
maps << m;
auto files = sm.getSysScriptFileNames(cat);
if (!files.isEmpty()) {
addPannelAction(group, ICONRES(QStringLiteral("scriptfolder")),
meta.name,
buildUpScriptDirMenu(group, files, true));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, files, true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolder")));
maps << m;
}
}
}
@ -255,18 +261,20 @@ ScriptManager::buildUpScriptRunnerContext(RibbonButtonGroup *group,
if (hideCats.contains(cat)) {
continue;
}
auto meta = sm.usrDirMeta(cat);
auto files = sm.getUsrScriptFileNames(cat);
if (!files.isEmpty()) {
addPannelAction(group, ICONRES(QStringLiteral("scriptfolderusr")),
meta.name,
buildUpScriptDirMenu(group, files, false));
addPannelAction(
group, ICONRES(QStringLiteral("scriptfolderusr")), meta.name,
buildUpScriptDirMenu(group, sm.getUsrScriptFileNames(cat), false));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, sm.getSysScriptFileNames(cat),
true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolderusr")));
maps << m;
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, files, true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolderusr")));
maps << m;
}
}
}

View File

@ -36,6 +36,7 @@ public:
QString license;
QString homepage;
QString comment;
bool isEmptyDir = false;
bool isContextMenu = false;
bool isSys; // a flag
};

View File

@ -37,6 +37,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_WINDOWSIZE, ("app.windowsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LANGUAGE, ("app.lang"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE, ("plugin.enableplugin"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE_MANAGER, ("plugin.enableman"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE_HEXEXT,
("plugin.enablehexext"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE_ROOT,
("plugin.rootenableplugin"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLEDPLUGINS_EXT, ("plugin.ext"))
@ -114,6 +117,8 @@ void SettingManager::load() {
READ_CONFIG_BOOL(m_enablePlugin, PLUGIN_ENABLE, true);
READ_CONFIG_BOOL(m_enablePlgInRoot, PLUGIN_ENABLE_ROOT, false);
READ_CONFIG_BOOL(m_enableMonitor, PLUGIN_ENABLE_MANAGER, true);
READ_CONFIG_BOOL(m_enableHexExt, PLUGIN_ENABLE_HEXEXT, true);
{
auto data = READ_CONFIG(PLUGIN_ENABLEDPLUGINS_EXT, {});
@ -206,6 +211,26 @@ QVariantList SettingManager::getVarList(
return varlist;
}
bool SettingManager::enableHexExt() const { return m_enableHexExt; }
void SettingManager::setEnableHexExt(bool newEnableHexExt) {
if (m_enableHexExt != newEnableHexExt) {
HANDLE_CONFIG;
WRITE_CONFIG(PLUGIN_ENABLE_HEXEXT, newEnableHexExt);
m_enableHexExt = newEnableHexExt;
}
}
bool SettingManager::enableMonitor() const { return m_enableMonitor; }
void SettingManager::setEnableMonitor(bool newEnableMonitor) {
if (m_enableMonitor != newEnableMonitor) {
HANDLE_CONFIG;
WRITE_CONFIG(PLUGIN_ENABLE_MANAGER, newEnableMonitor);
m_enableMonitor = newEnableMonitor;
}
}
QStringList SettingManager::enabledDevPlugins() const {
return m_enabledDevPlugins;
}
@ -485,6 +510,10 @@ void SettingManager::__reset(SETTINGS cat) {
if (cat.testFlag(SETTING::PLUGIN)) {
WRITE_CONFIG(PLUGIN_ENABLE, true);
WRITE_CONFIG(PLUGIN_ENABLE_ROOT, false);
WRITE_CONFIG(PLUGIN_ENABLE_MANAGER, true);
WRITE_CONFIG(PLUGIN_ENABLE_HEXEXT, true);
WRITE_CONFIG(PLUGIN_ENABLEDPLUGINS_DEV, {});
WRITE_CONFIG(PLUGIN_ENABLEDPLUGINS_EXT, {});
}
if (cat.testFlag(SETTING::EDITOR)) {
WRITE_CONFIG(EDITOR_FONTSIZE, _defaultFont.pointSize());

View File

@ -62,6 +62,8 @@ public:
QList<RecentFileManager::RecentInfo> recentHexFiles() const;
bool enablePlugin() const;
bool enableMonitor() const;
bool enableHexExt() const;
bool editorShowHeader() const;
QString appFontFamily() const;
QList<RecentFileManager::RecentInfo> recentScriptFiles() const;
@ -119,6 +121,8 @@ public slots:
void setEnabledExtPlugins(const QStringList &newEnabledPlugins);
void setEnabledDevPlugins(const QStringList &newEnabledDevPlugins);
void setEnableMonitor(bool newEnableMonitor);
void setEnableHexExt(bool newEnableHexExt);
public:
void checkWriteableAndWarn();
@ -150,6 +154,9 @@ private:
int m_editorfontSize = 18;
bool m_enablePlugin = true;
bool m_enablePlgInRoot = false;
bool m_enableMonitor = true;
bool m_enableHexExt = true;
QString m_defaultLang;
QByteArray m_dockLayout;
QByteArray m_scriptDockLayout;

View File

@ -62,6 +62,41 @@ EditorView::EditorView(QWidget *parent)
hexLayout->setSpacing(0);
hexLayout->setContentsMargins(0, 0, 0, 0);
m_hex = new QHexView(this);
_context = new EditorViewContext(m_hex);
if (PluginSystem::instance().hexEditorExtension()) {
connect(m_hex, &QHexView::onPaintCustomEventBegin, this, [this]() {
auto m =
PluginSystem::instance().hexEditorExtension()->contentMargins(
_context);
m.setLeft(qMax(0, m.left()));
m.setTop(qMax(0, m.top()));
m.setRight(qMax(0, m.right()));
m.setBottom(qMax(0, m.bottom()));
m_hex->viewport()->setContentsMargins(m);
});
}
connect(m_hex, &QHexView::onPaintCustomEvent, this,
[this](int XOffset, qsizetype firstVisible, qsizetype begin,
qsizetype end) {
auto vp = m_hex->viewport();
QPainter painter(vp);
auto &plgsys = PluginSystem::instance();
auto hext = plgsys.hexEditorExtension();
_context->setCurrentHorizontalOffset(XOffset);
_context->setFirstVisibleLine(firstVisible);
_context->setBeginLine(begin);
_context->setEndLine(end);
if (hext) {
painter.save();
hext->onPaintEvent(&painter, vp, _context);
painter.restore();
}
plgsys.dispatchEvent(
IWingPlugin::RegisteredEvent::HexEditorViewPaint,
{quintptr(&painter), quintptr(vp), quintptr(_context)});
});
hexLayout->addWidget(m_hex, 1);
m_goto = new GotoWidget(this);

View File

@ -26,6 +26,7 @@
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingdevice.h"
#include "WingPlugin/wingeditorviewwidget.h"
#include "class/editorviewcontext.h"
#include "dialog/finddialog.h"
#include "gotowidget.h"
#include "model/bookmarksmodel.h"
@ -543,6 +544,7 @@ private:
QStackedWidget *m_stack = nullptr;
GotoWidget *m_goto = nullptr;
QWidget *m_hexContainer = nullptr;
EditorViewContext *_context = nullptr;
bool _hasRegistered = false;
quintptr _oldbase = 0;

View File

@ -225,7 +225,7 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
});
plg.setMainWindow(this);
plg.loadAllPlugin();
plg.loadAllPlugins();
// Don't setup it too early, because the plugin can register script
// functions. Code completions of them will be not worked out.
@ -362,7 +362,10 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
splash->setInfoText(tr("SetupFinished"));
}
MainWindow::~MainWindow() { Logger::instance().disconnect(); }
MainWindow::~MainWindow() {
qDeleteAll(m_hexContextMenu);
Logger::instance().disconnect();
}
void MainWindow::buildUpRibbonBar() {
m_ribbon = new Ribbon(this);

View File

@ -53,6 +53,8 @@ GeneralSettingDialog::GeneralSettingDialog(QWidget *parent)
Utilities::addSpecialMark(ui->lblFontSize);
Utilities::addSpecialMark(ui->lblWinState);
reload();
connect(ui->cbLanguage, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &GeneralSettingDialog::optionNeedRestartChanged);
connect(ui->cbTheme, QOverload<int>::of(&QComboBox::currentIndexChanged),
@ -64,8 +66,6 @@ GeneralSettingDialog::GeneralSettingDialog(QWidget *parent)
connect(ui->cbWinState, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &GeneralSettingDialog::optionNeedRestartChanged);
reload();
auto sm = &SettingManager::instance();
connect(ui->cbLanguage, &QComboBox::currentIndexChanged, sm,
[this](int index) {

View File

@ -44,6 +44,8 @@ OtherSettingsDialog::OtherSettingsDialog(QWidget *parent)
Utilities::addSpecialMark(ui->lblCount);
Utilities::addSpecialMark(ui->cbCheckWhenStartup);
reload();
connect(ui->cbNativeTitile,
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
&QCheckBox::checkStateChanged,
@ -63,8 +65,6 @@ OtherSettingsDialog::OtherSettingsDialog(QWidget *parent)
connect(ui->cbLogLevel, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &OtherSettingsDialog::optionNeedRestartChanged);
reload();
auto set = &SettingManager::instance();
connect(ui->cbDontShowSplash, &QCheckBox::toggled, set,
&SettingManager::setDontUseSplash);

View File

@ -34,6 +34,11 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
Utilities::addSpecialMark(ui->cbEnablePlugin);
Utilities::addSpecialMark(ui->cbEnablePluginRoot);
Utilities::addSpecialMark(ui->cbEnableManager);
Utilities::addSpecialMark(ui->cbEnableHex);
reload();
connect(ui->cbEnablePlugin,
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
&QCheckBox::checkStateChanged,
@ -48,8 +53,20 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
&QCheckBox::stateChanged,
#endif
this, &PluginSettingDialog::optionNeedRestartChanged);
reload();
connect(ui->cbEnableManager,
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
&QCheckBox::checkStateChanged,
#else
&QCheckBox::stateChanged,
#endif
this, &PluginSettingDialog::optionNeedRestartChanged);
connect(ui->cbEnableHex,
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
&QCheckBox::checkStateChanged,
#else
&QCheckBox::stateChanged,
#endif
this, &PluginSettingDialog::optionNeedRestartChanged);
auto &plgsys = PluginSystem::instance();
auto pico = ICONRES("plugin");
@ -103,8 +120,6 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->plglist->addItem(lwi);
}
ui->txtc->clear();
pico = ICONRES("devext");
ui->devlist->clear();
for (auto &d : plgsys.devices()) {
@ -149,35 +164,31 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->devlist->addItem(lwi);
}
ui->txtd->clear();
auto minfo = plgsys.monitorManagerInfo();
if (minfo) {
auto sep = QStringLiteral(" : ");
ui->txtm->append(getWrappedText(tr("ID") + sep + minfo->id));
ui->txtm->append(getWrappedText(tr("License") + sep + minfo->license));
ui->txtm->append(getWrappedText(tr("Author") + sep + minfo->author));
ui->txtm->append(getWrappedText(tr("Vendor") + sep + minfo->vendor));
ui->txtm->append(
getWrappedText(tr("Version") + sep + minfo->version.toString()));
ui->txtm->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + minfo->url +
QStringLiteral("\">") + minfo->url + QStringLiteral("</a>")));
ui->txtm->append(getWrappedText(tr("Comment") + sep));
auto p = plgsys.monitorManager();
if (p) {
ui->txtm->append(getWrappedText(p->comment()));
}
} else {
ui->txtm->setText(tr("NoMonitorPlugin"));
QString mcomment;
auto mp = plgsys.monitorManager();
if (mp) {
mcomment = mp->comment();
}
loadPluginInfo(minfo, {}, mcomment, {}, ui->txtm);
auto hinfo = plgsys.hexEditorExtensionInfo();
QString hcomment;
auto hp = plgsys.hexEditorExtension();
if (hp) {
hcomment = hp->comment();
}
loadPluginInfo(hinfo, {}, hcomment, {}, ui->txtext);
auto set = &SettingManager::instance();
connect(ui->cbEnablePlugin, &QCheckBox::toggled, set,
&SettingManager::setEnablePlugin);
connect(ui->cbEnablePluginRoot, &QCheckBox::toggled, set,
&SettingManager::setEnablePlgInRoot);
connect(ui->cbEnableManager, &QCheckBox::toggled, set,
&SettingManager::setEnableMonitor);
connect(ui->cbEnableHex, &QCheckBox::toggled, set,
&SettingManager::setEnableHexExt);
connect(ui->plglist, &QListWidget::itemChanged, this,
[this](QListWidgetItem *item) {
@ -199,42 +210,19 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->btnplgSave->setEnabled(_plgChanged.containChanges());
});
connect(
ui->plglist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
}
auto info = current->data(PLUIGN_META).value<PluginInfo>();
auto plgName = current->data(PLUIGN_NAME).toString();
auto plgComment = current->data(PLUIGN_COMMENT).toString();
ui->txtc->clear();
static auto sep = QStringLiteral(" : ");
ui->txtc->append(getWrappedText(tr("ID") + sep + info.id));
ui->txtc->append(getWrappedText(tr("Name") + sep + plgName));
ui->txtc->append(
getWrappedText(tr("License") + sep + info.license));
ui->txtc->append(getWrappedText(tr("Author") + sep + info.author));
ui->txtc->append(getWrappedText(tr("Vendor") + sep + info.vendor));
ui->txtc->append(
getWrappedText(tr("Version") + sep + info.version.toString()));
ui->txtc->append(getWrappedText(tr("Comment") + sep + plgComment));
if (!info.dependencies.isEmpty()) {
ui->txtc->append(getWrappedText(tr("pluginDependencies:")));
for (auto &d : info.dependencies) {
ui->txtc->append(
getWrappedText(QString(4, ' ') + tr("PUID:") + d.puid));
ui->txtc->append(getWrappedText(QString(4, ' ') +
tr("Version:") +
d.version.toString()));
connect(ui->plglist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
}
}
ui->txtc->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + info.url +
QStringLiteral("\">") + info.url + QStringLiteral("</a> ")));
});
auto info = current->data(PLUIGN_META).value<PluginInfo>();
auto plgName = current->data(PLUIGN_NAME).toString();
auto plgComment = current->data(PLUIGN_COMMENT).toString();
loadPluginInfo(info, plgName, plgComment, info.dependencies,
ui->txtc);
});
connect(ui->devlist, &QListWidget::itemChanged, this,
[this](QListWidgetItem *item) {
@ -256,32 +244,19 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->btndevSave->setEnabled(_devChanged.containChanges());
});
connect(
ui->devlist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
}
connect(ui->devlist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
}
auto info = current->data(PLUIGN_META).value<PluginInfo>();
auto plgName = current->data(PLUIGN_NAME).toString();
auto plgComment = current->data(PLUIGN_COMMENT).toString();
auto info = current->data(PLUIGN_META).value<PluginInfo>();
auto plgName = current->data(PLUIGN_NAME).toString();
auto plgComment = current->data(PLUIGN_COMMENT).toString();
ui->txtd->clear();
static auto sep = QStringLiteral(" : ");
ui->txtd->append(getWrappedText(tr("ID") + sep + info.id));
ui->txtd->append(getWrappedText(tr("Name") + sep + plgName));
ui->txtd->append(
getWrappedText(tr("License") + sep + info.license));
ui->txtd->append(getWrappedText(tr("Author") + sep + info.author));
ui->txtd->append(getWrappedText(tr("Vendor") + sep + info.vendor));
ui->txtd->append(
getWrappedText(tr("Version") + sep + info.version.toString()));
ui->txtd->append(getWrappedText(tr("Comment") + sep + plgComment));
ui->txtd->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + info.url +
QStringLiteral("\">") + info.url + QStringLiteral("</a>")));
});
loadPluginInfo(info, plgName, plgComment, info.dependencies,
ui->txtd);
});
connect(ui->btnplgSave, &QPushButton::clicked, set, [this]() {
SettingManager::instance().setEnabledExtPlugins(
@ -335,6 +310,8 @@ void PluginSettingDialog::reload() {
auto &set = SettingManager::instance();
ui->cbEnablePlugin->setChecked(set.enablePlugin());
ui->cbEnablePluginRoot->setChecked(set.enablePlgInRoot());
ui->cbEnableManager->setChecked(set.enableMonitor());
ui->cbEnableHex->setChecked(set.enableHexExt());
this->blockSignals(false);
}
@ -457,6 +434,45 @@ void PluginSettingDialog::resetUIChagned() {
ui->btndevSave->setEnabled(false);
}
void PluginSettingDialog::loadPluginInfo(
const std::optional<WingHex::PluginInfo> &info, const QString &name,
const QString &comment, const QList<WingHex::WingDependency> &dependencies,
QTextBrowser *t) {
if (info) {
t->clear();
static auto sep = QStringLiteral(" : ");
if (!name.isEmpty()) {
t->append(getWrappedText(tr("Name") + sep + name));
}
t->append(getWrappedText(tr("ID") + sep + info->id));
t->append(getWrappedText(tr("License") + sep + info->license));
t->append(getWrappedText(tr("Author") + sep + info->author));
t->append(getWrappedText(tr("Vendor") + sep + info->vendor));
t->append(
getWrappedText(tr("Version") + sep + info->version.toString()));
t->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + info->url +
QStringLiteral("\">") + info->url + QStringLiteral("</a>")));
if (!dependencies.isEmpty()) {
ui->txtc->append(getWrappedText(tr("Dependencies") + sep));
for (auto &d : dependencies) {
ui->txtc->append(getWrappedText(QString(4, ' ') + tr("PUID") +
sep + d.puid));
ui->txtc->append(getWrappedText(QString(4, ' ') +
tr("Version") + sep +
d.version.toString()));
}
}
t->append(getWrappedText({}));
t->append(getWrappedText(tr("Comment") + sep));
t->append(getWrappedText(comment));
} else {
t->setText(tr("NoPluginLoaded"));
}
}
QString PluginSettingDialog::getWrappedText(const QString &str) {
return QStringLiteral("<a>") + str + QStringLiteral("</a>");
}

View File

@ -22,6 +22,7 @@
#include "class/changedstringlist.h"
#include <QListWidget>
#include <QTextBrowser>
#include <QWidget>
namespace Ui {
@ -63,6 +64,11 @@ private:
void resetChangedList();
void resetUIChagned();
void loadPluginInfo(const std::optional<WingHex::PluginInfo> &info,
const QString &name, const QString &comment,
const QList<WingHex::WingDependency> &dependencies,
QTextBrowser *t);
private:
QString getWrappedText(const QString &str);
};

View File

@ -146,6 +146,18 @@
<string>DevExtInfo</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>8</number>
</property>
<property name="rightMargin">
<number>8</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
@ -196,6 +208,25 @@
<string>APIMonitor</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>8</number>
</property>
<property name="rightMargin">
<number>8</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<item>
<widget class="QCheckBox" name="cbEnableManager">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="txtm">
<property name="openExternalLinks">
@ -205,6 +236,43 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabHexEditorExt">
<attribute name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/com.wingsummer.winghex/images/edit.png</normaloff>:/com.wingsummer.winghex/images/edit.png</iconset>
</attribute>
<attribute name="title">
<string>EditorExtension</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>8</number>
</property>
<property name="rightMargin">
<number>8</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<item>
<widget class="QCheckBox" name="cbEnableHex">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="txtext">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -29,6 +29,9 @@ ScriptSettingDialog::ScriptSettingDialog(QWidget *parent)
Utilities::addSpecialMark(ui->cbEnable);
Utilities::addSpecialMark(ui->cbAllowUsrScript);
loadData();
connect(ui->cbAllowUsrScript,
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
&QCheckBox::checkStateChanged,
@ -37,8 +40,6 @@ ScriptSettingDialog::ScriptSettingDialog(QWidget *parent)
#endif
this, &ScriptSettingDialog::optionNeedRestartChanged);
loadData();
connect(ui->listWidget, &QListWidget::itemChanged, this,
[this](QListWidgetItem *item) {
auto var = item->data(Qt::UserRole);
@ -160,10 +161,14 @@ void ScriptSettingDialog::loadData() {
bool ScriptSettingDialog::addCatagory(const ScriptManager::ScriptDirMeta &meta,
bool isUser, bool hidden) {
auto name = meta.name;
if (meta.isEmptyDir) {
name.append(' ').append(tr("[Empty]"));
}
auto lw =
new QListWidgetItem(isUser ? ICONRES(QStringLiteral("scriptfolderusr"))
: ICONRES(QStringLiteral("scriptfolder")),
meta.name, ui->listWidget);
name, ui->listWidget);
lw->setData(Qt::UserRole, QVariant::fromValue(meta));
lw->setCheckState(hidden ? Qt::Unchecked : Qt::Checked);
return hidden;

View File

@ -2956,6 +2956,7 @@ QHexView
qproperty-selBackgroundColor: #3daee9;
qproperty-headerColor: #07DBD7;
qproperty-addressColor: #07DBD7;
qproperty-borderColor: #eff0f1;
}
Toast

View File

@ -2960,6 +2960,7 @@ QHexView
qproperty-selBackgroundColor: rgba(51, 164, 223, 0.5);
qproperty-headerColor: #07DBD7;
qproperty-addressColor: #07DBD7;
qproperty-borderColor: #31363b;
}
Toast