fix: 修复损坏的搜索上下文显示;增强脚本宏和增加内置宏;
This commit is contained in:
parent
3f26766575
commit
960de3afb6
|
@ -437,17 +437,17 @@ void QHexDocument::findAllBytes(qsizetype begin, qsizetype end,
|
|||
}
|
||||
}
|
||||
|
||||
qsizetype QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end,
|
||||
const QString &pattern,
|
||||
QList<qsizetype> &results,
|
||||
const std::function<bool()> &pred) {
|
||||
void QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end,
|
||||
const QString &pattern,
|
||||
QList<qsizetype> &results,
|
||||
const std::function<bool()> &pred) {
|
||||
results.clear();
|
||||
if (end < 0) {
|
||||
end = m_buffer->length();
|
||||
}
|
||||
|
||||
if (pattern.isEmpty() || end > m_buffer->length() || begin >= end) {
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
qsizetype pos = begin;
|
||||
qsizetype n = pattern.size();
|
||||
|
@ -461,7 +461,6 @@ qsizetype QHexDocument::findAllBytesExt(qsizetype begin, qsizetype end,
|
|||
break;
|
||||
}
|
||||
}
|
||||
return results.isEmpty() ? -1 : results.first();
|
||||
}
|
||||
|
||||
bool QHexDocument::insert(qsizetype offset, uchar b) {
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
QList<qsizetype> &results,
|
||||
const std::function<bool()> &pred = [] { return true; });
|
||||
|
||||
qsizetype findAllBytesExt(
|
||||
void findAllBytesExt(
|
||||
qsizetype begin, qsizetype end, const QString &pattern,
|
||||
QList<qsizetype> &results,
|
||||
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
|
@ -55,6 +55,7 @@
|
|||
<item>typedef</item>
|
||||
<item>while</item>
|
||||
<item>xor</item>
|
||||
<item>co_await</item>
|
||||
</list>
|
||||
<list name="types">
|
||||
<item>void</item>
|
||||
|
|
|
@ -102,6 +102,15 @@ void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes,
|
|||
tip.name = p.nameSpace;
|
||||
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);
|
||||
|
|
|
@ -40,7 +40,8 @@ ASDataBase::ASDataBase(asIScriptEngine *engine) {
|
|||
"function", "interface", "shared", "this", "explicit", "override",
|
||||
"namespace", "get", "set", "super", "mixin", "false",
|
||||
"true", "null", "typename", "return", "typedef", "funcdef",
|
||||
"from", "import", "not", "xor", "or", "is"};
|
||||
"from", "import", "not", "xor", "or", "is",
|
||||
"co_await"};
|
||||
for (auto &k : kws) {
|
||||
CodeInfoTip t;
|
||||
t.type = CodeInfoTip::Type::KeyWord;
|
||||
|
|
|
@ -16,17 +16,25 @@
|
|||
*/
|
||||
|
||||
#include "aspreprocesser.h"
|
||||
#include "class/languagemanager.h"
|
||||
#include "class/qascodeparser.h"
|
||||
#include "class/scriptmachine.h"
|
||||
#include "class/skinmanager.h"
|
||||
#include "scriptaddon/aspromise.hpp"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QLibraryInfo>
|
||||
#include <QMetaEnum>
|
||||
#include <QStack>
|
||||
#include <QVersionNumber>
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(
|
||||
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__",
|
||||
"__WING_STRING__", "__WING_COLOR__", "__WING_JSON__", "__WING_REGEX__",
|
||||
"__WING_DICTIONARY__", "__WING_PRINT_VAR__", "__WING_PRINT_LN__",
|
||||
|
@ -44,6 +52,55 @@ AsPreprocesser::AsPreprocesser(asIScriptEngine *engine) : engine(engine) {
|
|||
for (auto &m : *DEFAULT_MARCO) {
|
||||
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(); }
|
||||
|
@ -130,6 +187,8 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
QStack<std::optional<bool>> m_condtionStack;
|
||||
|
||||
while (pos < modifiedScript.size()) {
|
||||
auto SECTION = sectionname.toUtf8();
|
||||
|
||||
asUINT len = 0;
|
||||
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
|
@ -164,7 +223,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
}
|
||||
|
||||
auto str = QObject::tr("IfDefNoWord");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -209,7 +268,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
#endif
|
||||
} else {
|
||||
auto str = QObject::tr("IfDefInvalidWord");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -218,7 +277,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -246,11 +305,15 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
auto &sm = ScriptMachine::instance();
|
||||
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) {
|
||||
auto str = QObject::tr("CalIfFailed");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -314,7 +377,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
default:
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -329,8 +392,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
|
@ -348,7 +410,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
continue;
|
||||
}
|
||||
auto str = QObject::tr("InvalidDef");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -376,16 +438,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// Warning
|
||||
auto str = QObject::tr("ReservedMarcoType");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_WARNING, str.toUtf8());
|
||||
} else {
|
||||
if (!definedWords.remove(word)) {
|
||||
auto str = QObject::tr("MarcoNotFound:") + word;
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_WARNING, str.toUtf8());
|
||||
SECTION, getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_WARNING, str.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,14 +453,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else {
|
||||
auto str = QObject::tr("InvalidDef");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -413,7 +472,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
}
|
||||
if (m_condtionStack.isEmpty()) {
|
||||
auto str = QObject::tr("NoMatchingIf");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -430,14 +489,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
if (endLinePassFailed(modifiedScript, pos - 1)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else {
|
||||
auto str = QObject::tr("DupElseDef");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -454,7 +512,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// Only remove the #endif if there was a matching #if
|
||||
if (m_condtionStack.isEmpty()) {
|
||||
auto str = QObject::tr("NoMatchingIf");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -466,7 +524,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
|
@ -476,13 +534,59 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
// define replace
|
||||
auto word = modifiedScript.sliced(pos, len);
|
||||
auto rword = findReplaceResult(word);
|
||||
if (word != rword) {
|
||||
modifiedScript.replace(pos, len, rword);
|
||||
len = rword.length();
|
||||
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);
|
||||
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;
|
||||
|
@ -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
|
||||
engine->SetEngineProperty(asEP_COPY_SCRIPT_SECTIONS, true);
|
||||
|
||||
|
@ -720,9 +818,6 @@ int AsPreprocesser::loadScriptSection(const QString &filename) {
|
|||
QFileInfo(filename).absoluteFilePath() + QStringLiteral("'");
|
||||
engine->WriteMessage(filename.toUtf8(), 0, 0, asMSGTYPE_ERROR,
|
||||
msg.toUtf8());
|
||||
|
||||
// TODO: Write the file where this one was included from
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -888,6 +983,37 @@ bool AsPreprocesser::endLinePassFailed(const QByteArray &modifiedScript,
|
|||
return endError;
|
||||
}
|
||||
|
||||
QByteArray
|
||||
AsPreprocesser::processIfExpression(const QByteArray &codes, int currentLine,
|
||||
const QByteArray ¤tSection) {
|
||||
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 r = v;
|
||||
while (definedWords.contains(r)) {
|
||||
|
|
|
@ -138,6 +138,9 @@ protected:
|
|||
|
||||
bool endLinePassFailed(const QByteArray &modifiedScript, int pos);
|
||||
|
||||
QByteArray processIfExpression(const QByteArray &codes, int currentLine,
|
||||
const QByteArray ¤tSection);
|
||||
|
||||
QByteArray findReplaceResult(const QByteArray &v);
|
||||
|
||||
asIScriptEngine *engine;
|
||||
|
|
|
@ -3126,8 +3126,8 @@ void PluginSystem::applyFunctionTables(IWingPluginBase *plg,
|
|||
plg->setProperty("__CALL_POINTER__", quintptr(this));
|
||||
}
|
||||
|
||||
QString PluginSystem::type2AngelScriptString(IWingPlugin::MetaType type,
|
||||
bool isArg, bool noModifier) {
|
||||
QString PluginSystem::type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier) {
|
||||
auto isArray = !!(type & WingHex::IWingPlugin::Array);
|
||||
auto isList = !!(type & WingHex::IWingPlugin::List);
|
||||
auto isContainer = isArray || isList;
|
||||
|
|
|
@ -175,8 +175,8 @@ public:
|
|||
|
||||
static QString getPUID(IWingPluginBase *p);
|
||||
|
||||
static QString type2AngelScriptString(IWingPlugin::MetaType type,
|
||||
bool isArg, bool noModifier = false);
|
||||
static QString type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier = false);
|
||||
|
||||
private:
|
||||
void loadExtPlugin();
|
||||
|
|
|
@ -147,7 +147,6 @@ bool ScriptMachine::isRunning(ConsoleMode mode) const {
|
|||
#define INS_2 INS_1 ", " INS_1
|
||||
#define INS_4 INS_2 ", " INS_2
|
||||
#define INS_8 INS_4 ", " INS_4
|
||||
#define INS_16 INS_8 ", " INS_8
|
||||
|
||||
bool ScriptMachine::configureEngine() {
|
||||
if (_engine == nullptr) {
|
||||
|
@ -219,7 +218,7 @@ bool ScriptMachine::configureEngine() {
|
|||
|
||||
// Register a couple of extra functions for the scripts
|
||||
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);
|
||||
Q_ASSERT(r >= 0);
|
||||
if (r < 0) {
|
||||
|
@ -227,7 +226,7 @@ bool ScriptMachine::configureEngine() {
|
|||
}
|
||||
|
||||
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);
|
||||
Q_ASSERT(r >= 0);
|
||||
if (r < 0) {
|
||||
|
@ -680,7 +679,7 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
|||
QScopeGuard guard([this, oldMode]() { _curMsgMode = oldMode; });
|
||||
|
||||
auto ccode = code;
|
||||
ccode.prepend("bool f(){ return (").append(");}");
|
||||
ccode.prepend("bool f(){ return bool(").append(");}");
|
||||
// start to compile
|
||||
|
||||
_curMsgMode = DefineEvaluator;
|
||||
|
|
|
@ -95,7 +95,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
|
|||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::structTypes),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType(MetaType::String | MetaType::Array);
|
||||
info.ret = MetaType::String | MetaType::Array;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("structTypes"), info);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
|
|||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::constDefines),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType(MetaType::String | MetaType::Array);
|
||||
info.ret = MetaType::String | MetaType::Array;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("constDefines"), info);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
|
|||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::readRaw), this,
|
||||
std::placeholders::_1);
|
||||
info.ret = MetaType(MetaType::Byte | MetaType::Array);
|
||||
info.ret = MetaType::Byte | MetaType::Array;
|
||||
|
||||
info.params.append(
|
||||
qMakePair(getqsizetypeMetaType(), QStringLiteral("offset")));
|
||||
|
@ -542,7 +542,6 @@ CScriptDictionary *WingCStruct::convert2AsDictionary(const QVariantHash &hash) {
|
|||
switch (type) {
|
||||
case QMetaType::Bool:
|
||||
case QMetaType::UChar:
|
||||
case QMetaType::Char:
|
||||
case QMetaType::Int:
|
||||
case QMetaType::Long:
|
||||
case QMetaType::LongLong:
|
||||
|
@ -564,6 +563,13 @@ CScriptDictionary *WingCStruct::convert2AsDictionary(const QVariantHash &hash) {
|
|||
case QMetaType::Float:
|
||||
dic->Set(p->first, var.toDouble());
|
||||
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)
|
||||
case QMetaType::Char16: {
|
||||
auto v = var.value<char16_t>();
|
||||
|
|
|
@ -242,8 +242,12 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
|
|||
contextLen = raw.length();
|
||||
m_findResults->setEncoding(result.encoding);
|
||||
d->findAllBytes(begin, end, raw, results);
|
||||
m_findResults->lastFindData() = qMakePair(data, contextLen);
|
||||
} 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();
|
||||
|
@ -257,12 +261,9 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
|
|||
r.col = r.offset % lineWidth;
|
||||
m_findResults->results().append(r);
|
||||
m_findResults->findData().append(
|
||||
readContextFinding(ritem, contextLen, FIND_CONTEXT_SIZE,
|
||||
FIND_MAX_DISPLAY_FIND_CHARS));
|
||||
readContextFinding(ritem, contextLen));
|
||||
}
|
||||
|
||||
m_findResults->lastFindData() = data;
|
||||
|
||||
m_findResults->endUpdate();
|
||||
|
||||
if (m_findResults->size() >= QHEXVIEW_FIND_LIMIT) {
|
||||
|
@ -804,34 +805,50 @@ bool EditorView::checkHasUnsavedState() const {
|
|||
}
|
||||
|
||||
FindResultModel::FindInfo EditorView::readContextFinding(qsizetype offset,
|
||||
qsizetype findSize,
|
||||
int contextSize,
|
||||
int maxDisplayBytes) {
|
||||
qsizetype findSize) {
|
||||
constexpr long DISPLAY_SIZE = 16;
|
||||
constexpr long FIND_CONTENXT_LEN = 10;
|
||||
constexpr long HT_SIZE = (DISPLAY_SIZE - FIND_CONTENXT_LEN) / 2;
|
||||
|
||||
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 header = doc->read(offset, qMin(findSize, halfSize));
|
||||
QByteArray tailer;
|
||||
if (header.size() < findSize) {
|
||||
auto len = qMin(findSize, qsizetype(maxDisplayBytes) - halfSize);
|
||||
tailer = doc->read(offset + findSize - len, len);
|
||||
auto headerlen = HT_SIZE + rs.quot + rs.rem;
|
||||
auto taillen = HT_SIZE + rs.quot;
|
||||
|
||||
auto begin = qMax(offset - headerlen, 0);
|
||||
auto end = qMin(offset + findSize + taillen, doc->length());
|
||||
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,
|
||||
|
|
|
@ -225,9 +225,7 @@ private:
|
|||
bool checkHasUnsavedState() const;
|
||||
|
||||
FindResultModel::FindInfo readContextFinding(qsizetype offset,
|
||||
qsizetype findSize,
|
||||
int contextSize,
|
||||
int maxDisplayBytes);
|
||||
qsizetype findSize);
|
||||
|
||||
void applyFunctionTables(WingHex::WingEditorViewWidget *view,
|
||||
const CallTable &fns);
|
||||
|
|
|
@ -102,3 +102,17 @@ bool QHexTextEdit::isHexMode() const { return m_isHexMode; }
|
|||
void QHexTextEdit::setIsHexMode(bool 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();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ public:
|
|||
bool isHexMode() const;
|
||||
void setIsHexMode(bool newIsHexMode);
|
||||
|
||||
public:
|
||||
// must be 'xx xx xx' style
|
||||
void setFindText(const QString &text);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
|
|
@ -52,6 +52,7 @@ void ScrollableLabel::wheelEvent(QWheelEvent *event) {
|
|||
void ScrollableLabel::resizeEvent(QResizeEvent *event) {
|
||||
QScrollArea::resizeEvent(event);
|
||||
updateLabelSize();
|
||||
adjustDisplayLogic();
|
||||
}
|
||||
|
||||
void ScrollableLabel::setupUI() {
|
||||
|
@ -60,7 +61,7 @@ void ScrollableLabel::setupUI() {
|
|||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
label.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
label.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
label.setWordWrap(false);
|
||||
label.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
|
||||
|
@ -82,3 +83,18 @@ void ScrollableLabel::updateLabelSize() {
|
|||
bool ScrollableLabel::shouldScroll() const {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ private:
|
|||
void updateLabelSize();
|
||||
|
||||
bool shouldScroll() const;
|
||||
|
||||
void adjustDisplayLogic();
|
||||
};
|
||||
|
||||
#endif // MARQUEELABEL_H
|
||||
|
|
|
@ -89,7 +89,7 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
|
|||
m_findMode->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
m_lineeditor->setText(info.str);
|
||||
m_lineeditor->setFindText(info.str);
|
||||
|
||||
auto regionw = new QWidget(this);
|
||||
auto regionLayout = new QHBoxLayout(regionw);
|
||||
|
|
|
@ -714,10 +714,17 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
|
|||
|
||||
cursor->moveTo(fm->resultAt(index.row()).offset);
|
||||
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"),
|
||||
tr("FindResult") + QStringLiteral(" (ASCII)"),
|
||||
m_findresult);
|
||||
|
@ -2127,7 +2134,6 @@ void MainWindow::on_findfile() {
|
|||
ExecAsync<EditorView::FindError>(
|
||||
[this, r]() -> EditorView::FindError {
|
||||
m_isfinding = true;
|
||||
|
||||
return currentEditor()->find(r);
|
||||
},
|
||||
[this](EditorView::FindError err) {
|
||||
|
@ -2151,6 +2157,14 @@ void MainWindow::on_findfile() {
|
|||
if (result) {
|
||||
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_isfinding = false;
|
||||
|
@ -2595,7 +2609,7 @@ void MainWindow::on_exportfindresult() {
|
|||
|
||||
auto d = findresitem->lastFindData();
|
||||
|
||||
fobj.insert(QStringLiteral("find"), d);
|
||||
fobj.insert(QStringLiteral("find"), d.first);
|
||||
QJsonArray arr;
|
||||
for (int i = 0; i < c; i++) {
|
||||
auto data = findresitem->resultAt(i);
|
||||
|
|
|
@ -135,7 +135,9 @@ QList<FindResultModel::FindInfo> &FindResultModel::findData() {
|
|||
return m_findData;
|
||||
}
|
||||
|
||||
QString &FindResultModel::lastFindData() { return m_lastFindData; }
|
||||
QPair<QString, qsizetype> &FindResultModel::lastFindData() {
|
||||
return m_lastFindData;
|
||||
}
|
||||
|
||||
void FindResultModel::beginUpdate() { this->beginResetModel(); }
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
QList<FindResult> &results();
|
||||
QList<FindInfo> &findData();
|
||||
QString &lastFindData();
|
||||
QPair<QString, qsizetype> &lastFindData();
|
||||
|
||||
void beginUpdate();
|
||||
void endUpdate();
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
private:
|
||||
QList<FindResult> m_results;
|
||||
QList<FindInfo> m_findData;
|
||||
QString m_lastFindData;
|
||||
QPair<QString, qsizetype> m_lastFindData;
|
||||
|
||||
QString m_encoding;
|
||||
};
|
||||
|
|
|
@ -52,9 +52,6 @@
|
|||
|
||||
#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) {
|
||||
return ":/com.wingsummer.winghex/images/" + name + ".png";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue