fix: 修复代码提示相关和字节搜索框问题;
This commit is contained in:
parent
1be1f7322f
commit
066ab5375b
|
@ -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
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
//===================================================
|
//===================================================
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue