From b49523e9522d5c731f19d38aafceefca7b3a0bc8 Mon Sep 17 00:00:00 2001 From: wingsummer <1326224942@qq.com> Date: Tue, 6 May 2025 13:44:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E9=A2=84=E5=A4=84=E7=90=86=E5=99=A8=E5=92=8C=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=E7=9A=84=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 +- lang/zh_CN/winghex_zh_CN.ts | 59 ++++++++++++++-------------- lang/zh_TW/winghex_zh_TW.ts | 59 ++++++++++++++-------------- src/class/aspreprocesser.cpp | 33 +++++++--------- src/class/scriptmachine.cpp | 65 ++++++++++++++++++++++++++++++- src/class/scriptmachine.h | 6 +++ src/scriptaddon/scriptqstring.cpp | 54 +++++++++++++++++++++++-- 7 files changed, 194 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee81fd5..4f7785e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(PROJECT_VERSION "2.2.2") +set(PROJECT_VERSION "2.2.3") find_package( QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network Concurrent @@ -40,7 +40,6 @@ add_definitions(-DWINGHEX_VERSION="${PROJECT_VERSION}" file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WINGHEX_VERSION" ${PROJECT_VERSION}) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/QT_VERSION" ${QT_VERSION_MAJOR}) - if(WIN32) find_package(QT NAMES Qt6 Qt5 REQUIRED AxContainer) find_package(Qt${QT_VERSION_MAJOR} REQUIRED AxContainer) diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts index ad92098..ddfa19d 100644 --- a/lang/zh_CN/winghex_zh_CN.ts +++ b/lang/zh_CN/winghex_zh_CN.ts @@ -2678,13 +2678,13 @@ 关闭标签 - + Failed to open script file 打开脚本文件失败 - - + + Invalid file name for #include; it contains a line-break: #include 的文件名无效;它包含换行符: @@ -2699,55 +2699,54 @@ ifdef 非法宏 - - - - - - - + + + + + + UnexceptedToken 非法标识 - + CalIfFailed 宏条件判断发生错误 - - + + InvalidDef 无效定义 - + ReservedMarcoType 被保留的宏样式 - + MarcoNotFound: 宏未找到: - - + + NoMatchingIf 未匹配的宏条件 - + DupElseDef 重复的另外条件宏 - + Invalid file name for #include; it contains a line-break or unpaired symbol #include 的文件名无效;它包含换行符或不成对的符号 - + Invalid #pragma directive #pragma 指令无效 @@ -2849,7 +2848,7 @@ - + Code must be exec in the main thread 脚本代码必须在主线程执行 @@ -2860,8 +2859,8 @@ - - + + Script failed to build 脚本编译失败 @@ -2882,19 +2881,19 @@ - + The script failed with an exception 异常被抛出,脚本执行失败 - + The script was aborted 脚本被终止 - + The script terminated unexpectedly 脚本异常退出 @@ -4405,18 +4404,18 @@ 嵌套调用过多 - - + + Assert failed 断言失败 - + BadDecl: 错误的声明: - + GlobalBadDecl 错误的全局声明 diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts index 9fbc61a..eba3ae7 100644 --- a/lang/zh_TW/winghex_zh_TW.ts +++ b/lang/zh_TW/winghex_zh_TW.ts @@ -2678,13 +2678,13 @@ 關閉標籤 - + Failed to open script file 打開腳本檔失敗 - - + + Invalid file name for #include; it contains a line-break: #include 的檔案名無效;它包含換行符: @@ -2699,55 +2699,54 @@ ifdef 非法宏 - - - - - - - + + + + + + UnexceptedToken 非法標識 - + CalIfFailed 宏條件判斷發生錯誤 - - + + InvalidDef 無效定義 - + ReservedMarcoType 被保留的宏樣式 - + MarcoNotFound: 宏未找到: - - + + NoMatchingIf 未匹配的宏條件 - + DupElseDef 重複的另外條件宏 - + Invalid file name for #include; it contains a line-break or unpaired symbol #include 的檔案名無效;它包含換行符或不成對的符號 - + Invalid #pragma directive #pragma 指令無效 @@ -2849,7 +2848,7 @@ - + Code must be exec in the main thread 腳本代碼必須在主線程執行 @@ -2860,8 +2859,8 @@ - - + + Script failed to build 腳本編譯失敗 @@ -2882,19 +2881,19 @@ - + The script failed with an exception 異常被拋出,腳本執行失敗 - + The script was aborted 腳本被終止 - + The script terminated unexpectedly 腳本異常退出 @@ -4405,18 +4404,18 @@ 嵌套調用過多 - - + + Assert failed 斷言失敗 - + BadDecl: 錯誤的聲明: - + GlobalBadDecl 錯誤的全局聲明 diff --git a/src/class/aspreprocesser.cpp b/src/class/aspreprocesser.cpp index 58633c1..283b069 100644 --- a/src/class/aspreprocesser.cpp +++ b/src/class/aspreprocesser.cpp @@ -32,13 +32,13 @@ Q_GLOBAL_STATIC_WITH_ARGS( QByteArrayList, DEFAULT_MARCO, ({// special marcos - "__LINE__", "__SECTION__", + "__LINE__", "__SECTION__", "__SECTION_BASE__", // functions "__AS_ARRAY__", "__AS_ANY__", "__AS_GRID__", "__AS_HANDLE__", "__AS_MATH__", "__AS_WEAKREF__", "__AS_COROUTINE__", "__WING_FILE__", "__WING_STRING__", "__WING_COLOR__", "__WING_JSON__", "__WING_REGEX__", "__WING_DICTIONARY__", "__WING_PRINT_VAR__", "__WING_PRINT_LN__", - "__AS_PROMISE__"})); + "__AS_PROMISE__", "__WING_CLIPBOARD__"})); AsPreprocesser::AsPreprocesser(asIScriptEngine *engine) : engine(engine) { Q_ASSERT(engine); @@ -273,15 +273,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script, 1, asMSGTYPE_ERROR, str.toUtf8()); return asERROR; } - - // ensure end line - if (endLinePassFailed(modifiedScript, pos)) { - auto str = QObject::tr("UnexceptedToken"); - engine->WriteMessage(SECTION, - getLineCount(modifiedScript, pos), - 1, asMSGTYPE_ERROR, str.toUtf8()); - return asERROR; - } } else if (isIf) { if (_isCodeCompleteMode) { auto pos = modifiedScript.indexOf('\n', start); @@ -580,6 +571,12 @@ int AsPreprocesser::processScriptSection(const QByteArray &script, modifiedScript.replace(pos, len, data); pos += data.length(); continue; + } else if (word == "__SECTION_BASE__") { + auto data = QFileInfo(SECTION).baseName().toUtf8(); + data.prepend('"').append('"'); + modifiedScript.replace(pos, len, data); + pos += data.length(); + continue; } else { auto rword = findReplaceResult(word); if (word != rword) { @@ -693,17 +690,16 @@ int AsPreprocesser::processScriptSection(const QByteArray &script, auto p = includefile.indexOf('\n'); auto ws = includefile.indexOf(' '); if (!includefile.isEmpty() && p >= 0 && ws >= 0) { - // TODO: Show the correct line number for - // the error auto str = QObject::tr( "Invalid file name for #include; " "it contains a line-break: ") + QStringLiteral("'") + includefile.left(p) + QStringLiteral("'"); - engine->WriteMessage(sectionname.toUtf8(), 0, 0, - asMSGTYPE_ERROR, - str.toUtf8()); + engine->WriteMessage( + sectionname.toUtf8(), + getLineCount(modifiedScript, pos), 1, + asMSGTYPE_ERROR, str.toUtf8()); } else { // Store it for later processing includes.append({includefile, false}); @@ -744,9 +740,10 @@ int AsPreprocesser::processScriptSection(const QByteArray &script, sectionname, pragmaParam) : -1; if (r < 0) { - // TODO: Report the correct line number engine->WriteMessage( - sectionname.toUtf8(), 0, 0, asMSGTYPE_ERROR, + sectionname.toUtf8(), + getLineCount(modifiedScript, pos), 1, + asMSGTYPE_ERROR, QObject::tr("Invalid #pragma directive") .toUtf8()); return r; diff --git a/src/class/scriptmachine.cpp b/src/class/scriptmachine.cpp index d220581..7b2e1c9 100644 --- a/src/class/scriptmachine.cpp +++ b/src/class/scriptmachine.cpp @@ -43,6 +43,8 @@ #include "scriptaddon/scriptqstring.h" #include "scriptaddon/scriptregex.h" +#include +#include #include #include @@ -153,8 +155,6 @@ bool ScriptMachine::configureEngine() { return false; } - _engine->SetDefaultAccessMask(0x1); - // we need utf8, the default is what we want _engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, true); _engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true); @@ -1998,6 +1998,8 @@ void ScriptMachine::translation() { } void ScriptMachine::registerEngineAddon(asIScriptEngine *engine) { + // all modules can access + engine->SetDefaultAccessMask(0x3); RegisterScriptArray(engine, true); RegisterQString(engine); RegisterScriptRegex(engine); @@ -2012,9 +2014,12 @@ void ScriptMachine::registerEngineAddon(asIScriptEngine *engine) { RegisterScriptHandle(engine); RegisterColor(engine); RegisterQJson(engine); + + engine->SetDefaultAccessMask(0x1); RegisterScriptFile(engine); registerExceptionRoutines(engine); registerEngineAssert(engine); + registerEngineClipboard(engine); AsDirectPromise::Register(engine); } @@ -2051,6 +2056,41 @@ void ScriptMachine::registerEngineAssert(asIScriptEngine *engine) { } } +void ScriptMachine::registerEngineClipboard(asIScriptEngine *engine) { + int r = engine->SetDefaultNamespace("clipboard"); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + + // The string type must be available + Q_ASSERT(engine->GetTypeInfoByDecl("string")); + + if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0) { + r = engine->RegisterGlobalFunction( + "void setText(const string &in text)", asFUNCTION(clip_setText), + asCALL_CDECL); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterGlobalFunction( + "void setBinary(const uint8[]@ data)", asFUNCTION(clip_setBinary), + asCALL_CDECL); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + } else { + r = engine->RegisterGlobalFunction( + "void setText(const string &in text)", WRAP_FN(clip_setText), + asCALL_GENERIC); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterGlobalFunction( + "void setBinary(const uint8[]@ data)", WRAP_FN(clip_setBinary), + asCALL_GENERIC); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + } + + engine->SetDefaultNamespace(""); +} + void ScriptMachine::registerCallBack(ConsoleMode mode, const RegCallBacks &callbacks) { _regcalls.insert(mode, callbacks); @@ -2079,6 +2119,27 @@ void ScriptMachine::scriptAssert_X(bool b, const QString &msg) { } } +void ScriptMachine::clip_setText(const QString &text) { + qApp->clipboard()->setText(text); +} + +void ScriptMachine::clip_setBinary(const CScriptArray &array) { + QByteArray buffer; + buffer.reserve(array.GetSize()); + array.AddRef(); + for (asUINT i = 0; i < array.GetSize(); ++i) { + auto item = reinterpret_cast(array.At(i)); + buffer.append(*item); + } + array.Release(); + + auto c = qApp->clipboard(); + auto mime = new QMimeData; + mime->setData(QStringLiteral("application/octet-stream"), + buffer); // don't use setText() + c->setMimeData(mime); +} + void ScriptMachine::scriptThrow(const QString &msg) { asIScriptContext *ctx = asGetActiveContext(); if (ctx) { diff --git a/src/class/scriptmachine.h b/src/class/scriptmachine.h index 6ee5cb7..7f108bc 100644 --- a/src/class/scriptmachine.h +++ b/src/class/scriptmachine.h @@ -28,6 +28,8 @@ #include #include +class CScriptArray; + class ScriptMachine : public QObject { Q_OBJECT private: @@ -118,6 +120,7 @@ public: static void registerEngineAddon(asIScriptEngine *engine); static void registerEngineAssert(asIScriptEngine *engine); + static void registerEngineClipboard(asIScriptEngine *engine); void registerCallBack(ConsoleMode mode, const RegCallBacks &callbacks); @@ -132,6 +135,9 @@ public: static void scriptAssert(bool b); static void scriptAssert_X(bool b, const QString &msg); + static void clip_setText(const QString &text); + static void clip_setBinary(const CScriptArray &array); + static void scriptThrow(const QString &msg); static QString scriptGetExceptionInfo(); diff --git a/src/scriptaddon/scriptqstring.cpp b/src/scriptaddon/scriptqstring.cpp index 6901390..aa1c9dd 100644 --- a/src/scriptaddon/scriptqstring.cpp +++ b/src/scriptaddon/scriptqstring.cpp @@ -148,6 +148,10 @@ static void ConstructString(QString *thisPointer) { new (thisPointer) QString(); } +static void ConstructStringChar(const QChar &ch, QString *thisPointer) { + new (thisPointer) QString(ch); +} + static void CopyConstructString(const QString &other, QString *thisPointer) { new (thisPointer) QString(other); } @@ -230,6 +234,16 @@ static QString &AddAssignFloatToString(float f, QString &dest) { return dest; } +static QString &AssignCharToString(const QChar &ch, QString &dest) { + dest = ch; + return dest; +} + +static QString &AddAssignCharToString(const QChar &ch, QString &dest) { + dest += ch; + return dest; +} + static QString &AssignBoolToString(bool b, QString &dest) { dest = b ? QStringLiteral("true") : QStringLiteral("false"); return dest; @@ -256,6 +270,14 @@ static QString AddFloatString(float f, const QString &str) { return QString::number(f) + str; } +static QString AddStringChar(const QString &str, const QChar &ch) { + return str + ch; +} + +static QString AddCharString(const QChar &ch, const QString &str) { + return ch + str; +} + static QString AddStringBool(const QString &str, bool b) { return str + (b ? QStringLiteral("true") : QStringLiteral("false")); } @@ -265,7 +287,7 @@ static QString AddBoolString(bool b, const QString &str) { } #endif -static char *StringCharAt(unsigned int i, QString &str) { +static QChar *StringCharAt(unsigned int i, QString &str) { if (asDWORD(i) >= asDWORD(str.size())) { // Set a script exception asIScriptContext *ctx = asGetActiveContext(); @@ -275,7 +297,7 @@ static char *StringCharAt(unsigned int i, QString &str) { return nullptr; } - return reinterpret_cast(str.data() + i); + return str.data() + i; } // AngelScript signature: @@ -595,6 +617,11 @@ void RegisterQString_Native(asIScriptEngine *engine) { asCALL_CDECL_OBJLAST); Q_ASSERT(r >= 0); Q_UNUSED(r); + r = engine->RegisterObjectBehaviour( + "string", asBEHAVE_CONSTRUCT, "void f(const char &in)", + asFUNCTION(ConstructStringChar), asCALL_CDECL_OBJLAST); + Q_ASSERT(r >= 0); + Q_UNUSED(r); r = engine->RegisterObjectMethod( "string", "string &opAssign(const string &in)", asMETHODPR(QString, operator=, (const QString &), QString &), @@ -717,8 +744,29 @@ void RegisterQString_Native(asIScriptEngine *engine) { Q_ASSERT(r >= 0); Q_UNUSED(r); + r = engine->RegisterObjectMethod( + "string", "string &opAssign(const char &in)", + asFUNCTION(AssignCharToString), asCALL_CDECL_OBJLAST); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterObjectMethod( + "string", "string &opAddAssign(const char &in)", + asFUNCTION(AddAssignCharToString), asCALL_CDECL_OBJLAST); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterObjectMethod( + "string", "string opAdd(const char &in) const", + asFUNCTION(AddStringChar), asCALL_CDECL_OBJFIRST); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterObjectMethod( + "string", "string opAdd_r(const char &in) const", + asFUNCTION(AddCharString), asCALL_CDECL_OBJLAST); + Q_ASSERT(r >= 0); + Q_UNUSED(r); + r = engine->RegisterObjectMethod("string", "string &opAssign(float)", - asFUNCTION(AssignFloatToString), + asFUNCTION(AssignCharToString), asCALL_CDECL_OBJLAST); Q_ASSERT(r >= 0); Q_UNUSED(r);