fix: 修复代码提示相关和字节搜索框问题;

This commit is contained in:
寂静的羽夏 2025-05-09 12:40:39 +08:00
parent 1be1f7322f
commit 066ab5375b
21 changed files with 1458 additions and 1614 deletions

View File

@ -67,7 +67,7 @@ if(WINGHEX_USE_FRAMELESS)
option(QWINDOWKIT_BUILD_STATIC "Build static libraries" TRUE) option(QWINDOWKIT_BUILD_STATIC "Build static libraries" TRUE)
option(QWINDOWKIT_INSTALL "Install library" OFF) option(QWINDOWKIT_INSTALL "Install library" OFF)
add_subdirectory(3rdparty/qwindowkit) add_subdirectory(3rdparty/qwindowkit)
add_definitions(-DWINGHEX_USE_FRAMELESS) add_compile_definitions(WINGHEX_USE_FRAMELESS)
endif() endif()
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
@ -194,8 +194,6 @@ set(CONTROL_SRC
src/control/qlistviewext.cpp src/control/qlistviewext.cpp
src/control/asobjtreewidget.h src/control/asobjtreewidget.h
src/control/asobjtreewidget.cpp src/control/asobjtreewidget.cpp
src/control/qtlonglongspinbox.cpp
src/control/qtlonglongspinbox.h
src/control/dockwidgettab.h src/control/dockwidgettab.h
src/control/dockwidgettab.cpp src/control/dockwidgettab.cpp
src/control/qhextextedit.h src/control/qhextextedit.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,9 @@
#include "class/aspreprocesser.h" #include "class/aspreprocesser.h"
#include "class/qascodeparser.h" #include "class/qascodeparser.h"
#include "class/scriptmachine.h" #include "class/scriptmachine.h"
#include "control/scripteditor.h"
#include "model/codecompletionmodel.h" #include "model/codecompletionmodel.h"
#include "utilities.h"
#include "wingcodeedit.h" #include "wingcodeedit.h"
#include <QAbstractItemView> #include <QAbstractItemView>
@ -141,7 +143,7 @@ void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) {
int AsCompletion::includeCallBack(const QString &include, bool quotedInclude, int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
const QString &from, AsPreprocesser *builder, const QString &from, AsPreprocesser *builder,
void *userParam) { void *userParam) {
Q_UNUSED(userParam); auto p = reinterpret_cast<AsCompletion *>(userParam);
QFileInfo info(include); QFileInfo info(include);
bool isAbsolute = info.isAbsolute(); bool isAbsolute = info.isAbsolute();
@ -151,7 +153,9 @@ int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
if (isAbsolute) { if (isAbsolute) {
inc = include; inc = include;
} else { } else {
auto pwd = QFileInfo(from).absoluteDir(); auto editor = qobject_cast<ScriptEditor *>(p->widget()->parent());
Q_ASSERT(editor);
auto pwd = QFileInfo(editor->fileName()).absoluteDir();
inc = pwd.absoluteFilePath(include); inc = pwd.absoluteFilePath(include);
} }
} else { } else {
@ -177,6 +181,42 @@ int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
return asSUCCESS; return asSUCCESS;
} }
void AsCompletion::pushCompleteDBData(const QString &fileName,
const QList<CodeInfoTip> &data) {
if (!QFile::exists(fileName)) {
return;
}
CompleteDB c;
c.data = data;
c.md5 = Utilities::getMd5(fileName);
c.time = 3;
comdb.insert(fileName, c);
}
void AsCompletion::remoteCompleteDBData(const QString &fileName) {
comdb.remove(fileName);
}
std::optional<AsCompletion::CompleteDB>
AsCompletion::getCompleteDBData(const QString &fileName) {
if (comdb.contains(fileName)) {
auto ret = comdb[fileName];
ret.time++;
return ret;
}
return std::nullopt;
}
void AsCompletion::clearCompleteDBUnused() {
for (auto &c : comdb) {
c.time--;
}
comdb.removeIf(
[](const QPair<QString, CompleteDB> &c) { return c.second.time == 0; });
}
void AsCompletion::clearFunctionTip() { emit onFunctionTip({}); } void AsCompletion::clearFunctionTip() { emit onFunctionTip({}); }
QString AsCompletion::wordSeperators() const { QString AsCompletion::wordSeperators() const {
@ -340,7 +380,7 @@ bool AsCompletion::processTrigger(const QString &trigger,
return basicType.contains(type); return basicType.contains(type);
}; };
auto clsNodes = parser.headerNodes(); auto clsNodes = parser.classNodes();
// filter the type we can use to auto-complete in docNodes // filter the type we can use to auto-complete in docNodes
for (auto &item : docNodes) { for (auto &item : docNodes) {
@ -348,6 +388,8 @@ bool AsCompletion::processTrigger(const QString &trigger,
auto name = item.nameSpace; auto name = item.nameSpace;
if (name.isEmpty()) { if (name.isEmpty()) {
name = item.name; name = item.name;
} else {
name += QStringLiteral("::") + item.name;
} }
clsNodes.insert(name, item.children); clsNodes.insert(name, item.children);
} }
@ -464,10 +506,29 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
for (auto &d : data) { for (auto &d : data) {
qsizetype offset = -1; qsizetype offset = -1;
QList<CodeInfoTip> dd;
if (d.section == QStringLiteral("ASCOMPLETION")) { if (d.section == QStringLiteral("ASCOMPLETION")) {
offset = editor->textCursor().position(); offset = editor->textCursor().position();
} else {
auto r = getCompleteDBData(d.section);
if (r) {
auto md5 = r->md5;
if (Utilities::getMd5(d.section) == md5) {
dd = r->data;
} else {
remoteCompleteDBData(d.section);
}
}
} }
ret.append(parseScriptData(offset, d.script));
if (dd.isEmpty()) {
dd = parseScriptData(offset, d.script);
if (offset < 0) {
pushCompleteDBData(d.section, dd);
}
}
ret.append(dd);
} }
return ret; return ret;
@ -476,8 +537,8 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
QList<CodeInfoTip> AsCompletion::parseMarcos() { QList<CodeInfoTip> AsCompletion::parseMarcos() {
static QList<CodeInfoTip> marcos; static QList<CodeInfoTip> marcos;
if (marcos.isEmpty()) { if (marcos.isEmpty()) {
QStringList m{"define", "undef", "if", "else", QStringList m{"define", "undef", "if", "else", "endif",
"endif", "ifdef", "ifndef"}; "ifdef", "ifndef", "include", "pragma"};
for (auto &i : m) { for (auto &i : m) {
CodeInfoTip tip; CodeInfoTip tip;
tip.name = i; tip.name = i;

View File

@ -64,6 +64,21 @@ private:
const QString &from, AsPreprocesser *builder, const QString &from, AsPreprocesser *builder,
void *userParam); void *userParam);
private:
struct CompleteDB {
QList<CodeInfoTip> data;
QByteArray md5;
uint time = 0;
};
QHash<QString, CompleteDB> comdb;
void pushCompleteDBData(const QString &fileName,
const QList<CodeInfoTip> &data);
std::optional<CompleteDB> getCompleteDBData(const QString &fileName);
void remoteCompleteDBData(const QString &fileName);
void clearCompleteDBUnused();
private: private:
ASDataBase parser; ASDataBase parser;
}; };

View File

@ -326,6 +326,42 @@ void ASDataBase::addClassCompletion(asIScriptEngine *engine) {
obj->Release(); obj->Release();
_headerNodes[ns].append(cls); _headerNodes[ns].append(cls);
auto cat = cls.nameSpace;
if (cat.isEmpty()) {
cat = cls.name;
} else {
cat += QStringLiteral("::") + cls.name;
}
auto data = cls.children;
data.removeIf([](const CodeInfoTip &tip) {
static QStringList opList{
"opNeg", "opCom", "opPreInc", "opPreDec",
"opPostInc", "opPostDec", "opEquals", "opCmp",
"opEquals", "opAssign", "opAddAssign", "opSubAssign",
"opMulAssign", "opDivAssign", "opModAssign", "opPowAssign",
"opAndAssign", "opOrAssign", "opXorAssign", "opShlAssign",
"opShrAssign", "opUShrAssign", "opAdd", "opAdd_r",
"opSub", "opSub_r", "opMul", "opMul_r",
"opDiv", "opDiv_r", "opMod", "opMod_r",
"opPow", "opPow_r", "opAnd", "opAnd_r",
"opOr", "opOr_r", "opXor", "opXor_r",
"opShl", "opShl_r", "opShr", "opShr_r",
"opUShr", "opUShr_r", "opIndex", "opCall",
"opConv", "opImplConv", "opCast", "opImplCast"};
return tip.addinfo.value(CodeInfoTip::RetType).isEmpty() ||
opList.contains(tip.name);
});
for (auto &d : data) {
d.addinfo.insert(
CodeInfoTip::Comment,
d.addinfo.value(CodeInfoTip::RetType) + QStringLiteral(" ") +
d.name + QStringLiteral("(") +
d.addinfo.value(CodeInfoTip::Args) + QStringLiteral(") ") +
d.addinfo.value(CodeInfoTip::SuffixQualifier));
}
_classNodes[cat].append(data);
} }
} }
@ -336,6 +372,10 @@ QString ASDataBase::getSuffixQualifier(asIScriptFunction *fn) {
return {}; return {};
} }
const QHash<QString, QList<CodeInfoTip>> &ASDataBase::classNodes() const {
return _classNodes;
}
const QList<CodeInfoTip> &ASDataBase::keywordNodes() const { const QList<CodeInfoTip> &ASDataBase::keywordNodes() const {
return _keywordNode; return _keywordNode;
} }

