feat: 可视化组件脚本支持鼠标单击和双击事件响应;代码填充支持关键字;

This commit is contained in:
寂静的羽夏 2025-02-07 21:24:11 +08:00
parent 557311c85f
commit 5bd8a870d1
24 changed files with 1383 additions and 880 deletions

View File

@ -46,16 +46,13 @@
QList<qsizetype> QHexDocument::getLineBookmarksPos(qsizetype line) {
QList<qsizetype> pos;
auto begin = m_hexlinewidth * line;
auto end = m_hexlinewidth + begin;
auto end = m_hexlinewidth + begin - 1;
auto lbound = _bookmarks.lowerBound(begin);
auto ubound = _bookmarks.upperBound(end);
for (auto p = lbound; p != ubound; ++p) {
auto off = p.key();
if (off >= begin && off < end) {
pos.append(off);
}
pos.append(p.key());
}
return pos;
@ -63,19 +60,12 @@ QList<qsizetype> QHexDocument::getLineBookmarksPos(qsizetype line) {
bool QHexDocument::lineHasBookMark(qsizetype line) {
auto begin = m_hexlinewidth * line;
auto end = m_hexlinewidth + begin;
auto end = m_hexlinewidth + begin - 1;
auto lbound = _bookmarks.lowerBound(begin);
auto ubound = _bookmarks.upperBound(end);
for (auto p = lbound; p != ubound; ++p) {
auto off = p.key();
if (off >= begin && off < end) {
return true;
}
}
return false;
return lbound != ubound;
}
void QHexDocument::addUndoCommand(QUndoCommand *command) {

View File

@ -267,7 +267,8 @@ set(CLASS_SRC
src/class/dockcomponentsfactory.h
src/class/dockcomponentsfactory.cpp
src/class/diffutil.h
src/class/diffutil.cpp)
src/class/diffutil.cpp
src/class/clickcallback.h)
set(INTERNAL_PLG_SRC
src/class/wingangelapi.h src/class/wingangelapi.cpp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -220,8 +220,6 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
return;
}
auto &_headerNodes = parser.headerNodes();
if (etoken.content.length() >= trigWordLen()) {
// completion for a.b.c or a::b.c or a::b::c.d or ::a::b.c
if (trigger == *DBL_COLON_TRIGGER) {
@ -284,6 +282,7 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
}
}
nodes.append(parser.keywordNode());
auto cur = c;
cur.movePosition(trigger.length());
pPopup->setCursor(cur);
@ -311,10 +310,10 @@ void AsCompletion::applyEmptyNsNode(QList<QCodeNode *> &nodes) {
nodes = _emptyNsNodes;
}
void AsCompletion::parse(const QDocumentCursor &c) {
auto codes = c.document()->text();
// asBuilder builder;
}
// void AsCompletion::parse(const QDocumentCursor &c) {
// auto codes = c.document()->text();
// // asBuilder builder;
// }
QList<QCodeNode *> AsCompletion::lookupNamespace(const QByteArrayList &ns) {
QList<QCodeNode *> nodes;

View File

@ -50,7 +50,7 @@ protected:
private:
void applyEmptyNsNode(QList<QCodeNode *> &nodes);
void parse(const QDocumentCursor &c);
// void parse(const QDocumentCursor &c);
QList<QCodeNode *> lookupNamespace(const QByteArrayList &ns);

70
src/class/clickcallback.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef CLICKCALLBACK_H
#define CLICKCALLBACK_H
#include "angelscript.h"
#include "plugin/iwingplugin.h"
class ClickCallBack {
public:
ClickCallBack() {}
ClickCallBack(const WingHex::WingPlugin::DataVisual::ClickedCallBack &b)
: _call(b) {}
explicit ClickCallBack(asIScriptEngine *engine, asIScriptFunction *func)
: _engine(engine), _func(func) {
if (_engine && _func) {
_func->AddRef();
}
}
~ClickCallBack() {
if (_func) {
_func->Release();
}
}
public:
ClickCallBack &
operator=(const WingHex::WingPlugin::DataVisual::ClickedCallBack &_Right) {
*this = ClickCallBack(_Right);
return *this;
}
ClickCallBack &
operator=(WingHex::WingPlugin::DataVisual::ClickedCallBack &&_Right) {
*this = ClickCallBack(_Right);
return *this;
}
public:
explicit operator bool() const noexcept {
return _call || (_engine && _func);
}
void operator()(const QModelIndex &index) {
if (_call) {
_call(index);
} else {
if (_engine && _func) {
auto ctx = _engine->CreateContext();
if (ctx) {
auto r = ctx->Prepare(_func);
if (r >= 0) {
auto idx = index;
ctx->SetArgObject(0, &idx);
ctx->Execute();
}
ctx->Release();
}
}
}
}
private:
WingHex::WingPlugin::DataVisual::ClickedCallBack _call;
asIScriptEngine *_engine = nullptr;
asIScriptFunction *_func = nullptr;
};
#endif // CLICKCALLBACK_H

View File

@ -86,50 +86,63 @@ Logger &Logger::instance() {
Logger::Level Logger::logLevel() const { return _level; }
void Logger::_log(const QString &message) { emit instance().log(message); }
void Logger::logPrint(const QString &message) { emit instance().log(message); }
void Logger::newLine() { _log({}); }
void Logger::newLine() { logPrint({}); }
void Logger::trace(const QString &message) {
if (instance()._level >= q5TRACE) {
QString str = message;
emit instance().log(tr("[Trace]") + str.replace("\n", "<br />"));
emit instance().log(packDebugStr(tr("[Trace]") + str));
}
}
void Logger::warning(const QString &message) {
if (instance()._level >= q2WARN) {
QString str = message;
emit instance().log(
WARNLOG(tr("[Warn]") + str.replace("\n", "<br />")));
emit instance().log(packWarnStr(tr("[Warn]") + str));
}
}
void Logger::info(const QString &message) {
if (instance()._level >= q3INFO) {
QString str = message;
emit instance().log(
INFOLOG(tr("[Info]") + str.replace("\n", "<br />")));
emit instance().log(packInfoStr(tr("[Info]") + str));
}
}
void Logger::debug(const QString &message) {
if (instance()._level >= q4DEBUG) {
QString str = message;
emit instance().log(tr("[Debug]") + str.replace("\n", "<br />"));
emit instance().log(packDebugStr(tr("[Debug]") + str));
}
}
void Logger::critical(const QString &message) {
if (instance()._level >= q0FATAL) {
QString str = message;
emit instance().log(
ERRLOG(tr("[Error]") + str.replace("\n", "<br />")));
emit instance().log(packErrorStr(tr("[Error]") + str));
}
}
void Logger::setLogLevel(Level level) { _level = level; }
QString Logger::packInfoStr(QString msg) {
return INFOLOG(msg.replace("\n", "<br />"));
}
QString Logger::packDebugStr(QString msg) {
return msg.replace("\n", "<br />");
}
QString Logger::packErrorStr(QString msg) {
return ERRLOG(msg.replace("\n", "<br />"));
}
QString Logger::packWarnStr(QString msg) {
return WARNLOG(msg.replace("\n", "<br />"));
}
QString Logger::getString(Level level) {
switch (level) {
case q0FATAL:

View File

@ -62,16 +62,20 @@ public slots:
static void info(const QString &message);
static void debug(const QString &message);
static void critical(const QString &message);
static void logPrint(const QString &message);
void setLogLevel(Level level);
static QString packInfoStr(QString msg);
static QString packDebugStr(QString msg);
static QString packErrorStr(QString msg);
static QString packWarnStr(QString msg);
private:
explicit Logger(QObject *parent = nullptr);
virtual ~Logger();
static void _log(const QString &message);
Q_DISABLE_COPY_MOVE(Logger)
private:

View File

@ -31,6 +31,29 @@ QAsParser::QAsParser(asIScriptEngine *engine)
addEnumCompletion(engine);
_buffer.clear();
_buffer.squeeze();
// generate keyword completion
_keywordNode = new QCodeNode;
_keywordNode->setNodeType(QCodeNode::Group);
QStringList kws{
"const", "in", "inout", "out", "auto", "public",
"protected", "private", "void", "int8", "int16", "int",
"int64", "uint8", "uint16", "uint", "uint64", "float",
"double", "bool", "enum", "string", "array", "any",
"for", "while", "do", "if", "else", "switch",
"break", "continue", "try", "catch", "throw", "abstract",
"delete", "cast", "class", "final", "property", "external",
"function", "interface", "shared", "this", "explicit", "override",
"namespace", "get", "set", "super", "mixin", "false",
"true", "null", "typename", "return", "typedef", "funcdef",
"from", "import", "not", "xor", "or", "is"};
for (auto &k : kws) {
auto knode = new QCodeNode;
knode->setParent(_keywordNode);
knode->setNodeType(QCodeNode::KeyWord);
knode->setRole(QCodeNode::Name, k.toUtf8());
_keywordNode->children().append(knode);
}
}
QAsParser::~QAsParser() {
@ -38,6 +61,7 @@ QAsParser::~QAsParser() {
_headerNodes.clear();
qDeleteAll(_nodes);
_nodes.clear();
delete _keywordNode;
}
QByteArray QAsParser::getFnParamDeclString(asIScriptFunction *fn,
@ -162,10 +186,10 @@ QByteArray QAsParser::getFnRetTypeString(asIScriptFunction *fn,
return {};
}
bool QAsParser::parse(qsizetype offset, const QString &code,
const QString &section) {
return ProcessScriptSection(code.toUtf8(), code.length(), section, 0);
}
// bool QAsParser::parse(qsizetype offset, const QString &code,
// const QString &section) {
// return ProcessScriptSection(code.toUtf8(), code.length(), section, 0);
// }
const QList<QCodeNode *> &QAsParser::headerNodes() const {
return _headerNodes;
@ -410,4 +434,6 @@ QCodeNode *QAsParser::newEnumCodeNode(const EnumInfo &info) {
return enode;
}
QCodeNode *QAsParser::keywordNode() const { return _keywordNode; }
QList<QCodeNode *> QAsParser::codeNodes() const { return _nodes; }

View File

@ -72,12 +72,15 @@ private:
QByteArray getFnRetTypeString(asIScriptFunction *fn, bool includeNamespace);
public:
bool parse(qsizetype offset, const QString &code, const QString &section);
// bool parse(qsizetype offset, const QString &code, const QString
// &section);
QList<QCodeNode *> codeNodes() const;
const QList<QCodeNode *> &headerNodes() const;
QCodeNode *keywordNode() const;
private:
void addGlobalFunctionCompletion(asIScriptEngine *engine);
void addEnumCompletion(asIScriptEngine *engine);
@ -96,6 +99,7 @@ private:
QHash<QString, QCodeNode *> _buffer;
QList<QCodeNode *> _headerNodes;
QCodeNode *_keywordNode;
};
#endif // !_QCPP_PARSER_H_

View File

@ -52,6 +52,7 @@ static QIcon icon(int cacheIndex) {
(*q_icon_cache)[ICON_CLASS] = getIcon(QStringLiteral("CVclass"));
// q_icon_cache[ICON_STRUCT] = QIcon(":/completion/CVstruct.png");
(*q_icon_cache)[ICON_KEYWORD] = getIcon(QStringLiteral("CVKeyword"));
(*q_icon_cache)[ICON_TYPEDEF] = getIcon(QStringLiteral("CVtypedef"));
@ -366,6 +367,9 @@ QVariant QCodeNode::data(int r) const {
// case Struct:
// return icon(ICON_STRUCT);
case KeyWord:
return icon(ICON_KEYWORD);
case Enum:
return icon(ICON_ENUM);

View File

@ -17,6 +17,7 @@
#include "scriptmachine.h"
#include "AngelScript/sdk/add_on/autowrapper/aswrappedcall.h"
#include "AngelScript/sdk/add_on/scriptany/scriptany.h"
#include "AngelScript/sdk/add_on/scriptarray/scriptarray.h"
#include "AngelScript/sdk/add_on/scriptdictionary/scriptdictionary.h"
@ -49,7 +50,7 @@ ScriptMachine::~ScriptMachine() {
bool ScriptMachine::inited() { return _engine != nullptr; }
bool ScriptMachine::isRunning() const { return _ctxMgr->isRunning(); }
bool ScriptMachine::isRunning() const { return _debugger->getEngine(); }
bool ScriptMachine::configureEngine(asIScriptEngine *engine) {
if (engine == nullptr) {
@ -1609,7 +1610,71 @@ void ScriptMachine::registerEngineAddon(asIScriptEngine *engine) {
RegisterScriptHandle(engine);
RegisterColor(engine);
RegisterScriptJson(engine);
RegisterExceptionRoutines(engine);
registerExceptionRoutines(engine);
registerEngineAssert(engine);
}
void ScriptMachine::registerEngineAssert(asIScriptEngine *engine) {
int r;
// The string type must be available
Q_ASSERT(engine->GetTypeInfoByDecl("string"));
if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0) {
r = engine->RegisterGlobalFunction("void assert(bool expression)",
asFUNCTION(scriptAssert),
asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"void assert_x(bool expression, const string &in msg)",
asFUNCTION(scriptAssert_X), asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
} else {
r = engine->RegisterGlobalFunction("void assert(bool expression)",
WRAP_FN(scriptAssert),
asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction(
"void assert_x(bool expression, const string &in msg)",
WRAP_FN(scriptAssert_X), asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
}
}
void ScriptMachine::scriptAssert(bool b) {
auto ctx = asGetActiveContext();
if (ctx) {
if (!b) {
QString buffer = tr("Assert failed");
ctx->SetException(buffer.toUtf8(), false);
}
}
}
void ScriptMachine::scriptAssert_X(bool b, const QString &msg) {
auto ctx = asGetActiveContext();
if (ctx) {
if (!b) {
auto m = msg;
if (m.isEmpty()) {
m = tr("Assert failed");
}
ctx->SetException(m.toUtf8(), false);
}
}
}
void ScriptMachine::scriptThrow(const QString &msg) {
asIScriptContext *ctx = asGetActiveContext();
if (ctx) {
ctx->SetException(msg.toUtf8());
}
}
bool ScriptMachine::isDebugMode() const {
@ -1750,3 +1815,49 @@ bool ScriptMachine::executeCode(const QString &code) {
return r >= 0;
}
QString ScriptMachine::scriptGetExceptionInfo() {
asIScriptContext *ctx = asGetActiveContext();
if (!ctx)
return {};
const char *msg = ctx->GetExceptionString();
if (msg == 0)
return {};
return QString(msg);
}
void ScriptMachine::registerExceptionRoutines(asIScriptEngine *engine) {
int r;
// The string type must be available
Q_ASSERT(engine->GetTypeInfoByDecl("string"));
if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0) {
r = engine->RegisterGlobalFunction("void throw(const string &in)",
asFUNCTION(scriptThrow),
asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction("string getExceptionInfo()",
asFUNCTION(scriptGetExceptionInfo),
asCALL_CDECL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
} else {
r = engine->RegisterGlobalFunction("void throw(const string &in)",
WRAP_FN(scriptThrow),
asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterGlobalFunction("string getExceptionInfo()",
WRAP_FN(scriptGetExceptionInfo),
asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
}
}

View File

@ -95,7 +95,19 @@ public:
void setInsteadFoundDisabled(bool newInsteadFoundDisabled);
static void registerEngineAddon(asIScriptEngine *engine);
static void registerEngineAssert(asIScriptEngine *engine);
public:
static void scriptAssert(bool b);
static void scriptAssert_X(bool b, const QString &msg);
static void scriptThrow(const QString &msg);
static QString scriptGetExceptionInfo();
static void registerExceptionRoutines(asIScriptEngine *engine);
public:
// debug or release?
bool isDebugMode() const;
void setDebugMode(bool isDbg);

View File

@ -150,21 +150,19 @@ void WingAngelAPI::registerScriptFns(const QString &ns,
void WingAngelAPI::installAPI(ScriptMachine *machine) {
Q_ASSERT(machine);
auto engine = machine->engine();
auto stringTypeID = machine->typeInfo(ScriptMachine::tString)->GetTypeId();
installBasicTypes(engine);
installExtAPI(engine);
installLogAPI(engine);
installMsgboxAPI(engine);
installInputboxAPI(engine, stringTypeID);
installInputboxAPI(engine);
installFileDialogAPI(engine);
installColorDialogAPI(engine);
installHexReaderAPI(engine);
installHexControllerAPI(engine);
installDataVisualAPI(engine, stringTypeID);
installDataVisualAPI(engine);
installScriptEnums(engine);
installScriptFns(engine);
@ -192,6 +190,85 @@ void WingAngelAPI::installBasicTypes(asIScriptEngine *engine) {
engine->SetDefaultNamespace("");
// QModelIndex
r = engine->RegisterObjectType("ModelIndex", sizeof(QModelIndex),
asOBJ_VALUE | asOBJ_POD |
asGetTypeTraits<QModelIndex>());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "ModelIndex parent() const",
asMETHOD(QModelIndex, parent),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "int row() const",
asMETHOD(QModelIndex, row),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "int column() const",
asMETHOD(QModelIndex, column),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
// extension function for data, we dont want to register QVariant to it
r = engine->RegisterObjectMethod("ModelIndex", "string dataString() const",
asFUNCTION(QModelIndex_dataString),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "char dataChar() const",
asFUNCTION(QModelIndex_dataChar),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "uint dataUInt() const",
asFUNCTION(QModelIndex_dataUInt),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "int dataInt() const",
asFUNCTION(QModelIndex_dataInt),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "int64 dataLongLong() const",
asFUNCTION(QModelIndex_dataLongLong),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod(
"ModelIndex", "uint64 dataULongLong() const",
asFUNCTION(QModelIndex_dataULongLong), asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "float dataFloat() const",
asFUNCTION(QModelIndex_dataFloat),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("ModelIndex", "double dataDouble() const",
asFUNCTION(QModelIndex_dataDouble),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterFuncdef(
"void ClickCallBack(const ModelIndex &in index)");
Q_ASSERT(r >= 0);
Q_UNUSED(r);
installHexBaseType(engine);
}
@ -312,7 +389,7 @@ void WingAngelAPI::installMsgboxAPI(asIScriptEngine *engine) {
engine->SetDefaultNamespace("");
}
void WingAngelAPI::installInputboxAPI(asIScriptEngine *engine, int stringID) {
void WingAngelAPI::installInputboxAPI(asIScriptEngine *engine) {
int r = engine->SetDefaultNamespace("inputbox");
Q_ASSERT(r >= 0);
Q_UNUSED(r);
@ -373,11 +450,10 @@ void WingAngelAPI::installInputboxAPI(asIScriptEngine *engine, int stringID) {
registerAPI<QString(const QString &, const QString &, const CScriptArray &,
int, bool, bool *, Qt::InputMethodHints)>(
engine,
std::bind(&WingAngelAPI::_InputBox_getItem, this, stringID,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4,
std::placeholders::_5, std::placeholders::_6,
std::placeholders::_7),
std::bind(&WingAngelAPI::_InputBox_getItem, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3,
std::placeholders::_4, std::placeholders::_5,
std::placeholders::_6, std::placeholders::_7),
"string getItem(const string &in title, const string &in label, "
"const string[] &in items, int current = 0, "
"bool editable = true, bool &out ok = false, "
@ -1186,7 +1262,7 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
engine->SetDefaultNamespace("");
}
void WingAngelAPI::installDataVisualAPI(asIScriptEngine *engine, int stringID) {
void WingAngelAPI::installDataVisualAPI(asIScriptEngine *engine) {
int r = engine->SetDefaultNamespace("visual");
Q_ASSERT(r >= 0);
Q_UNUSED(r);
@ -1199,28 +1275,35 @@ void WingAngelAPI::installDataVisualAPI(asIScriptEngine *engine, int stringID) {
std::placeholders::_1, std::placeholders::_2),
"bool updateText(string &in data, string &in title=\"\")");
registerAPI<bool(const CScriptArray &, const QString &)>(
registerAPI<bool(const CScriptArray &, const QString &, asIScriptFunction *,
asIScriptFunction *)>(
engine,
std::bind(&WingAngelAPI::_DataVisual_updateTextList, this, stringID,
std::placeholders::_1, std::placeholders::_2),
"bool updateTextList(string[] &in data, string &in title=\"\")");
registerAPI<bool(const QString &, const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::DataVisual::updateTextTree, datavis,
std::placeholders::_1, std::placeholders::_2,
WingHex::WingPlugin::DataVisual::ClickedCallBack(),
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack()),
"bool updateTextTree(string &in json, string &in title=\"\")");
registerAPI<bool(const QString &, const CScriptArray &,
const CScriptArray &, const QString &)>(
engine,
std::bind(&WingAngelAPI::_DataVisual_updateTextTable, this, stringID,
std::bind(&WingAngelAPI::_DataVisual_updateTextList, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4),
"bool updateTextList(string[] &in data, string &in title=\"\", "
"ClickCallBack @clickfn = null, ClickCallBack @dblclick = null)");
registerAPI<bool(const QString &, const QString &, asIScriptFunction *,
asIScriptFunction *)>(
engine,
std::bind(&WingAngelAPI::_DataVisual_updateTextTree, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4),
"bool updateTextTree(string &in json, string &in title=\"\", "
"ClickCallBack @clickfn = null, ClickCallBack @dblclick = null)");
registerAPI<bool(const QString &, const CScriptArray &,
const CScriptArray &, const QString &, asIScriptFunction *,
asIScriptFunction *)>(
engine,
std::bind(&WingAngelAPI::_DataVisual_updateTextTable, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4,
std::placeholders::_5, std::placeholders::_6),
"bool updateTextTable(string &in json, string[] &in headers, "
"string[] &in headerNames = {}, string &in title=\"\")");
"string[] &in headerNames = {}, string &in title=\"\", "
"ClickCallBack @clickfn = null, ClickCallBack @dblclick = null)");
engine->SetDefaultNamespace("");
}
@ -1992,6 +2075,38 @@ void WingAngelAPI::script_unsafe_call(asIScriptGeneric *gen) {
}
}
QString WingAngelAPI::QModelIndex_dataString(const QModelIndex &idx) {
return idx.data().toString();
}
QString WingAngelAPI::QModelIndex_dataChar(const QModelIndex &idx) {
return idx.data().toChar();
}
uint WingAngelAPI::QModelIndex_dataUInt(const QModelIndex &idx) {
return idx.data().toUInt();
}
int WingAngelAPI::QModelIndex_dataInt(const QModelIndex &idx) {
return idx.data().toInt();
}
qlonglong WingAngelAPI::QModelIndex_dataLongLong(const QModelIndex &idx) {
return idx.data().toLongLong();
}
qlonglong WingAngelAPI::QModelIndex_dataULongLong(const QModelIndex &idx) {
return idx.data().toULongLong();
}
float WingAngelAPI::QModelIndex_dataFloat(const QModelIndex &idx) {
return idx.data().toFloat();
}
double WingAngelAPI::QModelIndex_dataDouble(const QModelIndex &idx) {
return idx.data().toDouble();
}
bool WingAngelAPI::execScriptCode(const WingHex::SenderInfo &sender,
const QString &code) {
if (code.isEmpty()) {
@ -2176,20 +2291,29 @@ void WingAngelAPI::cleanUpHandles(const QVector<int> &handles) {
_handles = handles;
}
QString WingAngelAPI::_InputBox_getItem(int stringID, const QString &title,
QString WingAngelAPI::_InputBox_getItem(const QString &title,
const QString &label,
const CScriptArray &items, int current,
bool editable, bool *ok,
Qt::InputMethodHints inputMethodHints) {
bool o = false;
auto ret = cArray2QStringList(items, stringID, &o);
if (o) {
return WingInputDialog::getItem(nullptr, title, label, ret, current,
editable, ok, inputMethodHints);
} else {
*ok = false;
return {};
asIScriptContext *ctx = asGetActiveContext();
if (ctx) {
auto engine = ctx->GetEngine();
Q_ASSERT(engine);
auto stringID = engine->GetTypeIdByDecl("string");
Q_ASSERT(stringID >= 0);
bool o = false;
auto ret = cArray2QStringList(items, stringID, &o);
if (o) {
return WingInputDialog::getItem(nullptr, title, label, ret, current,
editable, ok, inputMethodHints);
} else {
*ok = false;
return {};
}
}
return {};
}
CScriptArray *WingAngelAPI::_FileDialog_getOpenFileNames(
@ -2394,40 +2518,82 @@ bool WingAngelAPI::_HexController_appendBytes(const CScriptArray &ba) {
return false;
}
return emit controller.appendBytes(bab);
} else {
return false;
}
return false;
}
bool WingAngelAPI::_DataVisual_updateTextList(int stringID,
const CScriptArray &data,
const QString &title) {
bool o = false;
auto ret = cArray2QStringList(data, stringID, &o);
if (o) {
return emit visual.updateTextList(ret, title);
} else {
return false;
bool WingAngelAPI::_DataVisual_updateTextList(const CScriptArray &data,
const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick) {
asIScriptContext *ctx = asGetActiveContext();
if (ctx) {
auto engine = ctx->GetEngine();
Q_ASSERT(engine);
auto stringID = engine->GetTypeIdByDecl("string");
Q_ASSERT(stringID >= 0);
// we dont call visual.updateTextList
bool o = false;
auto ret = cArray2QStringList(data, stringID, &o);
if (o) {
ClickCallBack c(engine, click);
ClickCallBack dblc(engine, dblclick);
return PluginSystem::instance().updateTextList_API(ret, title, c,
dblc);
}
}
return false;
}
bool WingAngelAPI::_DataVisual_updateTextTable(int stringID,
const QString &json,
bool WingAngelAPI::_DataVisual_updateTextTree(const QString &json,
const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick) {
asIScriptContext *ctx = asGetActiveContext();
if (ctx) {
auto engine = ctx->GetEngine();
Q_ASSERT(engine);
// we dont call visual.updateTextTree
ClickCallBack c(engine, click);
ClickCallBack dblc(engine, dblclick);
return PluginSystem::instance().updateTextTree_API(json, title, c,
dblc);
}
return false;
}
bool WingAngelAPI::_DataVisual_updateTextTable(const QString &json,
const CScriptArray &headers,
const CScriptArray &headerNames,
const QString &title) {
bool o = false;
auto h = cArray2QStringList(headers, stringID, &o);
if (o) {
auto hn = cArray2QStringList(headerNames, stringID, &o);
const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick) {
asIScriptContext *ctx = asGetActiveContext();
if (ctx) {
auto engine = ctx->GetEngine();
Q_ASSERT(engine);
auto stringID = engine->GetTypeIdByDecl("string");
Q_ASSERT(stringID >= 0);
// we dont call visual.updateTextTable
bool o = false;
auto h = cArray2QStringList(headers, stringID, &o);
if (o) {
return emit visual.updateTextTable(json, h, hn, title);
} else {
return false;
auto hn = cArray2QStringList(headerNames, stringID, &o);
if (o) {
ClickCallBack c(engine, click);
ClickCallBack dblc(engine, dblclick);
return PluginSystem::instance().updateTextTable_API(
json, h, hn, title, c, dblc);
}
}
} else {
return false;
}
return false;
}
void WingAngelAPI::setBindingConsole(ScriptingConsole *console) {

View File

@ -70,6 +70,7 @@ public:
void installBasicTypes(asIScriptEngine *engine);
void setBindingConsole(ScriptingConsole *console);
void unBindConsole();
static QString qvariantCastASString(const QMetaType::Type &id);
@ -89,13 +90,13 @@ private:
void installLogAPI(asIScriptEngine *engine);
void installExtAPI(asIScriptEngine *engine);
void installMsgboxAPI(asIScriptEngine *engine);
void installInputboxAPI(asIScriptEngine *engine, int stringID);
void installInputboxAPI(asIScriptEngine *engine);
void installFileDialogAPI(asIScriptEngine *engine);
void installColorDialogAPI(asIScriptEngine *engine);
void installHexBaseType(asIScriptEngine *engine);
void installHexReaderAPI(asIScriptEngine *engine);
void installHexControllerAPI(asIScriptEngine *engine);
void installDataVisualAPI(asIScriptEngine *engine, int stringID);
void installDataVisualAPI(asIScriptEngine *engine);
void installScriptFns(asIScriptEngine *engine);
void installScriptUnSafeFns(asIScriptEngine *engine);
void installScriptEnums(asIScriptEngine *engine);
@ -155,6 +156,16 @@ private:
static void script_unsafe_call(asIScriptGeneric *gen);
private:
static QString QModelIndex_dataString(const QModelIndex &idx);
static QString QModelIndex_dataChar(const QModelIndex &idx);
static uint QModelIndex_dataUInt(const QModelIndex &idx);
static int QModelIndex_dataInt(const QModelIndex &idx);
static qlonglong QModelIndex_dataLongLong(const QModelIndex &idx);
static qlonglong QModelIndex_dataULongLong(const QModelIndex &idx);
static float QModelIndex_dataFloat(const QModelIndex &idx);
static double QModelIndex_dataDouble(const QModelIndex &idx);
private:
WING_SERVICE bool execScriptCode(const WingHex::SenderInfo &sender,
const QString &code);
@ -192,9 +203,9 @@ private:
void cleanUpHandles(const QVector<int> &handles);
private:
QString _InputBox_getItem(int stringID, const QString &title,
const QString &label, const CScriptArray &items,
int current, bool editable, bool *ok,
QString _InputBox_getItem(const QString &title, const QString &label,
const CScriptArray &items, int current,
bool editable, bool *ok,
Qt::InputMethodHints inputMethodHints);
CScriptArray *_FileDialog_getOpenFileNames(const QString &caption,
@ -229,13 +240,22 @@ private:
bool _HexController_appendBytes(const CScriptArray &ba);
bool _DataVisual_updateTextList(int stringID, const CScriptArray &data,
const QString &title);
private:
bool _DataVisual_updateTextList(const CScriptArray &data,
const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick);
bool _DataVisual_updateTextTable(int stringID, const QString &json,
bool _DataVisual_updateTextTree(const QString &json, const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick);
bool _DataVisual_updateTextTable(const QString &json,
const CScriptArray &headers,
const CScriptArray &headerNames,
const QString &title);
const QString &title,
asIScriptFunction *click,
asIScriptFunction *dblclick);
private:
std::vector<std::any> _fnbuffer;

View File

@ -16,6 +16,7 @@
*/
#include "scriptingconsole.h"
#include "class/logger.h"
#include "class/scriptconsolemachine.h"
#include "qregularexpression.h"
@ -51,25 +52,48 @@ void ScriptingConsole::init() {
connect(_sp, &ScriptConsoleMachine::onOutput, this,
[=](ScriptConsoleMachine::MessageType type,
const ScriptConsoleMachine::MessageInfo &message) {
switch (type) {
case ScriptMachine::MessageType::Info:
stdOut(tr("[Info]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Warn:
stdWarn(tr("[Warn]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Error:
stdErr(tr("[Error]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Print:
stdOut(message.message);
break;
// If running ouput in the console,
// otherwise logging.
if (_sp->isRunning()) {
switch (type) {
case ScriptMachine::MessageType::Info:
stdOut(tr("[Info]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Warn:
stdWarn(tr("[Warn]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Error:
stdErr(tr("[Error]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Print:
stdOut(message.message);
break;
}
} else {
switch (type) {
case ScriptMachine::MessageType::Info:
Logger::logPrint(Logger::packInfoStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Warn:
Logger::logPrint(Logger::packWarnStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Error:
Logger::logPrint(Logger::packErrorStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Print:
Logger::logPrint(Logger::packDebugStr(
packUpLoggingStr(message.message)));
break;
}
}
});
@ -155,6 +179,10 @@ QString ScriptingConsole::getInput() {
return instr;
}
QString ScriptingConsole::packUpLoggingStr(const QString &message) {
return tr("[Console]") + message;
}
void ScriptingConsole::keyPressEvent(QKeyEvent *e) {
if (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_L) {
clearConsole();

View File

@ -58,6 +58,8 @@ private:
QString getInput();
QString packUpLoggingStr(const QString &message);
protected:
void keyPressEvent(QKeyEvent *e) override;

View File

@ -38,6 +38,7 @@
#include "QWingRibbon/ribbontabcontent.h"
#include "Qt-Advanced-Docking-System/src/DockManager.h"
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "class/clickcallback.h"
#include "class/recentfilemanager.h"
#include "class/scriptmanager.h"
#include "class/wingprogressdialog.h"
@ -61,9 +62,8 @@ class MainWindow : public FramelessMainWindow {
friend class PluginSystem;
using ClickedCallBack = WingHex::WingPlugin::DataVisual::ClickedCallBack;
using DblClickedCallBack =
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack;
using ClickedCallBack = ClickCallBack;
using DblClickedCallBack = ClickCallBack;
public:
explicit MainWindow(SplashDialog *splash);

View File

@ -1392,6 +1392,77 @@ void PluginSystem::registerPluginPages(IWingPluginBase *p) {
}
}
bool PluginSystem::updateTextList_API(const QStringList &data,
const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick) {
auto oldmodel = _win->m_infolist->model();
if (oldmodel) {
oldmodel->deleteLater();
}
_win->m_infolist->setProperty("__TITLE__", title);
auto model = new QStringListModel(data);
_win->m_infolist->setModel(model);
_win->m_infoclickfn = click;
_win->m_infodblclickfn = dblclick;
return true;
}
bool PluginSystem::updateTextTree_API(const QString &json, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick) {
auto oldmodel = _win->m_infotree->model();
if (oldmodel) {
oldmodel->deleteLater();
}
_win->m_infotree->setProperty("__TITLE__", title);
auto model = new QJsonModel;
if (model->loadJson(json.toUtf8())) {
_win->m_infotree->setModel(model);
_win->m_infotreeclickfn = click;
_win->m_infotreedblclickfn = dblclick;
return true;
}
return false;
}
bool PluginSystem::updateTextTable_API(const QString &json,
const QStringList &headers,
const QStringList &headerNames,
const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick) {
auto oldmodel = _win->m_infotable->model();
if (oldmodel) {
oldmodel->deleteLater();
}
QJsonTableModel::Header header;
if (headers.size() > headerNames.size()) {
for (auto &name : headers) {
QJsonTableModel::Heading heading;
heading["index"] = name;
heading["title"] = name;
header.append(heading);
}
} else {
auto np = headerNames.cbegin();
for (auto p = headers.cbegin(); p != headers.cend(); ++p, ++np) {
QJsonTableModel::Heading heading;
heading["index"] = *p;
heading["title"] = *np;
header.append(heading);
}
}
_win->m_infotable->setProperty("__TITLE__", title);
auto model = new QJsonTableModel(header);
model->setJson(QJsonDocument::fromJson(json.toUtf8()));
_win->m_infotable->setModel(model);
_win->m_infotableclickfn = click;
_win->m_infotabledblclickfn = dblclick;
return true;
}
void PluginSystem::connectInterface(IWingPlugin *plg) {
connectReaderInterface(plg);
connectControllerInterface(plg);
@ -2829,16 +2900,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
-> bool {
auto oldmodel = _win->m_infolist->model();
if (oldmodel) {
oldmodel->deleteLater();
}
_win->m_infolist->setProperty("__TITLE__", title);
auto model = new QStringListModel(data);
_win->m_infolist->setModel(model);
_win->m_infoclickfn = clicked;
_win->m_infodblclickfn = dblClicked;
return true;
return updateTextList_API(data, title, clicked, dblClicked);
});
connect(
visual, &WingPlugin::DataVisual::updateTextListByModel, _win,
@ -2865,19 +2927,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
-> bool {
auto oldmodel = _win->m_infotree->model();
if (oldmodel) {
oldmodel->deleteLater();
}
_win->m_infotree->setProperty("__TITLE__", title);
auto model = new QJsonModel;
if (model->loadJson(json.toUtf8())) {
_win->m_infotree->setModel(model);
_win->m_infotreeclickfn = clicked;
_win->m_infotreedblclickfn = dblClicked;
return true;
}
return false;
return updateTextTree_API(json, title, clicked, dblClicked);
});
connect(
visual, &WingPlugin::DataVisual::updateTextTreeByModel, _win,
@ -2905,36 +2955,8 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
-> bool {
auto oldmodel = _win->m_infotable->model();
if (oldmodel) {
oldmodel->deleteLater();
}
QJsonTableModel::Header header;
if (headers.size() > headerNames.size()) {
for (auto &name : headers) {
QJsonTableModel::Heading heading;
heading["index"] = name;
heading["title"] = name;
header.append(heading);
}
} else {
auto np = headerNames.cbegin();
for (auto p = headers.cbegin(); p != headers.cend();
++p, ++np) {
QJsonTableModel::Heading heading;
heading["index"] = *p;
heading["title"] = *np;
header.append(heading);
}
}
_win->m_infotable->setProperty("__TITLE__", title);
auto model = new QJsonTableModel(header);
model->setJson(QJsonDocument::fromJson(json.toUtf8()));
_win->m_infotable->setModel(model);
_win->m_infotableclickfn = clicked;
_win->m_infotabledblclickfn = dblClicked;
return true;
return updateTextTable_API(json, headers, headerNames, title,
clicked, dblClicked);
});
connect(
visual, &WingPlugin::DataVisual::updateTextTableByModel, _win,

View File

@ -29,6 +29,7 @@
#include <QToolButton>
#include <QVariant>
#include "class/clickcallback.h"
#include "class/wingangelapi.h"
#include "control/editorview.h"
#include "plugin/iwingdevice.h"
@ -257,6 +258,18 @@ private:
void registerPluginDockWidgets(IWingPluginBase *p);
void registerPluginPages(IWingPluginBase *p);
public:
bool updateTextList_API(const QStringList &data, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTree_API(const QString &json, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTable_API(const QString &json, const QStringList &headers,
const QStringList &headerNames,
const QString &title, const ClickCallBack &click,
const ClickCallBack &dblclick);
private:
template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {

View File

@ -46,8 +46,6 @@ QDocumentSwapTextCommand::QDocumentSwapTextCommand(const QString &text,
}
auto cursor = doc->editCursor();
_line = cursor->lineNumber();
_column = cursor->columnNumber();
setTargetCursor(cursor->handle());
}

View File

@ -36,8 +36,6 @@ private:
QList<QDocumentLineHandle *> _handles;
QList<QDocumentLineHandle *> _oldhandles;
QVector<DiffUtil::DiffEntry> diffs;
int _line, _column;
};
#endif // QDOCUMENTSWAPTEXTCOMMAND_H