Compare commits

...

6 Commits

55 changed files with 3705 additions and 2003 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());
@ -109,6 +111,19 @@ void QHexRenderer::renderFrame(QPainter *painter) {
painter->drawLine(endx, rect.top(), endx, rect.bottom());
}
void QHexRenderer::renderAdditonalFrame(QPainter *painter, bool top,
bool left) {
QRect rect = painter->window();
int endx = this->getEndColumnX();
painter->setPen(m_borderColor);
if (top) {
painter->drawLine(0, 0, endx, 0);
}
if (left) {
painter->drawLine(0, 0, 0, rect.bottom());
}
}
// modified by wingsummer
void QHexRenderer::render(QPainter *painter, qsizetype begin, qsizetype end,
qsizetype firstline) {
@ -872,6 +887,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

@ -43,6 +43,7 @@ public:
const QFontMetricsF &fontmetrics,
QObject *parent = nullptr);
void renderFrame(QPainter *painter);
void renderAdditonalFrame(QPainter *painter, bool top, bool left);
void render(QPainter *painter, qsizetype start, qsizetype end,
qsizetype firstline); // begin included, end excluded
void updateMetrics(const QFontMetricsF &fm);
@ -101,6 +102,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 +115,8 @@ private:
QByteArray getLine(qsizetype line) const;
qsizetype rendererLength() const;
public:
int getAddressWidth() const;
int getHexColumnX() const;
int getAsciiColumnX() const;
@ -178,6 +184,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,10 +323,19 @@ 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());
return pos + shift;
}
bool QHexView::disableInternalPaint() const { return m_disableInternalPaint; }
void QHexView::setDisableInternalPaint(bool newDisableInternalPaint) {
m_disableInternalPaint = newDisableInternalPaint;
update();
}
QHexCursor *QHexView::cursor() const { return m_cursor; }
qsizetype QHexView::copyLimit() const { return m_copylimit; }
@ -567,9 +576,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 +595,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 +603,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 +613,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 +621,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 +631,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 +639,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 +647,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,22 +789,31 @@ 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() - m.top()) / lineHeight; // included
const int lastPlusOne =
((r.bottom() - m.top() - m.bottom()) / lineHeight) + 1; // 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();
auto xOff = this->horizontalScrollBar()->value();
if (Q_LIKELY(!m_disableInternalPaint)) {
painter.save();
painter.translate(-this->horizontalScrollBar()->value(), 0);
painter.translate(-xOff + m.left(), m.top());
m_renderer->render(&painter, begin, end, firstVisible);
m_renderer->renderFrame(&painter);
m_renderer->renderAdditonalFrame(&painter, m.top() > 0, m.left() > 0);
painter.restore();
}
Q_EMIT onPaintCustomEvent(xOff, firstVisible, begin, end);
}
void QHexView::moveToSelection() {
QHexCursor *cur = m_cursor;
@ -1175,16 +1209,19 @@ void QHexView::adjustScrollBars() {
QScrollBar *hscrollbar = this->horizontalScrollBar();
int documentWidth = m_renderer->documentWidth();
int viewportWidth = viewport()->width();
auto margins = viewport()->contentsMargins();
if (documentWidth > viewportWidth) {
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,8 +1240,10 @@ qsizetype QHexView::lastVisibleLine() const {
}
qsizetype QHexView::visibleLines() const {
auto visLines =
qsizetype(std::ceil(this->height() / m_renderer->lineHeight() -
auto margins = viewport()->contentsMargins();
auto visLines = qsizetype(
std::ceil((this->height() - margins.top() - margins.bottom()) /
m_renderer->lineHeight() -
m_renderer->headerLineCount()));
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,69 @@ 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;
bool disableInternalPaint() const;
void setDisableInternalPaint(bool newDisableInternalPaint);
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 +147,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 +179,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);
@ -224,6 +231,7 @@ private:
qreal m_fontSize;
qreal m_scaleRate = 1.0;
bool m_disableInternalPaint = false;
qsizetype m_copylimit = 1; // MB
};

View File

@ -25,10 +25,12 @@ option(BUILD_TEST_PLUGIN OFF)
option(BUILD_SHARED_MEM_EXT OFF)
add_definitions(-DAS_NO_THREADS)
add_definitions(-DWING_SYSTEM_NAME="${CMAKE_SYSTEM_NAME}")
if(BUILD_TEST_PLUGIN)
add_subdirectory(TestPlugin)
add_subdirectory(TestBadPlugin)
add_subdirectory(TestHexExt)
add_subdirectory(TestManager)
endif()
@ -305,7 +307,11 @@ 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
src/class/consolehighlighanim.h
src/class/consolehighlighanim.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`协议。
### 使用声明
@ -126,6 +126,8 @@
6. 无论以任何为目的,如未获得我作者的授权,不得修改任意程序内指向的网络链接和软件关于信息,比如赞助和关于软件部分的内容等。
7. 不得在安装程序内插入任何含有商业推广的插件。
&emsp;&emsp;如果你是 Windows 用户,你可以到发行版区下载正式版,其他版本请自行编译;对于 Linux ,你可以尝试到发行区下载 run 文件或者自行编译;如果你使用的操作系统是基于 Arch 的,那么你可以安装`winghexexplorer2`这个包,也可以安装`winghexexplorer2-git`来体验日更版最新内容,但最好请不要将日更版应用于日常使用,虽然目前通常是比较稳定的。
### issue 前必读
&emsp;&emsp;如果你有任何形式的建议,在提交 issue 之前,请一定要阅读下面的声明,以免浪费我们双方宝贵的时间:

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
@ -126,6 +126,8 @@ First of all, I would like to express my sincere tanks for your enthusiastic hel
6. Regardless of the purpose, if you do not obtain the authorization of me, you may not modify any network links pointed to and the ABOUT contents in the program, such as sponsorship and content about the software.
7. You may not insert any plug-in containing commercial promotion in the installation program.
If you are a Windows user, you can download in the release page, or compile other versions by yourself; For Linuxers, you can try to download the RUN file or help yourself; If you are using Arch-based Linux, you can install the `winghexexplorer2` AUR package, or install `winghexexplorer2-git` to try the latest contents, but it is best not to use the nightly builds for daily use, although it is generally stable at present.
### Issue
If you have any suggestions, please be sure to read the following statement before submitting an issue to avoid wasting our precious time:

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"
}

136
TestHexExt/testhexext.cpp Normal file
View File

@ -0,0 +1,136 @@
/*==============================================================================
** 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);
m_aVisCol = 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 {
return {};
}
QMargins TestHexExt::contentMargins(WingHex::HexEditorContext *context) const {
auto visCol = context->property("TestHexExt.colVis").toBool();
if (!visCol) {
return {};
}
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);
return {int(colLen) + 1, 0, 0, 0};
}
void TestHexExt::prepareCallEditorContext(WingHex::HexEditorContext *context) {
_curContext = context;
auto b = isShowLinePannel(context);
m_aVisCol->blockSignals(true);
m_aVisCol->setChecked(b);
m_aVisCol->blockSignals(false);
}
void TestHexExt::finishCallEditorContext(WingHex::HexEditorContext *context) {
Q_UNUSED(context);
_curContext = nullptr;
}
void TestHexExt::onPaintEvent(QPainter *painter, const QWidget *w,
WingHex::HexEditorContext *context) {
auto visCol = isShowLinePannel(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);
}
// 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();
}
bool TestHexExt::isShowLinePannel(WingHex::HexEditorContext *context) {
auto pp = context->property("TestHexExt.colVis");
if (pp.isNull()) {
context->setProperty("TestHexExt.colVis", true);
return true;
}
return pp.toBool();
}
void TestHexExt::setColVisible(bool b) {
if (_curContext) {
_curContext->setProperty("TestHexExt.colVis", b);
}
}

77
TestHexExt/testhexext.h Normal file
View File

@ -0,0 +1,77 @@
/*==============================================================================
** 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
prepareCallEditorContext(WingHex::HexEditorContext *context) override;
virtual void
finishCallEditorContext(WingHex::HexEditorContext *context) override;
public:
virtual void onPaintEvent(QPainter *painter, const QWidget *w,
WingHex::HexEditorContext *context) override;
private:
bool isShowLinePannel(WingHex::HexEditorContext *context);
private slots:
void setColVisible(bool b);
private:
QMenu *m_context;
QAction *m_aVisCol;
WingHex::HexEditorContext *_curContext = nullptr;
};
#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="288"/>
<location filename="../testplugin.cpp" line="296"/>
<location filename="../testplugin.cpp" line="304"/>
<location filename="../testplugin.cpp" line="312"/>
<location filename="../testplugin.cpp" line="321"/>
<location filename="../testplugin.cpp" line="328"/>
<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="279"/>
<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);
@ -261,7 +263,7 @@ WingHex::UNSAFE_RET TestPlugin::colorTable(const QList<void *> &params) {
void *array = nullptr;
QVector<void *> colors;
for (auto &c : colorTable()) {
colors.append(new QColor(c));
colors.append(&c);
}
auto invoked =
@ -269,7 +271,6 @@ WingHex::UNSAFE_RET TestPlugin::colorTable(const QList<void *> &params) {
qReturnArg(array), WingHex::MetaType::Meta_Color, colors);
if (invoked) {
if (array) {
qDeleteAll(colors);
return array;
}
}
@ -581,3 +582,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 4492bf2aaba267b80ec324c456f0584dcd0efc03

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

147
main.cpp
View File

@ -1,8 +1,118 @@
#include "class/appmanager.h"
#include "class/languagemanager.h"
#include "class/settingmanager.h"
#include "class/wingmessagebox.h"
#include "define.h"
#include <QDebug>
#include <QProcessEnvironment>
#include <QSettings>
void loadEnvConfig(int argc, char *argv[]) {
QFileInfo info(argv[0]);
QDir appDir(info.absoluteDir());
if (!appDir.exists(QStringLiteral("config.ini"))) {
return;
}
auto path = appDir.absoluteFilePath(QStringLiteral("config.ini"));
QSettings set(path, QSettings::IniFormat);
// General
for (auto &kv : set.childKeys()) {
qputenv(qPrintable(kv), set.value(kv).toByteArray());
}
auto groups = set.childGroups();
auto evaluate = [](const QProcessEnvironment &env,
const QString &statement) {
// Parse and evaluate statements:
// $NAME -> check existence
// $NAME=VALUE -> ignore-case full match
// $NAME==VALUE -> case-sensitive full match
// $NAME:=VALUE -> ignore-case contains
// $NAME::=VALUE -> case-sensitive contains
// VALUE: unless pure digits, must be enclosed in "" or ''
static const QRegularExpression re(
R"(^\$([A-Za-z_][A-Za-z0-9_]*)(?:\s*(==|::=|:=|=)\s*(\d+|"[^"]*"|'[^']*'))?$)");
auto match = re.match(statement);
if (!match.hasMatch()) {
qWarning("[main::loadEnvConfig] Invalid syntax: %s",
qUtf8Printable(statement));
return false;
}
auto name = match.captured(1);
auto op = match.captured(2);
auto value = match.captured(3);
// Existence check: no operator provided
if (op.isEmpty()) {
return env.contains(name);
}
if (!value.isEmpty() &&
((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith('\'') && value.endsWith('\'')))) {
value.removeFirst().removeLast();
}
auto var = env.value(name);
// Evaluate based on operator
if (op == QStringLiteral(":=") || op == QStringLiteral("::=")) {
const QStringList items = var.split(QDir::listSeparator());
for (const QString &item : items) {
if (op == QStringLiteral(":=")) {
if (item.contains(value, Qt::CaseInsensitive)) {
return true;
}
} else {
if (item.contains(value, Qt::CaseSensitive)) {
return true;
}
}
}
return false;
}
if (op == "=") {
return QString::compare(var, value, Qt::CaseInsensitive) == 0;
} else if (op == "==") {
return var == value;
} else {
qWarning("[main::loadEnvConfig] Unknown operator: %s",
qUtf8Printable(op));
}
return false;
};
auto env = QProcessEnvironment::systemEnvironment();
constexpr auto syslen = std::char_traits<char>::length(WING_SYSTEM_NAME);
if (syslen) {
set.beginGroup(WING_SYSTEM_NAME);
for (auto &kv : set.childKeys()) {
qputenv(qPrintable(kv), set.value(kv).toByteArray());
}
set.endGroup();
}
for (auto &g : groups) {
if (evaluate(env, g)) {
set.beginGroup(g);
for (auto &kv : set.childKeys()) {
qputenv(qPrintable(kv), set.value(kv).toByteArray());
}
set.endGroup();
}
}
}
int main(int argc, char *argv[]) {
/* 有关对在 QT5 的 Win 平台禁用高 dpi 支持
*
@ -18,23 +128,13 @@ int main(int argc, char *argv[]) {
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
loadEnvConfig(argc, argv);
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
#ifdef Q_OS_LINUX
// fix wayland issue (a workaround): floating dock not work
// reference:
// https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/
// issues/714#issuecomment-2802752677
auto denv = qgetenv("XDG_SESSION_TYPE");
if (denv.isEmpty() ||
denv.compare(QByteArrayLiteral("wayland"), Qt::CaseInsensitive) == 0) {
qputenv("QT_QPA_PLATFORM", "xcb");
}
#endif
QApplication::setApplicationName(APP_NAME);
QApplication::setOrganizationName(APP_ORG);
QApplication::setApplicationVersion(WINGHEX_VERSION);
QApplication::setApplicationName(QStringLiteral(APP_NAME));
QApplication::setOrganizationName(QStringLiteral(APP_ORG));
QApplication::setApplicationVersion(QStringLiteral(WINGHEX_VERSION));
try {
AppManager a(argc, argv);
@ -61,5 +161,22 @@ int main(int argc, char *argv[]) {
return a.exec();
} catch (CrashCode errCode) {
return int(errCode);
} catch (const std::bad_alloc &) {
auto &lang = LanguageManager::instance();
auto df = lang.defaultLocale();
// this exception can only occur when your memory are too limit or
// you are writing more than 2GB with QByteArray on 32-bit operating
// system.
if (QLocale::China == df.territory()) {
WingMessageBox::critical(
nullptr, QStringLiteral(APP_NAME),
QStringLiteral("崩溃啦!发生内存溢出异常!"));
} else {
WingMessageBox::critical(
nullptr, QStringLiteral(APP_NAME),
QStringLiteral("WingHexExplorer2 is out of memory. Crashed!"));
}
return int(CrashCode::OutofMemory);
}
}

76
mkinstaller/AUR/PKGBUILD Normal file
View File

@ -0,0 +1,76 @@
# Maintainer: wingsummer <wing-summer@qq.com>
pkgname=winghexexplorer2
pkgver=2.2.3
pkgrel=1
pkgdesc='一个自由强大跨平台的十六进制编辑器 / A free, powerful, cross-platform hex editor'
url="https://github.com/Wing-summer/WingHexExplorer2"
arch=(x86_64 aarch64)
license=(AGPL-3.0-only)
conflicts=(winghexexplorer2-git)
depends=('qt6-base')
makedepends=('git' 'cmake' 'gcc' 'clang' 'qt6-tools' 'qt6-translations')
optdepends=('qt6-translations: translations')
source=("git+$url.git#tag=v$pkgver")
sha256sums=('SKIP')
install=winghexexplorer2.install
prepare() {
cd "$srcdir/WingHexExplorer2"
sed -i 's|git@github.com:|https://github.com/|g' .gitmodules
git submodule sync
git submodule update --init
git submodule foreach --recursive "
if [ -f .gitmodules ]; then
sed -i 's|git@github.com:|https://github.com/|g' .gitmodules
git submodule sync
fi
"
git submodule update --init --recursive
}
build() {
cd "$srcdir/WingHexExplorer2"
local _flags=(
-D CMAKE_INSTALL_PREFIX=/opt
-D CMAKE_BUILD_TYPE=Release
-D WINGHEX_USE_FRAMELESS=ON
-D BUILD_TEST_PLUGIN=OFF
-D BUILD_SHARED_MEM_EXT=OFF
)
cmake -S . -B build "${_flags[@]}"
cmake --build build -- -j"$(nproc)"
}
check() {
true
}
package() {
cd "$srcdir/WingHexExplorer2"
local _optdir="$pkgdir/opt/WingHexExplorer2"
local _mkinst="mkinstaller/pyscript"
mkdir -p "$_optdir"
install -Dm755 build/WingHexExplorer2 "$_optdir/WingHexExplorer2"
install -Dm644 build/WingPlugin/libWingPlugin.so "$_optdir/libWingPlugin.so"
for _sub in plugin scripts aslib; do
mkdir -p "$_optdir/$_sub"
done
cp -a "$_mkinst/share" "build/lang" "$_optdir/"
# install -Dm644 mkinstaller/config.ini "$_optdir/config.ini" // this file is not existed before 2.3.0
for _f in LICENSE authorband.svg licenseband.svg screenshot.png README.md images/author.jpg; do
install -Dm644 "$srcdir/WingHexExplorer2/${_f}" "$_optdir/${_f##*/}"
done
local md5=$(md5sum "$_optdir/WingHexExplorer2" | cut -d' ' -f1 | tr '[:lower:]' '[:upper:]')
echo "$md5" > "$_optdir/md5sums"
install -Dm644 "$_mkinst/com.wingsummer.winghexexplorer2.desktop" "$pkgdir/usr/share/applications/com.wingsummer.winghexexplorer2.desktop"
}

View File

@ -0,0 +1,81 @@
# Maintainer: wingsummer <wing-summer@qq.com>
pkgname=winghexexplorer2-git
pkgver=2.2.3.r16.g2ea09fa
pkgrel=1
pkgdesc='一个自由强大跨平台的十六进制编辑器(每日构建版) / A free, powerful, cross-platform hex editor (Nightly Builds)'
url="https://github.com/Wing-summer/WingHexExplorer2"
arch=(x86_64 aarch64)
license=(AGPL-3.0-only)
conflicts=(winghexexplorer2)
depends=('qt6-base')
makedepends=('git' 'cmake' 'gcc' 'clang' 'qt6-tools' 'qt6-translations')
optdepends=('qt6-translations: translations')
source=("git+$url.git#branch=main")
sha256sums=('SKIP')
install=winghexexplorer2.install
pkgver() {
cd "$srcdir/WingHexExplorer2"
git describe --long --tags --abbrev=7 | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
}
prepare() {
cd "$srcdir/WingHexExplorer2"
sed -i 's|git@github.com:|https://github.com/|g' .gitmodules
git submodule sync
git submodule update --init
git submodule foreach --recursive "
if [ -f .gitmodules ]; then
sed -i 's|git@github.com:|https://github.com/|g' .gitmodules
git submodule sync
fi
"
git submodule update --init --recursive
}
build() {
cd "$srcdir/WingHexExplorer2"
local _flags=(
-D CMAKE_INSTALL_PREFIX=/opt
-D CMAKE_BUILD_TYPE=Release
-D WINGHEX_USE_FRAMELESS=ON
-D BUILD_TEST_PLUGIN=OFF
-D BUILD_SHARED_MEM_EXT=OFF
)
cmake -S . -B build "${_flags[@]}"
cmake --build build -- -j"$(nproc)"
}
check() {
true
}
package() {
cd "$srcdir/WingHexExplorer2"
local _optdir="$pkgdir/opt/WingHexExplorer2"
local _mkinst="mkinstaller/pyscript"
mkdir -p "$_optdir"
install -Dm755 build/WingHexExplorer2 "$_optdir/WingHexExplorer2"
install -Dm644 build/WingPlugin/libWingPlugin.so "$_optdir/libWingPlugin.so"
for _sub in plugin scripts aslib; do
mkdir -p "$_optdir/$_sub"
done
cp -a "$_mkinst/share" "build/lang" "$_optdir/"
install -Dm644 mkinstaller/config.ini "$_optdir/config.ini"
for _f in LICENSE authorband.svg licenseband.svg screenshot.png README.md images/author.jpg; do
install -Dm644 "$srcdir/WingHexExplorer2/${_f}" "$_optdir/${_f##*/}"
done
local md5=$(md5sum "$_optdir/WingHexExplorer2" | cut -d' ' -f1 | tr '[:lower:]' '[:upper:]')
echo "$md5" > "$_optdir/md5sums"
install -Dm644 "$_mkinst/com.wingsummer.winghexexplorer2.desktop" "$pkgdir/usr/share/applications/com.wingsummer.winghexexplorer2.desktop"
}

View File

@ -0,0 +1,34 @@
post_install() {
echo "Updating MIME database and icon cache..."
xdg-mime install /opt/WingHexExplorer2/share/x-winghex.xml
xdg-mime default com.wingsummer.winghexexplorer2.desktop application/x-winghex
xdg-icon-resource install --context mimetypes --size 32 /opt/WingHexExplorer2/share/winghexpro32.png application-x-winghex
xdg-icon-resource install --context mimetypes --size 64 /opt/WingHexExplorer2/share/winghexpro64.png application-x-winghex
xdg-icon-resource install --context mimetypes --size 128 /opt/WingHexExplorer2/share/winghexpro128.png application-x-winghex
update-mime-database /usr/share/mime
xdg-icon-resource forceupdate
gtk-update-icon-cache /usr/share/icons/hicolor
update-desktop-database /usr/share/applications
}
post_upgrade() {
post_install
}
pre_remove() {
echo "Cleaning MIME database and icon cache..."
xdg-mime uninstall /opt/WingHexExplorer2/share/x-winghex.xml
xdg-icon-resource uninstall --context mimetypes --size 32 application-x-winghex
xdg-icon-resource uninstall --context mimetypes --size 64 application-x-winghex
xdg-icon-resource uninstall --context mimetypes --size 128 application-x-winghex
update-mime-database /usr/share/mime
xdg-icon-resource forceupdate
gtk-update-icon-cache /usr/share/icons/hicolor
update-desktop-database /usr/share/applications
}

60
mkinstaller/config.ini Normal file
View File

@ -0,0 +1,60 @@
; ========= 羽云十六进制编辑器2应用环境配置文件说明 ==========
;
; 如果区块名开头没有 $ 则认为普通区块General 会在所有的操作系统生效
; 如果你想在某些操作系统生效可以指定区块名为Windows, Linux 和 Darwin
; 对于 Linux 系统,如果包含 uname 工具,则区块名为 uname -s 的输出结果
;
; ================= 配置文件区块扩展语法说明 =================
;
; 语句格式:
; $NAME [OPERATOR VALUE]
;
; 各字段说明:
; $ • 语句起始标记,必需
;
; NAME • 环境变量名
; • 以字母或“_”开头后续可包含字母、数字或“_”
;
; OPERATOR • 可选运算符:
; = 忽略大小写全匹配
; == 区分大小写全匹配
; := 忽略大小写子串包含
; ::= 区分大小写子串包含
;
; VALUE • 可选比较值,仅在 OPERATOR 存在时使用
; • 格式必须是:
; — 纯数字(例如 12345
; — 或用双引号包裹的字符串("text"
; — 或用单引号包裹的字符串('text'
;
; 存在性检查:
; 若仅写 “$NAME”无 OPERATOR 和 VALUE即检查该环境变量是否已定义
;
; --------------------- 示例 ---------------------
; $XDG_SESSION_TYPE="wayland"
; → 忽略大小写地检查 XDG_SESSION_TYPE 是否等于 “wayland”
;
; $PATH:="/usr/local/bin"
; → 忽略大小写地检查 PATH 中是否包含 “/usr/local/bin”
;
; $HOME==12345
; → 区分大小写地检查 HOME 是否等于数字 12345
;
; $LD_LIBRARY_PATH::="/lib64"
; → 区分大小写地检查 LD_LIBRARY_PATH 中是否包含 “/lib64”
;
; $HOME
; → 检查 HOME 是否已定义(存在性检查)
; =====================================================
[General]
WING_DISABLE_PLUGIN_SYSTEM=0
WING_DISABLE_EXTDRV=0
WING_DISABLE_PLUGIN=0
WING_DEBUG=0
[$XDG_SESSION_TYPE="wayland"]
QT_QPA_PLATFORM=xcb

267
mkinstaller/pyscript/installer.py Executable file → Normal file
View File

@ -14,7 +14,9 @@ import subprocess
from colorama import Fore, Style
PACKAGE_NAME = "WingHexExplorer2"
INSTALL_PATH = f"/opt/{PACKAGE_NAME}"
DEFAULT_INSTALL_PATH = f"/opt/{PACKAGE_NAME}"
INSTALL_PATH = DEFAULT_INSTALL_PATH
APP_DESKTOP_PATH = "/usr/share/applications"
DESKTOP_FILE_NAME = "com.wingsummer.winghexexplorer2.desktop"
@ -59,163 +61,137 @@ def run_command_interactive(command):
if output:
print(Fore.GREEN + output.strip() + Style.RESET_ALL)
return_code = process.wait()
return return_code
return process.wait()
def create_dir(dir):
if not os.path.exists(dir):
os.mkdir(dir)
def create_dir(dir_path):
if not os.path.exists(dir_path):
os.mkdir(dir_path)
def update(build_path):
if (os.path.exists(INSTALL_PATH) == False):
print(
Fore.RED + "[Error] The installing path not exists! Please use 'install' instead." + Style.RESET_ALL)
if not os.path.exists(INSTALL_PATH):
print(Fore.RED + "[Error] The installing path not exists! Please use 'install' instead." + Style.RESET_ALL)
exit(3)
installer_path = os.path.dirname(os.path.abspath(__file__))
projectbase = os.path.abspath(os.path.join(installer_path, "../.."))
project_base = os.path.abspath(os.path.join(installer_path, "../.."))
print(Fore.GREEN + ">> Checking file integrity..." + Style.RESET_ALL)
if (os.path.exists(build_path) == False):
print(
Fore.RED + "[Error] Not found a CMake build directory!" + Style.RESET_ALL)
# 验证构建目录
if not os.path.isdir(build_path) or not os.path.exists(os.path.join(build_path, "CMakeCache.txt")):
print(Fore.RED + "[Error] Not a valid CMake build directory!" + Style.RESET_ALL)
exit(-1)
if (os.path.exists(os.path.join(build_path, "CMakeCache.txt")) == False):
print(
Fore.RED + "[Error] This is not a CMake build directory!" + Style.RESET_ALL)
# 版本文件检查
for vf in ("WINGHEX_VERSION", "QT_VERSION"):
if not os.path.exists(os.path.join(build_path, vf)):
print(Fore.RED + f"[Error] {vf} file not found!" + Style.RESET_ALL)
exit(-1)
version_file_src = os.path.join(build_path, "WINGHEX_VERSION")
if (os.path.exists(version_file_src) == False):
print(
Fore.RED + "[Error] WINGHEX_VERSION file not found, maybe not a CMake build directory!" + Style.RESET_ALL)
exit(-1)
version_qt_src = os.path.join(build_path, "QT_VERSION")
if (os.path.exists(version_qt_src) == False):
print(
Fore.RED + "[Error] QT_VERSION file not found, maybe not a CMake build directory!" + Style.RESET_ALL)
exit(-1)
# ok, start copying files
exemain_src = os.path.join(build_path, PACKAGE_NAME)
if (os.path.exists(exemain_src) == False):
print(
Fore.RED + f"[Error] {PACKAGE_NAME} is not found!" + Style.RESET_ALL)
# 可执行文件检查
exe_src = os.path.join(build_path, PACKAGE_NAME)
if not os.path.exists(exe_src):
print(Fore.RED + f"[Error] {PACKAGE_NAME} executable not found!" + Style.RESET_ALL)
exit(-3)
# calculate the md5 checksum
with open(exemain_src, 'rb') as file_to_check:
data = file_to_check.read()
md5_returned = hashlib.md5(data).hexdigest().upper()
print(Fore.GREEN + ">> Get MD5: " + md5_returned + Style.RESET_ALL)
# 计算 MD5
with open(exe_src, 'rb') as f:
md5sum = hashlib.md5(f.read()).hexdigest().upper()
print(Fore.GREEN + ">> Get MD5: " + md5sum + Style.RESET_ALL)
print(Fore.GREEN + ">> Installing..." + Style.RESET_ALL)
shutil.copy2(exemain_src, os.path.join(INSTALL_PATH, PACKAGE_NAME))
# 复制核心文件
shutil.copy2(exe_src, os.path.join(INSTALL_PATH, PACKAGE_NAME))
shutil.copy2(os.path.join(build_path, "WingPlugin", "libWingPlugin.so"),
os.path.join(INSTALL_PATH, "libWingPlugin.so"))
create_dir(os.path.join(INSTALL_PATH, "plugin"))
create_dir(os.path.join(INSTALL_PATH, "scripts"))
create_dir(os.path.join(INSTALL_PATH, "aslib"))
# 目录结构
for sub in ("plugin", "scripts", "aslib"):
create_dir(os.path.join(INSTALL_PATH, sub))
# 共享资源与多语言
shutil.copytree(os.path.join(installer_path, "share"),
os.path.join(INSTALL_PATH, "share"), dirs_exist_ok=True)
shutil.copytree(os.path.join(build_path, "lang"),
os.path.join(INSTALL_PATH, "lang"), dirs_exist_ok=True)
# 其他材料
print(Fore.GREEN + ">> Copying License and other materials..." + Style.RESET_ALL)
material_files = ["LICENSE", "authorband.svg",
"licenseband.svg", "screenshot.png", "README.md"]
material_files = ["LICENSE", "authorband.svg", "licenseband.svg", "screenshot.png", "README.md"]
for f in material_files:
shutil.copyfile(os.path.join(projectbase, f),
shutil.copyfile(os.path.join(project_base, f),
os.path.join(INSTALL_PATH, f))
shutil.copyfile(os.path.join(projectbase, "images", "author.jpg"),
shutil.copyfile(os.path.join(project_base, "images", "author.jpg"),
os.path.join(INSTALL_PATH, "author.jpg"))
with open(os.path.join(INSTALL_PATH, "md5sums"), 'w') as md5_file:
md5_file.write(md5_returned)
# 写 md5sums
with open(os.path.join(INSTALL_PATH, "md5sums"), 'w') as md5f:
md5f.write(md5sum)
# 桌面文件
shutil.copyfile(os.path.join(installer_path, DESKTOP_FILE_NAME),
os.path.join(APP_DESKTOP_PATH, DESKTOP_FILE_NAME))
run_command_interactive(
["xdg-mime", "install", "/opt/WingHexExplorer2/share/x-winghex.xml"])
run_command_interactive(
["xdg-mime", "default", "/usr/share/applications/com.wingsummer.winghexexplorer2.desktop", "application/x-winghex"])
run_command_interactive(
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "32", "/opt/WingHexExplorer2/share/winghexpro32.png", "application-x-winghex"])
run_command_interactive(
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "64", "/opt/WingHexExplorer2/share/winghexpro64.png", "application-x-winghex"])
run_command_interactive(
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "128", "/opt/WingHexExplorer2/share/winghexpro128.png", "application-x-winghex"])
run_command_interactive(
["update-mime-database", "/usr/share/mime"])
run_command_interactive(
["xdg-icon-resource", "forceupdate"])
run_command_interactive(
["gtk-update-icon-cache", "/usr/share/icons/hicolor"])
run_command_interactive(
["update-desktop-database", "/usr/share/applications"])
# 更新 mime 和图标缓存
cmds = [
["xdg-mime", "install", os.path.join(INSTALL_PATH, "share", "x-winghex.xml")],
["xdg-mime", "default", DESKTOP_FILE_NAME, "application/x-winghex"],
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "32",
os.path.join(INSTALL_PATH, "share", "winghexpro32.png"), "application-x-winghex"],
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "64",
os.path.join(INSTALL_PATH, "share", "winghexpro64.png"), "application-x-winghex"],
["xdg-icon-resource", "install", "--context", "mimetypes", "--size", "128",
os.path.join(INSTALL_PATH, "share", "winghexpro128.png"), "application-x-winghex"],
["update-mime-database", "/usr/share/mime"],
["xdg-icon-resource", "forceupdate"],
["gtk-update-icon-cache", "/usr/share/icons/hicolor"],
["update-desktop-database", "/usr/share/applications"],
]
for cmd in cmds:
run_command_interactive(cmd)
print(Fore.GREEN + ">> Installation finished..." + Style.RESET_ALL)
def install(build_path):
if (os.path.exists(INSTALL_PATH)):
print(
Fore.RED + "[Error] The installing path exists! Please use 'update' instead or 'uninstall' before it." + Style.RESET_ALL)
if os.path.exists(INSTALL_PATH):
print(Fore.RED + "[Error] The installing path exists! Please use 'update' or 'uninstall' first." + Style.RESET_ALL)
exit(3)
os.makedirs(INSTALL_PATH)
update(build_path)
def remove(path):
""" param <path> could either be relative or absolute. """
"""Remove file or directory recursively."""
if os.path.isfile(path) or os.path.islink(path):
os.remove(path) # remove the file
os.remove(path)
elif os.path.isdir(path):
shutil.rmtree(path) # remove dir and all contains
shutil.rmtree(path)
def is_empty(path):
if os.path.exists(path) and not os.path.isfile(path):
# Checking if the directory is empty or not
if not os.listdir(path):
return True
else:
return False
else:
return False
return os.path.isdir(path) and not os.listdir(path)
def uninstall():
run_command_interactive(
["xdg-mime", "uninstall", "/opt/WingHexExplorer2/share/x-winghex.xml"])
run_command_interactive(
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "32", "application-x-winghex"])
run_command_interactive(
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "64", "application-x-winghex"])
run_command_interactive(
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "128", "application-x-winghex"])
run_command_interactive(
["update-mime-database", "/usr/share/mime"])
run_command_interactive(
["xdg-icon-resource", "forceupdate"])
run_command_interactive(
["update-icon-caches", "/usr/share/icons/hicolor"])
cmds = [
["xdg-mime", "uninstall", os.path.join(INSTALL_PATH, "share", "x-winghex.xml")],
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "32", "application-x-winghex"],
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "64", "application-x-winghex"],
["xdg-icon-resource", "uninstall", "--context", "mimetypes", "--size", "128", "application-x-winghex"],
["update-mime-database", "/usr/share/mime"],
["xdg-icon-resource", "forceupdate"],
["update-icon-caches", "/usr/share/icons/hicolor"],
["update-desktop-database", "/usr/share/applications"],
]
for cmd in cmds:
run_command_interactive(cmd)
remove(os.path.join(APP_DESKTOP_PATH, DESKTOP_FILE_NAME))
run_command_interactive(
["update-desktop-database", "/usr/share/applications"])
remove(INSTALL_PATH)
print(Fore.GREEN + ">> Uninstallation finished..." + Style.RESET_ALL)
@ -225,82 +201,74 @@ CONF_FILE = "WingHexExplorer2.conf"
CONTENT_PATH = ".local/share/WingCloudStudio"
def clear_usrdata(usr):
usr_path = ""
if (usr == "root"):
usr_path = "/root"
def clear_usrdata(user):
if user == "root":
home = "/root"
else:
usr_path = f"/home/{usr}"
home = f"/home/{user}"
desktop_file = os.path.join(usr_path, AUTO_START, DESKTOP_FILE_NAME)
remove(desktop_file)
remove(os.path.join(home, AUTO_START, DESKTOP_FILE_NAME))
cfgdir = os.path.join(home, CFG_PATH)
remove(os.path.join(cfgdir, CONF_FILE))
if is_empty(cfgdir):
remove(cfgdir)
cfgpath = os.path.join(usr_path, CFG_PATH)
contentdir = os.path.join(home, CONTENT_PATH, PACKAGE_NAME)
remove(contentdir)
parent = os.path.join(home, CONTENT_PATH)
if is_empty(parent):
remove(parent)
remove(os.path.join(cfgpath, CONF_FILE))
if is_empty(cfgpath):
remove(cfgpath)
cfgpath = os.path.join(usr_path, CONTENT_PATH, PACKAGE_NAME)
remove(cfgpath)
cfgpath = os.path.join(usr_path, CONTENT_PATH)
if is_empty(cfgpath):
remove(cfgpath)
print(Fore.GREEN + f">> Purged ${usr}..." + Style.RESET_ALL)
print(Fore.GREEN + f">> Purged {user}..." + Style.RESET_ALL)
def purge():
uninstall()
for p in os.listdir("/home"):
if p == "lost+found":
for user in os.listdir("/home"):
if user == "lost+found":
continue
clear_usrdata(p)
clear_usrdata(user)
clear_usrdata("root")
print(Fore.GREEN + ">> Clean-up finished..." + Style.RESET_ALL)
def main():
parser = argparse.ArgumentParser(
prog="installer.py", description=f"A installing manager for {PACKAGE_NAME}")
parser.add_argument(
"action",
parser = argparse.ArgumentParser(prog="installer.py",
description=f"A installing manager for {PACKAGE_NAME}")
parser.add_argument("action",
choices=["install", "update", "uninstall", "purge"],
nargs="?",
default="install",
help="Action to perform: install (default), update, uninstall, or purge."
)
parser.add_argument(
"-b", "--build",
help="Action to perform: install (default), update, uninstall, or purge.")
parser.add_argument("-b", "--build",
type=str,
required=False,
help="Path to the building files for installation (required for 'install' and 'update' action)."
)
help="Path to the build directory (required for install/update).")
parser.add_argument("-p", "--prefix",
dest="install_path",
type=str,
default=DEFAULT_INSTALL_PATH,
help=f"Installation directory (default: {DEFAULT_INSTALL_PATH})")
args = parser.parse_args()
# 覆盖全局变量
global INSTALL_PATH
INSTALL_PATH = args.install_path
if check_is_running(PACKAGE_NAME):
print(
Fore.RED + f"[Error] You should exit {PACKAGE_NAME} berfore installation." + Style.RESET_ALL)
print(Fore.RED + f"[Error] Please exit {PACKAGE_NAME} before installation." + Style.RESET_ALL)
exit(1)
if not is_root():
print(
Fore.RED + "[Error] root is required for installation." + Style.RESET_ALL)
print(Fore.RED + "[Error] root privilege is required." + Style.RESET_ALL)
exit(2)
# checking build toolkits
if args.action == "install":
if not args.build:
print(
Fore.RED + "[Error] --build path is required for installation." + Style.RESET_ALL)
if args.action in ("install", "update") and not args.build:
print(Fore.RED + "[Error] --build path is required for install/update." + Style.RESET_ALL)
exit(2)
if args.action == "install":
install(args.build)
elif args.action == "update":
if not args.build:
print(
Fore.RED + "[Error] --build path is required for installation." + Style.RESET_ALL)
exit(2)
update(args.build)
elif args.action == "uninstall":
uninstall()
@ -313,5 +281,4 @@ def main():
if __name__ == "__main__":
main()
else:
print(
Fore.RED + "[Error] Please run this script in main mode" + Style.RESET_ALL)
print(Fore.RED + "[Error] Please run this script in main mode" + Style.RESET_ALL)

View File

@ -497,7 +497,6 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
// first preprocess the code
AsPreprocesser prepc(engine);
prepc.setIsCodeCompleteMode(true);
prepc.setIncludeCallback(&AsCompletion::includeCallBack, this);
auto r = prepc.loadSectionFromMemory(QStringLiteral("ASCOMPLETION"),

View File

@ -186,13 +186,15 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
QStack<std::optional<bool>> m_condtionStack;
bool isEndLine = true;
while (pos < modifiedScript.size()) {
auto SECTION = sectionname.toUtf8();
asUINT len = 0;
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
modifiedScript.size() - pos, &len);
if (t == asTC_UNKNOWN && modifiedScript[pos] == '#' &&
if (isEndLine && t == asTC_UNKNOWN && modifiedScript[pos] == '#' &&
(pos + 1 < modifiedScript.size())) {
int start = pos++;
@ -217,12 +219,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
if (std::any_of(modifiedScript.data() + pos,
modifiedScript.data() + pos + len,
[](char ch) { return ch == '\n'; })) {
if (_isCodeCompleteMode) {
pos = modifiedScript.indexOf('\n', pos);
continue;
}
auto str = QObject::tr("IfDefNoWord");
auto str = tr("IfDefNoWord");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
@ -234,16 +231,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
}
if (isIfDef || isIfnDef) {
if (_isCodeCompleteMode) {
auto pos = modifiedScript.indexOf('\n', start);
if (pos < 0) {
overwriteCode(modifiedScript, start,
modifiedScript.size() - start - 1);
} else {
overwriteCode(modifiedScript, start, pos - start);
}
continue;
}
if (t == asTC_IDENTIFIER) {
QByteArray word = modifiedScript.sliced(pos, len);
@ -267,23 +254,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
qDebug().noquote() << modifiedScript;
#endif
} else {
auto str = QObject::tr("IfDefInvalidWord");
auto str = tr("IfDefInvalidWord");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
}
} else if (isIf) {
if (_isCodeCompleteMode) {
auto pos = modifiedScript.indexOf('\n', start);
if (pos < 0) {
overwriteCode(modifiedScript, start,
modifiedScript.size() - start - 1);
} else {
overwriteCode(modifiedScript, start, pos - start);
}
continue;
}
// evalutate the string
auto npos = modifiedScript.indexOf('\n', pos);
QByteArray codes;
@ -303,7 +280,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
ok);
if (ret < 0) {
auto str = QObject::tr("CalIfFailed");
auto str = tr("CalIfFailed");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
@ -324,20 +301,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
QByteArray word = modifiedScript.sliced(pos, len);
pos += len;
if (_isCodeCompleteMode) {
defineWord(word, {});
auto pos = modifiedScript.indexOf('\n', start);
if (pos < 0) {
overwriteCode(modifiedScript, start,
modifiedScript.size() - start -
1);
} else {
overwriteCode(modifiedScript, start,
pos - start);
}
continue;
}
t = engine->ParseToken(modifiedScript.data() + pos,
modifiedScript.size() - pos,
&len);
@ -366,7 +329,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
defineWord(word, v);
} break;
default:
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(
SECTION,
getLineCount(modifiedScript, pos), 1,
@ -381,42 +344,20 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line
if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(
SECTION, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
}
} else {
if (_isCodeCompleteMode) {
auto pos = modifiedScript.indexOf('\n', start);
if (pos < 0) {
overwriteCode(modifiedScript, start,
modifiedScript.size() - start -
1);
} else {
overwriteCode(modifiedScript, start,
pos - start);
}
continue;
}
auto str = QObject::tr("InvalidDef");
auto str = tr("InvalidDef");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
}
} else if (isUnDef) {
if (_isCodeCompleteMode) {
auto pos = modifiedScript.indexOf('\n', start);
if (pos < 0) {
overwriteCode(modifiedScript, start,
modifiedScript.size() - start - 1);
} else {
overwriteCode(modifiedScript, start, pos - start);
}
continue;
}
if (t == asTC_IDENTIFIER) {
QByteArray word = modifiedScript.sliced(pos, len);
@ -427,13 +368,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
constexpr auto PREFIX = "__";
if (word.startsWith(PREFIX) && word.endsWith(PREFIX)) {
// Warning
auto str = QObject::tr("ReservedMarcoType");
auto str = tr("ReservedMarcoType");
engine->WriteMessage(
SECTION, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_WARNING, str.toUtf8());
} else {
if (!definedWords.remove(word)) {
auto str = QObject::tr("MarcoNotFound:") + word;
auto str = tr("MarcoNotFound:") + word;
engine->WriteMessage(
SECTION, getLineCount(modifiedScript, pos),
1, asMSGTYPE_WARNING, str.toUtf8());
@ -442,14 +383,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line
if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(
SECTION, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
}
} else {
auto str = QObject::tr("InvalidDef");
auto str = tr("InvalidDef");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
@ -457,12 +398,8 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
}
}
} else if (token == "else") {
if (_isCodeCompleteMode) {
overwriteCode(modifiedScript, start, pos - start);
continue;
}
if (m_condtionStack.isEmpty()) {
auto str = QObject::tr("NoMatchingIf");
auto str = tr("NoMatchingIf");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
@ -478,14 +415,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line
if (endLinePassFailed(modifiedScript, pos - 1)) {
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(
SECTION, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
}
} else {
auto str = QObject::tr("DupElseDef");
auto str = tr("DupElseDef");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
@ -496,13 +433,9 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
qDebug().noquote() << modifiedScript;
#endif
} else if (token == "endif") {
if (_isCodeCompleteMode) {
overwriteCode(modifiedScript, start, pos - start);
continue;
}
// Only remove the #endif if there was a matching #if
if (m_condtionStack.isEmpty()) {
auto str = QObject::tr("NoMatchingIf");
auto str = tr("NoMatchingIf");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
@ -514,7 +447,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line
if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
@ -524,17 +457,18 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
qDebug().noquote() << modifiedScript;
#endif
}
isEndLine = true;
} else {
if (!_isCodeCompleteMode) {
if (t == asTC_IDENTIFIER) {
// define replace
auto word = modifiedScript.sliced(pos, len);
if (word == PROMISE_AWAIT) {
auto npos = pos + len;
asUINT total = 0;
auto t = engine->ParseToken(
modifiedScript.data() + npos,
modifiedScript.size() - npos, &total);
auto t = engine->ParseToken(modifiedScript.data() + npos,
modifiedScript.size() - npos,
&total);
if (t == asTC_WHITESPACE) {
npos += total;
t = engine->ParseToken(modifiedScript.data() + npos,
@ -544,8 +478,8 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ok
auto word = modifiedScript.sliced(npos, total);
auto data = "(" + word +
")." PROMISE_YIELD
"()." PROMISE_UNWRAP "()";
")." PROMISE_YIELD "()." PROMISE_UNWRAP
"()";
auto oldLen = npos - pos + word.length();
modifiedScript.replace(pos, oldLen, data);
pos = npos;
@ -554,14 +488,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
}
}
auto str = QObject::tr("UnexceptedToken");
auto str = tr("UnexceptedToken");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
} else if (word == "__LINE__") {
auto data = QByteArray::number(
getLineCount(modifiedScript, pos));
auto data =
QByteArray::number(getLineCount(modifiedScript, pos));
modifiedScript.replace(pos, len, data);
pos += data.length();
continue;
@ -584,7 +518,10 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
len = rword.length();
}
}
}
} else if (t == asTC_WHITESPACE) {
isEndLine = std::any_of(modifiedScript.data() + pos,
modifiedScript.data() + pos + len,
[](char ch) { return ch == '\n'; });
}
pos += len;
}
@ -644,10 +581,10 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// line breaks
auto p = includefile.indexOf('\n');
if (p >= 0) {
auto str =
QObject::tr("Invalid file name for #include; "
auto str = tr("Invalid file name for #include; "
"it contains a line-break: ") +
QStringLiteral("'") + includefile.left(p) +
QStringLiteral("'") +
includefile.left(p) +
QStringLiteral("'");
engine->WriteMessage(
sectionname.toUtf8(),
@ -690,11 +627,10 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
auto p = includefile.indexOf('\n');
auto ws = includefile.indexOf(' ');
if (!includefile.isEmpty() && p >= 0 && ws >= 0) {
auto str =
QObject::tr(
"Invalid file name for #include; "
auto str = tr("Invalid file name for #include; "
"it contains a line-break: ") +
QStringLiteral("'") + includefile.left(p) +
QStringLiteral("'") +
includefile.left(p) +
QStringLiteral("'");
engine->WriteMessage(
sectionname.toUtf8(),
@ -710,8 +646,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
pos - start);
}
} else {
auto str =
QObject::tr("Invalid file name for #include; "
auto str = tr("Invalid file name for #include; "
"it contains a line-break or "
"unpaired symbol");
engine->WriteMessage(sectionname.toUtf8(), 0, 0,
@ -734,24 +669,21 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// to avoid compiler error
overwriteCode(modifiedScript, start, pos - start);
if (!_isCodeCompleteMode) {
int r = pragmaCallback
? pragmaCallback(pragmaText, this,
sectionname, pragmaParam)
? pragmaCallback(pragmaText, this, sectionname,
pragmaParam)
: -1;
if (r < 0) {
engine->WriteMessage(
sectionname.toUtf8(),
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR,
QObject::tr("Invalid #pragma directive")
.toUtf8());
tr("Invalid #pragma directive").toUtf8());
return r;
}
}
}
}
}
// Don't search for includes within statement blocks or
// between tokens in statements
else {
@ -810,8 +742,7 @@ int AsPreprocesser::loadScriptSection(const QString &filename) {
if (!f.open(QFile::ReadOnly)) {
// Write a message to the engine's message callback
auto msg = QObject::tr("Failed to open script file ") +
QStringLiteral("'") +
auto msg = tr("Failed to open script file ") + QStringLiteral("'") +
QFileInfo(filename).absoluteFilePath() + QStringLiteral("'");
engine->WriteMessage(filename.toUtf8(), 0, 0, asMSGTYPE_ERROR,
msg.toUtf8());
@ -953,7 +884,7 @@ void AsPreprocesser::overwriteCode(QByteArray &modifiedScript, int start,
int AsPreprocesser::getLineCount(const QByteArray &modifiedScript,
int pos) const {
pos = qBound(0, pos, int(modifiedScript.size()));
pos = qBound(0, pos, qsizetype(modifiedScript.size()));
return std::count_if(modifiedScript.begin(),
std::next(modifiedScript.begin(), pos),
[](char ch) -> bool { return ch == '\n'; }) +
@ -1022,12 +953,6 @@ QByteArray AsPreprocesser::findReplaceResult(const QByteArray &v) {
return r;
}
bool AsPreprocesser::isCodeCompleteMode() const { return _isCodeCompleteMode; }
void AsPreprocesser::setIsCodeCompleteMode(bool newIsCodeCompleteMode) {
_isCodeCompleteMode = newIsCodeCompleteMode;
}
QHash<QString, QByteArray> AsPreprocesser::definedMacros() const {
return definedWords;
}

View File

@ -35,6 +35,7 @@
#pragma warning(disable : 4786)
#endif
#include <QApplication>
#include <QEventLoop>
#include <QMap>
#include <QSet>
@ -74,6 +75,7 @@ typedef int (*PRAGMACALLBACK_t)(const QByteArray &pragmaText,
* * #ifndef <word>
*/
class AsPreprocesser {
Q_DECLARE_TR_FUNCTIONS(AsPreprocesser)
public:
explicit AsPreprocesser(asIScriptEngine *engine);
virtual ~AsPreprocesser();
@ -113,9 +115,6 @@ public:
QString sectionName(unsigned int idx) const;
bool isCodeCompleteMode() const;
void setIsCodeCompleteMode(bool newIsCodeCompleteMode);
QHash<QString, QByteArray> definedMacros() const;
protected:
@ -155,9 +154,6 @@ protected:
QStringList includedScripts;
QHash<QString, QByteArray> definedWords;
private:
bool _isCodeCompleteMode = false;
};
#endif // ASPREPROCESSER_H

View File

@ -0,0 +1,98 @@
/*==============================================================================
** 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 "consolehighlighanim.h"
#include <QApplication>
#include <QPalette>
#include <QWidget>
ConsoleHighlighAnim::ConsoleHighlighAnim(QObject *parent)
: QObject(parent), m_highlightColor(qApp->palette().highlight().color()),
m_alpha(0), _w(nullptr), _anim(nullptr) {
_anim = new QPropertyAnimation(this, QByteArrayLiteral("alpha"), this);
_anim->setStartValue(10);
_anim->setEndValue(100);
_anim->setDuration(1000);
_anim->setEasingCurve(QEasingCurve::InOutQuad);
_anim->setLoopCount(5);
connect(_anim, &QPropertyAnimation::finished, this, [this]() {
if (_w) {
_w->setStyleSheet({});
}
});
}
int ConsoleHighlighAnim::getAlpha() const { return m_alpha; }
void ConsoleHighlighAnim::setAlpha(int newAlpha) {
if (m_alpha == newAlpha)
return;
m_alpha = newAlpha;
auto clsname = _w->metaObject()->className();
auto ss = QStringLiteral("background-color: rgba(%1, %2, %3, %4);")
.arg(m_highlightColor.red())
.arg(m_highlightColor.green())
.arg(m_highlightColor.blue())
.arg(m_alpha);
if (clsname) {
ss.prepend('{').prepend(clsname).append('}');
}
if (_w) {
_w->setStyleSheet(ss);
}
Q_EMIT alphaChanged();
}
QWidget *ConsoleHighlighAnim::widget() const { return _w; }
void ConsoleHighlighAnim::setWidget(QWidget *newW) {
if (_w) {
_w->setStyleSheet({});
}
_w = newW;
auto ss = QStringLiteral("background-color: rgba(%1, %2, %3, %4);")
.arg(m_highlightColor.red())
.arg(m_highlightColor.green())
.arg(m_highlightColor.blue())
.arg(m_alpha);
if (_w) {
_w->setStyleSheet(ss);
}
}
void ConsoleHighlighAnim::start() {
if (_w == nullptr) {
return;
}
if (_anim->state() == QPropertyAnimation::Stopped) {
_anim->start();
}
}
void ConsoleHighlighAnim::stop() {
if (_anim->state() == QPropertyAnimation::Running) {
_anim->stop();
if (_w) {
_w->setStyleSheet({});
}
}
}

View File

@ -0,0 +1,55 @@
/*==============================================================================
** 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 CONSOLEHIGHLIGHANIM_H
#define CONSOLEHIGHLIGHANIM_H
#include <QColor>
#include <QObject>
#include <QPropertyAnimation>
class ConsoleHighlighAnim : public QObject {
Q_OBJECT
Q_PROPERTY(int alpha READ getAlpha WRITE setAlpha NOTIFY alphaChanged FINAL)
public:
explicit ConsoleHighlighAnim(QObject *parent = nullptr);
public:
int getAlpha() const;
void setAlpha(int newAlpha);
QWidget *widget() const;
void setWidget(QWidget *newW);
public:
void start();
// 停止动画并清除样式
void stop();
signals:
void alphaChanged();
private:
QColor m_highlightColor;
int m_alpha;
QWidget *_w;
QPropertyAnimation *_anim;
};
#endif // CONSOLEHIGHLIGHANIM_H

View File

@ -0,0 +1,322 @@
/*==============================================================================
** 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(view) {
Q_ASSERT(view);
}
QString EditorViewContext::docFileName() const {
return _view->windowFilePath();
}
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,114 @@
/*==============================================================================
** 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 QString docFileName() const override;
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

@ -513,14 +513,66 @@ bool PluginSystem::invokeServiceImpl(const QObject *sender, const QString &puid,
return false;
}
auto r =
std::find_if(_loadedplgs.begin(), _loadedplgs.end(),
[=](IWingPlugin *plg) { return getPUID(plg) == puid; });
QObject *obj = nullptr;
if (puid.compare(QStringLiteral("[MAN]"), Qt::CaseInsensitive) == 0) {
obj = _manager;
} else if (puid.compare(QStringLiteral("[HEXE]"), Qt::CaseInsensitive) ==
0) {
obj = _hexExt;
} else {
QString rpuid;
auto question = puid.indexOf('?');
enum { None, MustPlugin, MustExt } State = None;
if (question >= 0) {
rpuid = puid.sliced(0, question);
auto equest = puid.sliced(question + 1);
if (equest.compare(QStringLiteral("[PLG]"))) {
State = MustPlugin;
} else if (equest.compare(QStringLiteral("[EXT]"))) {
State = MustExt;
} else {
// warn and ignored
Logger::warning(
QStringLiteral("[PluginSystem::invokeServiceImpl] Cannot "
"parsing filter: '%1'")
.arg(equest));
}
} else {
rpuid = puid;
State = None;
}
auto r = std::find_if(
_loadedplgs.begin(), _loadedplgs.end(),
[=](IWingPlugin *plg) { return getPUID(plg) == rpuid; });
if (r == _loadedplgs.end()) {
return false;
}
auto obj = *r;
auto rc = *r;
switch (State) {
case None:
obj = rc;
break;
case MustPlugin:
if (qobject_cast<IWingPlugin *>(rc)) {
obj = rc;
}
break;
case MustExt:
if (qobject_cast<IWingDevice *>(rc)) {
obj = rc;
}
break;
}
}
if (obj == nullptr) {
qCritical("[PluginSystem::invokeServiceImpl] Null caller");
return false;
}
auto meta = obj->metaObject();
Qt::ConnectionType c;
@ -532,6 +584,7 @@ bool PluginSystem::invokeServiceImpl(const QObject *sender, const QString &puid,
std::tie(method, c, paramCount, parameters, typeNames, metaTypes) = infos;
if (parameters == nullptr || typeNames == nullptr || metaTypes == nullptr) {
qCritical("[PluginSystem::invokeServiceImpl] Invalid calling info");
return false;
}
@ -547,7 +600,7 @@ bool PluginSystem::invokeServiceImpl(const QObject *sender, const QString &puid,
if (met.name() == method) {
bool err = false;
for (int i = 1; i < paramCount; ++i) {
if (met.parameterType(i) != metaTypes[i]->typeId) {
if (met.parameterTypeName(i).compare(metaTypes[i]->name)) {
err = true;
break;
}
@ -561,6 +614,7 @@ bool PluginSystem::invokeServiceImpl(const QObject *sender, const QString &puid,
}
if (!m.isValid()) {
qCritical("[PluginSystem::invokeServiceImpl] Invalid MetaMethod");
return false;
}
@ -610,7 +664,37 @@ bool PluginSystem::invokeServiceImpl(const QObject *sender, const QString &puid,
m, obj, c, nparamCount, nparameters.data(), ntypeNames.data(),
nmetaTypes.data());
// errror report
auto cstr = [](QMetaMethodInvoker::InvokeFailReason r) -> const char * {
switch (r) {
case QMetaMethodInvoker::InvokeFailReason::ReturnTypeMismatch:
return "ReturnTypeMismatch";
case QMetaMethodInvoker::InvokeFailReason::DeadLockDetected:
return "DeadLockDetected";
case QMetaMethodInvoker::InvokeFailReason::CallViaVirtualFailed:
return "CallViaVirtualFailed";
case QMetaMethodInvoker::InvokeFailReason::ConstructorCallOnObject:
return "ConstructorCallOnObject";
case QMetaMethodInvoker::InvokeFailReason::ConstructorCallWithoutResult:
return "ConstructorCallWithoutResult";
case QMetaMethodInvoker::InvokeFailReason::ConstructorCallFailed:
return "ConstructorCallFailed";
case QMetaMethodInvoker::InvokeFailReason::CouldNotQueueParameter:
return "CouldNotQueueParameter";
case QMetaMethodInvoker::InvokeFailReason::None:
return "None";
case QMetaMethodInvoker::InvokeFailReason::TooFewArguments:
return "TooFewArguments";
case QMetaMethodInvoker::InvokeFailReason::FormalParameterMismatch:
return "FormalParameterMismatch";
break;
}
return "";
};
if (ret != QMetaMethodInvoker::InvokeFailReason::None) {
qCritical("[PluginSystem::invokeServiceImpl] MetaCall failed: %s (%d)",
cstr(ret), ret);
}
return ret == QMetaMethodInvoker::InvokeFailReason::None;
}
@ -2612,7 +2696,11 @@ IWingGeneric *PluginSystem::__createParamContext(const QObject *sender,
bool PluginSystem::passByFailedGuard(const QObject *sender, const char *func,
const QVariantList &params) {
if (_manager && sender != _manager) {
return !_manager->enterGuard(sender->metaObject(), func, params);
auto ret = !_manager->enterGuard(sender->metaObject(), func, params);
if (ret) {
qCritical("[GuardBlock] '%s' was blocked", func);
}
return ret;
}
return false;
}
@ -2631,6 +2719,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;
@ -3272,9 +3368,9 @@ std::optional<PluginInfo> PluginSystem::loadPlugin(const QFileInfo &fileinfo,
} else if constexpr (std::is_same_v<T, IWingDevice>) {
_blkdevs[BlockReason::BlockedByManager].append(m);
}
Logger::critical(QStringLiteral("{ ") + m.id +
QStringLiteral(" } ") +
tr("PluginBlockByManager"));
qCritical(
"[PluginSystem::loadPlugin] '%s' was blocked by manager",
qUtf8Printable(m.id));
return std::nullopt;
}
}
@ -3687,6 +3783,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 +3992,84 @@ 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;
registerHexContextMenu(p);
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 +4131,34 @@ 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::registerHexContextMenu(IWingHexEditorInterface *inter) {
Q_ASSERT(inter);
auto menu = inter->registeredHexContextMenu();
if (menu) {
_win->m_hexContextMenu.append(menu);
connect(menu, &QMenu::aboutToShow, this, [menu, inter]() {
auto pp = menu->property("__CONTEXT__");
auto ptr =
reinterpret_cast<HexEditorContext *>(pp.value<quintptr>());
if (ptr) {
inter->prepareCallEditorContext(ptr);
}
});
connect(menu, &QMenu::triggered, this, [menu, inter]() {
auto pp = menu->property("__CONTEXT__");
auto ptr =
reinterpret_cast<HexEditorContext *>(pp.value<quintptr>());
if (ptr) {
inter->finishCallEditorContext(ptr);
}
});
}
}
void PluginSystem::applyFunctionTables(QObject *plg, const CallTable &fns) {
@ -4024,13 +4236,7 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
// ensure call only once
registerRibbonTools(p->registeredRibbonTools());
registerPluginDockWidgets(p);
{
auto menu = p->registeredHexContextMenu();
if (menu) {
_win->m_hexContextMenu.append(menu);
}
}
registerHexContextMenu(p);
{
auto vieww = p->registeredEditorViewWidgets();
@ -4292,12 +4498,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,13 +4573,14 @@ void PluginSystem::loadAllPlugin() {
Logger::newLine();
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);
auto disdrv =
qEnvironmentVariableIntValue("WING_DISABLE_EXTDRV", &ok);
if (ok && disdrv != 0) {
enabledrv = false;
}
@ -4373,7 +4589,8 @@ void PluginSystem::loadAllPlugin() {
loadDevicePlugin();
}
auto displg = qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN", &ok);
auto displg =
qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN", &ok);
if ((ok && displg != 0) || !set.enablePlugin()) {
enableplg = false;
}
@ -4388,9 +4605,9 @@ void PluginSystem::loadAllPlugin() {
loadExtPlugin();
}
}
Logger::newLine();
}
}
void PluginSystem::destory() {
QDir udir(Utilities::getAppDataPath());
@ -4423,6 +4640,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);
@ -221,6 +224,8 @@ private:
private:
void registerEvents(IWingPlugin *plg);
void registerHexContextMenu(IWingHexEditorInterface *inter);
void applyFunctionTables(QObject *plg, const CallTable &fns);
bool isPluginLoaded(const WingDependency &d);
@ -259,12 +264,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 +767,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,39 +242,41 @@ ScriptManager::buildUpScriptRunnerContext(RibbonButtonGroup *group,
}
auto meta = sm.sysDirMeta(cat);
addPannelAction(
group, ICONRES(QStringLiteral("scriptfolder")), meta.name,
buildUpScriptDirMenu(group, sm.getSysScriptFileNames(cat), true));
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, sm.getSysScriptFileNames(cat),
true);
auto m = buildUpScriptDirMenu(parent, files, true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolder")));
maps << m;
}
}
}
hideCats = stm.usrHideCats();
for (auto &cat : sm.usrScriptsDbCats()) {
if (hideCats.contains(cat)) {
continue;
}
auto meta = sm.usrDirMeta(cat);
addPannelAction(
group, ICONRES(QStringLiteral("scriptfolderusr")), meta.name,
buildUpScriptDirMenu(group, sm.getUsrScriptFileNames(cat), false));
auto meta = sm.usrDirMeta(cat);
auto files = sm.getUsrScriptFileNames(cat);
if (!files.isEmpty()) {
addPannelAction(group, ICONRES(QStringLiteral("scriptfolderusr")),
meta.name,
buildUpScriptDirMenu(group, files, false));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, sm.getSysScriptFileNames(cat),
true);
auto m = buildUpScriptDirMenu(parent, files, true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolderusr")));
maps << m;
}
}
}
return maps;
}

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

@ -239,8 +239,10 @@ WingAngel::registerGlobalFunction(uint retMetaType, const ScriptFn &fn,
const QVector<QPair<uint, QString>> &params) {
auto sig = getScriptFnSig(retMetaType, fn, fnName, params);
if (sig.isEmpty()) {
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
QStringLiteral("::") + fnName);
Logger::critical(QStringLiteral("[WingAngel::registerGlobalFunction] "
"getScriptFnSig failed (") +
_plgsess + QStringLiteral("::") + fnName +
QStringLiteral(")"));
return WingHex::asRetCodes::asINVALID_ARG;
}
@ -250,8 +252,13 @@ WingAngel::registerGlobalFunction(uint retMetaType, const ScriptFn &fn,
sig.toUtf8(), asFUNCTION(WingAngelAPI::script_call),
asECallConvTypes::asCALL_GENERIC);
auto minfo = QMetaEnum::fromType<WingHex::asRetCodes>();
if (ret < 0) {
// TODO
Logger::critical(
QStringLiteral("[WingAngel::registerGlobalFunction] "
"RegisterGlobalFunction '%1' failed (%2)")
.arg(sig, minfo.valueToKey(ret)));
return returnValue(ret);
}
@ -264,6 +271,9 @@ WingAngel::registerGlobalFunction(uint retMetaType, const ScriptFn &fn,
f->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
} else {
Logger::critical(QStringLiteral("[WingAngel::registerGlobalFunction] "
"'%1' GetFunctionById failed")
.arg(sig));
return WingHex::asRetCodes::asINVALID_ARG;
}
@ -281,8 +291,8 @@ WingHex::asRetCodes
WingAngel::registerGlobalFunction(const QString &decl,
const WingHex::UNSAFE_SCFNPTR &fn) {
if (decl.isEmpty()) {
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
QStringLiteral("::") + decl);
Logger::critical(QStringLiteral(
"[WingAngel::registerGlobalFunction] Empty declaration"));
return WingHex::asRetCodes::asINVALID_ARG;
}
@ -292,8 +302,12 @@ WingAngel::registerGlobalFunction(const QString &decl,
decl.toUtf8(), asFUNCTION(WingAngelAPI::script_unsafe_call),
asECallConvTypes::asCALL_GENERIC);
auto minfo = QMetaEnum::fromType<WingHex::asRetCodes>();
if (ret < 0) {
// TODO
Logger::critical(
QStringLiteral("[WingAngel::registerGlobalFunction] "
"RegisterGlobalFunction '%1' failed (%2)")
.arg(decl, minfo.valueToKey(ret)));
return returnValue(ret);
}
@ -306,6 +320,9 @@ WingAngel::registerGlobalFunction(const QString &decl,
f->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
} else {
Logger::critical(QStringLiteral("[WingAngel::registerGlobalFunction] "
"'%1' GetFunctionById failed")
.arg(decl));
return WingHex::asRetCodes::asINVALID_ARG;
}
@ -319,8 +336,8 @@ void WingAngel::registerScriptMarco(const QString &marco) {
static auto sep = QStringLiteral("_");
_scriptMarcos.append(sep + _plgsess + sep + marco + sep);
} else {
// TODO
Logger::critical(QStringLiteral(
"[WingAngel::registerScriptMarco] isValidIdentifier failed"));
}
}

View File

@ -1061,12 +1061,10 @@ QStringList WingAngelAPI::cArray2QStringList(const CScriptArray &array,
QStringList buffer;
buffer.reserve(array.GetSize());
array.AddRef();
for (asUINT i = 0; i < array.GetSize(); ++i) {
auto item = reinterpret_cast<const QString *>(array.At(i));
buffer.append(*item);
}
array.Release();
return buffer;
}
@ -1217,9 +1215,10 @@ void WingAngelAPI::qvariantCastOp(
assignTmpBuffer(buffer, var.toULongLong());
fn(&buffer, type);
break;
case QMetaType::QChar:
fn(new QChar(var.toChar()), type);
break;
case QMetaType::QChar: {
auto obj = var.toChar();
fn(&obj, type);
} break;
case QMetaType::Float:
assignTmpBuffer(buffer, var.toULongLong());
fn(&buffer, type);
@ -1229,21 +1228,24 @@ void WingAngelAPI::qvariantCastOp(
fn(&buffer, type);
break;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case QMetaType::Char16:
fn(new QChar(var.value<char16_t>()), type);
break;
case QMetaType::Char32:
fn(new QChar(var.value<char32_t>()), type);
break;
case QMetaType::Char16: {
auto obj = QChar(var.value<char16_t>());
fn(&obj, type);
} break;
case QMetaType::Char32: {
auto obj = QChar(var.value<char32_t>());
fn(&obj, type);
} break;
#endif
case QMetaType::UChar:
case QMetaType::SChar:
case QMetaType::Char:
assignTmpBuffer(buffer, var.value<uchar>());
break;
case QMetaType::QString:
fn(new QString(var.toString()), type);
break;
case QMetaType::QString: {
auto obj = var.toString();
fn(&obj, type);
} break;
case QMetaType::QByteArray: {
auto value = var.toByteArray();
auto info = engine->GetTypeInfoByDecl("array<byte>");
@ -1298,9 +1300,10 @@ void WingAngelAPI::qvariantCastOp(
fn(arr, type);
arr->Release();
} break;
case QMetaType::QColor:
fn(new QColor(var.value<QColor>()), type);
break;
case QMetaType::QColor: {
auto obj = var.value<QColor>();
fn(&obj, type);
} break;
case QMetaType::Void:
break;
default:
@ -2000,7 +2003,9 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
if (info) {
auto len = content.length();
auto arr = CScriptArray::Create(info, len);
std::memcpy(arr->GetBuffer(), content.data(), len);
for (int i = 0; i < len; ++i) {
arr->SetValue(i, content.at(i));
}
return arr;
}
return nullptr;
@ -2009,37 +2014,8 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
WingHex::MetaType type,
const QList<void *> &content) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
static_assert(std::is_same_v<QList<int>, QVector<int>>);
return vector2AsArray(sender, type, content);
#else
Q_UNUSED(sender);
auto typeStr = type2AngelScriptString(MetaType(type | MetaType::Meta_Array),
false, true);
if (typeStr.isEmpty()) {
return nullptr;
}
auto engine = ScriptMachine::instance().engine();
auto info = engine->GetTypeInfoByDecl(typeStr.toUtf8());
if (info) {
auto len = content.length();
auto arr = CScriptArray::Create(info, len);
for (decltype(len) i = 0; i < len; ++i) {
arr->SetValue(i, content.at(i));
}
return arr;
}
return nullptr;
#endif
}
void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender,
void *array) {
Q_UNUSED(sender);
if (array) {
reinterpret_cast<CScriptArray *>(array)->Release();
}
}
void *WingAngelAPI::newAsDictionary(
@ -2063,14 +2039,6 @@ void *WingAngelAPI::newAsDictionary(
return dic;
}
void WingAngelAPI::deleteAsDictionary(const WingHex::SenderInfo &sender,
void *dic) {
Q_UNUSED(sender);
if (dic) {
reinterpret_cast<CScriptDictionary *>(dic)->Release();
}
}
void WingAngelAPI::cleanUpHandles(const QVector<int> &handles) {
for (auto &h : _handles) {
if (!handles.contains(h)) {

View File

@ -175,14 +175,10 @@ private:
WING_SERVICE void *list2AsArray(const WingHex::SenderInfo &sender,
WingHex::MetaType type,
const QList<void *> &content);
WING_SERVICE void deleteAsArray(const WingHex::SenderInfo &sender,
void *array);
WING_SERVICE void *newAsDictionary(
const WingHex::SenderInfo &sender,
const QHash<QString, QPair<WingHex::MetaType, void *>> &content);
WING_SERVICE void deleteAsDictionary(const WingHex::SenderInfo &sender,
void *dic);
// =========================================================

File diff suppressed because it is too large Load Diff

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"
@ -216,6 +217,8 @@ public:
void applySettings();
EditorViewContext *editorContext() const;
private:
inline qsizetype findAvailCloneIndex();
@ -235,260 +238,278 @@ private:
bool checkThreadAff();
private slots:
WING_API bool existsServiceHost(QObject *caller, const QString &puid);
WING_API bool existsServiceHost(const QObject *caller, const QString &puid);
WING_API bool invokeServiceImpl(const QObject *sender, const QString &puid,
const WingHex::MetaCallInfo &infos);
private slots:
WING_API QString currentDocFilename(QObject *caller);
WING_API QString currentDocFilename(const QObject *caller);
// document
WING_API bool isReadOnly(QObject *caller);
WING_API bool isInsertionMode(QObject *caller);
WING_API bool isKeepSize(QObject *caller);
WING_API bool isLocked(QObject *caller);
WING_API qsizetype documentLines(QObject *caller);
WING_API qsizetype documentBytes(QObject *caller);
WING_API WingHex::HexPosition currentPos(QObject *caller);
WING_API qsizetype currentRow(QObject *caller);
WING_API qsizetype currentColumn(QObject *caller);
WING_API qsizetype currentOffset(QObject *caller);
WING_API qsizetype selectedLength(QObject *caller);
WING_API bool isReadOnly(const QObject *caller);
WING_API bool isInsertionMode(const QObject *caller);
WING_API bool isKeepSize(const QObject *caller);
WING_API bool isLocked(const QObject *caller);
WING_API qsizetype documentLines(const QObject *caller);
WING_API qsizetype documentBytes(const QObject *caller);
WING_API WingHex::HexPosition currentPos(const QObject *caller);
WING_API qsizetype currentRow(const QObject *caller);
WING_API qsizetype currentColumn(const QObject *caller);
WING_API qsizetype currentOffset(const QObject *caller);
WING_API qsizetype selectedLength(const QObject *caller);
WING_API QByteArray selectedBytes(QObject *caller, qsizetype index);
WING_API QByteArrayList selectionBytes(QObject *caller);
WING_API QByteArray selectedBytes(const QObject *caller, qsizetype index);
WING_API QByteArrayList selectionBytes(const QObject *caller);
WING_API WingHex::HexPosition selectionStart(QObject *caller,
WING_API WingHex::HexPosition selectionStart(const QObject *caller,
qsizetype index);
WING_API WingHex::HexPosition selectionEnd(QObject *caller,
WING_API WingHex::HexPosition selectionEnd(const QObject *caller,
qsizetype index);
WING_API qsizetype selectionLength(QObject *caller, qsizetype index);
WING_API qsizetype selectionCount(QObject *caller);
WING_API qsizetype selectionLength(const QObject *caller, qsizetype index);
WING_API qsizetype selectionCount(const QObject *caller);
WING_API bool stringVisible(QObject *caller);
WING_API bool addressVisible(QObject *caller);
WING_API bool headerVisible(QObject *caller);
WING_API quintptr addressBase(QObject *caller);
WING_API bool isModified(QObject *caller);
WING_API bool stringVisible(const QObject *caller);
WING_API bool addressVisible(const QObject *caller);
WING_API bool headerVisible(const QObject *caller);
WING_API quintptr addressBase(const QObject *caller);
WING_API bool isModified(const QObject *caller);
WING_API qint8 readInt8(QObject *caller, qsizetype offset);
WING_API qint16 readInt16(QObject *caller, qsizetype offset);
WING_API qint32 readInt32(QObject *caller, qsizetype offset);
WING_API qint64 readInt64(QObject *caller, qsizetype offset);
WING_API quint8 readUInt8(QObject *caller, qsizetype offset);
WING_API quint16 readUInt16(QObject *caller, qsizetype offset);
WING_API quint32 readUInt32(QObject *caller, qsizetype offset);
WING_API quint64 readUInt64(QObject *caller, qsizetype offset);
WING_API float readFloat(QObject *caller, qsizetype offset);
WING_API double readDouble(QObject *caller, qsizetype offset);
WING_API QString readString(QObject *caller, qsizetype offset,
WING_API qint8 readInt8(const QObject *caller, qsizetype offset);
WING_API qint16 readInt16(const QObject *caller, qsizetype offset);
WING_API qint32 readInt32(const QObject *caller, qsizetype offset);
WING_API qint64 readInt64(const QObject *caller, qsizetype offset);
WING_API quint8 readUInt8(const QObject *caller, qsizetype offset);
WING_API quint16 readUInt16(const QObject *caller, qsizetype offset);
WING_API quint32 readUInt32(const QObject *caller, qsizetype offset);
WING_API quint64 readUInt64(const QObject *caller, qsizetype offset);
WING_API float readFloat(const QObject *caller, qsizetype offset);
WING_API double readDouble(const QObject *caller, qsizetype offset);
WING_API QString readString(const QObject *caller, qsizetype offset,
const QString &encoding);
WING_API QByteArray readBytes(QObject *caller, qsizetype offset,
WING_API QByteArray readBytes(const QObject *caller, qsizetype offset,
qsizetype count);
WING_API qsizetype findNext(QObject *caller, qsizetype begin,
WING_API qsizetype findNext(const QObject *caller, qsizetype begin,
const QByteArray &ba);
WING_API qsizetype findPrevious(QObject *caller, qsizetype begin,
WING_API qsizetype findPrevious(const QObject *caller, qsizetype begin,
const QByteArray &ba);
WING_API QString bookMarkComment(QObject *caller, qsizetype pos);
WING_API bool existBookMark(QObject *caller, qsizetype pos);
WING_API QString bookMarkComment(const QObject *caller, qsizetype pos);
WING_API bool existBookMark(const QObject *caller, qsizetype pos);
WING_API bool setLockedFile(QObject *caller, bool b);
WING_API bool setKeepSize(QObject *caller, bool b);
WING_API bool setStringVisible(QObject *caller, bool b);
WING_API bool setAddressVisible(QObject *caller, bool b);
WING_API bool setHeaderVisible(QObject *caller, bool b);
WING_API bool setAddressBase(QObject *caller, quintptr base);
WING_API bool setLockedFile(const QObject *caller, bool b);
WING_API bool setKeepSize(const QObject *caller, bool b);
WING_API bool setStringVisible(const QObject *caller, bool b);
WING_API bool setAddressVisible(const QObject *caller, bool b);
WING_API bool setHeaderVisible(const QObject *caller, bool b);
WING_API bool setAddressBase(const QObject *caller, quintptr base);
WING_API bool beginMarco(QObject *caller, const QString &txt);
bool endMarco(QObject *caller);
WING_API bool beginMarco(const QObject *caller, const QString &txt);
bool endMarco(const QObject *caller);
WING_API bool writeInt8(QObject *caller, qsizetype offset, qint8 value);
WING_API bool writeInt16(QObject *caller, qsizetype offset, qint16 value);
WING_API bool writeInt32(QObject *caller, qsizetype offset, qint32 value);
WING_API bool writeInt64(QObject *caller, qsizetype offset, qint64 value);
WING_API bool writeUInt8(QObject *caller, qsizetype offset, quint8 value);
WING_API bool writeUInt16(QObject *caller, qsizetype offset, quint16 value);
WING_API bool writeUInt32(QObject *caller, qsizetype offset, quint32 value);
WING_API bool writeUInt64(QObject *caller, qsizetype offset, quint64 value);
WING_API bool writeFloat(QObject *caller, qsizetype offset, float value);
WING_API bool writeDouble(QObject *caller, qsizetype offset, double value);
WING_API
bool writeString(QObject *caller, qsizetype offset, const QString &value,
const QString &encoding);
WING_API bool writeBytes(QObject *caller, qsizetype offset,
const QByteArray &data);
WING_API bool insertInt8(QObject *caller, qsizetype offset, qint8 value);
WING_API bool insertInt16(QObject *caller, qsizetype offset, qint16 value);
WING_API bool insertInt32(QObject *caller, qsizetype offset, qint32 value);
WING_API bool insertInt64(QObject *caller, qsizetype offset, qint64 value);
WING_API bool insertUInt8(QObject *caller, qsizetype offset, quint8 value);
WING_API
bool insertUInt16(QObject *caller, qsizetype offset, quint16 value);
WING_API
bool insertUInt32(QObject *caller, qsizetype offset, quint32 value);
WING_API bool insertUInt64(QObject *caller, qsizetype offset,
WING_API bool writeInt8(const QObject *caller, qsizetype offset,
qint8 value);
WING_API bool writeInt16(const QObject *caller, qsizetype offset,
qint16 value);
WING_API bool writeInt32(const QObject *caller, qsizetype offset,
qint32 value);
WING_API bool writeInt64(const QObject *caller, qsizetype offset,
qint64 value);
WING_API bool writeUInt8(const QObject *caller, qsizetype offset,
quint8 value);
WING_API bool writeUInt16(const QObject *caller, qsizetype offset,
quint16 value);
WING_API bool writeUInt32(const QObject *caller, qsizetype offset,
quint32 value);
WING_API bool writeUInt64(const QObject *caller, qsizetype offset,
quint64 value);
WING_API bool insertFloat(QObject *caller, qsizetype offset, float value);
WING_API bool insertDouble(QObject *caller, qsizetype offset, double value);
WING_API bool insertString(QObject *caller, qsizetype offset,
WING_API bool writeFloat(const QObject *caller, qsizetype offset,
float value);
WING_API bool writeDouble(const QObject *caller, qsizetype offset,
double value);
WING_API
bool writeString(const QObject *caller, qsizetype offset,
const QString &value, const QString &encoding);
WING_API bool insertBytes(QObject *caller, qsizetype offset,
WING_API bool writeBytes(const QObject *caller, qsizetype offset,
const QByteArray &data);
WING_API bool appendInt8(QObject *caller, qint8 value);
WING_API bool appendInt16(QObject *caller, qint16 value);
WING_API bool appendInt32(QObject *caller, qint32 value);
WING_API bool appendInt64(QObject *caller, qint64 value);
WING_API bool appendUInt8(QObject *caller, quint8 value);
WING_API bool appendUInt16(QObject *caller, quint16 value);
WING_API bool appendUInt32(QObject *caller, quint32 value);
WING_API bool appendUInt64(QObject *caller, quint64 value);
WING_API bool appendFloat(QObject *caller, float value);
WING_API bool appendDouble(QObject *caller, double value);
WING_API bool appendString(QObject *caller, const QString &value,
const QString &encoding);
WING_API bool appendBytes(QObject *caller, const QByteArray &data);
WING_API bool insertInt8(const QObject *caller, qsizetype offset,
qint8 value);
WING_API bool insertInt16(const QObject *caller, qsizetype offset,
qint16 value);
WING_API bool insertInt32(const QObject *caller, qsizetype offset,
qint32 value);
WING_API bool insertInt64(const QObject *caller, qsizetype offset,
qint64 value);
WING_API bool insertUInt8(const QObject *caller, qsizetype offset,
quint8 value);
WING_API
bool insertUInt16(const QObject *caller, qsizetype offset, quint16 value);
WING_API
bool insertUInt32(const QObject *caller, qsizetype offset, quint32 value);
WING_API bool insertUInt64(const QObject *caller, qsizetype offset,
quint64 value);
WING_API bool insertFloat(const QObject *caller, qsizetype offset,
float value);
WING_API bool insertDouble(const QObject *caller, qsizetype offset,
double value);
WING_API bool insertString(const QObject *caller, qsizetype offset,
const QString &value, const QString &encoding);
WING_API bool insertBytes(const QObject *caller, qsizetype offset,
const QByteArray &data);
WING_API bool removeBytes(QObject *caller, qsizetype offset, qsizetype len);
WING_API bool appendInt8(const QObject *caller, qint8 value);
WING_API bool appendInt16(const QObject *caller, qint16 value);
WING_API bool appendInt32(const QObject *caller, qint32 value);
WING_API bool appendInt64(const QObject *caller, qint64 value);
WING_API bool appendUInt8(const QObject *caller, quint8 value);
WING_API bool appendUInt16(const QObject *caller, quint16 value);
WING_API bool appendUInt32(const QObject *caller, quint32 value);
WING_API bool appendUInt64(const QObject *caller, quint64 value);
WING_API bool appendFloat(const QObject *caller, float value);
WING_API bool appendDouble(const QObject *caller, double value);
WING_API bool appendString(const QObject *caller, const QString &value,
const QString &encoding);
WING_API bool appendBytes(const QObject *caller, const QByteArray &data);
WING_API bool removeBytes(const QObject *caller, qsizetype offset,
qsizetype len);
// cursor
WING_API bool moveTo(QObject *caller, qsizetype line, qsizetype column,
int nibbleindex, bool clearSelection);
WING_API bool moveTo(QObject *caller, qsizetype offset,
WING_API bool moveTo(const QObject *caller, qsizetype line,
qsizetype column, int nibbleindex,
bool clearSelection);
WING_API bool select(QObject *caller, qsizetype offset, qsizetype length,
WingHex::SelectionMode mode);
WING_API bool setInsertionMode(QObject *caller, bool isinsert);
WING_API bool moveTo(const QObject *caller, qsizetype offset,
bool clearSelection);
WING_API bool select(const QObject *caller, qsizetype offset,
qsizetype length, WingHex::SelectionMode mode);
WING_API bool setInsertionMode(const QObject *caller, bool isinsert);
// metadata
WING_API bool metadata(QObject *caller, qsizetype begin, qsizetype length,
const QColor &fgcolor, const QColor &bgcolor,
const QString &comment);
WING_API bool metadata(const QObject *caller, qsizetype begin,
qsizetype length, const QColor &fgcolor,
const QColor &bgcolor, const QString &comment);
WING_API bool removeMetadata(QObject *caller, qsizetype offset);
WING_API bool clearMetadata(QObject *caller);
WING_API bool setMetaVisible(QObject *caller, bool b);
WING_API bool setMetafgVisible(QObject *caller, bool b);
WING_API bool setMetabgVisible(QObject *caller, bool b);
WING_API bool setMetaCommentVisible(QObject *caller, bool b);
WING_API bool removeMetadata(const QObject *caller, qsizetype offset);
WING_API bool clearMetadata(const QObject *caller);
WING_API bool setMetaVisible(const QObject *caller, bool b);
WING_API bool setMetafgVisible(const QObject *caller, bool b);
WING_API bool setMetabgVisible(const QObject *caller, bool b);
WING_API bool setMetaCommentVisible(const QObject *caller, bool b);
// bookmark
WING_API bool addBookMark(QObject *caller, qsizetype pos,
WING_API bool addBookMark(const QObject *caller, qsizetype pos,
const QString &comment);
WING_API bool modBookMark(QObject *caller, qsizetype pos,
WING_API bool modBookMark(const QObject *caller, qsizetype pos,
const QString &comment);
WING_API bool removeBookMark(QObject *caller, qsizetype pos);
WING_API bool clearBookMark(QObject *caller);
WING_API bool removeBookMark(const QObject *caller, qsizetype pos);
WING_API bool clearBookMark(const QObject *caller);
private slots:
WING_API void toast(QObject *caller, const QPixmap &icon,
WING_API void toast(const QObject *caller, const QPixmap &icon,
const QString &message);
WING_API void logTrace(QObject *caller, const QString &message);
WING_API void logDebug(QObject *caller, const QString &message);
WING_API void logWarn(QObject *caller, const QString &message);
WING_API void logError(QObject *caller, const QString &message);
WING_API void logInfo(QObject *caller, const QString &message);
WING_API void logTrace(const QObject *caller, const QString &message);
WING_API void logDebug(const QObject *caller, const QString &message);
WING_API void logWarn(const QObject *caller, const QString &message);
WING_API void logError(const QObject *caller, const QString &message);
WING_API void logInfo(const QObject *caller, const QString &message);
WING_API bool raiseDockWidget(QObject *caller, QWidget *w);
WING_API bool raiseDockWidget(const QObject *caller, QWidget *w);
// theme
WING_API WingHex::AppTheme currentAppTheme(QObject *caller);
WING_API WingHex::AppTheme currentAppTheme(const QObject *caller);
// not available for AngelScript
// only for plugin UI extenstion
WING_API QDialog *createDialog(QObject *caller, QWidget *content);
WING_API QDialog *createDialog(const QObject *caller, QWidget *content);
private slots:
WING_API void msgAboutQt(QObject *caller, QWidget *parent = nullptr,
WING_API void msgAboutQt(const QObject *caller, QWidget *parent = nullptr,
const QString &title = QString());
WING_API QMessageBox::StandardButton msgInformation(
QObject *caller, QWidget *parent, const QString &title,
const QObject *caller, QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
WING_API QMessageBox::StandardButton msgQuestion(
QObject *caller, QWidget *parent, const QString &title,
const QObject *caller, QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons =
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
WING_API QMessageBox::StandardButton msgWarning(
QObject *caller, QWidget *parent, const QString &title,
const QObject *caller, QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
WING_API QMessageBox::StandardButton msgCritical(
QObject *caller, QWidget *parent, const QString &title,
const QObject *caller, QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
WING_API void msgAbout(QObject *caller, QWidget *parent,
WING_API void msgAbout(const QObject *caller, QWidget *parent,
const QString &title, const QString &text);
WING_API QMessageBox::StandardButton
msgbox(QObject *caller, QWidget *parent, QMessageBox::Icon icon,
msgbox(const QObject *caller, QWidget *parent, QMessageBox::Icon icon,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
private slots:
WING_API QString dlgGetText(QObject *caller, QWidget *parent,
WING_API QString dlgGetText(const QObject *caller, QWidget *parent,
const QString &title, const QString &label,
QLineEdit::EchoMode echo, const QString &text,
bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_API QString dlgGetMultiLineText(QObject *caller, QWidget *parent,
WING_API QString dlgGetMultiLineText(const QObject *caller, QWidget *parent,
const QString &title,
const QString &label,
const QString &text, bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_API QString dlgGetItem(QObject *caller, QWidget *parent,
WING_API QString dlgGetItem(const QObject *caller, QWidget *parent,
const QString &title, const QString &label,
const QStringList &items, int current,
bool editable, bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_API int dlgGetInt(QObject *caller, QWidget *parent,
WING_API int dlgGetInt(const QObject *caller, QWidget *parent,
const QString &title, const QString &label,
int value, int minValue, int maxValue, int step,
bool *ok);
WING_API double dlgGetDouble(QObject *caller, QWidget *parent,
WING_API double dlgGetDouble(const QObject *caller, QWidget *parent,
const QString &title, const QString &label,
double value, double minValue, double maxValue,
int decimals, bool *ok, double step);
private slots:
WING_API QString dlgGetExistingDirectory(QObject *caller, QWidget *parent,
WING_API QString dlgGetExistingDirectory(const QObject *caller,
QWidget *parent,
const QString &caption,
const QString &dir,
QFileDialog::Options options);
WING_API QString dlgGetOpenFileName(QObject *caller, QWidget *parent,
WING_API QString dlgGetOpenFileName(const QObject *caller, QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
QString *selectedFilter,
QFileDialog::Options options);
WING_API QStringList dlgGetOpenFileNames(QObject *caller, QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
QString *selectedFilter,
WING_API QStringList dlgGetOpenFileNames(
const QObject *caller, QWidget *parent, const QString &caption,
const QString &dir, const QString &filter, QString *selectedFilter,
QFileDialog::Options options);
WING_API QString dlgGetSaveFileName(QObject *caller, QWidget *parent,
WING_API QString dlgGetSaveFileName(const QObject *caller, QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
@ -496,7 +517,7 @@ private slots:
QFileDialog::Options options);
private slots:
WING_API QColor dlgGetColor(QObject *caller, const QString &caption,
WING_API QColor dlgGetColor(const QObject *caller, const QString &caption,
QWidget *parent);
private:
@ -543,6 +564,7 @@ private:
QStackedWidget *m_stack = nullptr;
GotoWidget *m_goto = nullptr;
QWidget *m_hexContainer = nullptr;
EditorViewContext *_context = nullptr;
bool _hasRegistered = false;
quintptr _oldbase = 0;
@ -550,7 +572,6 @@ private:
QMenu *m_menu = nullptr;
QHash<QString, WingEditorViewWidget *> m_others;
QString m_fileName;
bool m_isNewFile = true;
QByteArray m_md5;

View File

@ -6,7 +6,8 @@ enum class CrashCode : int {
LanguageFile,
PluginSetting,
ScriptInitFailed,
GenericCallNotSupported
GenericCallNotSupported,
OutofMemory
};
namespace AsUserDataType {

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);
@ -462,6 +465,9 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
swapEditor(m_curEditor, editview);
_editorLock.unlock();
} else {
for (auto &menu : m_hexContextMenu) {
menu->setProperty("__CONTEXT__", {});
}
m_findresult->setModel(_findEmptyResult);
m_bookmarks->setModel(_bookMarkEmpty);
m_metadatas->setModel(_metadataEmpty);
@ -1080,10 +1086,13 @@ ads::CDockAreaWidget *
MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw) {
m_bgScriptOutput = new QPlainTextEdit(this);
m_bgScriptOutput->setPlaceholderText(tr("BgScriptOutputHere"));
m_bgScriptOutput->setReadOnly(true);
_hlAnim = new ConsoleHighlighAnim(m_bgScriptOutput);
auto a = newAction(
ICONRES(QStringLiteral("mStr")), tr("SelectAll"),
[this]() { m_bgScriptOutput->selectAll(); }, QKeySequence::SelectAll);
@ -1113,6 +1122,13 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
auto dw = buildDockWidget(dock, QStringLiteral("BgScriptOutput"),
tr("BgScriptOutput"), m_bgScriptOutput);
_hlAnim->setWidget(dw->tabWidget());
auto e = new EventFilter(QEvent::Show, dw);
connect(e, &EventFilter::eventTriggered, this,
[this]() { _hlAnim->stop(); });
m_bgScriptOutput->installEventFilter(e);
return dock->addDockWidget(area, dw, areaw);
}
@ -3330,7 +3346,6 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
doc->disconnect(m_aShowMetaComment);
}
Q_ASSERT(cur);
auto hexeditor = cur->hexEditor();
auto needReload = cur->property("__RELOAD__").toBool();
if (needReload) {
@ -3431,6 +3446,10 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
m_metadatas->selectionModel()->hasSelection());
});
for (auto &menu : m_hexContextMenu) {
menu->setProperty("__CONTEXT__", quintptr(cur->editorContext()));
}
_undoView->setStack(doc->undoStack());
m_curEditor = cur;
@ -3956,6 +3975,10 @@ void MainWindow::onOutputBgScriptOutput(
lastInfo.first = message.type;
lastInfo.second = qMakePair(message.row, message.col);
if (!m_bgScriptOutput->isVisible()) {
_hlAnim->start();
}
}
void MainWindow::closeEvent(QCloseEvent *event) {

View File

@ -44,6 +44,7 @@
#include "Qt-Advanced-Docking-System/src/DockManager.h"
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingplugin.h"
#include "class/consolehighlighanim.h"
#include "class/recentfilemanager.h"
#include "control/editorview.h"
#include "control/qtableviewext.h"
@ -479,6 +480,8 @@ private:
ScriptingConsole *m_scriptConsole = nullptr;
QPlainTextEdit *m_bgScriptOutput = nullptr;
ConsoleHighlighAnim *_hlAnim = nullptr;
bool m_isfinding = false;
ads::CDockWidget *m_find = nullptr;
QMenu *m_menuFind = nullptr;

View File

@ -74,7 +74,7 @@ SettingDialog::SettingDialog(QWidget *parent)
ui->btnRestore->setStyleSheet(
QStringLiteral("QToolButton::down-arrow {width:10px; height:10px; "
"subcontrol-position:right center; "
"subcontrol-origin:content; left: -2px;"));
"subcontrol-origin:content; left: -2px;}"));
auto menu = new QMenu(ui->btnRestore);
auto a = menu->addAction(tr("Restore current"));
connect(a, &QAction::triggered, this, [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(" : ");
QString mcomment;
auto mp = plgsys.monitorManager();
if (mp) {
mcomment = mp->comment();
}
loadPluginInfo(minfo, {}, mcomment, {}, ui->txtm);
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"));
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,8 +210,7 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->btnplgSave->setEnabled(_plgChanged.containChanges());
});
connect(
ui->plglist, &QListWidget::currentItemChanged, this,
connect(ui->plglist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
@ -210,30 +220,8 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
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()));
}
}
ui->txtc->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + info.url +
QStringLiteral("\">") + info.url + QStringLiteral("</a> ")));
loadPluginInfo(info, plgName, plgComment, info.dependencies,
ui->txtc);
});
connect(ui->devlist, &QListWidget::itemChanged, this,
@ -256,8 +244,7 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
ui->btndevSave->setEnabled(_devChanged.containChanges());
});
connect(
ui->devlist, &QListWidget::currentItemChanged, this,
connect(ui->devlist, &QListWidget::currentItemChanged, this,
[this](QListWidgetItem *current, QListWidgetItem *) {
if (current == nullptr) {
return;
@ -267,20 +254,8 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
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]() {
@ -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

@ -2741,12 +2741,12 @@ ads--CDockWidgetTab[activeTab="true"]
ads--CDockWidgetTab QLabel
{
background-color: #1b1d20;
background-color: transparent;
}
ads--CDockWidgetTab[activeTab="true"] QLabel
ads--CDockWidgetTab[activeTab="false"]:hover
{
background-color: #202326;
background-color: rgba(61, 173, 232, 0.1);
}
ads--CDockContainerWidget > QSplitter{
@ -2956,6 +2956,7 @@ QHexView
qproperty-selBackgroundColor: #3daee9;
qproperty-headerColor: #07DBD7;
qproperty-addressColor: #07DBD7;
qproperty-borderColor: #eff0f1;
}
Toast

View File

@ -2741,12 +2741,12 @@ ads--CDockWidgetTab[activeTab="true"]
ads--CDockWidgetTab QLabel
{
background-color: #d9d8d7;
background-color: transparent;
}
ads--CDockWidgetTab[activeTab="true"] QLabel
ads--CDockWidgetTab[activeTab="false"]:hover
{
background-color: #eff0f1;
background-color: rgba(61, 173, 232, 0.2);
}
ads--CDockContainerWidget > QSplitter{
@ -2960,6 +2960,7 @@ QHexView
qproperty-selBackgroundColor: rgba(51, 164, 223, 0.5);
qproperty-headerColor: #07DBD7;
qproperty-addressColor: #07DBD7;
qproperty-borderColor: #31363b;
}
Toast