View File

@ -43,6 +43,7 @@ private:
public: public:
const QHash<QString, QList<CodeInfoTip>> &headerNodes() const; const QHash<QString, QList<CodeInfoTip>> &headerNodes() const;
const QHash<QString, QList<CodeInfoTip>> &enumsNodes() const; const QHash<QString, QList<CodeInfoTip>> &enumsNodes() const;
const QHash<QString, QList<CodeInfoTip>> &classNodes() const;
const QList<CodeInfoTip> &keywordNodes() const; const QList<CodeInfoTip> &keywordNodes() const;
@ -57,6 +58,7 @@ private:
// <namespace, content> // <namespace, content>
QHash<QString, QList<CodeInfoTip>> _headerNodes; QHash<QString, QList<CodeInfoTip>> _headerNodes;
QHash<QString, QList<CodeInfoTip>> _enumsNodes; QHash<QString, QList<CodeInfoTip>> _enumsNodes;
QHash<QString, QList<CodeInfoTip>> _classNodes;
QList<CodeInfoTip> _keywordNode; QList<CodeInfoTip> _keywordNode;
}; };

View File

@ -1450,6 +1450,7 @@ void QAsCodeParser::parseNamespace() {
QList<QAsCodeParser::Symbol> QList<QAsCodeParser::Symbol>
QAsCodeParser::parseGlobalVarDecls(const QByteArrayList &ns, QAsCodeParser::parseGlobalVarDecls(const QByteArrayList &ns,
const QByteArray &code) { const QByteArray &code) {
reset();
_code = code; _code = code;
return parseDeclaration(-1, ns, false, true); return parseDeclaration(-1, ns, false, true);
} }

View File

@ -216,6 +216,8 @@ bool ScriptMachine::configureEngine() {
_rtypes[RegisteredType::tColor] = _rtypes[RegisteredType::tColor] =
q_check_ptr(_engine->GetTypeInfoByName("color")); q_check_ptr(_engine->GetTypeInfoByName("color"));
_engine->SetDefaultAccessMask(0x1);
// 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_8 ")", "void print(const ? &in obj, const ? &in = null," INS_8 ")",
@ -468,7 +470,7 @@ QString ScriptMachine::stringify(void *ref, int typeId) {
bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script, bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
bool isInDebug, int *retCode) { bool isInDebug, int *retCode) {
Q_ASSERT(mode != Interactive && mode != DefineEvaluator); Q_ASSERT(mode != Interactive);
if (QThread::currentThread() != qApp->thread()) { if (QThread::currentThread() != qApp->thread()) {
Logger::warning(tr("Code must be exec in the main thread")); Logger::warning(tr("Code must be exec in the main thread"));
return false; return false;
@ -576,6 +578,14 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true); asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
_ctx[mode] = ctx; _ctx[mode] = ctx;
if (mode == Background) {
MessageInfo info;
info.mode = mode;
info.message = tr("Run:") + script;
info.type = MessageType::Info;
outputMessage(info);
}
ctx->SetUserData(reinterpret_cast<void *>( ctx->SetUserData(reinterpret_cast<void *>(
AppManager::instance()->currentMSecsSinceEpoch()), AppManager::instance()->currentMSecsSinceEpoch()),
AsUserDataType::UserData_Timer); AsUserDataType::UserData_Timer);
@ -671,72 +681,71 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
} }
int ScriptMachine::evaluateDefine(const QString &code, bool &result) { int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
auto mod = createModuleIfNotExist(DefineEvaluator); QByteArray name =
if (mod) { QByteArrayLiteral("WINGDEF") +
asIScriptFunction *func = nullptr; QByteArray::number(AppManager::instance()->currentMSecsSinceEpoch());
auto oldMode = _curMsgMode; auto mod = _engine->GetModule(name.data(), asGM_ALWAYS_CREATE);
QScopeGuard guard([this, oldMode]() { _curMsgMode = oldMode; }); mod->SetAccessMask(0x2);
auto ccode = code; asIScriptFunction *func = nullptr;
ccode.prepend("bool f(){ return bool(").append(");}"); QScopeGuard guard([mod]() {
// start to compile // Before leaving, allow the engine to clean up remaining objects by
// discarding the module and doing a full garbage collection so that
// this can also be debugged if desired
mod->Discard();
});
_curMsgMode = DefineEvaluator; auto ccode = code;
auto cr = mod->CompileFunction(nullptr, ccode.toUtf8(), 0, 0, &func); ccode.prepend("bool f(){ return bool(").append(");}");
if (cr < 0) { // start to compile
return cr;
}
// Set up a context to execute the script auto cr = mod->CompileFunction(nullptr, ccode.toUtf8(), 0, 0, &func);
// The context manager will request the context from the if (cr < 0) {
// pool, which will automatically attach the debugger return cr;
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
_ctx[DefineEvaluator] = ctx;
ctx->SetUserData(reinterpret_cast<void *>(asPWORD(
AppManager::instance()->currentMSecsSinceEpoch())),
AsUserDataType::UserData_Timer);
asPWORD isDbg = 0;
ctx->SetUserData(reinterpret_cast<void *>(isDbg),
AsUserDataType::UserData_isDbg);
mod->SetUserData(reinterpret_cast<void *>(isDbg),
AsUserDataType::UserData_isDbg);
asPWORD umode = asPWORD(DefineEvaluator);
ctx->SetUserData(reinterpret_cast<void *>(umode),
AsUserDataType::UserData_ContextMode);
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback),
this, asCALL_THISCALL);
// Execute the script until completion
// The script may create co-routines. These will automatically
// be managed by the context manager
while (_ctxMgr->ExecuteScripts()) {
qApp->processEvents();
}
_ctx[DefineEvaluator] = nullptr;
// Check if the main script finished normally
int r = ctx->GetState();
if (r != asEXECUTION_FINISHED) {
r = -1;
} else {
result = bool(ctx->GetReturnByte());
r = 0;
}
func->Release();
// Return the context after retrieving the return value
_ctxMgr->DoneWithContext(ctx);
_engine->GarbageCollect();
return r;
} }
return asERROR;
// Set up a context to execute the script
// The context manager will request the context from the
// pool, which will automatically attach the debugger
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
ctx->SetUserData(reinterpret_cast<void *>(asPWORD(
AppManager::instance()->currentMSecsSinceEpoch())),
AsUserDataType::UserData_Timer);
asPWORD isDbg = 0;
ctx->SetUserData(reinterpret_cast<void *>(isDbg),
AsUserDataType::UserData_isDbg);
mod->SetUserData(reinterpret_cast<void *>(isDbg),
AsUserDataType::UserData_isDbg);
ctx->SetUserData(0, AsUserDataType::UserData_ContextMode);
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback), this,
asCALL_THISCALL);
// Execute the script until completion
// The script may create co-routines. These will automatically
// be managed by the context manager
while (_ctxMgr->ExecuteScripts()) {
qApp->processEvents();
}
// Check if the main script finished normally
int r = ctx->GetState();
if (r != asEXECUTION_FINISHED) {
r = -1;
} else {
result = bool(ctx->GetReturnByte());
r = 0;
}
func->Release();
// Return the context after retrieving the return value
_ctxMgr->DoneWithContext(ctx);
_engine->GarbageCollect();
return r;
} }
void ScriptMachine::abortDbgScript() { void ScriptMachine::abortDbgScript() {
@ -831,10 +840,6 @@ asIScriptModule *ScriptMachine::createModule(ConsoleMode mode) {
mod = _engine->GetModule("WINGSRV", asGM_ALWAYS_CREATE); mod = _engine->GetModule("WINGSRV", asGM_ALWAYS_CREATE);
mod->SetAccessMask(0x1); mod->SetAccessMask(0x1);
break; break;
case DefineEvaluator:
mod = _engine->GetModule("WINGDEF", asGM_ALWAYS_CREATE);
mod->SetAccessMask(0x2);
break;
} }
return mod; return mod;
@ -855,10 +860,6 @@ asIScriptModule *ScriptMachine::createModuleIfNotExist(ConsoleMode mode) {
mod = _engine->GetModule("WINGSRV", asGM_CREATE_IF_NOT_EXISTS); mod = _engine->GetModule("WINGSRV", asGM_CREATE_IF_NOT_EXISTS);
mod->SetAccessMask(0x1); mod->SetAccessMask(0x1);
break; break;
case DefineEvaluator:
mod = _engine->GetModule("WINGDEF", asGM_ALWAYS_CREATE);
mod->SetAccessMask(0x2);
break;
} }
return mod; return mod;
@ -872,8 +873,6 @@ asIScriptModule *ScriptMachine::module(ConsoleMode mode) {
return _engine->GetModule("WINGSCRIPT", asGM_ONLY_IF_EXISTS); return _engine->GetModule("WINGSCRIPT", asGM_ONLY_IF_EXISTS);
case Background: case Background:
return _engine->GetModule("WINGSRV", asGM_ONLY_IF_EXISTS); return _engine->GetModule("WINGSRV", asGM_ONLY_IF_EXISTS);
case DefineEvaluator:
return _engine->GetModule("WINGDEF", asGM_ONLY_IF_EXISTS);
} }
return nullptr; return nullptr;
} }
@ -2070,22 +2069,38 @@ void ScriptMachine::registerEngineClipboard(asIScriptEngine *engine) {
asCALL_CDECL); asCALL_CDECL);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
Q_UNUSED(r); Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"string text()", asFUNCTION(clip_getText), asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction( r = engine->RegisterGlobalFunction(
"void setBinary(const uint8[]@ data)", asFUNCTION(clip_setBinary), "void setBinary(const uint8[]@ data)", asFUNCTION(clip_setBinary),
asCALL_CDECL); asCALL_CDECL);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
Q_UNUSED(r); Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"uint8[]@ getBinary()", asFUNCTION(clip_getBinary), asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
} else { } else {
r = engine->RegisterGlobalFunction( r = engine->RegisterGlobalFunction(
"void setText(const string &in text)", WRAP_FN(clip_setText), "void setText(const string &in text)", WRAP_FN(clip_setText),
asCALL_GENERIC); asCALL_GENERIC);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
Q_UNUSED(r); Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"string text()", asFUNCTION(clip_getText), asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction( r = engine->RegisterGlobalFunction(
"void setBinary(const uint8[]@ data)", WRAP_FN(clip_setBinary), "void setBinary(const uint8[]@ data)", WRAP_FN(clip_setBinary),
asCALL_GENERIC); asCALL_GENERIC);
Q_ASSERT(r >= 0); Q_ASSERT(r >= 0);
Q_UNUSED(r); Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"uint8[]@ getBinary()", WRAP_FN(clip_getBinary), asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
} }
engine->SetDefaultNamespace(""); engine->SetDefaultNamespace("");
@ -2140,6 +2155,28 @@ void ScriptMachine::clip_setBinary(const CScriptArray &array) {
c->setMimeData(mime); c->setMimeData(mime);
} }
QString ScriptMachine::clip_getText() { return qApp->clipboard()->text(); }
CScriptArray *ScriptMachine::clip_getBinary() {
QClipboard *c = qApp->clipboard();
QByteArray data;
auto d = c->mimeData();
data = d->data(QStringLiteral("application/octet-stream"));
auto engine = ScriptMachine::instance().engine();
auto len = data.size();
auto arr =
CScriptArray::Create(engine->GetTypeInfoByDecl("array<uint8>"), len);
arr->AddRef();
for (int i = 0; i < len; ++i) {
auto addr = arr->At(i);
*reinterpret_cast<char *>(addr) = data.at(i);
}
arr->Release();
return arr;
}
void ScriptMachine::scriptThrow(const QString &msg) { void ScriptMachine::scriptThrow(const QString &msg) {
asIScriptContext *ctx = asGetActiveContext(); asIScriptContext *ctx = asGetActiveContext();
if (ctx) { if (ctx) {
@ -2183,7 +2220,7 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
asIScriptFunction *func = nullptr; asIScriptFunction *func = nullptr;
QList<QAsCodeParser::CodeSegment> ret; QList<QAsCodeParser::CodeSegment> ret;
if (mode != DefineEvaluator) { if (mode > 0) {
ret = parser.parse(ccode); ret = parser.parse(ccode);
} }

View File

@ -38,10 +38,9 @@ private:
public: public:
// we have three console modes // we have three console modes
enum ConsoleMode { enum ConsoleMode {
Interactive, // in a shell Interactive = 1, // in a shell
Scripting, // in scripting dialog Scripting, // in scripting dialog
Background, // run codes from other way Background, // run codes from other way
DefineEvaluator // define result calculator
}; };
public: public:
@ -137,6 +136,8 @@ public:
static void clip_setText(const QString &text); static void clip_setText(const QString &text);
static void clip_setBinary(const CScriptArray &array); static void clip_setBinary(const CScriptArray &array);
static QString clip_getText();
static CScriptArray *clip_getBinary();
static void scriptThrow(const QString &msg); static void scriptThrow(const QString &msg);

View File

@ -73,6 +73,11 @@ QString ScriptManager::readJsonObjString(const QJsonObject &jobj,
return {}; return {};
} }
bool ScriptManager::readJsonObjBool(const QJsonObject &jobj,
const QString &key) {
return jobj.value(key).toBool();
}
QMenu *ScriptManager::buildUpScriptDirMenu(QWidget *parent, QMenu *ScriptManager::buildUpScriptDirMenu(QWidget *parent,
const QStringList &files, const QStringList &files,
bool isSys) { bool isSys) {
@ -167,6 +172,7 @@ ScriptManager::ensureDirMeta(const QFileInfo &info) {
jobj.insert(QStringLiteral("license"), QLatin1String()); jobj.insert(QStringLiteral("license"), QLatin1String());
jobj.insert(QStringLiteral("homepage"), QLatin1String()); jobj.insert(QStringLiteral("homepage"), QLatin1String());
jobj.insert(QStringLiteral("comment"), QLatin1String()); jobj.insert(QStringLiteral("comment"), QLatin1String());
jobj.insert(QStringLiteral("hexmenu"), false);
QFile f(base.absoluteFilePath(QStringLiteral(".wingasmeta"))); QFile f(base.absoluteFilePath(QStringLiteral(".wingasmeta")));
if (f.open(QFile::WriteOnly | QFile::Text)) { if (f.open(QFile::WriteOnly | QFile::Text)) {
QJsonDocument jdoc(jobj); QJsonDocument jdoc(jobj);
@ -195,6 +201,8 @@ ScriptManager::ensureDirMeta(const QFileInfo &info) {
readJsonObjString(jobj, QStringLiteral("homepage")); readJsonObjString(jobj, QStringLiteral("homepage"));
meta.comment = meta.comment =
readJsonObjString(jobj, QStringLiteral("comment")); readJsonObjString(jobj, QStringLiteral("comment"));
meta.isContextMenu =
readJsonObjBool(jobj, QStringLiteral("hexmenu"));
} else { } else {
meta.name = info.fileName(); meta.name = info.fileName();
} }
@ -217,9 +225,10 @@ ScriptManager::sysDirMeta(const QString &cat) const {
return _sysDirMetas.value(cat); return _sysDirMetas.value(cat);
} }
ScriptManager::ScriptActionMaps QList<QMenu *>
ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) { ScriptManager::buildUpScriptRunnerContext(RibbonButtonGroup *group,
ScriptActionMaps maps; QWidget *parent) {
QList<QMenu *> maps;
auto &sm = ScriptManager::instance(); auto &sm = ScriptManager::instance();
auto &stm = SettingManager::instance(); auto &stm = SettingManager::instance();
@ -229,10 +238,20 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
if (hideCats.contains(cat)) { if (hideCats.contains(cat)) {
continue; continue;
} }
maps.sysList << addPannelAction(
group, ICONRES(QStringLiteral("scriptfolder")), auto meta = sm.sysDirMeta(cat);
sm.sysDirMeta(cat).name,
addPannelAction(
group, ICONRES(QStringLiteral("scriptfolder")), meta.name,
buildUpScriptDirMenu(group, sm.getSysScriptFileNames(cat), true)); buildUpScriptDirMenu(group, sm.getSysScriptFileNames(cat), true));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, sm.getSysScriptFileNames(cat),
true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolder")));
maps << m;
}
} }
hideCats = stm.usrHideCats(); hideCats = stm.usrHideCats();
@ -240,10 +259,19 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
if (hideCats.contains(cat)) { if (hideCats.contains(cat)) {
continue; continue;
} }
maps.usrList << addPannelAction( auto meta = sm.usrDirMeta(cat);
group, ICONRES(QStringLiteral("scriptfolderusr")),
sm.usrDirMeta(cat).name, addPannelAction(
group, ICONRES(QStringLiteral("scriptfolderusr")), meta.name,
buildUpScriptDirMenu(group, sm.getUsrScriptFileNames(cat), false)); buildUpScriptDirMenu(group, sm.getUsrScriptFileNames(cat), false));
if (meta.isContextMenu) {
auto m = buildUpScriptDirMenu(parent, sm.getSysScriptFileNames(cat),
true);
m->setTitle(meta.name);
m->setIcon(ICONRES(QStringLiteral("scriptfolderusr")));
maps << m;
}
} }
return maps; return maps;

View File

@ -24,7 +24,6 @@
#include <QObject> #include <QObject>
#include "QWingRibbon/ribbonbuttongroup.h" #include "QWingRibbon/ribbonbuttongroup.h"
#include "control/scriptingconsole.h"
#include "utilities.h" #include "utilities.h"
class ScriptManager : public QObject { class ScriptManager : public QObject {
@ -38,14 +37,10 @@ public:
QString license; QString license;
QString homepage; QString homepage;
QString comment; QString comment;
bool isContextMenu = false;
bool isSys; // a flag bool isSys; // a flag
}; };
struct ScriptActionMaps {
QList<QToolButton *> sysList;
QList<QToolButton *> usrList;
};
public: public:
static ScriptManager &instance(); static ScriptManager &instance();
@ -68,7 +63,8 @@ public:
ScriptDirMeta usrDirMeta(const QString &cat) const; ScriptDirMeta usrDirMeta(const QString &cat) const;
ScriptDirMeta sysDirMeta(const QString &cat) const; ScriptDirMeta sysDirMeta(const QString &cat) const;
static ScriptActionMaps buildUpRibbonScriptRunner(RibbonButtonGroup *group); static QList<QMenu *> buildUpScriptRunnerContext(RibbonButtonGroup *group,
QWidget *parent);
private: private:
static QToolButton *addPannelAction(RibbonButtonGroup *pannel, static QToolButton *addPannelAction(RibbonButtonGroup *pannel,
@ -119,6 +115,8 @@ private:
QString readJsonObjString(const QJsonObject &jobj, const QString &key); QString readJsonObjString(const QJsonObject &jobj, const QString &key);
bool readJsonObjBool(const QJsonObject &jobj, const QString &key);
static QMenu *buildUpScriptDirMenu(QWidget *parent, static QMenu *buildUpScriptDirMenu(QWidget *parent,
const QStringList &files, bool isSys); const QStringList &files, bool isSys);

View File

@ -1188,13 +1188,15 @@ QByteArray WingAngelAPI::cArray2ByteArray(const CScriptArray &array, int byteID,
return {}; return {};
} }
auto len = array.GetSize();
QByteArray buffer; QByteArray buffer;
buffer.reserve(array.GetSize()); buffer.resize(len);
array.AddRef(); array.AddRef();
for (asUINT i = 0; i < array.GetSize(); ++i) {
auto item = reinterpret_cast<const asBYTE *>(array.At(i)); std::memcpy(buffer.data(), const_cast<CScriptArray &>(array).GetBuffer(),
buffer.append(*item); len);
}
array.Release(); array.Release();
return buffer; return buffer;
} }
@ -1993,9 +1995,7 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
if (info) { if (info) {
auto len = content.length(); auto len = content.length();
auto arr = CScriptArray::Create(info, len); auto arr = CScriptArray::Create(info, len);
for (decltype(len) i = 0; i < len; ++i) { std::memcpy(arr->GetBuffer(), content.data(), len);
arr->SetValue(i, content.at(i));
}
return arr; return arr;
} }
return nullptr; return nullptr;
@ -2003,6 +2003,10 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender, void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
MetaType type, const QList<void *> &content) { 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); Q_UNUSED(sender);
auto typeStr = PluginSystem::type2AngelScriptString( auto typeStr = PluginSystem::type2AngelScriptString(
MetaType(type | MetaType::Array), false, true); MetaType(type | MetaType::Array), false, true);
@ -2021,6 +2025,7 @@ void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
return arr; return arr;
} }
return nullptr; return nullptr;
#endif
} }
void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender, void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender,

