fix: 修复损坏的搜索上下文显示;增强脚本宏和增加内置宏;

This commit is contained in:
寂静的羽夏 2025-05-05 15:05:33 +08:00
parent 3f26766575
commit 960de3afb6
25 changed files with 1607 additions and 1397 deletions

View File

@ -437,17 +437,17 @@ void QHexDocument::findAllBytes(qsizetype begin, qsizetype end,
} }
} }
qsizetype QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end, void QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end,
const QString &pattern, const QString &pattern,
QList<qsizetype> &results, QList<qsizetype> &results,
const std::function<bool()> &pred) { const std::function<bool()> &pred) {
results.clear(); results.clear();
if (end < 0) { if (end < 0) {
end = m_buffer->length(); end = m_buffer->length();
} }
if (pattern.isEmpty() || end > m_buffer->length() || begin >= end) { if (pattern.isEmpty() || end > m_buffer->length() || begin >= end) {
return -1; return;
} }
qsizetype pos = begin; qsizetype pos = begin;
qsizetype n = pattern.size(); qsizetype n = pattern.size();
@ -461,7 +461,6 @@ qsizetype QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end,
break; break;
} }
} }
return results.isEmpty() ? -1 : results.first();
} }
bool QHexDocument::insert(qsizetype offset, uchar b) { bool QHexDocument::insert(qsizetype offset, uchar b) {

View File

@ -107,7 +107,7 @@ public:
QList<qsizetype> &results, QList<qsizetype> &results,
const std::function<bool()> &pred = [] { return true; }); const std::function<bool()> &pred = [] { return true; });
qsizetype findAllBytesExt( void findAllBytesExt(
qsizetype begin, qsizetype end, const QString &pattern, qsizetype begin, qsizetype end, const QString &pattern,
QList<qsizetype> &results, QList<qsizetype> &results,
const std::function<bool()> &pred = [] { return true; }); const std::function<bool()> &pred = [] { return true; });

@ -1 +1 @@
Subproject commit 8d86c185041572bd4735b272669d4117765c2176 Subproject commit 1f53c308498e529e5cfbed16c9f7f68c77a3e8e5

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,7 @@
<item>typedef</item> <item>typedef</item>
<item>while</item> <item>while</item>
<item>xor</item> <item>xor</item>
<item>co_await</item>
</list> </list>
<list name="types"> <list name="types">
<item>void</item> <item>void</item>

View File

@ -102,6 +102,15 @@ void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes,
tip.name = p.nameSpace; tip.name = p.nameSpace;
nodes.append(tip); nodes.append(tip);
} }
if (p.type == CodeInfoTip::Type::Class) {
for (auto &c : p.children) {
if (c.type == CodeInfoTip::Type::ClsFunction ||
c.type == CodeInfoTip::Type::Property) {
nodes.append(c);
}
}
}
} }
nodes.append(emptyNsNodes); nodes.append(emptyNsNodes);

View File

@ -40,7 +40,8 @@ ASDataBase::ASDataBase(asIScriptEngine *engine) {
"function", "interface", "shared", "this", "explicit", "override", "function", "interface", "shared", "this", "explicit", "override",
"namespace", "get", "set", "super", "mixin", "false", "namespace", "get", "set", "super", "mixin", "false",
"true", "null", "typename", "return", "typedef", "funcdef", "true", "null", "typename", "return", "typedef", "funcdef",
"from", "import", "not", "xor", "or", "is"}; "from", "import", "not", "xor", "or", "is",
"co_await"};
for (auto &k : kws) { for (auto &k : kws) {
CodeInfoTip t; CodeInfoTip t;
t.type = CodeInfoTip::Type::KeyWord; t.type = CodeInfoTip::Type::KeyWord;

View File

@ -16,17 +16,25 @@
*/ */
#include "aspreprocesser.h" #include "aspreprocesser.h"
#include "class/languagemanager.h"
#include "class/qascodeparser.h" #include "class/qascodeparser.h"
#include "class/scriptmachine.h" #include "class/scriptmachine.h"
#include "class/skinmanager.h"
#include "scriptaddon/aspromise.hpp" #include "scriptaddon/aspromise.hpp"
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QLibraryInfo>
#include <QMetaEnum>
#include <QStack> #include <QStack>
#include <QVersionNumber>
Q_GLOBAL_STATIC_WITH_ARGS( Q_GLOBAL_STATIC_WITH_ARGS(
QByteArrayList, DEFAULT_MARCO, QByteArrayList, DEFAULT_MARCO,
({"__AS_ARRAY__", "__AS_ANY__", "__AS_GRID__", "__AS_HANDLE__", ({// special marcos
"__LINE__", "__SECTION__",
// functions
"__AS_ARRAY__", "__AS_ANY__", "__AS_GRID__", "__AS_HANDLE__",
"__AS_MATH__", "__AS_WEAKREF__", "__AS_COROUTINE__", "__WING_FILE__", "__AS_MATH__", "__AS_WEAKREF__", "__AS_COROUTINE__", "__WING_FILE__",
"__WING_STRING__", "__WING_COLOR__", "__WING_JSON__", "__WING_REGEX__", "__WING_STRING__", "__WING_COLOR__", "__WING_JSON__", "__WING_REGEX__",
"__WING_DICTIONARY__", "__WING_PRINT_VAR__", "__WING_PRINT_LN__", "__WING_DICTIONARY__", "__WING_PRINT_VAR__", "__WING_PRINT_LN__",
@ -44,6 +52,55 @@ AsPreprocesser::AsPreprocesser(asIScriptEngine *engine) : engine(engine) {
for (auto &m : *DEFAULT_MARCO) { for (auto &m : *DEFAULT_MARCO) {
definedWords.insert(m, {}); definedWords.insert(m, {});
} }
static QHash<QString, QByteArray> addInfos;
if (addInfos.isEmpty()) {
// software infos
auto ver = QVersionNumber::fromString(WINGHEX_VERSION);
addInfos.insert(QStringLiteral("__WING_VERSION__"),
"\"" WINGHEX_VERSION "\"");
addInfos.insert(QStringLiteral("__WING_VERSION_MAJOR__"),
QByteArray::number(ver.majorVersion()));
addInfos.insert(QStringLiteral("__WING_VERSION_MINOR__"),
QByteArray::number(ver.minorVersion()));
addInfos.insert(QStringLiteral("__WING_VERSION_PATCH__"),
QByteArray::number(ver.microVersion()));
addInfos.insert(QStringLiteral("__ANGELSCRIPT_VERSION__"),
"\"" ANGELSCRIPT_VERSION_STRING "\"");
addInfos.insert(QStringLiteral("__ANGELSCRIPT_VERSION_MAJOR__"),
QByteArray::number(ANGELSCRIPT_VERSION / 10000));
addInfos.insert(QStringLiteral("__ANGELSCRIPT_VERSION_MINOR__"),
QByteArray::number((ANGELSCRIPT_VERSION / 100) % 100));
addInfos.insert(QStringLiteral("__ANGELSCRIPT_VERSION_PATCH__"),
QByteArray::number(ANGELSCRIPT_VERSION % 100));
addInfos.insert(QStringLiteral("__WINGHEX_APPNAME__"),
"\"" APP_NAME "\"");
addInfos.insert(QStringLiteral("__WINGHEX_AUTHOR__"), "\"wingsummer\"");
ver = QLibraryInfo::version();
addInfos.insert(QStringLiteral("__QT_VERSION__"),
ver.toString().toUtf8().prepend('"').append('"'));
addInfos.insert(QStringLiteral("__QT_VERSION_MAJOR__"),
QByteArray::number(ver.majorVersion()));
addInfos.insert(QStringLiteral("__QT_VERSION_MINOR__"),
QByteArray::number(ver.minorVersion()));
addInfos.insert(QStringLiteral("__QT_VERSION_PATCH__"),
QByteArray::number(ver.microVersion()));
// UI
addInfos.insert(QStringLiteral("__LANG__"), LanguageManager::instance()
.defaultLocale()
.name()
.toUtf8()
.prepend('"')
.append('"'));
auto theme = SkinManager::instance().currentTheme();
auto te = QMetaEnum::fromType<SkinManager::Theme>();
addInfos.insert(
QStringLiteral("__THEME__"),
QByteArray(te.valueToKey(int(theme))).prepend('"').append('"'));
}
definedWords.insert(addInfos);
} }
AsPreprocesser::~AsPreprocesser() { void ClearAll(); } AsPreprocesser::~AsPreprocesser() { void ClearAll(); }
@ -130,6 +187,8 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
QStack<std::optional<bool>> m_condtionStack; QStack<std::optional<bool>> m_condtionStack;
while (pos < modifiedScript.size()) { while (pos < modifiedScript.size()) {
auto SECTION = sectionname.toUtf8();
asUINT len = 0; asUINT len = 0;
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos, asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
modifiedScript.size() - pos, &len); modifiedScript.size() - pos, &len);
@ -164,7 +223,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
} }
auto str = QObject::tr("IfDefNoWord"); auto str = QObject::tr("IfDefNoWord");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -209,7 +268,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
#endif #endif
} else { } else {
auto str = QObject::tr("IfDefInvalidWord"); auto str = QObject::tr("IfDefInvalidWord");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -218,7 +277,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line // ensure end line
if (endLinePassFailed(modifiedScript, pos)) { if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -246,11 +305,15 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
auto &sm = ScriptMachine::instance(); auto &sm = ScriptMachine::instance();
bool ok = false; bool ok = false;
auto ret = sm.evaluateDefine(codes, ok); // if expression should processed the marcos
auto ret = sm.evaluateDefine(
processIfExpression(
codes, getLineCount(modifiedScript, pos), SECTION),
ok);
if (ret < 0) { if (ret < 0) {
auto str = QObject::tr("CalIfFailed"); auto str = QObject::tr("CalIfFailed");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -314,7 +377,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
default: default:
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION,
getLineCount(modifiedScript, pos), 1, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -329,8 +392,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
if (endLinePassFailed(modifiedScript, pos)) { if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION, getLineCount(modifiedScript, pos), 1,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
} }
@ -348,7 +410,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
continue; continue;
} }
auto str = QObject::tr("InvalidDef"); auto str = QObject::tr("InvalidDef");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -376,16 +438,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// Warning // Warning
auto str = QObject::tr("ReservedMarcoType"); auto str = QObject::tr("ReservedMarcoType");
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION, getLineCount(modifiedScript, pos), 1,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_WARNING, str.toUtf8()); asMSGTYPE_WARNING, str.toUtf8());
} else { } else {
if (!definedWords.remove(word)) { if (!definedWords.remove(word)) {
auto str = QObject::tr("MarcoNotFound:") + word; auto str = QObject::tr("MarcoNotFound:") + word;
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION, getLineCount(modifiedScript, pos),
getLineCount(modifiedScript, pos), 1, 1, asMSGTYPE_WARNING, str.toUtf8());
asMSGTYPE_WARNING, str.toUtf8());
} }
} }
@ -393,14 +453,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
if (endLinePassFailed(modifiedScript, pos)) { if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION, getLineCount(modifiedScript, pos), 1,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
} }
} else { } else {
auto str = QObject::tr("InvalidDef"); auto str = QObject::tr("InvalidDef");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -413,7 +472,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
} }
if (m_condtionStack.isEmpty()) { if (m_condtionStack.isEmpty()) {
auto str = QObject::tr("NoMatchingIf"); auto str = QObject::tr("NoMatchingIf");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -430,14 +489,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
if (endLinePassFailed(modifiedScript, pos - 1)) { if (endLinePassFailed(modifiedScript, pos - 1)) {
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage( engine->WriteMessage(
sectionname.toUtf8(), SECTION, getLineCount(modifiedScript, pos), 1,
getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
} }
} else { } else {
auto str = QObject::tr("DupElseDef"); auto str = QObject::tr("DupElseDef");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8()); 1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -454,7 +512,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// Only remove the #endif if there was a matching #if // Only remove the #endif if there was a matching #if
if (m_condtionStack.isEmpty()) { if (m_condtionStack.isEmpty()) {
auto str = QObject::tr("NoMatchingIf"); auto str = QObject::tr("NoMatchingIf");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -466,7 +524,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
// ensure end line // ensure end line
if (endLinePassFailed(modifiedScript, pos)) { if (endLinePassFailed(modifiedScript, pos)) {
auto str = QObject::tr("UnexceptedToken"); auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage(sectionname.toUtf8(), engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos), 1, getLineCount(modifiedScript, pos), 1,
asMSGTYPE_ERROR, str.toUtf8()); asMSGTYPE_ERROR, str.toUtf8());
return asERROR; return asERROR;
@ -476,13 +534,59 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
#endif #endif
} }
} else { } else {
if (t == asTC_IDENTIFIER) { if (!_isCodeCompleteMode) {
// define replace if (t == asTC_IDENTIFIER) {
auto word = modifiedScript.sliced(pos, len); // define replace
auto rword = findReplaceResult(word); auto word = modifiedScript.sliced(pos, len);
if (word != rword) { if (word == PROMISE_AWAIT) {
modifiedScript.replace(pos, len, rword); auto npos = pos + len;
len = rword.length(); asUINT total = 0;
auto t = engine->ParseToken(
modifiedScript.data() + npos,
modifiedScript.size() - npos, &total);
if (t == asTC_WHITESPACE) {
npos += total;
t = engine->ParseToken(modifiedScript.data() + npos,
modifiedScript.size() - npos,
&total);
if (t == asTC_IDENTIFIER) {
// ok
auto word = modifiedScript.sliced(npos, total);
auto data = "(" + word +
")." PROMISE_YIELD
"()." PROMISE_UNWRAP "()";
auto oldLen = npos - pos + word.length();
modifiedScript.replace(pos, oldLen, data);
pos = npos;
pos += data.length() - oldLen + word.length();
continue;
}
}
auto str = QObject::tr("UnexceptedToken");
engine->WriteMessage(SECTION,
getLineCount(modifiedScript, pos),
1, asMSGTYPE_ERROR, str.toUtf8());
return asERROR;
} else if (word == "__LINE__") {
auto data = QByteArray::number(
getLineCount(modifiedScript, pos));
modifiedScript.replace(pos, len, data);
pos += data.length();
continue;
} else if (word == "__SECTION__") {
auto data = SECTION;
data.prepend('"').append('"');
modifiedScript.replace(pos, len, data);
pos += data.length();
continue;
} else {
auto rword = findReplaceResult(word);
if (word != rword) {
modifiedScript.replace(pos, len, rword);
len = rword.length();
}
}
} }
} }
pos += len; pos += len;
@ -658,12 +762,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
} }
} }
// asPromise co_await keyword expansion
size_t len = modifiedScript.size();
auto data = AsGeneratePromiseEntrypoints(modifiedScript.data(), &len);
modifiedScript = QByteArray(data, len);
asFreeMem(data);
// Build the actual script // Build the actual script
engine->SetEngineProperty(asEP_COPY_SCRIPT_SECTIONS, true); engine->SetEngineProperty(asEP_COPY_SCRIPT_SECTIONS, true);
@ -720,9 +818,6 @@ int AsPreprocesser::loadScriptSection(const QString &filename) {
QFileInfo(filename).absoluteFilePath() + QStringLiteral("'"); QFileInfo(filename).absoluteFilePath() + QStringLiteral("'");
engine->WriteMessage(filename.toUtf8(), 0, 0, asMSGTYPE_ERROR, engine->WriteMessage(filename.toUtf8(), 0, 0, asMSGTYPE_ERROR,
msg.toUtf8()); msg.toUtf8());
// TODO: Write the file where this one was included from
return -1; return -1;
} }
@ -888,6 +983,37 @@ bool AsPreprocesser::endLinePassFailed(const QByteArray &modifiedScript,
return endError; return endError;
} }
QByteArray
AsPreprocesser::processIfExpression(const QByteArray &codes, int currentLine,
const QByteArray &currentSection) {
QByteArray ret;
int pos = 0;
auto total = codes.length();
while (pos < total) {
asUINT len = 0;
auto t =
engine->ParseToken(codes.data() + pos, codes.size() - pos, &len);
auto word = codes.sliced(pos, len);
if (t == asTC_IDENTIFIER) {
if (word == "__LINE__") {
ret.append(currentLine);
} else if (word == "__SECTION__") {
auto s = currentSection;
s.prepend('"').append('"');
ret.append(s);
} else {
ret.append(findReplaceResult(word));
}
} else {
ret.append(word);
}
pos += len;
}
return ret;
}
QByteArray AsPreprocesser::findReplaceResult(const QByteArray &v) { QByteArray AsPreprocesser::findReplaceResult(const QByteArray &v) {
QByteArray r = v; QByteArray r = v;
while (definedWords.contains(r)) { while (definedWords.contains(r)) {

View File

@ -138,6 +138,9 @@ protected:
bool endLinePassFailed(const QByteArray &modifiedScript, int pos); bool endLinePassFailed(const QByteArray &modifiedScript, int pos);
QByteArray processIfExpression(const QByteArray &codes, int currentLine,
const QByteArray &currentSection);
QByteArray findReplaceResult(const QByteArray &v); QByteArray findReplaceResult(const QByteArray &v);
asIScriptEngine *engine; asIScriptEngine *engine;

View File

@ -3126,8 +3126,8 @@ void PluginSystem::applyFunctionTables(IWingPluginBase *plg,
plg->setProperty("__CALL_POINTER__", quintptr(this)); plg->setProperty("__CALL_POINTER__", quintptr(this));
} }
QString PluginSystem::type2AngelScriptString(IWingPlugin::MetaType type, QString PluginSystem::type2AngelScriptString(uint type, bool isArg,
bool isArg, bool noModifier) { bool noModifier) {
auto isArray = !!(type & WingHex::IWingPlugin::Array); auto isArray = !!(type & WingHex::IWingPlugin::Array);
auto isList = !!(type & WingHex::IWingPlugin::List); auto isList = !!(type & WingHex::IWingPlugin::List);
auto isContainer = isArray || isList; auto isContainer = isArray || isList;

View File

@ -175,8 +175,8 @@ public:
static QString getPUID(IWingPluginBase *p); static QString getPUID(IWingPluginBase *p);
static QString type2AngelScriptString(IWingPlugin::MetaType type, static QString type2AngelScriptString(uint type, bool isArg,
bool isArg, bool noModifier = false); bool noModifier = false);
private: private:
void loadExtPlugin(); void loadExtPlugin();

View File

@ -147,7 +147,6 @@ bool ScriptMachine::isRunning(ConsoleMode mode) const {
#define INS_2 INS_1 ", " INS_1 #define INS_2 INS_1 ", " INS_1
#define INS_4 INS_2 ", " INS_2 #define INS_4 INS_2 ", " INS_2
#define INS_8 INS_4 ", " INS_4 #define INS_8 INS_4 ", " INS_4
#define INS_16 INS_8 ", " INS_8
bool ScriptMachine::configureEngine() { bool ScriptMachine::configureEngine() {
if (_engine == nullptr) { if (_engine == nullptr) {
@ -219,7 +218,7 @@ bool ScriptMachine::configureEngine() {
// Register a couple of extra functions for the scripts // Register a couple of extra functions for the scripts
r = _engine->RegisterGlobalFunction( r = _engine->RegisterGlobalFunction(
"void print(const ? &in obj, const ? &in = null," INS_16 ")", "void print(const ? &in obj, const ? &in = null," INS_8 ")",
asFUNCTION(print), asCALL_GENERIC); asFUNCTION(print), asCALL_GENERIC);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
if (r < 0) { if (r < 0) {
@ -227,7 +226,7 @@ bool ScriptMachine::configureEngine() {
} }
r = _engine->RegisterGlobalFunction( r = _engine->RegisterGlobalFunction(
"void println(const ? &in obj, const ? &in = null," INS_16 ")", "void println(const ? &in obj, const ? &in = null," INS_8 ")",
asFUNCTION(println), asCALL_GENERIC); asFUNCTION(println), asCALL_GENERIC);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
if (r < 0) { if (r < 0) {
@ -680,7 +679,7 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
QScopeGuard guard([this, oldMode]() { _curMsgMode = oldMode; }); QScopeGuard guard([this, oldMode]() { _curMsgMode = oldMode; });
auto ccode = code; auto ccode = code;
ccode.prepend("bool f(){ return (").append(");}"); ccode.prepend("bool f(){ return bool(").append(");}");
// start to compile // start to compile
_curMsgMode = DefineEvaluator; _curMsgMode = DefineEvaluator;

View File

@ -95,7 +95,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
info.fn = std::bind( info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::structTypes), QOverload<const QVariantList &>::of(&WingCStruct::structTypes),
this, std::placeholders::_1); this, std::placeholders::_1);
info.ret = MetaType(MetaType::String | MetaType::Array); info.ret = MetaType::String | MetaType::Array;
_scriptInfo.insert(QStringLiteral("structTypes"), info); _scriptInfo.insert(QStringLiteral("structTypes"), info);
} }
@ -125,7 +125,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
info.fn = std::bind( info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::constDefines), QOverload<const QVariantList &>::of(&WingCStruct::constDefines),
this, std::placeholders::_1); this, std::placeholders::_1);
info.ret = MetaType(MetaType::String | MetaType::Array); info.ret = MetaType::String | MetaType::Array;
_scriptInfo.insert(QStringLiteral("constDefines"), info); _scriptInfo.insert(QStringLiteral("constDefines"), info);
} }
@ -166,7 +166,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
info.fn = std::bind( info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::readRaw), this, QOverload<const QVariantList &>::of(&WingCStruct::readRaw), this,
std::placeholders::_1); std::placeholders::_1);
info.ret = MetaType(MetaType::Byte | MetaType::Array); info.ret = MetaType::Byte | MetaType::Array;
info.params.append( info.params.append(
qMakePair(getqsizetypeMetaType(), QStringLiteral("offset"))); qMakePair(getqsizetypeMetaType(), QStringLiteral("offset")));
@ -542,7 +542,6 @@ CScriptDictionary *WingCStruct::convert2AsDictionary(const QVariantHash &hash) {
switch (type) { switch (type) {
case QMetaType::Bool: case QMetaType::Bool:
case QMetaType::UChar: case QMetaType::UChar:
case QMetaType::Char:
case QMetaType::Int: case QMetaType::Int:
case QMetaType::Long: case QMetaType::Long:
case QMetaType::LongLong: case QMetaType::LongLong:
@ -564,6 +563,13 @@ CScriptDictionary *WingCStruct::convert2AsDictionary(const QVariantHash &hash) {
case QMetaType::Float: case QMetaType::Float:
dic->Set(p->first, var.toDouble()); dic->Set(p->first, var.toDouble());
break; break;
case QMetaType::Char: {
auto v = var.value<char>();
auto ch = new QChar(v);
auto id = engine->GetTypeIdByDecl("char");
dic->Set(p->first, ch, id);
break;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case QMetaType::Char16: { case QMetaType::Char16: {
auto v = var.value<char16_t>(); auto v = var.value<char16_t>();

View File

@ -242,8 +242,12 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
contextLen = raw.length(); contextLen = raw.length();
m_findResults->setEncoding(result.encoding); m_findResults->setEncoding(result.encoding);
d->findAllBytes(begin, end, raw, results); d->findAllBytes(begin, end, raw, results);
m_findResults->lastFindData() = qMakePair(data, contextLen);
} else { } else {
contextLen = d->findAllBytesExt(begin, end, result.str, results); // assuming the find pattern is 'xx xx xx xx'
contextLen = std::count(data.begin(), data.end(), ' ') + 1;
d->findAllBytesExt(begin, end, result.str, results);
m_findResults->lastFindData() = qMakePair(data, contextLen);
} }
m_findResults->beginUpdate(); m_findResults->beginUpdate();
@ -257,12 +261,9 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
r.col = r.offset % lineWidth; r.col = r.offset % lineWidth;
m_findResults->results().append(r); m_findResults->results().append(r);
m_findResults->findData().append( m_findResults->findData().append(
readContextFinding(ritem, contextLen, FIND_CONTEXT_SIZE, readContextFinding(ritem, contextLen));
FIND_MAX_DISPLAY_FIND_CHARS));
} }
m_findResults->lastFindData() = data;
m_findResults->endUpdate(); m_findResults->endUpdate();
if (m_findResults->size() >= QHEXVIEW_FIND_LIMIT) { if (m_findResults->size() >= QHEXVIEW_FIND_LIMIT) {
@ -804,34 +805,50 @@ bool EditorView::checkHasUnsavedState() const {
} }
FindResultModel::FindInfo EditorView::readContextFinding(qsizetype offset, FindResultModel::FindInfo EditorView::readContextFinding(qsizetype offset,
qsizetype findSize, qsizetype findSize) {
int contextSize, constexpr long DISPLAY_SIZE = 16;
int maxDisplayBytes) { constexpr long FIND_CONTENXT_LEN = 10;
constexpr long HT_SIZE = (DISPLAY_SIZE - FIND_CONTENXT_LEN) / 2;
auto doc = m_hex->document(); auto doc = m_hex->document();
if (findSize <= FIND_CONTENXT_LEN) {
long leftsize = FIND_CONTENXT_LEN - findSize;
auto rs = std::div(leftsize, 2l);
qsizetype halfSize = maxDisplayBytes / 2; auto headerlen = HT_SIZE + rs.quot + rs.rem;
auto header = doc->read(offset, qMin(findSize, halfSize)); auto taillen = HT_SIZE + rs.quot;
QByteArray tailer;
if (header.size() < findSize) { auto begin = qMax(offset - headerlen, 0);
auto len = qMin(findSize, qsizetype(maxDisplayBytes) - halfSize); auto end = qMin(offset + findSize + taillen, doc->length());
tailer = doc->read(offset + findSize - len, len); auto boff = offset - begin;
auto buffer = doc->read(begin, end - begin + 1);
FindResultModel::FindInfo info;
info.cheader = buffer.left(boff);
info.hbuffer = buffer.sliced(boff, findSize);
info.tbuffer = {};
info.ctailer = buffer.sliced(boff + findSize);
return info;
} else {
constexpr long FIND_CONTENXT_HALF = FIND_CONTENXT_LEN / 2;
auto hbegin = qMax(offset - HT_SIZE, 0);
auto hlen = offset - hbegin + FIND_CONTENXT_HALF;
auto header = doc->read(hbegin, hlen);
auto toff = offset - hbegin;
auto tbegin = offset + findSize - FIND_CONTENXT_HALF;
auto tlen = HT_SIZE + FIND_CONTENXT_HALF;
auto tailer = doc->read(tbegin, tlen);
FindResultModel::FindInfo info;
info.cheader = header.left(toff);
info.hbuffer = header.sliced(toff);
info.tbuffer = tailer.left(FIND_CONTENXT_HALF);
info.ctailer = tailer.sliced(FIND_CONTENXT_HALF);
return info;
} }
auto left = qsizetype(maxDisplayBytes) - header.size() - tailer.size();
// append to contextSize
contextSize += (left / 2);
auto cheader = doc->read(offset - contextSize, contextSize);
auto ctailer = doc->read(offset + findSize, contextSize);
FindResultModel::FindInfo info;
info.cheader = cheader;
info.hbuffer = header;
info.tbuffer = tailer;
info.ctailer = ctailer;
return info;
} }
void EditorView::applyFunctionTables(WingEditorViewWidget *view, void EditorView::applyFunctionTables(WingEditorViewWidget *view,

View File

@ -225,9 +225,7 @@ private:
bool checkHasUnsavedState() const; bool checkHasUnsavedState() const;
FindResultModel::FindInfo readContextFinding(qsizetype offset, FindResultModel::FindInfo readContextFinding(qsizetype offset,
qsizetype findSize, qsizetype findSize);
int contextSize,
int maxDisplayBytes);
void applyFunctionTables(WingHex::WingEditorViewWidget *view, void applyFunctionTables(WingHex::WingEditorViewWidget *view,
const CallTable &fns); const CallTable &fns);

View File

@ -102,3 +102,17 @@ bool QHexTextEdit::isHexMode() const { return m_isHexMode; }
void QHexTextEdit::setIsHexMode(bool newIsHexMode) { void QHexTextEdit::setIsHexMode(bool newIsHexMode) {
m_isHexMode = newIsHexMode; m_isHexMode = newIsHexMode;
} }
void QHexTextEdit::setFindText(const QString &text) {
mText = text;
mText = mText
.removeIf([](const QChar &ch) {
return !std::isalnum(ch.unicode()) && ch != '?';
})
.toUpper();
setText(text);
auto cur = this->textCursor();
cur.movePosition(QTextCursor::End);
setTextCursor(cur);
mCurserPositionPre = cur.position();
}

View File

@ -28,6 +28,10 @@ public:
bool isHexMode() const; bool isHexMode() const;
void setIsHexMode(bool newIsHexMode); void setIsHexMode(bool newIsHexMode);
public:
// must be 'xx xx xx' style
void setFindText(const QString &text);
protected: protected:
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;

View File

@ -52,6 +52,7 @@ void ScrollableLabel::wheelEvent(QWheelEvent *event) {
void ScrollableLabel::resizeEvent(QResizeEvent *event) { void ScrollableLabel::resizeEvent(QResizeEvent *event) {
QScrollArea::resizeEvent(event); QScrollArea::resizeEvent(event);
updateLabelSize(); updateLabelSize();
adjustDisplayLogic();
} }
void ScrollableLabel::setupUI() { void ScrollableLabel::setupUI() {
@ -60,7 +61,7 @@ void ScrollableLabel::setupUI() {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
label.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); label.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
label.setWordWrap(false); label.setWordWrap(false);
label.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); label.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
@ -82,3 +83,18 @@ void ScrollableLabel::updateLabelSize() {
bool ScrollableLabel::shouldScroll() const { bool ScrollableLabel::shouldScroll() const {
return label.width() > viewport()->width(); return label.width() > viewport()->width();
} }
void ScrollableLabel::adjustDisplayLogic() {
QFontMetrics fm(label.font());
const int contentWidth = fm.horizontalAdvance(label.text());
const int containerWidth = width();
if (contentWidth > containerWidth) {
label.setFixedSize(contentWidth, fm.height());
label.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
horizontalScrollBar()->setValue(0);
} else {
label.setFixedSize(containerWidth, fm.height());
label.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
}
}

View File

@ -47,6 +47,8 @@ private:
void updateLabelSize(); void updateLabelSize();
bool shouldScroll() const; bool shouldScroll() const;
void adjustDisplayLogic();
}; };
#endif // MARQUEELABEL_H #endif // MARQUEELABEL_H

View File

@ -89,7 +89,7 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
m_findMode->setCurrentIndex(0); m_findMode->setCurrentIndex(0);
} }
m_lineeditor->setText(info.str); m_lineeditor->setFindText(info.str);
auto regionw = new QWidget(this); auto regionw = new QWidget(this);
auto regionLayout = new QHBoxLayout(regionw); auto regionLayout = new QHBoxLayout(regionw);

View File

@ -714,10 +714,17 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
cursor->moveTo(fm->resultAt(index.row()).offset); cursor->moveTo(fm->resultAt(index.row()).offset);
if (cursor->selectionCount() <= 1 && index.column() >= 3) { if (cursor->selectionCount() <= 1 && index.column() >= 3) {
cursor->select(fm->lastFindData().length()); cursor->select(fm->lastFindData().second);
} }
}); });
auto header = m_findresult->horizontalHeader();
auto font = QFontMetrics(m_findresult->font());
auto len = font.horizontalAdvance('F') * (15 + 16 * 2);
if (header->sectionSize(3) < len) {
header->resizeSection(3, len);
}
auto dw = buildDockWidget(dock, QStringLiteral("FindResult"), auto dw = buildDockWidget(dock, QStringLiteral("FindResult"),
tr("FindResult") + QStringLiteral(" (ASCII)"), tr("FindResult") + QStringLiteral(" (ASCII)"),
m_findresult); m_findresult);
@ -2127,7 +2134,6 @@ void MainWindow::on_findfile() {
ExecAsync<EditorView::FindError>( ExecAsync<EditorView::FindError>(
[this, r]() -> EditorView::FindError { [this, r]() -> EditorView::FindError {
m_isfinding = true; m_isfinding = true;
return currentEditor()->find(r); return currentEditor()->find(r);
}, },
[this](EditorView::FindError err) { [this](EditorView::FindError err) {
@ -2151,6 +2157,14 @@ void MainWindow::on_findfile() {
if (result) { if (result) {
m_findEncoding.value(result->encoding())->setChecked(true); m_findEncoding.value(result->encoding())->setChecked(true);
} }
auto header = m_findresult->horizontalHeader();
auto font = QFontMetrics(m_findresult->font());
auto len = font.horizontalAdvance('F') * (15 + 16 * 2);
if (header->sectionSize(3) < len) {
header->resizeSection(3, len);
}
m_find->raise(); m_find->raise();
m_isfinding = false; m_isfinding = false;
@ -2595,7 +2609,7 @@ void MainWindow::on_exportfindresult() {
auto d = findresitem->lastFindData(); auto d = findresitem->lastFindData();
fobj.insert(QStringLiteral("find"), d); fobj.insert(QStringLiteral("find"), d.first);
QJsonArray arr; QJsonArray arr;
for (int i = 0; i < c; i++) { for (int i = 0; i < c; i++) {
auto data = findresitem->resultAt(i); auto data = findresitem->resultAt(i);

View File

@ -135,7 +135,9 @@ QList<FindResultModel::FindInfo> &FindResultModel::findData() {
return m_findData; return m_findData;
} }
QString &FindResultModel::lastFindData() { return m_lastFindData; } QPair<QString, qsizetype> &FindResultModel::lastFindData() {
return m_lastFindData;
}
void FindResultModel::beginUpdate() { this->beginResetModel(); } void FindResultModel::beginUpdate() { this->beginResetModel(); }

View File

@ -42,7 +42,7 @@ public:
QList<FindResult> &results(); QList<FindResult> &results();
QList<FindInfo> &findData(); QList<FindInfo> &findData();
QString &lastFindData(); QPair<QString, qsizetype> &lastFindData();
void beginUpdate(); void beginUpdate();
void endUpdate(); void endUpdate();
@ -67,7 +67,7 @@ public:
private: private:
QList<FindResult> m_results; QList<FindResult> m_results;
QList<FindInfo> m_findData; QList<FindInfo> m_findData;
QString m_lastFindData; QPair<QString, qsizetype> m_lastFindData;
QString m_encoding; QString m_encoding;
}; };

View File

@ -52,9 +52,6 @@
#define PROEXT ".wingpro" #define PROEXT ".wingpro"
Q_DECL_UNUSED constexpr auto FIND_CONTEXT_SIZE = 3;
Q_DECL_UNUSED constexpr auto FIND_MAX_DISPLAY_FIND_CHARS = 8;
Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) { Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) {
return ":/com.wingsummer.winghex/images/" + name + ".png"; return ":/com.wingsummer.winghex/images/" + name + ".png";
} }