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_INSTALL "Install library" OFF)
|
||||
add_subdirectory(3rdparty/qwindowkit)
|
||||
add_definitions(-DWINGHEX_USE_FRAMELESS)
|
||||
add_compile_definitions(WINGHEX_USE_FRAMELESS)
|
||||
endif()
|
||||
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
|
@ -194,8 +194,6 @@ set(CONTROL_SRC
|
|||
src/control/qlistviewext.cpp
|
||||
src/control/asobjtreewidget.h
|
||||
src/control/asobjtreewidget.cpp
|
||||
src/control/qtlonglongspinbox.cpp
|
||||
src/control/qtlonglongspinbox.h
|
||||
src/control/dockwidgettab.h
|
||||
src/control/dockwidgettab.cpp
|
||||
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/qascodeparser.h"
|
||||
#include "class/scriptmachine.h"
|
||||
#include "control/scripteditor.h"
|
||||
#include "model/codecompletionmodel.h"
|
||||
#include "utilities.h"
|
||||
#include "wingcodeedit.h"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
|
@ -141,7 +143,7 @@ void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) {
|
|||
int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
|
||||
const QString &from, AsPreprocesser *builder,
|
||||
void *userParam) {
|
||||
Q_UNUSED(userParam);
|
||||
auto p = reinterpret_cast<AsCompletion *>(userParam);
|
||||
|
||||
QFileInfo info(include);
|
||||
bool isAbsolute = info.isAbsolute();
|
||||
|
@ -151,7 +153,9 @@ int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
|
|||
if (isAbsolute) {
|
||||
inc = include;
|
||||
} 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);
|
||||
}
|
||||
} else {
|
||||
|
@ -177,6 +181,42 @@ int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
|
|||
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({}); }
|
||||
|
||||
QString AsCompletion::wordSeperators() const {
|
||||
|
@ -340,7 +380,7 @@ bool AsCompletion::processTrigger(const QString &trigger,
|
|||
return basicType.contains(type);
|
||||
};
|
||||
|
||||
auto clsNodes = parser.headerNodes();
|
||||
auto clsNodes = parser.classNodes();
|
||||
|
||||
// filter the type we can use to auto-complete in docNodes
|
||||
for (auto &item : docNodes) {
|
||||
|
@ -348,6 +388,8 @@ bool AsCompletion::processTrigger(const QString &trigger,
|
|||
auto name = item.nameSpace;
|
||||
if (name.isEmpty()) {
|
||||
name = item.name;
|
||||
} else {
|
||||
name += QStringLiteral("::") + item.name;
|
||||
}
|
||||
clsNodes.insert(name, item.children);
|
||||
}
|
||||
|
@ -464,10 +506,29 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
|
||||
for (auto &d : data) {
|
||||
qsizetype offset = -1;
|
||||
QList<CodeInfoTip> dd;
|
||||
|
||||
if (d.section == QStringLiteral("ASCOMPLETION")) {
|
||||
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;
|
||||
|
@ -476,8 +537,8 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
QList<CodeInfoTip> AsCompletion::parseMarcos() {
|
||||
static QList<CodeInfoTip> marcos;
|
||||
if (marcos.isEmpty()) {
|
||||
QStringList m{"define", "undef", "if", "else",
|
||||
"endif", "ifdef", "ifndef"};
|
||||
QStringList m{"define", "undef", "if", "else", "endif",
|
||||
"ifdef", "ifndef", "include", "pragma"};
|
||||
for (auto &i : m) {
|
||||
CodeInfoTip tip;
|
||||
tip.name = i;
|
||||
|
|
|
@ -64,6 +64,21 @@ private:
|
|||
const QString &from, AsPreprocesser *builder,
|
||||
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:
|
||||
ASDataBase parser;
|
||||
};
|
||||
|
|
|
@ -326,6 +326,42 @@ void ASDataBase::addClassCompletion(asIScriptEngine *engine) {
|
|||
obj->Release();
|
||||
|
||||
_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 {};
|
||||
}
|
||||
|
||||
const QHash<QString, QList<CodeInfoTip>> &ASDataBase::classNodes() const {
|
||||
return _classNodes;
|
||||
}
|
||||
|
||||
const QList<CodeInfoTip> &ASDataBase::keywordNodes() const {
|
||||
return _keywordNode;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ private:
|
|||
public:
|
||||
const QHash<QString, QList<CodeInfoTip>> &headerNodes() const;
|
||||
const QHash<QString, QList<CodeInfoTip>> &enumsNodes() const;
|
||||
const QHash<QString, QList<CodeInfoTip>> &classNodes() const;
|
||||
|
||||
const QList<CodeInfoTip> &keywordNodes() const;
|
||||
|
||||
|
@ -57,6 +58,7 @@ private:
|
|||
// <namespace, content>
|
||||
QHash<QString, QList<CodeInfoTip>> _headerNodes;
|
||||
QHash<QString, QList<CodeInfoTip>> _enumsNodes;
|
||||
QHash<QString, QList<CodeInfoTip>> _classNodes;
|
||||
QList<CodeInfoTip> _keywordNode;
|
||||
};
|
||||
|
||||
|
|
|
@ -1450,6 +1450,7 @@ void QAsCodeParser::parseNamespace() {
|
|||
QList<QAsCodeParser::Symbol>
|
||||
QAsCodeParser::parseGlobalVarDecls(const QByteArrayList &ns,
|
||||
const QByteArray &code) {
|
||||
reset();
|
||||
_code = code;
|
||||
return parseDeclaration(-1, ns, false, true);
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ bool ScriptMachine::configureEngine() {
|
|||
_rtypes[RegisteredType::tColor] =
|
||||
q_check_ptr(_engine->GetTypeInfoByName("color"));
|
||||
|
||||
_engine->SetDefaultAccessMask(0x1);
|
||||
|
||||
// Register a couple of extra functions for the scripts
|
||||
r = _engine->RegisterGlobalFunction(
|
||||
"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 isInDebug, int *retCode) {
|
||||
Q_ASSERT(mode != Interactive && mode != DefineEvaluator);
|
||||
Q_ASSERT(mode != Interactive);
|
||||
if (QThread::currentThread() != qApp->thread()) {
|
||||
Logger::warning(tr("Code must be exec in the main thread"));
|
||||
return false;
|
||||
|
@ -576,6 +578,14 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
|
||||
_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 *>(
|
||||
AppManager::instance()->currentMSecsSinceEpoch()),
|
||||
AsUserDataType::UserData_Timer);
|
||||
|
@ -671,18 +681,25 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
}
|
||||
|
||||
int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
||||
auto mod = createModuleIfNotExist(DefineEvaluator);
|
||||
if (mod) {
|
||||
asIScriptFunction *func = nullptr;
|
||||
QByteArray name =
|
||||
QByteArrayLiteral("WINGDEF") +
|
||||
QByteArray::number(AppManager::instance()->currentMSecsSinceEpoch());
|
||||
|
||||
auto oldMode = _curMsgMode;
|
||||
QScopeGuard guard([this, oldMode]() { _curMsgMode = oldMode; });
|
||||
auto mod = _engine->GetModule(name.data(), asGM_ALWAYS_CREATE);
|
||||
mod->SetAccessMask(0x2);
|
||||
|
||||
asIScriptFunction *func = nullptr;
|
||||
QScopeGuard guard([mod]() {
|
||||
// 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();
|
||||
});
|
||||
|
||||
auto ccode = code;
|
||||
ccode.prepend("bool f(){ return bool(").append(");}");
|
||||
// start to compile
|
||||
|
||||
_curMsgMode = DefineEvaluator;
|
||||
auto cr = mod->CompileFunction(nullptr, ccode.toUtf8(), 0, 0, &func);
|
||||
if (cr < 0) {
|
||||
return cr;
|
||||
|
@ -692,7 +709,6 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
|||
// The context manager will request the context from the
|
||||
// pool, which will automatically attach the debugger
|
||||
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
|
||||
_ctx[DefineEvaluator] = ctx;
|
||||
|
||||
ctx->SetUserData(reinterpret_cast<void *>(asPWORD(
|
||||
AppManager::instance()->currentMSecsSinceEpoch())),
|
||||
|
@ -703,13 +719,10 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
|||
AsUserDataType::UserData_isDbg);
|
||||
mod->SetUserData(reinterpret_cast<void *>(isDbg),
|
||||
AsUserDataType::UserData_isDbg);
|
||||
ctx->SetUserData(0, AsUserDataType::UserData_ContextMode);
|
||||
|
||||
asPWORD umode = asPWORD(DefineEvaluator);
|
||||
ctx->SetUserData(reinterpret_cast<void *>(umode),
|
||||
AsUserDataType::UserData_ContextMode);
|
||||
|
||||
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback),
|
||||
this, asCALL_THISCALL);
|
||||
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback), this,
|
||||
asCALL_THISCALL);
|
||||
|
||||
// Execute the script until completion
|
||||
// The script may create co-routines. These will automatically
|
||||
|
@ -718,8 +731,6 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
|||
qApp->processEvents();
|
||||
}
|
||||
|
||||
_ctx[DefineEvaluator] = nullptr;
|
||||
|
||||
// Check if the main script finished normally
|
||||
int r = ctx->GetState();
|
||||
if (r != asEXECUTION_FINISHED) {
|
||||
|
@ -736,8 +747,6 @@ int ScriptMachine::evaluateDefine(const QString &code, bool &result) {
|
|||
_engine->GarbageCollect();
|
||||
return r;
|
||||
}
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
void ScriptMachine::abortDbgScript() {
|
||||
if (_debugger->getEngine()) {
|
||||
|
@ -831,10 +840,6 @@ asIScriptModule *ScriptMachine::createModule(ConsoleMode mode) {
|
|||
mod = _engine->GetModule("WINGSRV", asGM_ALWAYS_CREATE);
|
||||
mod->SetAccessMask(0x1);
|
||||
break;
|
||||
case DefineEvaluator:
|
||||
mod = _engine->GetModule("WINGDEF", asGM_ALWAYS_CREATE);
|
||||
mod->SetAccessMask(0x2);
|
||||
break;
|
||||
}
|
||||
|
||||
return mod;
|
||||
|
@ -855,10 +860,6 @@ asIScriptModule *ScriptMachine::createModuleIfNotExist(ConsoleMode mode) {
|
|||
mod = _engine->GetModule("WINGSRV", asGM_CREATE_IF_NOT_EXISTS);
|
||||
mod->SetAccessMask(0x1);
|
||||
break;
|
||||
case DefineEvaluator:
|
||||
mod = _engine->GetModule("WINGDEF", asGM_ALWAYS_CREATE);
|
||||
mod->SetAccessMask(0x2);
|
||||
break;
|
||||
}
|
||||
|
||||
return mod;
|
||||
|
@ -872,8 +873,6 @@ asIScriptModule *ScriptMachine::module(ConsoleMode mode) {
|
|||
return _engine->GetModule("WINGSCRIPT", asGM_ONLY_IF_EXISTS);
|
||||
case Background:
|
||||
return _engine->GetModule("WINGSRV", asGM_ONLY_IF_EXISTS);
|
||||
case DefineEvaluator:
|
||||
return _engine->GetModule("WINGDEF", asGM_ONLY_IF_EXISTS);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2070,22 +2069,38 @@ void ScriptMachine::registerEngineClipboard(asIScriptEngine *engine) {
|
|||
asCALL_CDECL);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"string text()", asFUNCTION(clip_getText), asCALL_CDECL);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"void setBinary(const uint8[]@ data)", asFUNCTION(clip_setBinary),
|
||||
asCALL_CDECL);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"uint8[]@ getBinary()", asFUNCTION(clip_getBinary), asCALL_CDECL);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
} else {
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"void setText(const string &in text)", WRAP_FN(clip_setText),
|
||||
asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"string text()", asFUNCTION(clip_getText), asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"void setBinary(const uint8[]@ data)", WRAP_FN(clip_setBinary),
|
||||
asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
r = engine->RegisterGlobalFunction(
|
||||
"uint8[]@ getBinary()", WRAP_FN(clip_getBinary), asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
}
|
||||
|
||||
engine->SetDefaultNamespace("");
|
||||
|
@ -2140,6 +2155,28 @@ void ScriptMachine::clip_setBinary(const CScriptArray &array) {
|
|||
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) {
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if (ctx) {
|
||||
|
@ -2183,7 +2220,7 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
asIScriptFunction *func = nullptr;
|
||||
|
||||
QList<QAsCodeParser::CodeSegment> ret;
|
||||
if (mode != DefineEvaluator) {
|
||||
if (mode > 0) {
|
||||
ret = parser.parse(ccode);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,9 @@ private:
|
|||
public:
|
||||
// we have three console modes
|
||||
enum ConsoleMode {
|
||||
Interactive, // in a shell
|
||||
Interactive = 1, // in a shell
|
||||
Scripting, // in scripting dialog
|
||||
Background, // run codes from other way
|
||||
DefineEvaluator // define result calculator
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -137,6 +136,8 @@ public:
|
|||
|
||||
static void clip_setText(const QString &text);
|
||||
static void clip_setBinary(const CScriptArray &array);
|
||||
static QString clip_getText();
|
||||
static CScriptArray *clip_getBinary();
|
||||
|
||||
static void scriptThrow(const QString &msg);
|
||||
|
||||
|
|
|
@ -73,6 +73,11 @@ QString ScriptManager::readJsonObjString(const QJsonObject &jobj,
|
|||
return {};
|
||||
}
|
||||
|
||||
bool ScriptManager::readJsonObjBool(const QJsonObject &jobj,
|
||||
const QString &key) {
|
||||
return jobj.value(key).toBool();
|
||||
}
|
||||
|
||||
QMenu *ScriptManager::buildUpScriptDirMenu(QWidget *parent,
|
||||
const QStringList &files,
|
||||
bool isSys) {
|
||||
|
@ -167,6 +172,7 @@ ScriptManager::ensureDirMeta(const QFileInfo &info) {
|
|||
jobj.insert(QStringLiteral("license"), QLatin1String());
|
||||
jobj.insert(QStringLiteral("homepage"), QLatin1String());
|
||||
jobj.insert(QStringLiteral("comment"), QLatin1String());
|
||||
jobj.insert(QStringLiteral("hexmenu"), false);
|
||||
QFile f(base.absoluteFilePath(QStringLiteral(".wingasmeta")));
|
||||
if (f.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QJsonDocument jdoc(jobj);
|
||||
|
@ -195,6 +201,8 @@ ScriptManager::ensureDirMeta(const QFileInfo &info) {
|
|||
readJsonObjString(jobj, QStringLiteral("homepage"));
|
||||
meta.comment =
|
||||
readJsonObjString(jobj, QStringLiteral("comment"));
|
||||
meta.isContextMenu =
|
||||
readJsonObjBool(jobj, QStringLiteral("hexmenu"));
|
||||
} else {
|
||||
meta.name = info.fileName();
|
||||
}
|
||||
|
@ -217,9 +225,10 @@ ScriptManager::sysDirMeta(const QString &cat) const {
|
|||
return _sysDirMetas.value(cat);
|
||||
}
|
||||
|
||||
ScriptManager::ScriptActionMaps
|
||||
ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
|
||||
ScriptActionMaps maps;
|
||||
QList<QMenu *>
|
||||
ScriptManager::buildUpScriptRunnerContext(RibbonButtonGroup *group,
|
||||
QWidget *parent) {
|
||||
QList<QMenu *> maps;
|
||||
|
||||
auto &sm = ScriptManager::instance();
|
||||
auto &stm = SettingManager::instance();
|
||||
|
@ -229,10 +238,20 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
|
|||
if (hideCats.contains(cat)) {
|
||||
continue;
|
||||
}
|
||||
maps.sysList << addPannelAction(
|
||||
group, ICONRES(QStringLiteral("scriptfolder")),
|
||||
sm.sysDirMeta(cat).name,
|
||||
|
||||
auto meta = sm.sysDirMeta(cat);
|
||||
|
||||
addPannelAction(
|
||||
group, ICONRES(QStringLiteral("scriptfolder")), meta.name,
|
||||
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();
|
||||
|
@ -240,10 +259,19 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
|
|||
if (hideCats.contains(cat)) {
|
||||
continue;
|
||||
}
|
||||
maps.usrList << addPannelAction(
|
||||
group, ICONRES(QStringLiteral("scriptfolderusr")),
|
||||
sm.usrDirMeta(cat).name,
|
||||
auto meta = sm.usrDirMeta(cat);
|
||||
|
||||
addPannelAction(
|
||||
group, ICONRES(QStringLiteral("scriptfolderusr")), meta.name,
|
||||
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;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <QObject>
|
||||
|
||||
#include "QWingRibbon/ribbonbuttongroup.h"
|
||||
#include "control/scriptingconsole.h"
|
||||
#include "utilities.h"
|
||||
|
||||
class ScriptManager : public QObject {
|
||||
|
@ -38,14 +37,10 @@ public:
|
|||
QString license;
|
||||
QString homepage;
|
||||
QString comment;
|
||||
bool isContextMenu = false;
|
||||
bool isSys; // a flag
|
||||
};
|
||||
|
||||
struct ScriptActionMaps {
|
||||
QList<QToolButton *> sysList;
|
||||
QList<QToolButton *> usrList;
|
||||
};
|
||||
|
||||
public:
|
||||
static ScriptManager &instance();
|
||||
|
||||
|
@ -68,7 +63,8 @@ public:
|
|||
ScriptDirMeta usrDirMeta(const QString &cat) const;
|
||||
ScriptDirMeta sysDirMeta(const QString &cat) const;
|
||||
|
||||
static ScriptActionMaps buildUpRibbonScriptRunner(RibbonButtonGroup *group);
|
||||
static QList<QMenu *> buildUpScriptRunnerContext(RibbonButtonGroup *group,
|
||||
QWidget *parent);
|
||||
|
||||
private:
|
||||
static QToolButton *addPannelAction(RibbonButtonGroup *pannel,
|
||||
|
@ -119,6 +115,8 @@ private:
|
|||
|
||||
QString readJsonObjString(const QJsonObject &jobj, const QString &key);
|
||||
|
||||
bool readJsonObjBool(const QJsonObject &jobj, const QString &key);
|
||||
|
||||
static QMenu *buildUpScriptDirMenu(QWidget *parent,
|
||||
const QStringList &files, bool isSys);
|
||||
|
||||
|
|
|
@ -1188,13 +1188,15 @@ QByteArray WingAngelAPI::cArray2ByteArray(const CScriptArray &array, int byteID,
|
|||
return {};
|
||||
}
|
||||
|
||||
auto len = array.GetSize();
|
||||
|
||||
QByteArray buffer;
|
||||
buffer.reserve(array.GetSize());
|
||||
buffer.resize(len);
|
||||
array.AddRef();
|
||||
for (asUINT i = 0; i < array.GetSize(); ++i) {
|
||||
auto item = reinterpret_cast<const asBYTE *>(array.At(i));
|
||||
buffer.append(*item);
|
||||
}
|
||||
|
||||
std::memcpy(buffer.data(), const_cast<CScriptArray &>(array).GetBuffer(),
|
||||
len);
|
||||
|
||||
array.Release();
|
||||
return buffer;
|
||||
}
|
||||
|
@ -1993,9 +1995,7 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
|
|||
if (info) {
|
||||
auto len = content.length();
|
||||
auto arr = CScriptArray::Create(info, len);
|
||||
for (decltype(len) i = 0; i < len; ++i) {
|
||||
arr->SetValue(i, content.at(i));
|
||||
}
|
||||
std::memcpy(arr->GetBuffer(), content.data(), len);
|
||||
return arr;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -2003,6 +2003,10 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
|
|||
|
||||
void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
|
||||
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);
|
||||
auto typeStr = PluginSystem::type2AngelScriptString(
|
||||
MetaType(type | MetaType::Array), false, true);
|
||||
|
@ -2021,6 +2025,7 @@ void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
|
|||
return arr;
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
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.encoding.isEmpty()) {
|
||||
m_lineeditor->setIsHexMode(false);
|
||||
m_findMode->setCurrentText(info.encoding);
|
||||
}
|
||||
} else {
|
||||
m_lineeditor->setIsHexMode(true);
|
||||
m_findMode->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
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);
|
||||
group->setExclusive(true);
|
||||
|
||||
|
@ -134,18 +110,9 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
|
|||
}
|
||||
});
|
||||
group->addButton(b, id++);
|
||||
b->setEnabled(!info.isBigFile);
|
||||
b->setChecked(true);
|
||||
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++);
|
||||
buttonLayout->addWidget(b);
|
||||
|
||||
|
@ -183,7 +150,6 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
|
|||
|
||||
group->addButton(b, id++);
|
||||
buttonLayout->addWidget(b);
|
||||
group->button(info.isBigFile ? 1 : 0)->setChecked(true);
|
||||
|
||||
layout->addWidget(btnBox);
|
||||
|
||||
|
@ -195,9 +161,6 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
|
|||
auto s = new QShortcut(key, this);
|
||||
connect(s, &QShortcut::activated, this, &FindDialog::on_accept);
|
||||
|
||||
layout->addWidget(regionw);
|
||||
regionw->hide();
|
||||
|
||||
layout->addSpacing(20);
|
||||
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();
|
||||
done(1);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#define FINDDIALOG_H
|
||||
|
||||
#include "control/qhextextedit.h"
|
||||
#include "control/qtlonglongspinbox.h"
|
||||
#include "framelessdialogbase.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
@ -28,15 +27,13 @@
|
|||
#include <QRadioButton>
|
||||
#include <QTextEdit>
|
||||
|
||||
enum class SearchDirection { None, Region, Foreword, Backword, Selection };
|
||||
enum class SearchDirection { None, Foreword, Backword, Selection };
|
||||
|
||||
class FindDialog : public FramelessDialogBase {
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct Result {
|
||||
SearchDirection dir = SearchDirection::None;
|
||||
qsizetype start = 0;
|
||||
qsizetype stop = 0;
|
||||
|
||||
// for searching info
|
||||
bool isStringFind;
|
||||
|
@ -45,10 +42,7 @@ public:
|
|||
};
|
||||
|
||||
struct FindInfo {
|
||||
bool isBigFile;
|
||||
bool isStringFind;
|
||||
qlonglong start;
|
||||
qlonglong stop;
|
||||
bool isSel;
|
||||
|
||||
// for searching info
|
||||
|
@ -70,9 +64,6 @@ private:
|
|||
QComboBox *m_findMode;
|
||||
QTextEdit *m_preview;
|
||||
|
||||
QtLongLongSpinBox *m_regionStart;
|
||||
QtLongLongSpinBox *m_regionStop;
|
||||
|
||||
Result _result;
|
||||
};
|
||||
|
||||
|
|
|
@ -1525,7 +1525,8 @@ RibbonTabContent *MainWindow::buildScriptPage(RibbonTabContent *tab) {
|
|||
pannel->setVisible(false);
|
||||
connect(pannel, &RibbonButtonGroup::emptyStatusChanged, this,
|
||||
[pannel](bool isEmpty) { pannel->setVisible(!isEmpty); });
|
||||
_scriptMaps = ScriptManager::buildUpRibbonScriptRunner(pannel);
|
||||
_scriptContexts =
|
||||
ScriptManager::buildUpScriptRunnerContext(pannel, this);
|
||||
m_scriptDBGroup = pannel;
|
||||
}
|
||||
|
||||
|
@ -2118,9 +2119,6 @@ void MainWindow::on_findfile() {
|
|||
auto hexeditor = editor->hexEditor();
|
||||
|
||||
static FindDialog::FindInfo info;
|
||||
info.isBigFile = editor->isBigFile();
|
||||
info.start = 0;
|
||||
info.stop = hexeditor->documentBytes();
|
||||
info.isSel = hexeditor->selectionCount() == 1;
|
||||
|
||||
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) {
|
||||
editor->registerQMenu(m);
|
||||
}
|
||||
|
@ -3238,6 +3241,8 @@ void MainWindow::connectEditorView(EditorView *editor) {
|
|||
if (editor->isBigFile()) {
|
||||
auto fileName = editor->fileName();
|
||||
if (!QFile::exists(fileName)) {
|
||||
activateWindow();
|
||||
raise();
|
||||
editor->raise();
|
||||
WingMessageBox::critical(this, tr("Error"),
|
||||
tr("FileCloseBigFile"));
|
||||
|
|
|
@ -524,7 +524,7 @@ private:
|
|||
|
||||
RibbonButtonGroup *m_scriptDBGroup = nullptr;
|
||||
RibbonButtonGroup *m_pluginSettingsGroup = nullptr;
|
||||
ScriptManager::ScriptActionMaps _scriptMaps;
|
||||
QList<QMenu *> _scriptContexts;
|
||||
|
||||
//===================================================
|
||||
|
||||
|
|
|
@ -801,6 +801,21 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) {
|
|||
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);
|
||||
|
||||
auto ev = m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS);
|
||||
|
@ -875,6 +890,19 @@ void ScriptingDialog::swapEditor(ScriptEditor *old, ScriptEditor *cur) {
|
|||
|
||||
m_curEditor = cur;
|
||||
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) {
|
||||
|
@ -1371,7 +1399,8 @@ void ScriptingDialog::on_runscript() {
|
|||
PluginSystem::instance().scriptPragmaBegin();
|
||||
|
||||
editor->setReadOnly(true);
|
||||
// ScriptMachine::instance().executeScript(editor->fileName());
|
||||
ScriptMachine::instance().executeScript(ScriptMachine::Scripting,
|
||||
editor->fileName());
|
||||
editor->setReadOnly(false);
|
||||
updateRunDebugMode();
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ void ScriptSettingDialog::loadData() {
|
|||
auto &set = SettingManager::instance();
|
||||
|
||||
this->blockSignals(true);
|
||||
ui->listWidget->clear();
|
||||
ui->cbEnable->setChecked(set.scriptEnabled());
|
||||
ui->cbAllowUsrScript->setChecked(set.allowUsrScriptInRoot());
|
||||
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("Author:") + meta.author);
|
||||
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("Comment:"));
|
||||
auto cur = info->textCursor();
|
||||
|
|
Loading…
Reference in New Issue