View File

@ -1,257 +0,0 @@
/*==============================================================================
** 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 "qtlonglongspinbox.h"
#include <QEvent>
#include <QKeyEvent>
#include <QLineEdit>
#include <limits>
QtLongLongSpinBox::QtLongLongSpinBox(QWidget *parent)
: QAbstractSpinBox(parent) {
m_minimum = std::numeric_limits<qlonglong>::min();
m_maximum = std::numeric_limits<qlonglong>::max();
m_value = 0;
m_singleStep = 1;
m_base = 10;
setValue(m_value);
}
qlonglong QtLongLongSpinBox::value() const { return m_value; }
void QtLongLongSpinBox::setValue(qlonglong expectedNewValue) {
const qlonglong newValue = qBound(m_minimum, expectedNewValue, m_maximum);
const QString newValueString = QString::number(newValue, m_base);
lineEdit()->setText(m_prefix + newValueString + m_suffix);
if (m_value != newValue) {
m_value = newValue;
emit valueChanged(newValue);
}
}
QString QtLongLongSpinBox::prefix() const { return m_prefix; }
void QtLongLongSpinBox::setPrefix(const QString &prefix) {
m_prefix = prefix;
setValue(m_value);
}
QString QtLongLongSpinBox::suffix() const { return m_suffix; }
void QtLongLongSpinBox::setSuffix(const QString &suffix) {
m_suffix = suffix;
setValue(m_value);
}
QString QtLongLongSpinBox::cleanText() const {
return QString::number(m_value);
}
qlonglong QtLongLongSpinBox::singleStep() const { return m_singleStep; }
void QtLongLongSpinBox::setSingleStep(qlonglong step) { m_singleStep = step; }
qlonglong QtLongLongSpinBox::minimum() const { return m_minimum; }
void QtLongLongSpinBox::setMinimum(qlonglong min) {
m_minimum = min;
if (m_maximum < m_minimum) {
m_maximum = m_minimum;
}
setValue(m_value);
}
qlonglong QtLongLongSpinBox::maximum() const { return m_maximum; }
void QtLongLongSpinBox::setMaximum(qlonglong max) {
m_maximum = max;
if (m_maximum < m_minimum) {
m_maximum = m_minimum;
}
setValue(m_value);
}
void QtLongLongSpinBox::setRange(qlonglong min, qlonglong max) {
if (min < max) {
m_minimum = min;
m_maximum = max;
} else {
m_minimum = max;
m_maximum = min;
}
setValue(m_value);
}
void QtLongLongSpinBox::setDisplayIntegerBase(int base) {
if (m_base != base) {
m_base = base;
setValue(m_value);
}
}
int QtLongLongSpinBox::displayIntegerBase() const { return m_base; }
void QtLongLongSpinBox::keyPressEvent(QKeyEvent *event) {
switch (event->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
selectCleanText();
lineEditEditingFinalize();
}
QAbstractSpinBox::keyPressEvent(event);
}
void QtLongLongSpinBox::focusOutEvent(QFocusEvent *event) {
lineEditEditingFinalize();
QAbstractSpinBox::focusOutEvent(event);
}
QAbstractSpinBox::StepEnabled QtLongLongSpinBox::stepEnabled() const {
if (isReadOnly()) {
return StepNone;
}
StepEnabled se = StepNone;
if (wrapping() || m_value < m_maximum) {
se |= StepUpEnabled;
}
if (wrapping() || m_value > m_minimum) {
se |= StepDownEnabled;
}
return se;
}
void QtLongLongSpinBox::stepBy(int steps) {
if (isReadOnly()) {
return;
}
if (m_prefix + QString::number(m_value) + m_suffix != lineEdit()->text()) {
lineEditEditingFinalize();
}
qlonglong newValue = m_value + (steps * m_singleStep);
if (wrapping()) {
// emulating the behavior of QSpinBox
if (newValue > m_maximum) {
if (m_value == m_maximum) {
newValue = m_minimum;
} else {
newValue = m_maximum;
}
} else if (newValue < m_minimum) {
if (m_value == m_minimum) {
newValue = m_maximum;
} else {
newValue = m_minimum;
}
}
} else {
newValue = qBound(m_minimum, newValue, m_maximum);
}
setValue(newValue);
selectCleanText();
}
QValidator::State QtLongLongSpinBox::validate(QString &input, int &pos) const {
// first, we try to interpret as a number without prefixes
bool ok;
const qlonglong value = input.toLongLong(&ok);
if (input.isEmpty() || (ok && value <= m_maximum)) {
input = m_prefix + input + m_suffix;
pos += m_prefix.length();
return QValidator::Acceptable;
}
// if string of text editor aren't simple number, try to interpret it
// as a number with prefix and suffix
bool valid = true;
if (!m_prefix.isEmpty() && !input.startsWith(m_prefix)) {
valid = false;
}
if (!m_suffix.isEmpty() && !input.endsWith(m_suffix)) {
valid = false;
}
if (valid) {
const int start = m_prefix.length();
const int length = input.length() - start - m_suffix.length();
bool ok;
const QString number = input.mid(start, length);
const qlonglong value = number.toLongLong(&ok);
if (number.isEmpty() || (ok && value <= m_maximum)) {
return QValidator::Acceptable;
}
}
// otherwise not acceptable
return QValidator::Invalid;
}
void QtLongLongSpinBox::lineEditEditingFinalize() {
const QString text = lineEdit()->text();
// first, we try to read as a number without prefixes
bool ok;
qlonglong value = text.toLongLong(&ok);
if (ok) {
setValue(value);
return;
}
// if string of text editor aren't simple number, try to interpret it
// as a number with prefix and suffix
bool valid = true;
if (!m_prefix.isEmpty() && !text.startsWith(m_prefix)) {
valid = false;
} else if (!m_suffix.isEmpty() && !text.endsWith(m_suffix)) {
valid = false;
}
if (valid) {
const int start = m_prefix.length();
const int length = text.length() - start - m_suffix.length();
bool ok;
const qlonglong value = text.mid(start, length).toLongLong(&ok);
if (ok) {
setValue(value);
return;
}
}
// otherwise set old value
setValue(m_value);
}
void QtLongLongSpinBox::selectCleanText() {
lineEdit()->setSelection(m_prefix.length(), lineEdit()->text().length() -
m_prefix.length() -
m_suffix.length());
}

View File

@ -1,85 +0,0 @@
/*==============================================================================
** 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 QTLONGLONGSPINBOX_H
#define QTLONGLONGSPINBOX_H
#include <QAbstractSpinBox>
#include <QtGlobal>
class QtLongLongSpinBox : public QAbstractSpinBox {
Q_OBJECT
public:
explicit QtLongLongSpinBox(QWidget *parent = 0);
qlonglong value() const;
QString prefix() const;
void setPrefix(const QString &prefix);
QString suffix() const;
void setSuffix(const QString &suffix);
QString cleanText() const;
qlonglong singleStep() const;
void setSingleStep(qlonglong val);
qlonglong minimum() const;
void setMinimum(qlonglong min);
qlonglong maximum() const;
void setMaximum(qlonglong max);
void setRange(qlonglong min, qlonglong max);
void setDisplayIntegerBase(int base);
int displayIntegerBase() const;
public slots:
void setValue(qlonglong value);
signals:
void valueChanged(qlonglong i);
protected:
virtual void keyPressEvent(QKeyEvent *event);
virtual void focusOutEvent(QFocusEvent *event);
virtual void stepBy(int steps);
virtual StepEnabled stepEnabled() const;
virtual QValidator::State validate(QString &input, int &pos) const;
private:
void lineEditEditingFinalize();
void selectCleanText();
private:
QString m_prefix;
QString m_suffix;
qlonglong m_singleStep;
qlonglong m_minimum;
qlonglong m_maximum;
qlonglong m_value;
int m_base;
private:
Q_DISABLE_COPY(QtLongLongSpinBox)
};
#endif // QTLONGLONGSPINBOX_H

View File

@ -83,40 +83,16 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
if (info.isStringFind) { if (info.isStringFind) {
if (!info.encoding.isEmpty()) { if (!info.encoding.isEmpty()) {
m_lineeditor->setIsHexMode(false);
m_findMode->setCurrentText(info.encoding); m_findMode->setCurrentText(info.encoding);
} }
} else { } else {
m_lineeditor->setIsHexMode(true);
m_findMode->setCurrentIndex(0); m_findMode->setCurrentIndex(0);
} }
m_lineeditor->setFindText(info.str); m_lineeditor->setFindText(info.str);
auto regionw = new QWidget(this);
auto regionLayout = new QHBoxLayout(regionw);
regionLayout->addWidget(new QLabel(tr("Region:"), regionw));
m_regionStart = new QtLongLongSpinBox(regionw);
Q_ASSERT(info.stop >= info.start);
m_regionStart->setRange(info.start, info.stop);
m_regionStart->setEnabled(false);
m_regionStart->setValue(info.start);
m_regionStart->setDisplayIntegerBase(16);
m_regionStart->setPrefix(QStringLiteral("0x"));
regionLayout->addWidget(m_regionStart, 1);
regionLayout->addWidget(new QLabel(QStringLiteral(" - "), regionw));
m_regionStop = new QtLongLongSpinBox(regionw);
m_regionStop->setRange(info.start, info.stop);
connect(m_regionStart, &QtLongLongSpinBox::valueChanged, m_regionStop,
&QtLongLongSpinBox::setMinimum);
m_regionStop->setEnabled(false);
m_regionStop->setValue(qMin(info.start + 1024 * 1024, info.stop));
m_regionStop->setDisplayIntegerBase(16);
m_regionStop->setPrefix(QStringLiteral("0x"));
regionLayout->addWidget(m_regionStop, 1);
auto group = new QButtonGroup(this); auto group = new QButtonGroup(this);
group->setExclusive(true); group->setExclusive(true);
@ -134,18 +110,9 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
} }
}); });
group->addButton(b, id++); group->addButton(b, id++);
b->setEnabled(!info.isBigFile); b->setChecked(true);
buttonLayout->addWidget(b); buttonLayout->addWidget(b);
b = new QPushButton(tr("Region"), this);
b->setCheckable(true);
connect(b, &QPushButton::toggled, this, [=](bool b) {
if (b) {
_result.dir = SearchDirection::Region;
}
regionw->setVisible(b);
regionw->setEnabled(b);
});
group->addButton(b, id++); group->addButton(b, id++);
buttonLayout->addWidget(b); buttonLayout->addWidget(b);
@ -183,7 +150,6 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
group->addButton(b, id++); group->addButton(b, id++);
buttonLayout->addWidget(b); buttonLayout->addWidget(b);
group->button(info.isBigFile ? 1 : 0)->setChecked(true);
layout->addWidget(btnBox); layout->addWidget(btnBox);
@ -195,9 +161,6 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
auto s = new QShortcut(key, this); auto s = new QShortcut(key, this);
connect(s, &QShortcut::activated, this, &FindDialog::on_accept); connect(s, &QShortcut::activated, this, &FindDialog::on_accept);
layout->addWidget(regionw);
regionw->hide();
layout->addSpacing(20); layout->addSpacing(20);
layout->addWidget(dbbox); layout->addWidget(dbbox);
@ -221,14 +184,6 @@ void FindDialog::on_accept() {
} }
} }
if (m_regionStart->isEnabled()) {
_result.start = m_regionStart->value();
_result.stop = m_regionStop->value();
} else {
_result.start = 0;
_result.stop = 0;
}
_result.encoding = m_findMode->currentText(); _result.encoding = m_findMode->currentText();
done(1); done(1);
} }

View File

@ -19,7 +19,6 @@
#define FINDDIALOG_H #define FINDDIALOG_H
#include "control/qhextextedit.h" #include "control/qhextextedit.h"
#include "control/qtlonglongspinbox.h"
#include "framelessdialogbase.h" #include "framelessdialogbase.h"
#include <QComboBox> #include <QComboBox>
@ -28,15 +27,13 @@
#include <QRadioButton> #include <QRadioButton>
#include <QTextEdit> #include <QTextEdit>
enum class SearchDirection { None, Region, Foreword, Backword, Selection }; enum class SearchDirection { None, Foreword, Backword, Selection };
class FindDialog : public FramelessDialogBase { class FindDialog : public FramelessDialogBase {
Q_OBJECT Q_OBJECT
public: public:
struct Result { struct Result {
SearchDirection dir = SearchDirection::None; SearchDirection dir = SearchDirection::None;
qsizetype start = 0;
qsizetype stop = 0;
// for searching info // for searching info
bool isStringFind; bool isStringFind;
@ -45,10 +42,7 @@ public:
}; };
struct FindInfo { struct FindInfo {
bool isBigFile;
bool isStringFind; bool isStringFind;
qlonglong start;
qlonglong stop;
bool isSel; bool isSel;
// for searching info // for searching info
@ -70,9 +64,6 @@ private:
QComboBox *m_findMode; QComboBox *m_findMode;
QTextEdit *m_preview; QTextEdit *m_preview;
QtLongLongSpinBox *m_regionStart;
QtLongLongSpinBox *m_regionStop;
Result _result; Result _result;
}; };

View File

@ -1525,7 +1525,8 @@ RibbonTabContent *MainWindow::buildScriptPage(RibbonTabContent *tab) {
pannel->setVisible(false); pannel->setVisible(false);
connect(pannel, &RibbonButtonGroup::emptyStatusChanged, this, connect(pannel, &RibbonButtonGroup::emptyStatusChanged, this,
[pannel](bool isEmpty) { pannel->setVisible(!isEmpty); }); [pannel](bool isEmpty) { pannel->setVisible(!isEmpty); });
_scriptMaps = ScriptManager::buildUpRibbonScriptRunner(pannel); _scriptContexts =
ScriptManager::buildUpScriptRunnerContext(pannel, this);
m_scriptDBGroup = pannel; m_scriptDBGroup = pannel;
} }
@ -2118,9 +2119,6 @@ void MainWindow::on_findfile() {
auto hexeditor = editor->hexEditor(); auto hexeditor = editor->hexEditor();
static FindDialog::FindInfo info; static FindDialog::FindInfo info;
info.isBigFile = editor->isBigFile();
info.start = 0;
info.stop = hexeditor->documentBytes();
info.isSel = hexeditor->selectionCount() == 1; info.isSel = hexeditor->selectionCount() == 1;
FindDialog fd(info, this); FindDialog fd(info, this);
@ -3050,6 +3048,11 @@ void MainWindow::registerEditorView(EditorView *editor, const QString &ws) {
}); });
} }
} }
for (auto &m : _scriptContexts) {
editor->registerQMenu(m);
}
for (auto &m : m_hexContextMenu) { for (auto &m : m_hexContextMenu) {
editor->registerQMenu(m); editor->registerQMenu(m);
} }
@ -3238,6 +3241,8 @@ void MainWindow::connectEditorView(EditorView *editor) {
if (editor->isBigFile()) { if (editor->isBigFile()) {
auto fileName = editor->fileName(); auto fileName = editor->fileName();
if (!QFile::exists(fileName)) { if (!QFile::exists(fileName)) {
activateWindow();
raise();
editor->raise(); editor->raise();
WingMessageBox::critical(this, tr("Error"), WingMessageBox::critical(this, tr("Error"),
tr("FileCloseBigFile")); tr("FileCloseBigFile"));

View File

@ -524,7 +524,7 @@ private:
RibbonButtonGroup *m_scriptDBGroup = nullptr; RibbonButtonGroup *m_scriptDBGroup = nullptr;
RibbonButtonGroup *m_pluginSettingsGroup = nullptr; RibbonButtonGroup *m_pluginSettingsGroup = nullptr;
ScriptManager::ScriptActionMaps _scriptMaps; QList<QMenu *> _scriptContexts;
//=================================================== //===================================================

View File

@ -801,6 +801,21 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) {
message + QStringLiteral("</font></b>")); message + QStringLiteral("</font></b>"));
}); });
connect(editor, &ScriptEditor::need2Reload, this, [editor, this]() {
editor->editor()->setContentModified(true);
if (currentEditor() == editor) {
activateWindow();
raise();
auto ret = WingMessageBox::question(this, tr("Reload"),
tr("ReloadNeededYesOrNo"));
if (ret == QMessageBox::Yes) {
editor->reload();
}
} else {
editor->setProperty("__RELOAD__", true);
}
});
m_views.append(editor); m_views.append(editor);
auto ev = m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS); auto ev = m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS);
@ -875,6 +890,19 @@ void ScriptingDialog::swapEditor(ScriptEditor *old, ScriptEditor *cur) {
m_curEditor = cur; m_curEditor = cur;
updateCursorPosition(); updateCursorPosition();
if (cur) {
auto needReload = cur->property("__RELOAD__").toBool();
if (needReload) {
auto ret = WingMessageBox::question(this, tr("Reload"),
tr("ReloadNeededYesOrNo"));
if (ret == QMessageBox::Yes) {
cur->reload();
}
cur->setProperty("__RELOAD__", false);
}
}
} }
void ScriptingDialog::updateRunDebugMode(bool disable) { void ScriptingDialog::updateRunDebugMode(bool disable) {
@ -1371,7 +1399,8 @@ void ScriptingDialog::on_runscript() {
PluginSystem::instance().scriptPragmaBegin(); PluginSystem::instance().scriptPragmaBegin();
editor->setReadOnly(true); editor->setReadOnly(true);
// ScriptMachine::instance().executeScript(editor->fileName()); ScriptMachine::instance().executeScript(ScriptMachine::Scripting,
editor->fileName());
editor->setReadOnly(false); editor->setReadOnly(false);
updateRunDebugMode(); updateRunDebugMode();
} }

View File

@ -46,6 +46,7 @@ void ScriptSettingDialog::loadData() {
auto &set = SettingManager::instance(); auto &set = SettingManager::instance();
this->blockSignals(true); this->blockSignals(true);
ui->listWidget->clear();
ui->cbEnable->setChecked(set.scriptEnabled()); ui->cbEnable->setChecked(set.scriptEnabled());
ui->cbAllowUsrScript->setChecked(set.allowUsrScriptInRoot()); ui->cbAllowUsrScript->setChecked(set.allowUsrScriptInRoot());
ui->sbTimeout->setValue(set.scriptTimeout()); ui->sbTimeout->setValue(set.scriptTimeout());
@ -151,6 +152,9 @@ void ScriptSettingDialog::on_listWidget_currentRowChanged(int currentRow) {
info->append(tr("Name:") + meta.name); info->append(tr("Name:") + meta.name);
info->append(tr("Author:") + meta.author); info->append(tr("Author:") + meta.author);
info->append(tr("License:") + meta.license); info->append(tr("License:") + meta.license);
info->append(tr("ContextMenu:") + (meta.isContextMenu
? QStringLiteral("true")
: QStringLiteral("false")));
info->append(tr("HomePage:") + meta.homepage); info->append(tr("HomePage:") + meta.homepage);
info->append(tr("Comment:")); info->append(tr("Comment:"));
auto cur = info->textCursor(); auto cur = info->textCursor();